Serial Read to NANO and segment display

Hey all, this is only my second topic on this forum. I got great help from here on my last project but hit a dead end and am going a different route with my project. Here is the background on my new project. I am currently trying to build a scoreboard that uses (6) 7 segment displays to show lap count on the first 2, and lap time in the last 4 digits. This is for a RC timing system using Zround software for the race management system.

https://www.zround.com/wiki/doku.php/scoreboards

this is the link to the protocol’s they are using for the scoreboard system in question. My skill level is very basic, hardware is my forte. UKHeliBob helped me a great deal understanding my last project and teaching me some basics along with my own research. This will be my first project sending information from my PC to the Arduino in this way. I have only done the opposite. I have tried a test code that I wrote that I can get to communicate with the software and do some rudimentary LED lighting to make sure communication was working. I got it to work just lighting three LED’s based on each command received. All good there. Now I am looking to send the lap count and lap time to my shift registers and segment displays and I am having a hard time understanding how to send the info they state in the link to display on my seg’s. Here is my test code. I am sure there is a lot wrong with it, so please, feel free to tell me what I did wrong.

//=====[ INCLUDE ]==============================================================

 
//=====[ CONSTANTS ]============================================================
#define RESET   "$RESET#"
#define TIME    "$TIME;<hh>:<mm>:<ss>#"
#define LAP     "$LAP;<N*>;<P>;<LL>;<NICK>;<LAP_TIME>;<BEST_LAP>#"
#define bSize       64 


//=====[ PINS ]=================================================================
int latchPin = 4;
int clockPin = 5;
int dataPin = 3;
byte segdisp[10] = {2,158,36,12,152,72,64,30,0,24};
 
//=====[ VARIABLES ]============================================================
char Buffer[bSize];        // Serial buffer
char ShadowBuffer[bSize];  // Serial buffer
char Command[10];

//=====[ ReadSerialCommand ]====================================================
int ReadSerialCommand(void) {
  int BytesCount = -1;
  BytesCount =  Serial.readBytesUntil('\n',Buffer,bSize-1);  
  if (BytesCount  > 0) {
    Buffer[BytesCount]='\0';
  }
  else{
    Buffer[0]='\0';
  } 
  return BytesCount;
}


//=====[ SETUP ]===============================================================
void setup() {
  
    Serial.begin(9600); 
    pinMode(Blue, OUTPUT);
    pinMode(Red, OUTPUT);
    pinMode(Green, OUTPUT);
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    digitalWrite(latchPin, HIGH);
}


//=====[ LOOP ]===============================================================
void loop() {
 
  if(ReadSerialCommand()>0){
   
    strcpy(ShadowBuffer,Buffer);        
    strcpy(Command,strtok(ShadowBuffer,","));        
    
    if(strcmp(Command, RESET))
    {
      Serial.print("RESET");
      digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    digitalWrite(latchPin, HIGH);
      
    }
      if(strcmp(Command, LAP))
      {
        Serial.print("LAP");
        digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 158);
    shiftOut(dataPin, clockPin, LSBFIRST, 158);
    digitalWrite(latchPin, HIGH);
 
      }
        if(strcmp(Command, TIME))
        {
          Serial.print("LAP TIME");
              digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    shiftOut(dataPin, clockPin, LSBFIRST, 2);
    digitalWrite(latchPin, HIGH);
              
      }
    }
  }

some of this code was dissected from the starting lights code from that same website hoping it would help me understand what to do with the information Zround sent. Like I said before, it appears to connect and communicate with Zround, and if I just light up 3 different LED’s based on the command Zround would send, the LED’s would like up as they should. I just need to translate from the info received to display on the seg displays. Thanks for any help and suggestions.

@OP

I have understood your post as follows based on the information of the link that you have provided:

1. The Arduino NANO/UNO based display unit will contain 8-digits (not 6-digit s you have said) -- first 2-digit (DP0-DP1) will show the Racer's Number, the rest 6-digit (DP2-DP7) will show the Race Time in hr-min-sec format.

2. The command $RESET# delivered to the UNO/UNO from the Serial Monitor will clear the display unit. I assume that clear refers to showing all 0s on the display unit. The display will show: 00 00 00 00

3. The command $TIME;<01>:<35>:<47># delivered to the NANO/UNO from the Serial Monitor will show 01 35 47 on DP2-DP7 positions of the display unit.

4. he command $LAP;<13*>;

;;;<LAP_TIME>;<BEST_LAP># delivered to the NANO/UNO from the Serial Monitor will show 13 on DP0-DP1 positions of the display unit.

5. If my above propositions make sense, then I would like build the 8-digit display unit in the following ways:
max7219_8digit.png

OR

muxdispla8y.png

6. The driving sketches are yet to develop that depend on the choice of schematic.

max7219_8digit.png

muxdispla8y.png

sorry, I should have explained my hardware setup a little better. I have dissected an old countdown timer display and want to use it to display only in 6 digits. It is a large digit display unit using shift registers for each digit. The display works great. Being that this is my first time using 'Serial' to send the information I want displayed, I don't know how to setup the code to use the information Zround sends to make the display show the correct laps and times.

Does this make more sense? sorry for my lack of information in my first post.

Please, post a diagram (hand drawn one will be OK) of your 6-digit display unit along with shift registers and the Arduino.

The hardware isn't a problem, but i will work on getting a schematic drawn up for it and put it in my next post. My problem is translating the information that Zround sends to the Nano and displaying the given information on the display. I have 3 wires from the Nano to the 1st shift register and from there it 'shifts out' to the remaining digits.

Yes, when Zround sends the RESET command it should just show all zero's for lap count and time. I was hoping for something similar to this

LAP COUNT LAP TIME
12 34:56

I don't have enough digits to show all the information that Zround is able to send, so I was hoping to use the layout above on the 6 digits I have. I will also attach a picture of my current display setup to give you an idea of what I have to work with. Thanks for the help. I love this forum.

Hello again :slight_smile:
Because I can’t resist fiddling with things I wrote the following pair of programs that may serve to give you some ideas

Because I don’t have a race system to try this with I used a Nano to send lap data via SoftSerial

Transmitter

#include <SoftwareSerial.h>
SoftwareSerial dataOut(A7, 13);

//Lap info. “$LAP;<N*>;<P>;<LL>;<NICK>;<LAP_TIME>;<BEST_LAP>#”
//                 racer's number;Position;Laps;Nickname;Lap time;Best lap
char * data[] = {"$LAP;0;1;1;TOM;9.977;9.971#",
                 "$LAP;1;2;1;DICK;10.819;10.811#",
                 "$LAP;2;5;2;HARRY;11.761;9.977#"
                };

void setup()
{
  dataOut.begin(9600);
  Serial.begin(115200);
}

void loop()
{
  if (Serial.available())
  {
    char key = Serial.read();
    if (key >= '0' && key <= '2')
    {
      dataOut.print(data[key - '0']);
    }
  }
}

If you enter 0, 1 or 2 in the Serial monitor data is sent via SoftSerial to emulate what you might get from the race system

It is read and decoded by this code
Receiver/decoder

#include <SoftwareSerial.h>
SoftwareSerial dataIn(A0, A1);

char buffer[100]; //plenty of space for the messages

void setup()
{
  Serial.begin(115200);
  dataIn.begin(9600);
}

void loop()
{
  if (dataIn.available())
  {
    int numRead = dataIn.readBytesUntil('#', buffer, 100);
    buffer[numRead] = '\0';
    Serial.println(buffer);
    char *cmd;
    cmd = strtok(buffer, ";");  // Look for ;
    Serial.print(F("Command is : "));
    Serial.println(cmd);
    if (strcmp(cmd, "$LAP") == 0)
    {
      int racerNum = atoi( strtok (NULL, ";"));
      Serial.print(F("Racer's number :     "));
      Serial.println(racerNum);
      int position = atoi(strtok (NULL, ";"));
      Serial.print(F("Position :           "));
      Serial.println(position);
      int laps = atoi(strtok (NULL, ";"));
      Serial.print(F("Laps :               "));
      Serial.println(laps);
      char * nickname = strtok (NULL, ";");
      Serial.print(F("Nickname             "));
      Serial.println(nickname);
      float lapTime = atof(strtok (NULL, ";"));
      Serial.print(F("Lap time :           "));
      Serial.println(lapTime, 3);
      float bestLap = atof(strtok (NULL, ";"));
      Serial.print(F("Best lap :           "));
      Serial.println(bestLap, 3);
    }
  }
}

As written, each of the data items received (I used the default set but you may have yours set up differently) is decoded and displayed on the Serial monitor. In practice, bearing in mind your other thread, you might choose to use the driver number as the index to an array of structs holding data for each truck into which the data would be inserted. Then you could call a separate function to display the data as and when required.

Hey UKHeliBob, thanks for following me to my new thread and thanks for this code. I just wanted to bring up a quick few things so hopefully I don't throw any surprises in at last minute like last time, then I have a few quick questions.

Same as my last thread, all I want to do is display lap count in the first 2 digits, and lap time in the last 4 digits. In the Zround software, it will display all this information and more with time down to the milliseconds. Our lap times are well under a minute and lap count very rarely can go above 99. This is all I want to display, I am not concerned with all the other information Zround sends. All this is done using shift registers shifting out to each digit. The displays are all working. Okay, so....

Questions. Considering this is my first time ever doing this type of communication, I have a ton of questions but think I will start simple first. Am I wrong in assuming since that Zround already has a registration system for each transponder that every time that transponder is detected, Zround should be sending ALL the information for that transponder? Is there a need for a 'struct trucks' if Zround already has this. I was assuming that every time a transponder is detected the displays will be updated based on the information Zround just sent, and the next transponder that is detected is then displayed, so on and so forth.

I was hoping that every time a race starts the display is automatically cleared (ALL ZERO's), then when the 1st transponder is detected it will show that transponders lap count and lap time and continue to display this information until the next transponder is detected, and continue to do this until race ends. The display can either hold the last transponder detected until the new race starts or reset when race is finished

I tried just a simple alteration to shift out to the displays all 1's in your example code at the end to try and get something to happen with no luck, here is what I tried.

const byte latchPin = 4;
const byte clockPin = 5;
const byte dataPin = 3;
byte segdisp[10] =  { B11100110,//9
                              B11111110,//8
                              B11100000,//7
                              B10111110,//6
                              B10110110,//5
                              B01100110,//4
                              B11110010,//3
                              B11011010,//2
                              B01100000,//1
                              B11111100,//0
                             };

char buffer[100]; //plenty of space for the messages

void setup()
{
  Serial.begin(115200);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, B11111110);
  shiftOut(dataPin, clockPin, LSBFIRST, B11111110);  
  digitalWrite(latchPin, HIGH);
}

void loop()
{
  if (Serial.available())
  {
    int numRead = Serial.readBytesUntil('#', buffer, 100);
    buffer[numRead] = '\0';
    Serial.println(buffer);
    char *cmd;
    cmd = strtok(buffer, ";");  // Look for ;
    Serial.print(F("Command is : "));
    Serial.println(cmd);
    if (strcmp(cmd, "$LAP") == 0)
    {
      int racerNum = atoi( strtok (NULL, ";"));
      Serial.print(F("Racer's number :     "));
      Serial.println(racerNum);
      int position = atoi(strtok (NULL, ";"));
      Serial.print(F("Position :           "));
      Serial.println(position);
      int laps = atoi(strtok (NULL, ";"));
      Serial.print(F("Laps :               "));
      Serial.println(laps);
      char * nickname = strtok (NULL, ";");
      Serial.print(F("Nickname             "));
      Serial.println(nickname);
      float lapTime = atof(strtok (NULL, ";"));
      Serial.print(F("Lap time :           "));
      Serial.println(lapTime, 3);
      float bestLap = atof(strtok (NULL, ";"));
      Serial.print(F("Best lap :           "));
      Serial.println(bestLap, 3);
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, LSBFIRST, B11111100);
      shiftOut(dataPin, clockPin, LSBFIRST, B11111100);  
      digitalWrite(latchPin, HIGH);
    }
  }
}

Nothing changed when I did this, but I don't really think I expected a change considering I don't really understand any of this.

I don't have any other boards to try your transmitter and receiver code as you did. When I enable the scoreboard in Zround it says it connected, and I can see the RX light on my Nano flashing when it receives information from Zround, but that is all I have for reference right now.

Thanks again for your help. This is great. I have the hardware side down really well, just need to learn the programming side.

xxxWALDOxxx:
Thanks again for your help. This is great. I have the hardware side down really well, just need to learn the programming side.

Kindly post your schematics showing the Arduino, the shift register (along with type no), and 7-segment display devices. I would like to play around a bit with your setup.

I am not concerned with all the other information Zround sends

Then ignore it or don't send it. Zround appears to be configurable so that you can choose what you send. From

CAR LAP/TIME: ZRound sends the racer’s lap/time. You can setup the message and you to send the racer’s number, position, laps, and race time.

every time that transponder is detected, Zround should be sending ALL the information for that transponder?

From the same page linked above

On every pass, all racer's data is sent (not only for the detected car).

Is there a need for a 'struct trucks' if Zround already has this.

Not strictly necessary but beware of updating the display too frequently when data has not changed as it could cause flickering and/or loss of data reads.

I was hoping that every time a race starts the display is automatically cleared (ALL ZERO's),

The RESET message from Zround allows for this

I don't have any other boards to try your transmitter and receiver code as you did.

Do you see anything pn the Serial monitor when you run my receiver/decoder program ?

Okay, starting to make sense, I thought....

On every pass, all racer's data is sent

meant that on every pass that transponder had all of its information sent, not that every transponders data was sent. My confusion.

I cannot view the serial monitor when connected to Zround as the port is busy, so I can't see any kind of results from there, unless there is a way to do this I am unaware of (pretty likely).

I guess I am not sure where to start with specifying how to know, or ID each truck unless I can do it based on transponder number. I am not sure exactly what information Zround has that is unique to each truck other than IR Hex code.

I am working on getting my schematic posted, just haven't had a chance to get anything drawn up, will post it as soon as I get it done for everyone to check out.

I cannot view the serial monitor when connected to Zround as the port is busy,

My receiver/decoder program uses SoftwareSerial to receive data on pins of your choice (A0 and A1 in the original). Note that the Nano needs to be receive TTL level signals rather than RS232 but if the Nano is already getting data from Zround then it will be at the correct levels.

I ordered up a few things today, one being another Nano and also a USB to TTL converter, I thought about making my own but figure ordering one was easier. Hopefully this will allow some better experimenting. I am working on my schematic tonight, probably be a quick rough layout, but should get the idea across.

So, I will do a little research the next couple days to try and understand how the serial communication works with Zround, but I did not see any part of your code that showed the 'RESET' command. I guess I am just so new to this I don't know where to start or how to know how and where to call a function based on commands received from Zround. I have been playing around with my previous threads code that you wrote to help understand the struct part well, just not sure how to call to it from what Zround is sending. Maybe once I see how the information is sent with the TTL converter will help me understand what to do with it.

I figured if I used the transponder code to define the trucks and call to the struct would work, but I don't see that in the received information from Zround either. If I start a race in Zround, the racer number is given to the order the trucks hit the sensor bridge for the first time, so every race the racer number can be different for each truck.

"$LAP;0;1;1;TOM;9.977;9.971#"
None of the information above is a constant, except name, but that can change based on a few scenario's throughout the race season.

Am I making this way more complicated than necessary?

attached is a quick schematic for the diagram I have only showing 2 displays, if you add more you just simply follow the diagram from the 1st to second for the remaining displays. Hope this helps. Make sure and follow the pin definitions, not the pin number as it is wrong for the pin number on the 74HC595 shift register.

I played with you code a little bit and got a pretty good idea what I need to do. Here is where I ended for the night and got the reset code working for the display. I am just working with 2 displays as I built a breakout board and is easy to work with just 2 digits. I added a really rough trial just to try and get a reaction from the code and it worked as expected, so this was just trial and error knowing this isn’t right, but was a way to get a reaction from the code to make sure I was on the right track.

const byte latchPin = 4;
const byte clockPin = 5;
const byte dataPin = 3;
byte segdisp[10] =  {         B11100110,//9
                              B11111110,//8
                              B11100000,//7
                              B10111110,//6
                              B10110110,//5
                              B01100110,//4
                              B11110010,//3
                              B11011010,//2
                              B01100000,//1
                              B11111100,//0
                             };

char buffer[100]; //plenty of space for the messages

void setup()
{
  Serial.begin(9600);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, B11111110);
  shiftOut(dataPin, clockPin, LSBFIRST, B11111110);  
  digitalWrite(latchPin, HIGH);
}

void loop()
{
  if (Serial.available())
  {
    int numRead = Serial.readBytesUntil('#', buffer, 100);
    buffer[numRead] = '\0';
    Serial.println(buffer);
    char *cmd;
    cmd = strtok(buffer, ";");  // Look for ;
    Serial.print(F("Command is : "));
    Serial.println(cmd);
    if (strcmp(cmd, "$LAP") == 0)
    {
      int racerNum = atoi( strtok (NULL, ";"));
      int position = atoi(strtok (NULL, ";"));
      int laps = atoi(strtok (NULL, ";"));
      char * nickname = strtok (NULL, ";");
      float lapTime = atof(strtok (NULL, ";"));
      float bestLap = atof(strtok (NULL, ";"));
    }
    if (strcmp(cmd, "$RESET#"))
    {
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, LSBFIRST, B11111100);
      shiftOut(dataPin, clockPin, LSBFIRST, B11111100);  
      digitalWrite(latchPin, HIGH);
    }
    if ( int racerNum = 1 )
    {
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, LSBFIRST, B01100000);
      shiftOut(dataPin, clockPin, LSBFIRST, B11111100);  
      digitalWrite(latchPin, HIGH);
    }
  }
}

Reset works great, the racer number works as soon as it detects the first IR code and then will not go away, which is what I expected and at least it got me a result so I knew what I was doing was effective. Now my question would be how to manage the ‘struct trucks’ into this. I was thinking the same as my previous thread where I look for the driver name, but since Zround sends all drivers data out upon any detection, how will that work? Suggestions? Ideas?

GolamMostafa, attached is another quick diagram I slapped together for my setup, keep in mind each brand or model segment display has different pinouts, so verify those, but the shift registers should be right, I didn’t throw in my capacitor I have on the shift registers, but they aren’t really needed for testing, I am sure someone will have a comment on that statement, but to each their own. Hope this helps.

Now my question would be how to manage the 'struct trucks' into this.

It looks like you could use what I named racerNum as the index to the array then instead of

float lapTime = atof(strtok (NULL, ";"));

do

truckData[racerNum].lapTime = atof(strtok (NULL, ";"));

Of course, this depends on the value of racerNum and I don't know what sets that.

@OP

I have devised the following mechanism to receive these commands: $RESET#, $TIME;<01>:<35>:<47>#, and $LAP;<13*>;

;;;<LAP_TIME>;<BEST_LAP># randomly from Serial Monitor and then take appropriate action as per directive of the specific command. I have tested the mechanism using UNO and L (built-in LED of UNO); I could not test on 7-segment display unit due to lack of 74LS595 shift registers; however, driving the 7-segment display unit would be a straightforward job.

/*
  1.  The command $RESET# delivered to the UNO/UNO
  from the Serial Monitor will clear the display unit.
  I assume that clear refers to showing all 0s on the display unit. The display will show: 00 00 00 00

  2.  The command $TIME;<01>:<35>:<47># delivered to the NANO/UNO
  from the Serial Monitor will show 01 35 47 on DP2-DP7 positions of the display unit.

  3.  he command $LAP;<13*>;<P>;<LL>;<NICK>;<LAP_TIME>;<BEST_LAP># delivered to the NANO/UNO
  from the Serial Monitor will show 13 on DP0-DP1 positions of the display unit.
*/
//char resetCmnd[50]; //$RESET#
char timeCount[50] =   ""; //$TIME;<01>:<35>:<47>#
//char lapCount[50];  //$LAP;<13*>;<P>;<LL>;<NICK>;<LAP_TIME>;<BEST_LAP>#
char dataArray[50] = "";
int dataArrayPointer = 0;
bool flag1 = LOW;
bool freset = LOW;
bool ftime = LOW;
bool flap = LOW;


void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); //RESET command will amke it HIGH -- testing
}

void loop()
{
  if (freset == HIGH)
  {
    //process RESET command
    digitalWrite(13, HIGH);//implement RESET Command -- testing ; OP will write 0s on DP0 - DP5
    freset = LOW;
  }
  else
  {
    if (ftime == HIGH)
    {
      //process Time Command
      digitalWrite(13, HIGH);  //testing
      ftime = LOW;
    }
    else
    {
      if (flap == HIGH)
      {
        //process Lap command
        digitalWrite(13, HIGH); //testing
        flap = LOW;//[s]ftime = LOW;[/s]
      }
    }
  }
}

void serialEvent()  //avaiable only for Hardware UART Port
{
  if (flag1 == LOW) //no $ has not yet been received
  {
    if (Serial.read() == '

Any criticism/feedback would be highly appreciated.) //beginning of any of the 3 commands
   {
     flag1 = HIGH;
     //Serial.println(flag1, BIN);
   }
 }
 else
 {
   byte x = Serial.read();
   if (x != ‘#’)
   {
     dataArray[dataArrayPointer] = x;
     dataArrayPointer++;
   }
   else
   {
     if (dataArray[0] == ‘R’)  //R is the 1st character of RESET Command
     {
       freset = HIGH;     //RESET Command has been received
     }
     else
     {
       if (dataArray[0] == ‘T’)
       {
         ftime = HIGH; //Time Command received
       }
       else
       {
         if (dataArray[0] = ‘L’)
         {
           flap = HIGH;   //Lap command received
         }
       }
     }
   }
 }
}


Any criticism/feedback would be highly appreciated.

It has always seemed to me that the serialEvent() function was a waste of time. If it were interrupt driven then maybe it would be useful but as it is it is simply called at the end of loop() if Serial data is available. You might just as well use

if (Serial.available())

in your own code.

bool flag1 = LOW;
bool freset = LOW;
bool ftime = LOW;
bool flap = LOW;

bools make more sense if they are given values of true or false. Whilst HIGH and LOW have the same value, as do 1 and 0, using true and false makes the code easier to follow

I have devised the following mechanism to receive these commands: $RESET#, $TIME;<01>:<35>:<47>#, and $LAP;<13*>;

;;;<LAP_TIME>;<BEST_LAP>#

The code has no provision to read the data for each command so I don’t know exactly what you mean. Note too that the data is not actually sent in the format that you gave, rather that appears to be the way in which it is referred to in Zround. In practice there is no < and > around the data

if (dataArray[0] == ‘R’) //R is the 1st character of RESET Command

The code would be more robust if the whole command was decoded rather than just the first character. Serial comms is not very reliable and messages are easily corrupted. Whilst it is unlikely that there will be a driver with a nickname of RESET, for example, there may well be one named ROGER. Imagine the effect of the message becoming corrupted and the R of ROGER being received at the wrong time. Unlikely but quite possible.

      if (flap == HIGH)
      {
        //process Lap command
        digitalWrite(13, HIGH); //testing
        ftime = LOW;
      }

Copy/paste has let you down here as flap is never reset to LOW

So lovely criticisms/feedback…! (K+)

1. In this particular application, I have found the serialEvent() function as a great aid to my need though many have serious objections against its use. The serialEvent() function has allowed me to keep the loop() function far away from receiving and storing the commands and the clumsy nested if-else structures.

2. I am noting that the boolean variables should have been sensibly initialized by true/false rather that HIGH/LOW values.

3. The Time Command is this: TIME;<01>:<35>:<47>#. All the characters except (beginning mark and # (ending mark) have been saved in the character type array. The ASCII codes of the time (01 35 47) could be easily collected from this array and then converted into integer (using atoi() function) for the purpose of displaying it on 7-segment display unit.

The AND has been used here as a ‘coordinating conjunction’.

4. Yes! I agree that the full command name (RESET) should have been decoded (through ‘string comparison’) to avoid possible ambiguity.

5. The copy/paste tradition has laid down the lives of many innocents!

The serialEvent() function has allowed me to keep the loop() function far away from receiving and storing the commands and the clumsy nested if-else structures.

So would

if (Serial.available())
{
  readData();  //call a function to read data
}

The Time Command is this: $TIME;<01>:<35>:<47>#

Are you absolutely certain about that ?

Here are some example messages from the Zround wiki Zround Scoreboard

$RESET#
$TIME;00:00:01#
$TIME;00:00:02#
$LAP;1;1;1;ALO;9.977;9.977#
$LAP;2;2;1;WEB;10.811;10.811#
$LAP;1;1;2;ALO;11.761;9.977#

The ASCII codes of the time (01 35 47) could be easily collected from this array and then converted into integer (using atoi() function) for the purpose of displaying it on 7-segment display unit.

I suspect that is what the OP needs most help with, hence my earlier example using the strtok() function

Looks like I need to play a little catch-up here. Going back to post #14

It looks like you could use what I named racerNum as the index to the array

racerNum is a random number given in the order the trucks pass the sensor bridge for the first time, so each race that number can be different. So when I build the 'struct trucks' I will try and name each driver based on the racers I have currently and see how that goes. I have no problem updating the program as new drivers start coming into the season for now.

Is my added code for the RESET function not the right way to approach it, it worked, but want to make sure I'm on the right track.

I am just going to try and stick with UKHeliBob's latest code as that's what has been working for me thus far, unless I should be trying something different. It's always nice to be completely oblivious to how the program works, spend the time studying, and then start to grasp it and see something work. It was a nice little breakthrough when I realized how the commands were working and able to make the RESET function happen. I love this, just wish it came a little easier to me.