Category Archives: Uncategorized

TX Module is here!

Following on from the ‘The First PCB’, my TX module PCBs arrived from China this week and I excitedly wired one up. Well, right up to the point that I realised I’d ran out of 16Mhz crystals! (Needed to run the Arduino/Atmega 328 at full speed) So a frustrating couple of days followed whilst I waited for my trusty eBay vendor to despatch the goods. Here’s the bare PCB:

IMG_20160413_205607

Anyway, Wednesday arrived and my precious crystals were waiting behind the front door in a padded envelope, here’s the completed PCB in all it’s glory:

IMG_20160413_205634

Of course, it wouldn’t do to not show the PCB working so here you go:

Start Light LED clusters have arrived!

I did promise this project would be non-linear and so it is turning out! I complete parts of the project as I find the time, and to be totally honest, as the fancy takes me. It’s my project and my spare time, after all.

Anyway, after learning that I shouldn’t use a very hot soldering iron on my original start light LED clusters, I went back to the drawing board and decided to make them as large as possible within the 5cm x 5cm limit I had set myself (this is the limit of PCB size that most of the Chinese PCB manufacturers will do for $10!). So here’s the bare board:

IMG_20160413_204436

And here’s one populated with components:

IMG_20160413_204449

 

4-digit 7-segment displays

When I was thinking of all the different ways I could display the race information, I quite liked the idea of these little displays:

TM1637

However, in reality they are REALLY tiny and about the same price as the 8×32 LED matrix displays seen earlier in this blog. There’s kind of no point pursuing this avenue as I don’t see anyone wanting a display of this type, but just to show you one working, here goes!

LED Matrix Displays

This project has a few strands but the basic conecpt of what I want is:

  • Red and Green lights that illuminate at the start and end of the race
  • Timing information displayed

This post is about the display of timing information. I’m looking at several sizes of display; from handheld devices which may be handy for long Nitro races to large wall-mounted timing displays. In this post I’m going to look at these small, 8×32 LED matrix displays.

The pictures kind of lie to you. It looks maybe 22cm long? It’s not. It’s about 15cm, maybe less. So it’s not very big – however that makes it ideal for putting on your pit-table. So that’s what these displays are going to do.

Since the size and resolution of the display limits me in what information I can display, I’ve figured out how to switch between virtual ‘screens’ which display different information. In the first video you can see the display switching between the round/heat information and the time elapsed information:

As a request from a friend following my RCIB Facebook group, I connected two of these displays together to show all the infomartion being shown at once:

The code is up on Github for anyone following along! Wiring instructions are in the description at the top of the code listing.

Coding almost complete

So now, in February 2016, I am finally at the point where I have the code 99% complete. I have a prototype system up and working, in which there is a TX device (which has inputs of race information and start light information) and two RX devices (one which displays race info and the other which displays red/green start lights). The working prototype is in the video below (there is a fault on one of the TPIC6B595s which means that one of the red LEDs is constantly illuminated):

I have attached the code for the devices in the ‘Download’ tab in the Navigation Menu above. Just download this, unzip the folder then open it in the Arduino IDE and upload to your Arduino. You can find explanations of the prototype code, prototype wiring diagrams and schematics in the section relevant to each device.

A recap

As mentioned in the first post of this blog, I have a full time job (and a young family) as well as helping out at my local model car club, so for all these reasons, sometimes life takes over and these projects take a back seat. However, recently I’ve had the urge again to get on with this project and see where I can get with it.

So let me take you back first to 2014 & 2015, a quick recap as it were. I’d started this blog in which I was trying to explain what I wanted to do (the requirements) and the high-level explanation of how I was going to do it (the algorithm in coding terms). At the same time as this was happening, I was getting some actual code in to my programming platform (the Arduino) to see what I could get from the PC running RC-Timing.

RC-Timing (and other RC timing programs) outputs race information and start lights information on serial (COM) ports, so to find out what info I could get from RC-Timing, I needed code that would read the incoming data on the serial port and let me see it.

This first piece of code just used the Arduino Serial Event tutorial mixed with the use of the Liquid Crystal library to report what the serial port was getting from RC-Timing. I could see that I was getting data in the format:

[RdNo:HtNo:MM:SS:etc etc]

After an email from Dale Burr (who is the developer of RC-Timing) I learned the format is thus:

[roundno:raceno:minutes:seconds:car1,carN,:laps1,lapsN,:improver1,improverN,:]

At this time, I hacked together a program that used a mess of loops and nested IF statements that let me extract the various bits of data from the string above. It really was a mess and, thank goodness, I’ve learned a lot since then and tidied it up a lot. Anyway, soon enough I had this working:

Soon enough, I was already thinking about the LED 7-segment displays I wanted to use for the board. I ended up making my own using some foamboard and lots of 5mm LEDs. Changing the output code from LCD library calls to ShiftOut calls although I have to say I used a TPIC6B595 shift register rather than the 74HC595 in the tutorial due to the amount of current needed to drive the LEDs. This tutorial by Mika Tuupola helped me translate the pinouts between the two different shift registers. Anyway, this next video is a quick demo of the ‘seconds’ display in action:

And with that done, the project kind of stalled there. Life took over and then early in 2015 I was busy helping out at the club. I didn’t really pick the project up again until after the outdoor season had finished in late 2015.

The Arduino Program – Initial Pseudocode / Algorithm

From an earlier post, let’s recap what we need the Arduino to do – it needs to read in data given to it by the RC timing program, process it, and pass it out on the Arduino’s output pins (to the 74HC595 shift registers but more about them another time).

So we know what it has to do. Now we need to figure out how to code it. In order to help us to do this, I’m going to use a thing called pseudocode. Pseudocode is NOT code – this won’t work as a program. It’s almost code – it describes in detail what the program will do, in terms that we can all understand.

So start off with, I guess I should explain that any Arduino program MUST have at least two functions – the SETUP function and the LOOP function. The SETUP function runs once and we can perform actions there to set the board up in it’s initial state. The LOOP function runs over and over (it LOOPs round on itself and starts over). We will use other functions also, and I’ll explain what these do as we go on.

SETUP function

1) Set the board up in it’s initial state (LEDs all OFF? Or everything set to 0?)

2) Open the USB port to listen for output from the RC timing program

 

LOOP function

If (we find out that something from the timing output has changed) Then

     Update the Board

Otherwise Do Nothing

 

SERIAL INPUT FUNCTION (this runs whenever new data comes in via USB)

Get the data

If (the Data is for Time Elapsed) Then

     Store this data with a label saying TimeElapsed

If (the Data is for Round Number) Then

     Store this with a label saying RoundNumber

If (the Data is for Heat Number) Then

     Store this with a label saying HeatNumber

Tell the Loop function that something from the timing output has changed

 

UPDATE THE BOARD function

Find out what data has changed

If it’s for Time Elapsed Then

     Find out what the data is for TimeElapsed

     Change it into the correct format for the TimeElapsed shift registers

     Push it out on the Arduino Output Pins

If it’s for Round Number Then

     Find out what the data is for RoundNumber

    Change it into the correct format for the RoundNumber shift registers

     Push it out on the Arduino Output Pins

If it’s for Time Elapsed Then

     Find out what the data is for HeatNumber

     Change it into the correct format for the Heat Number shift registers

     Push it out on the Arduino Output Pins

 

That’s it so far, I’m sure this pseudocode is a) incomplete and b) wrong by some programming purist’s standards, but I don’t really care. What it does do is it informs the structure of my code. This will be my starting point. Actually – it won’t be quite be my starting point as I’ll be coding other programs in the meantime to accomplish tasks such as:

a) Working out what information the RC timing program is giving us

b) Testing the circuit designs for our 7-segment displays

 

In my next blog, I’m probably going to start discussing the 7-segment displays and how exactly I envision them working.

The Design (A brief outline)

In the last blog, I briefly explained the objectives of the project. Numbers 1 to 3 can be seen as being the ‘Arduino-side’ of the project; data input, processing, and output. No 4 is the ‘display-hardware’ side of the project. So we have two main areas to design.

1) The Arduino side

This part of the project takes the output of the RC timing program as an input via the Arduino’s serial communications port (USB). It then processes the information (deciding whether the information relates to time elapsed, or round number, or heat number etc) then passing the information to a process which will then convert the information into a form that the display hardware can use. Lastly, it pushes the processed information out via the Arduino’s output pins.

Looking at this closer, there are several things for me to find out.

a) How do I get information into the Arduino via USB?

b) Once I’ve done that, how do I get information into the Arduino from a RC timing program?

c) What does the display board output of an RC timing program look like?

d) How do I process the information received by the Arduino?

e) How often do I process it and how do I code the frequency at which I process it?

f) What form should my processed information take? (i.e. what are the requirements of my display hardware?)

g) How do I push the information to the display hardware via the output pins? And how often do I do this?

 

2) The Display Hardware side

Assuming I can code the Arduino correctly, I should be looking at dealing with the processed information coming out towards my display hardware on the Arduino’s output pins. As mentioned previously the initial objective is to design and construct a board that displays:

Round Number (1 digit)

Heat Number (2 digits – although the second (tens) digit only needs to display the number 1 when required)

Time Elapsed in race / Time remaining to next heat (4 digits)
In the interests of (mainly) keeping the project as cheap as possible, I’m looking at use an array of standard high brightness LEDs to mimic the operation of a 7-segment display. Each 7-segment display will be around 8 inches high, and each of the 7 segments will use 4 LEDs. So we’re looking at 28 LEDs for each digit. Looking at our initial requirement, we need 7 digits, plus 2 segments to show the number 1 for heat numbers.

Doing the math for a second – 28 LEDs per digit, 7 digits required = 28 x 7 = 196 LEDs + 8 LEDs (2 segments @ 4 LEDs each for the second digit of Heat Numbers) = 204 LEDs

This brings up the next point to consider – these LEDs consume 20mA of current each, so 204 LEDs are going to consume just over 4A between them. This is way beyond the output capabilities of an Arduino output pin, so a power supply external to the Arduino will be needed to drive the LEDs. This brings me to a choice in my circuit design, do I drive the LEDs in each segment in series or parallel? If I drive them in parallel, I need lots of resistors to give current protection, whereas as a series circuit would enable me to use one resistor in series with the 4 LEDs. I’ve decided to drive the LEDs in series, this saves time, expense and simplifies the circuit. This means I need a power supply higher than 8.4V

Having looked online for what power supplies are available, it seems 12v power supplies are pretty commonplace and also cheap, so I’ll be using a 12V supply in this project and will therefore base my calculations on 12V.

7 digits = 7 x 7 segments = 49 individual segments. The Arduino cannot support switching this many individual components with the pin headers it has, so we need to look at how to achieve switching these segments without using as many wires! I’ve decided to use the 74HC595 shift register to achieve this. It allows me to drive an entire digit on the display, at the cost of 3 output pins on the Arduino. But it gets better still – it’s possible to daisy-chain the shift registers together to drive more digits for the same pin cost at the Arduino. So our time elapsed display (4-digits) will use 4 shift registers daisy-chained together all whilst using only 3 pins on the Arduino. More on the 74HC595 shift register in a later post.

Coming back to the power all those LEDs are consuming. We know the Arduino can’t output the power we need to drive the LEDs, and neither can the shift registers. That’s why we’re using an external supply. Well, we still need a way to have the Arduino switch the LED segments on and off as required. To do this, I’ve decided to use a NPN transistor (PN2222) to switch the LED segments on. So the voltage that the Arduino (and hence the shift register) supplies on the output pins will switch the transistor to allow 12v through the segments and the collector to the emitter and ground, lighting the segment.

Anyway, I realise this post is quite long and quite haphazard in it’s structure – this has been more about me putting my thoughts down about how the implementation looks in my head. In later posts I will explore all these individual areas seperately and in better detail (with circuit diagrams!)

The Objectives

Obviously, the end aim is to produce a working RC Race Information Display board. There’s a long way to go to that, though, and a lot of basic aims need to be met first. So we’ll be taking small steps (“baby steps”) all the way. Let’s look at what the board does.

At it’s most basic level, it takes information from the RC timing program, does some processing on it, and then updates the board with the information received. So there are our three of the four main areas of work. I’ll go into each of these in detail in later posts. But a brief description of the objectives for each work area is probably helpful.

1) Take input from RC timing program

The first objective here is to have the Arduino read in data via USB. Then, once we have demonstrated that this is possible, we need to get the RC timing program and the Arduino talking to each other. After that, we need to get the RC timing program to pass the Arduino some data, and finally, we want the Arduino to store the information passed to it for further processing.

2) Process the information/data

What we need to do here is to identify the type of data that has been read in (e.g. time elapsed in race) , and then to convert it to a format which the display hardware will understand.

3) Update the board

This is where we take the processed information and load it into the hardware that will display the information on the board. We then ‘flick the switch’ and update the board with the information.

4) Design & Operate the display hardware

This is the basic electronics end of the project. LEDs, Shift Registers, transistor, resistors, capacitors etc. Don’t worry if you don’t know what that means right now.

Disclaimer

I aplogise in advance – I will definitely not be tackling each phase of the project in the order you see above. It is after all my I’ll be experimenting with things as I go along and with ideas as they come to me, so although there is a basic structure to the project, it’s growth may be somewhat organic! I’ll refer to these four area whenever I post

The Analysis

I suppose the first thing I should do is to explain what an ‘RC race information board’ does.

Well it’s self-explanatory I suppose, it displays information about RC races. It shows things like time elapsed in the race, which heat of which round is being run, and sometimes has other information like: number of laps that the leader has completed, and race positions (i.e. 1st – car number 3, 2nd – car number 2, etc).

So the analysis is very simple. What are my requirements? I need to identify what RC race information I want to display.

Having given it some thought, my initial requirements are:

Current Round Number

Current Heat Number

Time Elapsed in current race / time to next race

Car Positions (Car 1 to Car 10)

 

 

Looking at it a little further, I also need to work out how many digits each I need for each piece of information.

Current Round Number

Round number only requires 1 digit as I do not envisage ever running more than 9 rounds of qualifying!

Current Heat Number

Heat Number requires 2 digits as we sometimes run up to 12 heats. The 2nd (tens) digit only needs to display the number 1 as we will never run more than 19 heats in a single round!

Time Elapsed in current race / time to next race

Time elapsed needs to be 4 digits. Our club runs Nitro/Gas meetings where we regularly run 30 minute finals so we need to be able to display this. This should be in the format MM:SS

Car Positions (Car 1 to Car 10)

This can either be single digit (numbers 1 through 0 for cars 1 to 10) or 2-digit (with the second (tens) digit displaying the number 1 when required. The display of car positions is not essential, and also takes a lot of space to display, so this will be tackled at a later stage in the project. Rest assured though, it will be tackled.