0% found this document useful (0 votes)
3 views

RC and Arduino Setup

Uploaded by

DeathKX
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

RC and Arduino Setup

Uploaded by

DeathKX
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

Race Coordinator Arduino Connection.

I’ve been looking in to connecting Arduino lights to Race Coordinator on my layout and it
seems to me that there is a lot of information out there in Slot Forum but it takes a bit of
hunting down to get all the relevant bits together. So this is my attempt to to do so. It’s not
exhaustive, as I don’t have all the components that are listed as options; I have only digital
Scalextrics and can’t test analogue; and I don’t have a great deal to go on using the code.
However, I see it as a working document that I am happy for others to complete, if they are
able to do so. I’m also going to shamelessly plagiarise and paraphrase what I have found on
the Forum, so a lot of what I put here is not my content, though I may change it to my
requirements.

I want to start at the beginning and I assuming that interested people don’t have prior
knowledge of Arduino and configuration of RC (as I didn’t when I started looking in to it).

I read somewhere that Dave (Race Coordinator guru) was willing to host a document like this
on his website and I am happy with that, if he wants.

Please feel free to edit, add contradict, correct anything of the following posts, as I am pretty
new to it all and I feel sure that there are many mistakes and gaps in my knowledge.

I'll also attach this as a document, so that you can read it 'offline'.

Connal
What Is Arduino?

Essentially it is a micro-computer, similar to a Raspberry Pi and others. They are small


circuit boards with a micro-processor, memory, input-output channels and some supporting
hardware like a power regulator. Users can store programme instructions in the memory
and the micro-processor will execute those instructions. The instructions are known as a
script, or in Arduino-speak, a ’sketch’. A two-way USB interface is provided for linking to a
PC for sending the sketch into memory and/or communication with software on the PC.
What Can It Do (As Far As Race Coordinator Is Concerned)?

Inputs can come from switches, Infra-Red diodes, raw contacts, etc.

The instructions can be simple things to turn on/off LEDs, turn power on/off to the track
(analogue only), detect laps (analogue only), detect pit stops, fuel indicators, etc.

Writing/coding the script can be quite complex but adding LEDs and switches to the
hardware is easy enough, particularly with Race Coordinator.

Which Arduinos Are Supported?

Uno (and clones)


Mega (and clones)
Viasue Hub
How Do I Wire Up The Arduino?

At its most basic, the layout is as follows:

All of this will be explained in more details later but, in summary;

On the PC, you will have the Race Coordinator programme of choice: RC Analogue, RC
Digital or Drag RC.

The PC connects to the Arduino through (normally, these days) a USB port, to which is
assigned a ‘Com’ port.

On the Arduino is the ‘sketch’ or code for the Arduino and it controls the flow of information
to and from the PC and track and/or lights.

From the Arduino, physical connections are made to the track, LEDs or other devices.
Wiring for track relays and Single LEDs (not addressable strips):

This is a diagram for four analogue lanes, plus lights and bluetooth connection.

The power supply is regulated 14.2v, to power all four lanes.


The Arduino should be powered separately.
The yellow, red, white and blue LED'S tells who is leading the race.
The five red lights are the start lights.
On the left are four relay board designed to work with Arduino, 5v relay coils.
The devices at the top are the controller hookup points (3 connections).
The button is a track call

Below is taken from “Arduino Uno and Race Coordinator.pdf”, which can be located in
C:\Program Files (x86)\Race Coordinator\data\arduino\lapCounter
or
C:\Program Files (x86)\Race Coordinator Digital\data\arduino\lapCounter
Details on different types of alternative sensors can be found in this document.
Connecting LED Individually Addressable Strip Lights

Notes:
To minimise current drain on the Arduino, connect a separate power supply (5v or 12v,
depending on the LED strip) and ensure that the Ground (Earth) is connected between the
two.

The resistor and the capacitor are not strictly needed but they are good ‘insurance’, as the
Arduino is very sensitive to EMI and car noise. Make sure you get the polarity of the
capacitor correct. Negative has a string of ‘-’ down one side.

For connection of up to four addressable LED strips, A0-A3 are set as default within the
Arduino sketch. These correspond to Led Strings 1,2,3 and 4 on the RC (see later)

Connecting 4 wire LED strips looks a lot more complicated. Probably best to avoid.
Arduino Set Up and Configuration

You can find more detailed steps online, if you need them.

Step 1 − Connect the USB/printer cable between pc and Arduino.

Step 2 − Download Arduino IDE Software.


https://www.arduino.cc/en/software
Step 3 − Power up your board.
Step 4 − Launch Arduino IDE.
Step 5 − Select your Arduino board.
To avoid any error while uploading your program to the board, you must select the correct
Arduino board name, which matches with the board connected to your computer.
Go to Tools → Board and select your board.
Here, we have selected Arduino Uno board according to our tutorial, but you must select
the name matching the board that you are using.

Step 6 − Add the FastLED library


On the IDE’s menu go to Sketch>Include Library>Manage Libraries.
● In the Library Manager window, type FastLED in the search box.
● When FastLED appears, click on Install.

Step 7 − Select your serial port.


Select the serial device of the Arduino board. Go to Tools → Serial Port menu. This is
likely to be COM3 or higher (COM1 and COM2 are usually reserved for hardware serial
ports). To find out, you can disconnect your Arduino board and re-open the menu, the
entry that disappears should be of the Arduino board. Reconnect the board and select that
serial port.

Step 8 − Upload the programme to your board.

Click on File/Open and navigate to the RC Arduino folder (usually C:\Program Files
(x86)\Race Coordinator\data\arduino\lapCounter and select lapCounter.ino
The sketch takes care of pretty much everything for an initial set up but there are a couple
of basic things that need to be configured.
NOTE: The version at the time of writing is V1.0.0.12 (though it shows V1.0.0.11 on line 4
of the sketch.
To make life a bit easier, click on File/Preferences and tick ‘Display line numbers’ and click
OK.
On line 34, uncomment the #define WITH_FAST_LED.

The default for the LED strings is to use pins A0-A3. If you do not use these pins, you will
need to redefine the in this section (lines 164-167, on the current version of the sketch).
Don’t change the MAX_RGB_LED_STRINGS, even if you don’t use them all.

#ifdef WITH_FAST_LED
// RGB pixels
#define MAX_RGB_LED_STRINGS 4
#define STRING_PIN_1 A0
#define STRING_PIN_2 A1
#define STRING_PIN_3 A2
#define STRING_PIN_4 A3

On lines 171 to 181 are the LED strips that are currently supported.

// #define LED_TYPE_1 TM1803


// #define LED_TYPE_1 TM1804
// #define LED_TYPE_1 TM1809
// #define LED_TYPE_1 WS2811
// #define LED_TYPE_1 WS2812
// #define LED_TYPE_1 WS2812B
// #define LED_TYPE_1 APA104
// #define LED_TYPE_1 UCS1903
// #define LED_TYPE_1 UCS1903B
// #define LED_TYPE_1 GW6205
// #define LED_TYPE_1 GW6205_400

Find your one and ensure that lines 183 to 186 have the correct type. Default is WS2811,
as it is the most common.

#define LED_TYPE_1 WS2811


#define LED_TYPE_2 WS2811
#define LED_TYPE_3 WS2811
#define LED_TYPE_4 WS2811

If you have Neopixels, then leave lines 196 to 199 as is. If you don’t, remove the ‘//’ from
lines 191 to 194 and add the, to lines 196 to 199.
//#define SETUP_LED_1(leds, numLeds) FastLED.addLeds<LED_TYPE_1,
STRING_PIN_1, RGB>(leds, numLeds);
//#define SETUP_LED_2(leds, numLeds) FastLED.addLeds<LED_TYPE_2,
STRING_PIN_2, RGB>(leds, numLeds);
//#define SETUP_LED_3(leds, numLeds) FastLED.addLeds<LED_TYPE_3,
STRING_PIN_3, RGB>(leds, numLeds);
//#define SETUP_LED_4(leds, numLeds) FastLED.addLeds<LED_TYPE_4,
STRING_PIN_4, RGB>(leds, numLeds);

#define SETUP_LED_1(leds, numLeds) FastLED.addLeds<NEOPIXEL,


STRING_PIN_1>(leds, numLeds);
#define SETUP_LED_2(leds, numLeds) FastLED.addLeds<NEOPIXEL,
STRING_PIN_2>(leds, numLeds);
#define SETUP_LED_3(leds, numLeds) FastLED.addLeds<NEOPIXEL,
STRING_PIN_3>(leds, numLeds);
#define SETUP_LED_4(leds, numLeds) FastLED.addLeds<NEOPIXEL,
STRING_PIN_4>(leds, numLeds);

That should be it.

If everything is set up correctly, you should be able to click on the

to verify the code, then the

to upload the code to the Arduino.

If there are problems in the message box below, chances are that you have made a
mistake in one of the steps above. Check the wiring carefully, the com port is correct, you
have the FastLED library installed and your specific Arduino selected.

Note: Some Led strings have multiple (usually three) LEDs per address, others have only
one. When there are three LEDs per address, every command that is sent to the LED in
RC, three will light up instead of one.
Race Coordinator Configuration
(Common to all requirements)

If you use RC Digital or have more than one Arduino/other device in RC Analogue, then
you need to enable Multi-Track. This can be found under Option/Preferences

tick ‘Multi-Track’ and click ‘Accept’

Then go into Track Manager, which is under Track Setup/Expert Track Setup.

With your Arduino switched on and plugged in to your pc, select the Arduino track interface
on the left hand side, and click ‘configure’.
This will take you in to the Manage Arduino page, where you set up the light configuration.
If your connection to the Arduino is ok, then you should see the ‘Connection’ light lit (it isn’t
in my screenshot).
You should see the com port in the top left, though you may have a choice, if you have
other devices connected. If you are not sure which is the Arduino, disconnect the Arduino
and see which com port disappears. You may have to refresh the screen by closing it and
reopening it.
LED Strip Configuration

Select the ‘Analog Setup’ tab at the top and set Pin A0, A1, A2 and A3 to ‘Reserved’

This indicates (for your own benefit) that these pins on the Arduino are being used for
something else: In this case the LED strip(s).

The Led String 1,2 3 and 4 tabs correspond to the Arduino connections A0, A1, A2 and
A3. So, if you have only one LED string connected to A0, you need only configure Led
String 1 on RC.
On the Led String 1 tab (and in each of the other LED string tabs) there are 25 LEDs
available for use by RC. Jeremy Corbert put together this really useful guide:

command to
effect on the led at the track
assign
unused does nothing
when you start a race the LED flashes red on countdown number 1 then goes green as race
countdown 1
starts, then goes off
when you start a race the LED flashes red on countdown number 2 then goes green as race
countdown 2
starts, then goes off
when you start a race the LED flashes red on countdown number 3 then goes green as race
countdown 3
starts, then goes off
when you start a race the LED flashes red on countdown number 4 then goes green as race
countdown 4
starts, then goes off
when you start a race the LED flashes red on countdown number 5 then goes green as race
countdown 5
starts, then goes off
lane 1, full fuel green, half tank yellow, low fuel red.upon refueling, colors blink and change
fuel level 1
back to yellow, then green for full tank.
lane 2 ,full fuel green, half tank yellow, low fuel red.upon refueling, colors blink and change
fuel level 2
back to yellow, then green for full tank
lane 3, full fuel green, half tank yellow, low fuel red.upon refueling, colors blink and change
fuel level 3
back to yellow, then green for full tank
lane 4, full fuel green, half tank yellow, low fuel red.upon refueling, colors blink and change
fuel level 4
back to yellow, then green for full tank
lane 5, full fuel green, half tank yellow, low fuel red.upon refueling, colors blink and change
fuel level 5
back to yellow, then green for full tank
lane 6, full fuel green, half tank yellow, low fuel red.upon refueling, colors blink and change
fuel level 6
back to yellow, then green for full tank
lane 7, full fuel green, half tank yellow, low fuel red.upon refueling, colors blink and change
fuel level 7
back to yellow, then green for full tank
lane 8, full fuel green, half tank yellow, low fuel red.upon refueling, colors blink and change
fuel level 8
back to yellow, then green for full tank
led is green at start of race, turns yellow half way through the heat, turns red near the end of
heat time
the heat
heat leader the current heat leaders color is displayed on this led
heat leader 1 If lane 1 is the heat leader, this led will turn on.
heat leader 2 If lane 2 is the heat leader, this led will turn on.
heat leader 3 If lane 3 is the heat leader, this led will turn on.
heat leader 4 If lane 4 is the heat leader, this led will turn on.
heat leader 5 If lane 5 is the heat leader, this led will turn on.
heat leader 6 If lane 6 is the heat leader, this led will turn on.
heat leader 7 If lane 7 is the heat leader, this led will turn on.
heat leader 8 If lane 8 is the heat leader, this led will turn on.
lap indicator
if lane 1makes a lap, this led flashes in their color.
1
lap indicator
if lane 2 makes a lap, this led flashes in their color.
2
lap indicator
if lane 3 makes a lap, this led flashes in their color.
3
lap indicator
if lane 4 makes a lap, this led flashes in their color.
4
lap indicator
if lane 5 makes a lap, this led flashes in their color.
5
lap indicator
if lane 6 makes a lap, this led flashes in their color.
6
lap indicator
if lane 7 makes a lap, this led flashes in their color.
7
lap indicator
if lane 8 makes a lap, this led flashes in their color.
8
lap sensor 1 when lane 1 triggers a lap this sensor shows the open/closed state of the lap sensor
lap sensor 2 when lane 2 triggers a lap this sensor shows the open/closed state of the lap sensor
lap sensor 3 when lane 3 triggers a lap this sensor shows the open/closed state of the lap sensor
lap sensor 4 when lane 4 triggers a lap this sensor shows the open/closed state of the lap sensor
lap sensor 5 when lane 5 triggers a lap this sensor shows the open/closed state of the lap sensor
lap sensor 6 when lane 6 triggers a lap this sensor shows the open/closed state of the lap sensor
lap sensor 7 when lane 7 triggers a lap this sensor shows the open/closed state of the lap sensor
lap sensor 8 when lane 8 triggers a lap this sensor shows the open/closed state of the lap sensor
race state 1 LED goes yellow on countdown of (1,2,3,4, or 5), goes green for racing, goes yellow for
pause (Yellow Flag). Under Yellow Flag, the LED blinks at the rate set in Track Setup > Led
General > Yellow Flag Flash Rate.
LED goes yellow on countdown of (1,2,3,4, or 5), goes green for racing, goes yellow for
race state 2 pause (Yellow Flag). Under Yellow Flag, the LED blinks at the rate set in Track Setup > Led
General > Yellow Flag Flash Rate.
LED goes yellow on countdown of (1,2,3,4, or 5), goes green for racing, goes yellow for
race state 3 pause (Yellow Flag). Under Yellow Flag, the LED blinks at the rate set in Track Setup > Led
General > Yellow Flag Flash Rate.
LED goes yellow on countdown of (1,2,3,4, or 5), goes green for racing, goes yellow for
race state 4 pause (Yellow Flag). Under Yellow Flag, the LED blinks at the rate set in Track Setup > Led
General > Yellow Flag Flash Rate.
LED goes yellow on countdown of (1,2,3,4, or 5), goes green for racing, goes yellow for
race state 5 pause (Yellow Flag). Under Yellow Flag, the LED blinks at the rate set in Track Setup > Led
General > Yellow Flag Flash Rate.
led goes white when drivers pass under, if car stays under sensor LED stays on to indicate
Refueling 1
refueling and goes off when fuel is topped off
led goes white when drivers pass under, if car stays under sensor LED stays on to indicate
Refueling 2
refueling and goes off when fuel is topped off
led goes white when drivers pass under, if car stays under sensor LED stays on to indicate
Refueling 3
refueling and goes off when fuel is topped off
led goes white when drivers pass under, if car stays under sensor LED stays on to indicate
Refueling 4
refueling and goes off when fuel is topped off
led goes white when drivers pass under, if car stays under sensor LED stays on to indicate
Refueling 5
refueling and goes off when fuel is topped off
led goes white when drivers pass under, if car stays under sensor LED stays on to indicate
Refueling 6
refueling and goes off when fuel is topped off
led goes white when drivers pass under, if car stays under sensor LED stays on to indicate
Refueling 7
refueling and goes off when fuel is topped off
led goes white when drivers pass under, if car stays under sensor LED stays on to indicate
Refueling 8
refueling and goes off when fuel is topped off

A command can be used on more than one LED and on more than one LED string. Also, if
you connect two or more LED strings to the same Arduino port, then those strings will light
up on the same commands from RC (depending on the power drain).

So, for a Starting Tree, you might have five LEDs set for Countdown[1-5], which will light
the LEDs red in sequence, then all green on ‘Go’.

When you have finished, Click ‘Accept’. On the Track Manager screen, click ‘Add’ or
‘Update’ as applicable.

Note: If you have more than one Arduino (or other) interface
connected to your track, they should all appear in the
‘Current Interfaces box on the Track Manager screen.

If you want to edit the LED string configuration, select the


Arduino interface com port (in this example, Arduino 1) and
click on ‘Edit’.
A useful check as to whether or not the LEDs are working,
is to click on the ‘LED’ to the right of the command. If it is
working correctly, this ‘LED’ should change to green and
the corresponding LED on you strip, should also change
colour.
Arduino Analogue Connections

If you are using the Arduino analogue connections as described


above, select the ‘Analog Setup’ tab at the top and set the pins as
required. In the wiring diagram above (and excerpt to the right),
Pin A0 to A4 are ‘Start Led [1-5]’ and blue, white ,red and yellow
leds (pins 2,3,13,a5) represent each lane and tell you who is in
the lead.
Arduino Digital Connections

If you are using the Arduino


digital connections as
described above, select the
‘Digital Setup’ tab at the top
and set the pins as required.
In the wiring diagram above
(and excerpt to the right),Pin
2,3 and 13 are ??? (for
leaders).
8-11 are ‘Relay’; 4-7 are
‘Lap’; 0-1 are ????(for
bluetooth); and 12 is
‘Callbutton’
Extended Protocol

Within the lapCounter sketch, there is a section of ‘extended protocol’. This allows
configuration of the Arduino for conditions that are not directly supported by RC.

RC will deliver data to the Arduino but the Arduino (by programming the sketch, will then
decide what to do with this information. So, it can be used to drive LCD screens, for
example or, in my case, a couple of LED strings showing a certain combination of start
lights not supported by RC.

Note: I have spent a lot of time just ‘pressing buttons at random’ to find out what they do. I
am quite sure there are mistakes in the following and I am sure that the coding could be a
LOT better. However, it does what I want it to do and, in the absence of any more
information, I am happy with that. If you know how it SHOULD be done, please let me
know and I will update the documentation, (if not my code).
‘Background’ Information Gleaned From Slot Forum

Information to/from RC/Arduino is communicated in ‘buffers’. These buffers are actually in the
form of an array and is called ‘inBuffer’ or ‘outBuffer’. Each element of the array then has a
further array within it. Most of the buffers are outside the scope of this document (and I don't’
have a clue what they do). However, to retain the information in one spot, I’ve listed it below.

So inBuffer[0] can have one of a number of values:

inBuffer[0]
// Bytes for messages
const byte resetRequest = 0x52; // R this is the text equivalent of this value
const byte pinModeRequest = 0x50; // P
const byte writeRequest = 0x4F; // O
const byte analogRequest = 0x41; // A
const byte digitalRequest = 0x44; // D
const byte extendedRequest = 0x45; // E
const byte getInfoRequest = 0x47; // G
const byte versionRequest = 0x56; // V
const byte timeResetRequest = 0x54; // T
const byte debounceRequest = 0x64; // d
const byte ledModeRequest = 0x6C; // l
const byte ledWriteRequest = 0x4C; // L

For Extended Protocol (the section of interest here), inBuffer[0] = 0x45 (extendedRequest).
Within inBuffer[0] = 0x45, there is a second array, inBuffer[1], which also has a number of
values. And within that array, is a further array, as shown below:

Race State
inbuffer[1] == 0
inbuffer[2] == 0 - End Of Heat
inbuffer[2] == 2 - Countdown
inbuffer[2] == 3 - Countdown
inbuffer[2] == 4 - Race Go (Green)
inbuffer[2] == 5 - Yellow Flag
inbuffer[2] == 6 - Heat Over
inbuffer[2] == 7 - Race Over

For the start lights the following has to be met.


inbuffer[1] == 0 & inbuffer[2] == 2 or 3
inbuffer[3] then counts down from 4

Position:
inbuffer[1] == 2
inbuffer[3] == lane number of 1st
inbuffer[4] == lane number of 2nd
inbuffer[5] == lane number of 3rd
inbuffer[6] == lane number of 5th

Fuel Level:
inBuffer[1] == 3
inBuffer[2] == lane getting fuel level update [0, (numLanes - 1)]
inBuffer[3] == fuel level percentage [0, 255] (yes, 255% of capacity is the max. This is because
you can start a heat with more fuel than you can refuel to. 0 means out of fuel, 100 or higher
means full or more than full)

Refuelling:
inBuffer[1] == 4
inBuffer[2] == lane refuelling [0, (numLanes - 1)]
inBuffer[3] == isRefueling (0 == not refuelling, 1 == refuelling)
*** This should be sent right when the car starts getting fuel, NOT when its over the sensor.
This means you will need to adjust the refuel delay to make this come on sooner... We can talk
about this one but anything else is just going to cause the LED using this to flicker unless you
put the same code in the sketch I have in RC already.

Time
inBuffer[1] == 5
inBuffer[2] == Percent remaining.
***NOTE: This is state based, which you can get/store from the other API you're already using
for the start lights. If the heat is currently racing, this is the time left in the heat. If the heat is
over and we're waiting to auto advance, this is the percent time left before the auto advance,
and if the heat is waiting to be auto started, this is the time remaining before the auto start.

Crash & Learn


inBuffer[1] == 6
outbuffer[2] is the lane
outbuffer[3] is the count
outbuffer[4] is the max count

Lap Performance
Inbuffer[1] == 7 : Indicates the lap performance data
Inbuffer[2] == [0..n] : Lane the lap occurred on
Inbuffer[3] == 0, 1, 2 where 0 indicates a lap time slower than the overall race record average
lap time, 1 indicates a lap time faster than the overall race record average and 2 indicates there
is no race record and thus this value is not applicable
Inbuffer[4] == 0, 1, 2 where 0 indicates a lap time slower than the current heat leaders average
lap time, 1 indicates a lap time faster than the current heat leaders lap time and 2 indicates
there is no heat leader (may not be possible). ***NOTE: If the current driver is the heat leader,
this ends up being the same as inbuffer[5]
Inbuffer[5] == 0, 1, 2. See above only the comparison is against the drivers own average lap
time
Inbuffer[6] == 0, 1 where 0 indicates this lap was not the drivers best lap for the entire race and
1 indicates it was the fastest lap for the driver's entire race.
Inbuffer[7] == 0, 1 where 0 indicates this lap was not the driver’s best lap for the driver in the
current heat, and 1 indicates the lap was the driver’s best lap in the current heat.
FastLED Info

I have tried to capture some of the FastLED library commands that are either used or may be
of help.

CRGB leds[NUM_LEDS]; Array of LEDs called leds, with the number of LEDS,
NUM_LEDS. leds[0] is data regarding LED 1 on the strip;
leds[1] is LED 2, etc

#define NUM_LEDS Number of LEDs in strip, eg #define NUM_LEDS 10


[number of LEDs]

#define DATA_PIN ? Data pin use - A signifies analogue, no ‘A’ signifies digital.
Eg A0 is analogue pin 0. 3 is digital pin 3

#define CLOCK_PIN ? If you have four wires to the LED strip, you need to use a
clock pin

FastLED.addLeds<[LED For example - FastLED.addLeds<WS2811, DATA_PIN,


type],[data pin], [colour RGB>(leds, NUM_LEDS); means add the LED strip that uses
order]>([LED type WS2811, the data pin defined above, the colour order
array],[number of LEDs in RGB (but could be GRB or BGR); and apply it to the led
trip]); array leds’, defined above with the number of LEDs,
NUM_LEDS, defined above

FastLED.setBrightness([ Sets the brightness Uint8_t number, which means 0-255


0-255])

led[LED number] = CRGB is the means of defining a colour in RGB numbers;


CRGB::[colour] [0-255],[0-255],[0-255]. So, to define a colour on LED ‘i’ could
be leds[i] = CRGB( 50, 100, 150). CRGB::Green, is another
way of defining the any html defined colours.

FastLED.show(); Light LEDs

delay([time in Delays the time before something happens. This isn’t


milliseconds); recommended as it prevents the Arduino from doing
anything
Information from the Sketch

I started, but didn’t get very far, to document the meaning of the various variables of interest
within extended protocol.

stringNum = number of the string in use (0-3) - inBuffer[1]


numLeds = number of LEDs in that string - inBuffer[2]
rgbLedBrightness = brightness for that string - inBuffer[3]
rgbLedUpdateRateMs = update rate - inBuffer[4] = 10ms?
rgbLedStrings = array of LEDs
Pixel = which LED on the string
R,g,b = values of red, green and blue on that pixel
My Start Light Solution

I remind everyone that this is my take on using extended protocol. It works for me but it may
not work for everyone.

I have two strips of LEDS, each with five LEDs, connected on pins A1 and A2 on the Arduino
(not A0 and A1, which is default).

I want to have the lights blank before the countdown starts and only come on one at a time. At
the end of 5,4,3,2,1, the lights will go green for a second the blank.

For a yellow flag, I want the lights to flash yellow for approximately 0.5 seconds. On the restart,
I want lights to be red, as per the start.

RC Configuration Observations

1 On the Arduino Management Page, either Race State 5 or Countdown 5 needs to be


configured on any of the LEDS, other than the first five used by the sketch. If 1-5 are used,
that LED will llight, until overwritten by the sketch. If Race State/Countdown 4/3/2/1 are used,
then that number of LEDs will light during the countdown. It's easier to see than to explain...

2 If all LEDs on LED String setup are set to 'unused' (which is what I read somewhere), no
lights appear at any time on that strip. It also loses the connection to the Arduino and
everything needs to be reset.

2 The sketch overwrites the RC setup but only in certain circumstances. 'Pause' overwrote
the sketch configured LEDs; but the sketch configured Start LEDS overwrote RC. So, I'm not
sure what takes precedence, here. I'm sure there is logic to it but we haven't figured it out.

3 During the countdown, inBuffer[3] is used to determine which number the countdown is 'at'.
So, inBuffer[3] = 4, the lady will shout, 'Five', 3='Four', etc. inBuffer[3] = -250 is the 'Go' state.
I found that if I didn't have this Go state included the lights wouldn't turn Green.

Caveat: This was before I found the next item. So, this appears to be if the ‘case:’ statement
doesn't have the contents in curly brackets { }. I had lost the will to live by this time, so I
haven't rechecked this.

4 According to C++ syntax, there should be no need to have the case: statement inside curly
brackets. This is lifted from the Internet:

switch(expression) {
case x:
// code block
break;
case y:
// code block
break;
}

However, what I found was that the LEDs were unpredictable if the case statements weren't
in the following format:

switch(expression) {
case x:
{
// code block
}
break;
case y:
{
// code block
}
break;
}

RC Configuration

Analogue pins are set to reserved for the pins I am using (A1 and A2)
Both LED Strings 1 and 2 are set with ‘dummy’ configuration (I am using LEDs 0 to 4).
Arduino Code

I have attached the modified sketch for reference and I will list the changes I have made here:

1 Uncomment #define WITH_FAST_LED


2 Within the first #ifdef WITH_FAST_LED, add the lines:
#define LIGHT_ON_TIME_US (1000L * 1000L) //defines the duration of the flashing
light being on
#define LIGHT_OFF_TIME_US (1000L * 1000L) //defines the duration of the flashing
light being off

boolean lightPowerOn; //if the lights are set flash, are the lights currently on or off
boolean lightOn; //do we want the lights to flash at the moment
long lightTimeUs; //used as a countdown

3 Set the pins I will be using (starting at A1):


#define STRING_PIN_1 A1
#define STRING_PIN_2 A2
#define STRING_PIN_3 A3
#define STRING_PIN_4 A4
4 I’m not using Neopixels:
#define SETUP_LED_1(leds, numLeds) FastLED.addLeds<LED_TYPE_1, STRING_PIN_1,
RGB>(leds, numLeds);
#define SETUP_LED_2(leds, numLeds) FastLED.addLeds<LED_TYPE_2, STRING_PIN_2,
RGB>(leds, numLeds);
#define SETUP_LED_3(leds, numLeds) FastLED.addLeds<LED_TYPE_3, STRING_PIN_3,
RGB>(leds, numLeds);
#define SETUP_LED_4(leds, numLeds) FastLED.addLeds<LED_TYPE_4, STRING_PIN_4,
RGB>(leds, numLeds);

//#define SETUP_LED_1(leds, numLeds) FastLED.addLeds<NEOPIXEL, STRING_PIN_1>(leds,


numLeds);
//#define SETUP_LED_2(leds, numLeds) FastLED.addLeds<NEOPIXEL, STRING_PIN_2>(leds,
numLeds);
//#define SETUP_LED_3(leds, numLeds) FastLED.addLeds<NEOPIXEL, STRING_PIN_3>(leds,
numLeds);
//#define SETUP_LED_4(leds, numLeds) FastLED.addLeds<NEOPIXEL, STRING_PIN_4>(leds,
numLeds);

5 Create new function (terminology??) for when the lights are flashing:

void flashLights(unsigned long ulDeltaUs) {


lightTimeUs -= ulDeltaUs;
if (lightOn){
if (lightTimeUs < 0) {
if (lightPowerOn) {
// Turn power off
lightTimeUs = LIGHT_OFF_TIME_US;
lightPowerOn = false;
rgbLedStrings[0].leds[0] = CRGB(255,100,0);
rgbLedStrings[0].leds[1] = CRGB::Black;
rgbLedStrings[0].leds[2] = CRGB(255,100,0);
rgbLedStrings[0].leds[3] = CRGB::Black;
rgbLedStrings[0].leds[4] = CRGB(255,100,0);
rgbLedStrings[1].leds[0] = CRGB::Black;
rgbLedStrings[1].leds[1] = CRGB(255,100,0);
rgbLedStrings[1].leds[2] = CRGB::Black;
rgbLedStrings[1].leds[3] = CRGB(255,100,0);
rgbLedStrings[1].leds[4] = CRGB::Black;
}
else {
// Turn power on
lightTimeUs = LIGHT_ON_TIME_US;
lightPowerOn = true;
rgbLedStrings[0].leds[0] = CRGB::Black;
rgbLedStrings[0].leds[1] = CRGB(255,100,0);
rgbLedStrings[0].leds[2] = CRGB::Black;
rgbLedStrings[0].leds[3] = CRGB(255,100,0);
rgbLedStrings[0].leds[4] = CRGB::Black;
rgbLedStrings[1].leds[0] = CRGB(255,100,0);
rgbLedStrings[1].leds[1] = CRGB::Black;
rgbLedStrings[1].leds[2] = CRGB(255,100,0);
rgbLedStrings[1].leds[3] = CRGB::Black;
rgbLedStrings[1].leds[4] = CRGB(255,100,0);
}
}
}
}

Note: my light’s ‘Yellow’ colour is more green than yellow, so I have substituted the rgb colour I
like.

6 In the loop function, call the flashLights function, to check on the race state. ie do we
have a yellow flag or not.

#ifdef WITH_FAST_LED
flashLights(ulDeltaUs);
#endif

7 Code for Extended Protocol, add the code in the ‘Race State’ section (inBuffer[1] = 0)

switch ((inBuffer[1] TXT_TO_INT_CONVERSION)) {


case extRaceState:
{
SERIAL_PRINTLN("Got extRaceState");

// Race State
switch ((inBuffer[2] TXT_TO_INT_CONVERSION)) {
case 0:
// Race not started (count down interrupted during start sequence)

{
rgbLedStrings[0].leds[0] = CRGB::Blue; //set string 0, LED 0 to blue
rgbLedStrings[0].leds[1] = CRGB::Red; //set string 0, LED 1 to red, etc
rgbLedStrings[0].leds[2] = CRGB::Blue;
rgbLedStrings[0].leds[3] = CRGB::Red;
rgbLedStrings[0].leds[4] = CRGB::Blue;
rgbLedStrings[1].leds[0] = CRGB::Red;
rgbLedStrings[1].leds[1] = CRGB::Blue;
rgbLedStrings[1].leds[2] = CRGB::Red;
rgbLedStrings[1].leds[3] = CRGB::Blue;
rgbLedStrings[1].leds[4] = CRGB::Red;
}
break;

case 1:
// Heat not restarted (1)(count down interrupted during start sequence)

{
rgbLedStrings[0].leds[0] = CRGB::Blue;
rgbLedStrings[0].leds[1] = CRGB::Red;
rgbLedStrings[0].leds[2] = CRGB::Blue;
rgbLedStrings[0].leds[3] = CRGB::Red;
rgbLedStrings[0].leds[4] = CRGB::Blue;
rgbLedStrings[1].leds[0] = CRGB::Red;
rgbLedStrings[1].leds[1] = CRGB::Blue;
rgbLedStrings[1].leds[2] = CRGB::Red;
rgbLedStrings[1].leds[3] = CRGB::Blue;
rgbLedStrings[1].leds[4] = CRGB::Red;
}

break;

case 2:
// Initial countdown Start
{
lightOn = false;
int LED = 4 - (inBuffer[3] TXT_TO_INT_CONVERSION);
if (LED < 0)
{
for (int i = 0; i < 5; i++)
{
rgbLedStrings[0].leds[i] = CRGB::Black;
rgbLedStrings[1].leds[i] = CRGB::Black;
}
}
if (LED == 4)
{
rgbLedStrings[1].leds[4] = CRGB::Red;
rgbLedStrings[0].leds[4] = CRGB::Red;
}
if (LED == 3)
{
rgbLedStrings[1].leds[3] = CRGB::Red;
rgbLedStrings[0].leds[3] = CRGB::Red;
}
if (LED == 2)
{
rgbLedStrings[1].leds[2] = CRGB::Red;
rgbLedStrings[0].leds[2] = CRGB::Red;
}
if (LED == 1)
{
rgbLedStrings[1].leds[1] = CRGB::Red;
rgbLedStrings[0].leds[1] = CRGB::Red;
}
if (LED == 0)
{
rgbLedStrings[1].leds[0] = CRGB::Red;
rgbLedStrings[0].leds[0] = CRGB::Red;
}
}

break;

case 3:
// Restart countdown Start

{
lightOn = false;
int LED = 4 - (inBuffer[3] TXT_TO_INT_CONVERSION);
if (LED < 0)
{
for (int i = 0; i < 5; i++)
{
rgbLedStrings[0].leds[i] = CRGB::Black;
rgbLedStrings[1].leds[i] = CRGB::Black;
}
}
if (LED == 4)
{
rgbLedStrings[1].leds[4] = CRGB::Red;
rgbLedStrings[0].leds[4] = CRGB::Red;
}
if (LED == 3)
{
rgbLedStrings[1].leds[3] = CRGB::Red;
rgbLedStrings[0].leds[3] = CRGB::Red;
}
if (LED == 2)
{
rgbLedStrings[1].leds[2] = CRGB::Red;
rgbLedStrings[0].leds[2] = CRGB::Red;
}
if (LED == 1)
{
rgbLedStrings[1].leds[1] = CRGB::Red;
rgbLedStrings[0].leds[1] = CRGB::Red;
}
if (LED == 0)
{
rgbLedStrings[1].leds[0] = CRGB::Red;
rgbLedStrings[0].leds[0] = CRGB::Red;
}
}

break;

case 4:
// Race Started (green flag)
{
for (int i = 0; i < 5; i++)
{
rgbLedStrings[0].leds[i] = CRGB::Green;
rgbLedStrings[1].leds[i] = CRGB::Green;
}

FastLED.delay(1000);

for (int i = 0; i < 5; i++)


{
rgbLedStrings[0].leds[i] = CRGB::Black;
rgbLedStrings[1].leds[i] = CRGB::Black;
}
}
break;

case 5:
// Heat is paused

lightOn = true; //sets the variable, so that it is picked up in the loop/function

break;

case 6:
// Heat ended

for (int i = 0; i < 5; i++)


{
rgbLedStrings[0].leds[i] = CRGB::Blue; //this will get changed so it’s flashing white/black
rgbLedStrings[1].leds[i] = CRGB::Blue;
}
break;

case 7:
// Race ended
{
for (int i = 0; i < 5; i++){
rgbLedStrings[0].leds[i] = CRGB::Blue;
rgbLedStrings[1].leds[i] = CRGB::Blue;
}
}
break;

case 8:
// RC is closing
{
for (int i = 0; i < 5; i++){
rgbLedStrings[0].leds[i] = CRGB::Black;
rgbLedStrings[1].leds[i] = CRGB::Black;
}
}
break;
}
break;
} //end of Race State conditions

You might also like