Ver 0.9.d

This commit is contained in:
Luca Borsari 2020-07-30 12:10:39 +02:00
parent 8b761685cc
commit cc1c937458
10 changed files with 829 additions and 610 deletions

View file

@ -1,6 +1,23 @@
Revisions history Revisions history
----------------- -----------------
* 2020-07-28: Ver 0.9.d - Luca
- Tested OK on Arduino Every
- Configuration Values NOW SAVED in EEPROM to enable
OLR Configuration via a Software client running on a computer.
- Laps (Single Race duration)
- Led Number in the Racetrack (MAXLED)
- Box Length
- Ramp: init,center,end,high
The User Interface running on the Computer is currently under development.
Advanced users can already change Cfg Values via Serial (See Protocol documentation)
Function Activation:
Even if you can configure Box and Slope parameters, the activation is
still managed by user via Controls
- Winner Visual effect changed (too long for 1200 MAXLED)
* 2020-07-16: Ver 0.9.c - Luca * 2020-07-16: Ver 0.9.c - Luca
- Changes in [I/O Pin]<>[Car Color] association to match - Changes in [I/O Pin]<>[Car Color] association to match
the desired Phisical Buttons Layout (Quick Start Guide) the desired Phisical Buttons Layout (Quick Start Guide)

View file

@ -1,15 +1,6 @@
# Serial Protocol (OLRBoard←→Host) # Serial Protocol (OLRBoard←→Host)
- - -
**Revisions:**
-
- - -
-
In the present doc the terms Board and Host indicate: In the present doc the terms Board and Host indicate:
- ***Board***: OLR Board - The microcontroller managing the led strip (Arduino) - ***Board***: OLR Board - The microcontroller managing the led strip (Arduino)
- ***Host***: The Host running the OpenLedRace COnfiguration software (PC, RPI, etc) - ***Host***: The Host running the OpenLedRace COnfiguration software (PC, RPI, etc)
@ -25,16 +16,11 @@ The Board is currently connected to the Host via Serial interface (USB)
## Message formats ## Message formats
- Messages are composed by 2 parts: **Command**, **Parameters**. - Messages are composed by 2 parts: **Command**, **Parameters**.
- Messages with multiple parameters, the char **'.'** is used as **"Parameters Separator"** - Messages with multiple parameters, the char **','** is used as **"Parameters Separator"**
- Messages sending back command confirmation uses "**<i>command</i>OK**" and "**<i>command</i>NOK**" - Messages sending back command confirmation uses "**<i>command</i>OK**" and "**<i>command</i>NOK**"
- Example: **CNOK** is the 'error' answer sent for a C command - Example: **CNOK** is the 'error' answer sent for a **C** command
- Telemetry Messages (see below) have fixed lenght parameters, and no -Messages end with the "EOC" (End Of Command) char:
message terminator. - [EOC] - Line Feed = ASCII 10/0x0A = new line = \n
- Any other message ends with the "EOC" (End Of Command) char:
- [LF] - Line Feed = ASCII 10/0x0A = new line = \n
- The following command, for example, is used by a OLR Device (Arduino)
to send the “Setup OK - Configuration Complete” message:
- `R0[LF] `
* * * * * *
@ -47,12 +33,13 @@ $ | Get UID | Get Board Unique Id
% | Get Version | Get Board Software version % | Get Version | Get Board Software version
: | Set Unique ID | Set Board Unique ID : | Set Unique ID | Set Board Unique ID
! | Send log/error msg | Send a log/error message to peer ! | Send log/error msg | Send a log/error message to peer
**C** | **C**onfiguration Race | Set basic race configuration **C** | **C**onfiguration Race | Set basic race configuration (Number of **laps** for a single race)
**R** | Race phase | Command used to Change/Notify current Race phase
**T** | Track length configuration | Command used to configure the Total Number of LEDs in the track.
**B** | Box length configuration | Command used to configure the number of LEDS at the end of the LED Strip reserved for Boxes (Pitlane).
**A** | Ramp configuration | Command used to configure the Ramp in the track.
**D** | Load Track and ramp defult | Command used to Reset to Default parameters (Race, Ramp, Pitlane)
**Q** | Query board cfg | Host request the current situation of the Config Parameters Set **Q** | Query board cfg | Host request the current situation of the Config Parameters Set
**R** | Race phase | Command used to notify current Race phase
**T** | Track configuration | Command used to configure a new track setup.
**A** | Ramp configuration | Command used to configure a ramp in the track.
**D** | Load Track and ramp defult | Command used to set default parameter for ramp and track
**p** | Car current position in OLR | Current position of the car in the OLR **p** | Car current position in OLR | Current position of the car in the OLR
**w** | Car Win the Race | A car just win the current race **w** | Car Win the Race | A car just win the current race
@ -64,33 +51,32 @@ $ | Get UID | Get Board Unique Id
In the following sections the column "**Initiate**" contains the id of the board sending the message. In the following sections the column "**Initiate**" contains the id of the board sending the message.
- ***B*** - ***Board***: OLR Board (Arduino Nano) - ***B*** - ***Board***: OLR Board (Arduino Nano)
- ***H*** - ***Host***: Host where the OpenLedRace Manger program is running (RPI, PC, ...). - ***H*** - ***Host***: Host where the OpenLedRace Manger program is running (Computer).
Same rule applies to the "***From***" column in "***Response***" Same rule applies to the "***From***" column in "***Response***"
Some commands may be originated by both peers (ex: Handshake command) Some commands may be originated by both peers (ex: Handshake command)
The string **_[LF]_** indicates the EOC (End of Command) char = "line feed / new line", (ASCII 10/0A) The string **_[EOC]_** indicates the EOC (End of Command) char, currently = "line feed", (ASCII 0A)
- - - - - -
### [#] - Protocol Handshaking [Implmented] ### [#] - Protocol Handshaking
|initiate| Syntax | Description |initiate| Syntax | Description
|------|--------|------------ |------|--------|------------
|B, H|**#**_[LF]_ | **Protocol Handshaking** |B, H|**#**_[EOC]_ | **Protocol Handshaking**
|| | Sent to initialize a connection (Board and Host) | || | Sent to initialize a connection (Board and Host) |
|**Response**| **From** | **Notes** |**Response**| **From** | **Notes**
|**#**_[LF]_ |H, B | The connection opens succesfully when a “**#**” is received 'back' from the peer |**#**_[EOC]_ |H, B | The connection opens succesfully when a “**#**” is received 'back' from the peer
||| **Please Note:**
||| Board and Host send back only one ACK (send back a '#' just once)
- - - - - -
### [@] - Reset [To be implemented] ### [@] - Reset [To be implemented]
|initiate| Syntax | Description |initiate| Syntax | Description
|------|--------|------------ |------|--------|------------
|H |**@**_[LF]_|**OLR Board Reset request** |H |**@**_[EOC]_|**OLR Board Reset request**
| | | Sent from Host to Reset the OLR Board to the initial state (before handshake) | | | Sent from Host to Reset the OLR Board to the initial state (before handshake)
|**Response**| **From** | **Notes** |**Response**| **From** | **Notes**
| | | No response expected from Board | | | No response expected from Board
@ -98,78 +84,95 @@ The string **_[LF]_** indicates the EOC (End of Command) char = "line feed / new
- - - - - -
### [$] - Get Board UID [Implemented] ### [$] - Get Board UID
| initiate | Syntax | Description | | initiate | Syntax | Description |
|----------|-------------|------------------------------------| |----------|-------------|------------------------------------|
| H | **$**_[LF]_ | **OLR Board UID request** | | H | **$**_[EOC]_ | **OLR Board UID request** |
| | | Sent from Host to get Board's UID | | | | Sent from Host to get Board's UID |
|**Response**| **From** | **Notes** |**Response**| **From** | **Notes**
|------|--------|------------ |------|--------|------------
|**$**Id[LF] | B | Send the UID strings |**$**Id[EOC] | B | Send the UID strings
#### UID String format #### UID String format
-- to be defined Unique Board Id (UID) string format:<br>
**^[\x33-\x7E]{16}$**
- Lenght: 16 chars
- Valid Chars: Ascii 7-bit Printable Chars excluding space=ASCII 32 (this means ASCII chars between 33 (0x21) and 126 (0x7E) inclusive
#### Examples #### Examples
|Origin|Command|| |Origin|Command||
|---|----|----| |---|----|----|
|H|**$[LF]**| Host send a **get info** request |H|**$[EOC]**| Host send a **get info** request
|B|**?3179c3ec6e28a[LF]**|The message from the Board contains Id="3179c3ec6e28a" |B|**?3179c3ec6e28a[EOC]**|Board answer: Id="3179c3ec6e28a"
|Origin|Command|| |Origin|Command||
|---|----|----| |---|----|----|
|H|**?[LF]**| Host send a **get info** request |H|**?[EOC]**| Host send a **get info** request
|B|**?[LF]**|The message from the Board indicates ID not set. |B|**??????????[EOC]**|The Board send back an invalid UID (if you are looking at it in a Serial Console, you usually see a bunch of question marks or other chars / non-printable ASCII).<br> This usually happens when the UID is not set yet, so the Board send back the contents of the area of the EEPROM where the UID is supposed to be stored.
- - - - - -
### [%] - Get Software Version [Implemented] ### [%] - Get Software Version
Used to check software compatibility between Board and Host program's versions Used to check software compatibility between Board and Host program's versions
| initiate | Syntax | Description | | initiate | Syntax | Description |
|----------|-------------|------------------------------------| |----------|-------------|------------------------------------|
| H | **%** [LF] | **OLR Board software version request** | | H | **%** [EOC] | **OLR Board software version request** |
|**Response**| **From** | **Notes** |**Response**| **From** | **Notes**
|------|--------|------------ |------|--------|------------
|**%**Ver[LF] | B | String representing the Software Version |**%**Ver[EOC] | B | String representing the Software Version
#### Software Version String format #### Software Version String format
-- to be defined [0-9]+\.[0-9]+\.[0-9a-zA-Z]+
Two dot-separated decimal numbers plus a third part composed by numbers and/or letters.
#### Examples #### Examples
|Origin|Command|| |Origin|Command||
|---|----|----| |---|----|----|
|H|**%[LF]**| Host send a **get info** request |H|**%[EOC]**| Host send a **get info** request
|B|**%1.0[LF]**|The message from the Board indicates Version="1.0.1" |B|**%0.9.d[EOC]**|The message from the Board indicates Version="0.9.d"
#### Guidelines to Assign a version number to the Arduino Software:
The three numbers represents the “Major.Minor.Patch” version.
• Major version zero (0.y.z) is for initial development. Anything MAY change at any time.
• Version 1.0.0 defines first Stable version
• Increment:
◦ MAJOR version when you make incompatible changes
◦ MINOR version when you add functionality in a backwards compatible manner
◦ PATCH version when you make backwards compatible bug fixes.
- - - - - -
### [:] - Set board Unique Id [Implemented] ### [:] - Set board Unique Id
The software running on the Board contains a routine to write an ID to EEPROM.<br>
The first time a Board is connected to a OLRNetwork the Unique Id may be empty (not every Board comes with the ID preloaded in EEPROM).<br>
The Host calculates an ID and send this **Set Id** command to the Board that will store
it in EEPROM.<br>
From now on this is the ID the board will send back when receiving a **Get Info '$'** command.
|initiate| Syntax | Description |initiate| Syntax | Description
|------|--------|------------ |------|--------|------------
|H |**:**id[LF]|**OLR Board Set UniqueId request** |H |**:**id[EOC]|**OLR Board Set UniqueId request**
|| | Sent from Host to Set Board's Unique Id || | Sent from Host to Set Board's Unique Id
|Parameters | | | |Parameters | | |
@ -179,13 +182,13 @@ From now on this is the ID the board will send back when receiving a **Get Info
|Response| | |Response| |
|---|--- |---|---
|**OK**[LF] | Board sends "OK" string (ACK) |**OK**[EOC] | Board sends "OK" string (ACK)
|**NOK**[LF] | Board indicates that something went wrong |**NOK**[EOC] | Board indicates that something went wrong
- - - - - -
### [!] - Send log/error message [Work in progress] ### [!] - Send log/error message
The software running on the Board use this command to send messages to be written into the Host logfile.<br> The software running on the Board use this command to send messages to be written into the Host logfile.<br>
The Host will log the message and decide what to do with the relay race according to the "Severity" parameter (nothing, stop it, etc.) The Host will log the message and decide what to do with the relay race according to the "Severity" parameter (nothing, stop it, etc.)
@ -193,7 +196,7 @@ The Host will log the message and decide what to do with the relay race accordin
|initiate| Syntax | Description |initiate| Syntax | Description
|------|--------|------------ |------|--------|------------
|B |**!**Severity,Message[LF]|**OLR Board Sends an error message to Host** |B |**!**Severity,Message[EOC]|**OLR Board Sends an error message to Host**
|Parameters | | | |Parameters | | |
|----------------|---|---| |----------------|---|---|
@ -215,12 +218,14 @@ The Host will log the message and decide what to do with the relay race accordin
- - - - - -
### [**C**] - Set basic race configuration [Implemented] ### [**C**] - Set basic race configuration
This configuration is stored in non-volatile memory.
|initiate| Syntax | Description |initiate| Syntax | Description
|------|--------|------------ |------|--------|------------
|H |**C**start.nlap.repeat.finish[LF] |**Host Set basic race configuration** |H |**C**start.nlap.repeat.finish[EOC] |**Host Set basic race configuration**
@ -228,114 +233,182 @@ The Host will log the message and decide what to do with the relay race accordin
| Parameter |Format| Description | Parameter |Format| Description
|--------|---|--------- |--------|---|---------
| **start** | [0-1] |**Start Line** of the race is in this Board (Y/N) (0=No, 1=Yes) | **start** | [0-1] | OLRNetwork Only **Always 1 for standalone OLR**
| **nlap** | [1-9][0-9]? |Number of consecutive laps in each **section** of the Relay Race | **nlap** | [1-9][0-9]? |Number of laps of a Race
| | | max 2 chars (range 1-99)<br>Number of consecutive laps the cars will “run” before race finish **or** car get trough the OutTunnel | | | max 2 chars (range 1-99)
| **repeat** |[1-9][0-9]?| Number of times to **repeat the configured section** of nlap laps. | **repeat** |[1-9][0-9]?| OLRNetwork Only **Always 1 for standalone OLR**
| | | max 2 chars (range 1-99)<br>How many times the section of L laps will be repeated | | |
| **finish** |[0-1] |**Finish Line** of the race is in this Board (Y/N) (0=No, 1=Yes) | **finish** |[0-1] | OLRNetwork Only **Always 1 for standalone OLR**
|Response| | |Response| |
|---|--- |---|---
|**OK**[LF] | Board sends "OK" string (ACK) |**OK**[EOC] | Board sends "OK" string (ACK)
|**NOK**[LF] |Board indicates that something went wrong |**NOK**[EOC] |Board indicates that something went wrong
#### Examples #### Examples
|Origin|Command|| |Origin|Command||
|---|----|----| |---|----|----|
|H|**C0,5,2,1**|**start=0**: The Race starts in another OLR The Board will be waiting for messages like “Race Started”, “Car 1 Leaving”, Car 1 Leaved”, etc... |H|**C1,3,1,1**|**laps=3**: Each car will need to complete 3 laps before it can cross the Finish Line
|||**laps=5**: Each car will need to complete 5 laps before it can cross the Finish Line **or** get to the next OLR through the OutTunne.<br>(see 'repeat' param) |B|**OK[EOC]**| This is the Response from the Board to the previous example(ACK)
|||**repeat=2**: Each car will need to repoeat 2 times the section of nlap laps.<br>This means well expect each car will be sent back here (through the InTunnel) after we previously sent it out to another Racetrack. |||The message from the Board indicates that the value for Position,Laps, Repeat and Finish line has been set correctly as requested by the host.
|||**finish=1**: The Race ends here.This OLR will manage the Finsh Line Procedure.
|B|**OK[LF]**| This is the Response from the Board to the previous example(ACK)
|||The message from the Board indicates that the value for Position,laps, repeat and finish line has been set correctly as requested by the host.
| | | |
|H|**C1,2,3,0[LF]**| Position in Race is “1” The Race starts here
|||The Board will be managing the Start Race phase (Semaphore, etc.) |
|||Each car will need to complete 2 loops here before can get to the next Racetrack (through the OutTunne) .
|||Each car will need to repoeat 3 times the section of nlap laps.
|||The Race ends in another OLR.
|B|**NOK[LF]**| This is a Response from the Board (ACK)
|||The [NOK] value from the Board indicates that something went wrong (the board received some invalid paramenter value). |
- - - - - -
### [T] - **T**rack configuration [ Implemented ] ### [T] - **T**rack configuration - Total LEDs Number
This configuration is stored in non-volatile memory. This configuration is stored in non-volatile memory.
|initiate| Syntax | Description |initiate| Syntax | Description
|------|--------|------------ |------|--------|------------
|H |**T**box.tbd[LF] |**Host Set basic race configuration** |H |**T**nled[EOC] |**Host Set Racetrack Length Configuration**
#### Parameters #### Parameters
| Parameter |Format| Description | Parameter |Format| Description
|--------|---|--------- |--------|---|---------
| **box** | [0-MAXLED] | Number of the led where the box starts. Set 0 to remove box. | **nled** | Total number of LEDs in the Track | Ex: 300 for a single 5mt - 60 LED/mt LED Strip <br>**Please Note:<br>**After changing the LEDs number ** you need to reboot the board **
| **tbd** | [TBD] | Not used yet, set to 0.
|Response| | |Response| |
|---|--- |---|---
|**TOK**[LF] | Board sends "OK" string (ACK) |**TOK**[EOC] | Board sends "OK" string (ACK)
|**TNOK**[LF] |Board indicates that something went wrong |**TNOK**[EOC] |Board indicates that something went wrong
|Origin|Command|| |Origin|Command||
|---|----|----| |---|----|----|
|H|**T260,0**|: Set the box line in led number 260. |H|**T600**| Total Length is 600 (2 x 300 LED Strip connected).
- - - - - -
### [A] - r**A**ramp configuration [ Implemented ] ### [B] - **T**rack configuration - Pitlane Lenght (Boxes)
This configuration is stored in non-volatile memory. This configuration is stored in non-volatile memory.
|initiate| Syntax | Description |initiate| Syntax | Description
|------|--------|------------ |------|--------|------------
|H |**A**center.high[LF] |**Host Set basic race configuration** |H |**B**nled[EOC] |**Host Set Pitlane (boxex) Length Configuration**
#### Parameters #### Parameters
| Parameter |Format| Description | Parameter |Format| Description
|--------|---|--------- |--------|---|---------
| **center** | [0-MAXLED] | Number of the led where ramp is centered. Set 0 to remove box. | **nled** | Total number of LEDs, at the end of the Racetrack, reserved for the Pitlane | Ex: 120
|Response| |
|---|---
|**BOK**[EOC] | Board sends "OK" string (ACK)
|**BNOK**[EOC] |Board indicates that something went wrong
|Origin|Command||
|---|----|----|
|H|**B120**| Total Length for Pitlane is 120
- - -
### [A] - r**A**ramp configuration
This configuration is stored in non-volatile memory.
|initiate| Syntax | Description
|------|--------|------------
|H |**A**start,center,end,high[EOC] |**Host Set basic Ramp configuration**
#### Parameters
| Parameter |Format| Description
|--------|---|---------
| **start** | | LED number where the ramp Starts
| **center** | | LED Number where ramp is centered.
| **end** | | LED number where the ramp ends
| **height** | [ 0 - 1023] | Ramp elevation | **height** | [ 0 - 1023] | Ramp elevation
|Response| | |Response| |
|---|--- |---|---
|**AOK**[LF] | Board sends "OK" string (ACK) |**AOK**[EOC] | Board sends "OK" string (ACK)
|**ANOK**[LF] |Board indicates that something went wrong |**ANOK**[EOC] |Board indicates that something went wrong
|Origin|Command|| |Origin|Command||
|---|----|----| |---|----|----|
|H|**A150,12**|: Set the ramp centered in led 150. |H|**A140,150,160,12**|: Set the ramp centered in led 150, starts 10 LED before it and ends 10 LEDs after it, Elevation 12.
- - - - - -
### [D] - **D**efault configuration [ Implemented ] ### [D] - **D**efault configuration [ Implemented ]
Set default configuration to track and ramp settings. Reset to default configuration parametrs (Track lenght, Ramp, Boxes and Race Laps).
|initiate| Syntax | Description |initiate| Syntax | Description
|------|--------|------------ |------|--------|------------
|H |**D**[LF] |**Host Set basic race configuration** |H |**D**[EOC] |**Host Request Board to Reset configuration parameters to Default**
- - -
### [Q] - Query current parameters set
| initiate | Syntax | Description |
|----------|-------------|------------------------------------|
| H | **Q**_[EOC]_ | **Get Current Parameters request** |
| | | Sent from Host to get Board's Cfg |
#### Returned Parameters format
|**Response**| **From** | **Notes**
|------|--------|------------
|Board issue 3 answers:<br>**TRACK:**a,b,c,d,e[EOC]<br> **RAMP:**a,b,c,d[EOC]<br> **RACE:**a,b,c,d[EOC]<br>| B | Send the Parameters Set
| | | |
| **TRACK** params | | |
| | **nled_total** | Total number of LEDs in the Racetrack (**configurable with "T" command**) |
| | nled_main | Internal parameter (when Pitlane is active: number of LEDs currently in the Main Path) |
| | nled_aux | Internal parameter (when Pitlane is active: number of LEDs currently in the Pitlane Path)|
| | nled_init_aux | Internal parameter (position of the Pitlane entrance) |
| | **box_len** | Total number of LEDs, at the end of the Racetrack, reserved for the Pitlane (**configurable with "B" command**) |
| **RAMP** params | | |
|| **start** | LED number where the ramp Starts
|| **center** | LED Number where ramp is centered.
|| **end** | LED number where the ramp ends
|| **height** | Ramp elevation
| **RACE** params | | |
|| **start** | OLRNetwork Only **Always 1 for standalone OLR**
|| **nlap** |Number of laps of a Race (**Configurable with 2nd parameter of "C" Command**)
|| **repeat** | OLRNetwork Only **Always 1 for standalone OLR**
|| **finish** | OLRNetwork Only **Always 1 for standalone OLR**
#### Examples
|Origin|Command||
|---|----|----|
|H|**Q[EOC]**| Host send a **get current paremeters Set** request
|B|**TRACK:1200,1200,0,-1,60[EOC]<br>RAMP:180,190,200,15[EOC]<br>RACE:1,2,1,1[EOC]<br>**|Messages from the Board with the current cfg values
- - - - - -
### [**p**] - Current Car **p**osition in Race [Implemented] ### [**p**] - Current Car **p**osition in Race
|initiate| Syntax | Description |initiate| Syntax | Description
|------|--------|------------ |------|--------|------------
|B|**p**NumTrackNlapRpos[LF]|**Position for each car in the race** |B|**p**NumTrackNlapRpos[EOC]|**Position for each car in the race**
|||Sent during race for each car currently in this Board. |||Sent during race for each car currently in this Board.
|Parameters | | | |Parameters | | |
@ -357,16 +430,16 @@ Set default configuration to track and ramp settings.
#### Examples #### Examples
|Origin|Command|| |Origin|Command||
|---|----|----| |---|----|----|
|B|**p**1B1.95**p**2M5.45[LF]| Two cars are currentry "running" in the Board. Car "1" is in Track "B" in Lap number "1" Relative Lap Position 95%. Car "2" is in Track "M" in Lap number "5" Relative Lap Position 45% |B|**p**1B1.95**p**2M5.45[EOC]| Two cars are currentry "running" in the Board. Car "1" is in Track "B" in Lap number "1" Relative Lap Position 95%. Car "2" is in Track "M" in Lap number "5" Relative Lap Position 45%
- - - - - -
### [w] - Car Win te Race [Implemented] ### [w] - Car Win te Race
|initiate| Syntax | Description |initiate| Syntax | Description
|------|--------|------------ |------|--------|------------
|B|**w**Num[LF]|**Car 'Num' just win the race** |B|**w**Num[EOC]|**Car 'Num' just win the race**
|||Sent by the circuit managing the "Finish Line" when a car cross it. |||Sent by the circuit managing the "Finish Line" when a car cross it.
|Parameters | | | |Parameters | | |
@ -383,5 +456,16 @@ Set default configuration to track and ramp settings.
|---|----|----| |---|----|----|
|B|**w**1| Car "1" win the race |B|**w**1| Car "1" win the race
30_Network_Protocol_Serial.md
Mostrando 30_Network_Protocol_Serial.md.
- - -
**Revisions:**
- 2020 07 28
- Command T: Syntax mofied
- Command A: Syntax mofied
- Command B: Added
-
- - -

View file

@ -73,4 +73,3 @@ float controller_getAccel ( void ) {
bool controller_isActive( int pin ) { bool controller_isActive( int pin ) {
return !digitalRead( pin ); return !digitalRead( pin );
} }

View file

@ -23,6 +23,7 @@ void update_track( track_t* tck, car_t* car ) {
controller_t* ct = car->ct; controller_t* ct = car->ct;
struct cfgtrack const* cfg = &tck->cfg.track; struct cfgtrack const* cfg = &tck->cfg.track;
if ( car->trackID == TRACK_MAIN if ( car->trackID == TRACK_MAIN
&& (int)car->dist % cfg->nled_main == (cfg->init_aux-(cfg->nled_aux)) && (int)car->dist % cfg->nled_main == (cfg->init_aux-(cfg->nled_aux))
// && controller_getStatus( ct ) == 0 ) { //change track by switch // && controller_getStatus( ct ) == 0 ) { //change track by switch
@ -105,20 +106,58 @@ bool box_isactive( track_t* tck ) {
return tck->boxactive; return tck->boxactive;
} }
int box_configure( track_t* tck, int init_box ) {
int tracklen_configure( track_t* tck, int nled ) {
struct cfgtrack* cfg = &tck->cfg.track; struct cfgtrack* cfg = &tck->cfg.track;
if( init_box >= cfg->nled_main ) return -1; if( nled <= 0 ) return -1;
cfg->nled_total = nled;
return 0;
}
int boxlen_configure( track_t* tck, int box_len ) {
struct cfgtrack* cfg = &tck->cfg.track;
if( box_len <= 0 || box_len >= cfg->nled_total ) return -1;
cfg->box_len = box_len;
return 0;
}
int track_configure( track_t* tck, int init_box ) {
struct cfgtrack* cfg = &tck->cfg.track;
if(init_box >= cfg->nled_total ) return -1;
cfg->nled_main = ( init_box == 0 ) ? cfg->nled_total : init_box; cfg->nled_main = ( init_box == 0 ) ? cfg->nled_total : init_box;
cfg->nled_aux = ( init_box == 0 ) ? 0 : cfg->nled_total - init_box; cfg->nled_aux = ( init_box == 0 ) ? 0 : cfg->nled_total - init_box;
cfg->init_aux = init_box - 1; cfg->init_aux = init_box - 1;
return 0; return 0;
} }
int ramp_configure( track_t* tck, int center, int high ) {
int ramp_configure( track_t* tck, int init, int center, int end, int high ) {
struct cfgramp* ramp = &tck->cfg.ramp; struct cfgramp* ramp = &tck->cfg.ramp;
if ( center >= tck->cfg.track.nled_main || center <= 0 ) return -1; if ( init >= tck->cfg.track.nled_main || init <= 0 ) return -1;
if ( center >= tck->cfg.track.nled_main || center <= 0 ) return -2;
if ( end >= tck->cfg.track.nled_main || end <= 0 ) return -3;
if ( ! (center > init && center < end) ) return -4;
ramp->init = init;
ramp->center = center; ramp->center = center;
ramp->end = end;
ramp->high = high; ramp->high = high;
return 0; return 0;
} }
int race_configure( track_t* tck, int startline, int nlap, int nrepeat, int finishline ) {
struct cfgrace* race = &tck->cfg.race;
if ( startline != 0 && startline != 1 ) return -1;
if ( finishline != 0 && finishline != 1 ) return -1;
race->startline = startline;
race->finishline = finishline;
race->nlap = nlap;
race->nrepeat = nrepeat;
return 0;
}

View file

@ -76,14 +76,19 @@ void box_init( track_t* tck );
bool box_isactive( track_t* tck ); bool box_isactive( track_t* tck );
int box_configure( track_t* tck, int init_box ); int tracklen_configure( track_t* tck, int nled );
int boxlen_configure( track_t* tck, int box_len );
int track_configure( track_t* tck, int init_box );
void ramp_init( track_t* tck ); void ramp_init( track_t* tck );
bool ramp_isactive( track_t* tck ); bool ramp_isactive( track_t* tck );
int ramp_configure( track_t* tck, int center, int high ); int ramp_configure( track_t* tck, int init, int center, int end, int high );
int race_configure( track_t* tck, int startline, int nlap, int nrepeat, int finishline );
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

View file

@ -3,19 +3,21 @@
void param_setdefault( struct cfgparam* cfg ) { void param_setdefault( struct cfgparam* cfg ) {
cfg->setted = true; cfg->setted = true;
cfg->race.startline = true;
cfg->race.nlap = NUMLAP;
cfg->race.nrepeat = 1;
cfg->race.finishline = true;
cfg->ramp.init = 80; cfg->ramp.init = 80;
cfg->ramp.center = 90; cfg->ramp.center = 90;
cfg->ramp.end = 100; cfg->ramp.end = 100;
cfg->ramp.high = 2; cfg->ramp.high = 3;
cfg->track.nled_total = MAXLED; cfg->track.nled_total = MAXLED;
cfg->track.nled_main = 300; //240 cfg->track.nled_main = MAXLED; // 240 when boxes length = 60
cfg->track.nled_aux = 0; // 60 cfg->track.nled_aux = 0; // 60
cfg->track.init_aux = -1; // 239 cfg->track.init_aux = -1; // 239
cfg->track.box_len = BOXLEN;
cfg->track.kf = 0.015; //friction constant cfg->track.kf = 0.015; //friction constant
cfg->track.kg = 0.003; //gravity constant cfg->track.kg = 0.003; //gravity constant
} }

View file

@ -11,20 +11,35 @@ extern "C"{
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#define MAXLED 240+60 // 466 MAX LEDs actives on strip #define MAXLED 300
#define BOXLEN 60
#define NUMLAP 5
enum{ enum{
LEN_UID = 16, LEN_UID = 16,
CFG_VER = 3, CFG_VER = 4, // "4" in V0.9.d
}; };
struct cfgrace{
bool startline; // Used only in OLRNetwork
int nlap;
int nrepeat; // Used only in OLRNetwork
bool finishline; // Used only in OLRNetwork
};
// ramp centred in LED 100 with 10 led fordward and 10 backguard //
struct cfgtrack { struct cfgtrack {
int nled_total; int nled_total;
int nled_main; int nled_main;
int nled_aux; int nled_aux;
int init_aux; int init_aux;
int box_len; // used to hold the Box Length if the default get changed.
// it's not possible to implicitly store it in nled_main,nled_aux
// because, if these are different to the default, box gets always activated
// (the software does not chek "box_isactive" to draw car position)
float kf; float kf;
float kg; float kg;
}; };
@ -43,6 +58,7 @@ struct brdinfo {
struct cfgparam { struct cfgparam {
bool setted; bool setted;
struct cfgrace race; // added in ver 0.9.d
struct cfgtrack track; struct cfgtrack track;
struct cfgramp ramp; struct cfgramp ramp;
struct brdinfo info; struct brdinfo info;

View file

@ -18,24 +18,22 @@
First public version by: First public version by:
Angel Maldonado (https://gitlab.com/angeljmc) Angel Maldonado (https://gitlab.com/angeljmc)
Gerardo Barbarov (gbarbarov AT singulardevices DOT com)
Basen on original idea and 2 players code by: Basen on original idea and 2 players code by:
gbarbarov@singulardevices.com for Arduino day Seville 2019 Gerardo Barbarov for Arduino day Seville 2019
https://github.com/gbarbarov/led-race https://github.com/gbarbarov/led-race
Public Repository for this code: Public Repository for this code:
https://gitlab.com/open-led-race/olr-arduino https://gitlab.com/open-led-race/olr-arduino
2020/07/16 - Ver 0.9.c
--see changelog.txt
*/ */
char const version[] = "0.9.c";
// 2020/07/29 - Ver 0.9.d
// --see changelog.txt
char const version[] = "0.9.d";
@ -87,12 +85,6 @@ typedef struct ack{
}ack_t; }ack_t;
struct cfgrace{
bool startline;
int nlap;
int nrepeat;
bool finishline;
};
struct cfgcircuit{ struct cfgcircuit{
int outtunnel; int outtunnel;
@ -165,7 +157,8 @@ AsyncSerial asyncSerial(data, dataLength,
[](AsyncSerial& sender) { ack_t ack = parseCommands( sender ); sendresponse( &ack ); } [](AsyncSerial& sender) { ack_t ack = parseCommands( sender ); sendresponse( &ack ); }
); );
Adafruit_NeoPixel track = Adafruit_NeoPixel( MAXLED, PIN_LED, NEO_GRB + NEO_KHZ800 ); //Adafruit_NeoPixel track = Adafruit_NeoPixel( MAXLED, PIN_LED, NEO_GRB + NEO_KHZ800 );
Adafruit_NeoPixel track;
char tmpmsg [20]; char tmpmsg [20];
@ -177,6 +170,8 @@ void setup() {
controller_setup( ); controller_setup( );
param_load( &tck.cfg ); param_load( &tck.cfg );
track = Adafruit_NeoPixel( tck.cfg.track.nled_total, PIN_LED, NEO_GRB + NEO_KHZ800 );
controller_init( &switchs[0], DIGITAL_MODE, DIG_CONTROL_1 ); controller_init( &switchs[0], DIGITAL_MODE, DIG_CONTROL_1 );
car_init( &cars[0], &switchs[0], COLOR1 ); car_init( &cars[0], &switchs[0], COLOR1 );
controller_init( &switchs[1], DIGITAL_MODE, DIG_CONTROL_2 ); controller_init( &switchs[1], DIGITAL_MODE, DIG_CONTROL_2 );
@ -201,7 +196,11 @@ void setup() {
// Check Box before Physic/Sound to allow user to have Box and Physics with no sound // Check Box before Physic/Sound to allow user to have Box and Physics with no sound
if ( digitalRead( DIG_CONTROL_2 ) == 0 ) { //push switch 2 on reset for activate boxes (pit lane) if ( digitalRead( DIG_CONTROL_2 ) == 0 ) { //push switch 2 on reset for activate boxes (pit lane)
box_init( &tck ); box_init( &tck );
box_configure( &tck, 240 ); //box_configure( &tck, 240 );
//box_configure( &tck, MAXLED - BOXLEN );
track_configure( &tck, tck.cfg.track.nled_total - tck.cfg.track.box_len );
} else{
track_configure( &tck, 0 );
} }
if ( digitalRead( DIG_CONTROL_1 ) == 0 ) { //push switch 1 on reset for activate physics if ( digitalRead( DIG_CONTROL_1 ) == 0 ) { //push switch 1 on reset for activate physics
@ -215,11 +214,11 @@ void setup() {
} }
race.cfg.startline = tck.cfg.race.startline;// true;
race.cfg.nlap = tck.cfg.race.nlap;// NUMLAP;
race.cfg.nrepeat = tck.cfg.race.nrepeat;// 1;
race.cfg.finishline = tck.cfg.race.finishline;// true;
race.cfg.startline = true;
race.cfg.nlap = 5;
race.cfg.nrepeat = 1;
race.cfg.finishline = true;
race.phase = READY; race.phase = READY;
} }
@ -456,7 +455,7 @@ void draw_coin( track_t* tck ) {
void draw_winner( track_t* tck, uint32_t color) { void draw_winner( track_t* tck, uint32_t color) {
struct cfgtrack const* cfg = &tck->cfg.track; struct cfgtrack const* cfg = &tck->cfg.track;
for(int i=16; i < cfg->nled_main; i=i+2){ for(int i=16; i < cfg->nled_main; i=i+(8 * cfg->nled_main / 300 )){
track.setPixelColor( i , color ); track.setPixelColor( i , color );
track.setPixelColor( i-16 ,0 ); track.setPixelColor( i-16 ,0 );
track.show(); track.show();
@ -541,7 +540,6 @@ ack_t parseCommands(AsyncSerial &serial) {
} }
} }
else if( cmd[0] == 'C' ) { //Parse race configuration -> C1.2.3.0 else if( cmd[0] == 'C' ) { //Parse race configuration -> C1.2.3.0
struct cfgrace cfg;
ack.type = cmd[0]; ack.type = cmd[0];
char * pch = strtok (cmd,"C"); char * pch = strtok (cmd,"C");
@ -549,21 +547,33 @@ ack_t parseCommands(AsyncSerial &serial) {
pch = strtok (pch, "," ); pch = strtok (pch, "," );
if( !pch ) return ack; if( !pch ) return ack;
cfg.startline = atoi( pch ); //cfg.startline = atoi( pch );
int startline = atoi( pch );
pch = strtok (NULL, ","); pch = strtok (NULL, ",");
if( !pch ) return ack; if( !pch ) return ack;
cfg.nlap = atoi( pch ); //cfg.nlap = atoi( pch );
int nlap = atoi( pch );
pch = strtok (NULL, ","); pch = strtok (NULL, ",");
if( !pch ) return ack; if( !pch ) return ack;
cfg.nrepeat = atoi( pch ); //cfg.nrepeat = atoi( pch );
int nrepeat = atoi( pch );
pch = strtok (NULL, ","); pch = strtok (NULL, ",");
if( !pch ) return ack; if( !pch ) return ack;
cfg.finishline = atoi( pch ); //cfg.finishline = atoi( pch );
int finishline = atoi( pch );
int err = race_configure( &tck, startline, nlap, nrepeat, finishline);
if( err ) return ack;
EEPROM.put( eeadrInfo, tck.cfg );
race.cfg.startline = tck.cfg.race.startline;
race.cfg.nlap = tck.cfg.race.nlap;
race.cfg.nrepeat = tck.cfg.race.nrepeat;
race.cfg.finishline = tck.cfg.race.finishline;
race.cfg = cfg;
race.newcfg = true; race.newcfg = true;
ack.rp = OK; ack.rp = OK;
if ( verbose >= DEBUG ) { //VERBOSE if ( verbose >= DEBUG ) { //VERBOSE
@ -575,50 +585,81 @@ ack_t parseCommands(AsyncSerial &serial) {
printdebug( txbuff, DEBUG ); printdebug( txbuff, DEBUG );
} }
} }
else if( cmd[0] == 'T' ) { //Parse track configuration -> T1,2 else if( cmd[0] == 'T' ) { //Parse Track configuration -> Track length
ack.type = cmd[0]; ack.type = cmd[0];
char * pch = strtok (cmd,"T"); char * pch = strtok (cmd,"T");
if( !pch ) return ack; if( !pch ) return ack;
pch = strtok (pch, "," ); int nled = atoi( cmd + 1 );
if( !pch ) return ack; int err = tracklen_configure( &tck, nled);
int init_aux = atoi( pch );
pch = strtok (NULL, ",");
if( !pch ) return ack;
int err = box_configure( &tck, init_aux );
if( err ) return ack; if( err ) return ack;
track_configure( &tck, 0);
if( err ) return ack;
EEPROM.put( eeadrInfo, tck.cfg ); EEPROM.put( eeadrInfo, tck.cfg );
box_init( &tck );
ack.rp = OK; ack.rp = OK;
if ( verbose >= DEBUG ) { //VERBOSE if ( verbose >= DEBUG ) { //VERBOSE
struct cfgtrack const* cfg = &tck.cfg.track; struct cfgtrack const* cfg = &tck.cfg.track;
sprintf( txbuff, "%s %d, %d, %d, %d", "TRACK CONFIG: ", sprintf( txbuff, "%s %d, %d, %d, %d, %d", "TRACK CONFIG: ",
cfg->nled_total, cfg->nled_total,
cfg->nled_main, cfg->nled_main,
cfg->nled_aux, cfg->nled_aux,
cfg->init_aux ); cfg->init_aux,
cfg->box_len);
printdebug( txbuff, DEBUG ); printdebug( txbuff, DEBUG );
} }
} }
else if( cmd[0] == 'P' ) { //Parse ramp configuration -> T1,2 else if( cmd[0] == 'B' ) { //Parse BoxLenght Configuration
ack.type = cmd[0]; ack.type = cmd[0];
char * pch = strtok (cmd,"R"); char * pch = strtok (cmd,"B");
if( !pch ) return ack;
int boxlen = atoi( cmd + 1 );
int err = boxlen_configure( &tck, boxlen);
if( err ) return ack;
EEPROM.put( eeadrInfo, tck.cfg );
ack.rp = OK;
if ( verbose >= DEBUG ) { //VERBOSE
struct cfgtrack const* cfg = &tck.cfg.track;
sprintf( txbuff, "%s %d, %d, %d, %d, %d", "TRACK CONFIG: ",
cfg->nled_total,
cfg->nled_main,
cfg->nled_aux,
cfg->init_aux,
cfg->box_len);
printdebug( txbuff, DEBUG );
}
}
else if( cmd[0] == 'A' ) { // Parse Ramp configuration -> A<center>.<high>
ack.type = cmd[0];
char * pch = strtok (cmd,"A");
if( !pch ) return ack; if( !pch ) return ack;
pch = strtok (pch, "," ); pch = strtok (pch, "," );
if( !pch ) return ack; if( !pch ) return ack;
int init = atoi( pch );
pch = strtok (NULL, "," );
if( !pch ) return ack;
int center = atoi( pch ); int center = atoi( pch );
pch = strtok (NULL, "," );
if( !pch ) return ack;
int end = atoi( pch );
pch = strtok (NULL, ","); pch = strtok (NULL, ",");
if( !pch ) return ack; if( !pch ) return ack;
int high = atoi( pch ); int high = atoi( pch );
int err = ramp_configure( &tck, center, high ); int err = ramp_configure( &tck, init, center, end, high );
if( err ) return ack; if( err ) return ack;
EEPROM.put( eeadrInfo, tck.cfg ); EEPROM.put( eeadrInfo, tck.cfg );
@ -634,6 +675,7 @@ ack_t parseCommands(AsyncSerial &serial) {
printdebug( txbuff, DEBUG ); printdebug( txbuff, DEBUG );
} }
} }
else if( cmd[0] == 'D') { else if( cmd[0] == 'D') {
ack.type = cmd[0]; ack.type = cmd[0];
param_setdefault( &tck.cfg ); param_setdefault( &tck.cfg );
@ -666,20 +708,29 @@ ack_t parseCommands(AsyncSerial &serial) {
} }
else if( cmd[0] == 'Q' ) { // Get configuration Info else if( cmd[0] == 'Q' ) { // Get configuration Info
struct cfgparam const* cfg = &tck.cfg; struct cfgparam const* cfg = &tck.cfg;
sprintf( txbuff, "%s:%d,%d,%d,%d%c", "TCFG ", sprintf( txbuff, "%s:%d,%d,%d,%d,%d%c", "TRACK",
cfg->track.nled_total, cfg->track.nled_total,
cfg->track.nled_main, cfg->track.nled_main,
cfg->track.nled_aux, cfg->track.nled_aux,
cfg->track.init_aux, cfg->track.init_aux,
cfg->track.box_len,
EOL ); EOL );
Serial.print( txbuff ); Serial.print( txbuff );
sprintf( txbuff, "%s:%d,%d,%d,%d%c", "RCFG: ", sprintf( txbuff, "%s:%d,%d,%d,%d%c", "RAMP",
cfg->ramp.init, cfg->ramp.init,
cfg->ramp.center, cfg->ramp.center,
cfg->ramp.end, cfg->ramp.end,
cfg->ramp.high, cfg->ramp.high,
EOL ); EOL );
Serial.print( txbuff ); Serial.print( txbuff );
sprintf( txbuff, "%s:%d,%d,%d,%d%c", "RACE",
cfg->race.startline,
cfg->race.nlap,
cfg->race.nrepeat,
cfg->race.finishline,
EOL );
Serial.print( txbuff );
ack.rp = NOTHING; ack.rp = NOTHING;
} }
@ -701,6 +752,8 @@ void sendresponse( ack_t *ack) {
memset( &cmd, '\0' , sizeof(cmd) ); memset( &cmd, '\0' , sizeof(cmd) );
} }
void param_load( struct cfgparam* cfg ) { void param_load( struct cfgparam* cfg ) {
int cfgversion; int cfgversion;
int eeAdress = eeadrInfo; int eeAdress = eeadrInfo;
@ -708,12 +761,16 @@ void param_load( struct cfgparam* cfg ) {
eeAdress += sizeof( cfgparam ); eeAdress += sizeof( cfgparam );
EEPROM.get( eeAdress, cfgversion ); EEPROM.get( eeAdress, cfgversion );
sprintf( txbuff, "%s:%d%c", "Parameters Loaded from EEPROM Ver:", cfgversion, EOL );
Serial.print( txbuff );
if ( cfgversion != CFG_VER ) { if ( cfgversion != CFG_VER ) {
param_setdefault( &tck.cfg ); param_setdefault( &tck.cfg );
eeAdress = 0; eeAdress = 0;
EEPROM.put( eeAdress, tck.cfg ); EEPROM.put( eeAdress, tck.cfg );
eeAdress += sizeof( cfgparam ); eeAdress += sizeof( cfgparam );
EEPROM.put( eeAdress, CFG_VER ); EEPROM.put( eeAdress, CFG_VER );
Serial.print("LOAD DEFAULT\n"); Serial.print("DEFAULT PAREMETRS LOADED (and Stored in EEPROM)\n");
} }
} }