COM Port Variable Troubles

I’m following this post >https://forum.arduino.cc/index.php?topic=396450< and following to make my incoming variables from another program that are sent in this format “x/x/x/x” into 4 separate variables.

Testing in the Arduino Serial Monitor I can input that format and get each variable on a separate line except for the last variable without adding an extra “/” on the end. I can’t edit the format on the incoming data so I can’t use the example with a start and end which does work.

Even if I use the one that does work and have each of the variables show on different lines correctly in the Serial Monitor, I don’t know how to set them into the 4 variables in need.

This is the current code, you can ignore the RGBSelection, I was just testing to see if this did anything with the other variables.

#include "FastLED.h"
#define NUM_LEDS 300
int saberS, red, green, blue;
CRGB leds[NUM_LEDS];
const byte numChars = 100;
char receivedChars[numChars];
boolean newData = false;

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS);
int red = 255;
int blue = 255;
int green = 255;
}

void loop() {
    recvWithEndMarker();
    showNewData();
    RGBSelection();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '/';
    char rc;
    
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        Serial.println(saberS);
        Serial.println(red);
        Serial.println(green);
        Serial.println(blue);
        newData = false;
    }
}


void RGBSelection() {
if (Serial.available() > 0) {
  saberS = Serial.read();
  red = Serial.read();
  green= Serial.read();
  blue = Serial.read();
  }
fill_solid(leds, NUM_LEDS, CRGB(red,green,blue)); FastLED.show();
}

I’m not completely code illiterate but I don’t understand anything about COM port stuff.

I'm afraid I don't understand your description of the problem.

Can you please post a sample of data that is sent to your Arduino and a sample of the output from the Arduino.

Have you tried using the program in my Tutorial without any changes?

In this function

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        Serial.println(saberS);
        Serial.println(red);
        Serial.println(green);
        Serial.println(blue);
        newData = false;
    }
}

I don't know why you are printing the values saberS etc as there is no code to extract values from receivedChars. Have you studied the parse example in my Tutorial.

...R

Robin2:
I'm afraid I don't understand your description of the problem.

Can you please post a sample of data that is sent to your Arduino and a sample of the output from the Arduino.

Have you tried using the program in my Tutorial without any changes?

In this function

void showNewData() {

if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        Serial.println(saberS);
        Serial.println(red);
        Serial.println(green);
        Serial.println(blue);
        newData = false;
    }
}



I don't know why you are printing the values saberS etc as there is no code to extract values from receivedChars[]. Have you studied the parse example in my Tutorial.

...R

saberS doesn't have anything set to it yet I just have it as a place holder right now. I tried just you example and it works but I don't know how to put the output into a variable.

What is getting sent is in this order:
c1/255/20/90

"Left/Right" which is indicated as c1 or c2
"Red"
"Green" -- RGB etc.
"Blue"

I don't know how to call what I receive from your code into each of their own variables to use in the FastLED library.

ichimo:
I don’t know how to call what I receive from your code into each of their own variables to use in the FastLED library.

You need to study the parse example in my Tutorial. It uses a comma as the separator so you would need to change that to ‘/’

…R

Robin2:
You need to study the parse example in my Tutorial. It uses a comma as the separator so you would need to change that to '/'

...R

I know, I did change it to a slash, but I still don't know how to put each separated piece into a variable.

Example 5 - Receiving and parsing several pieces of data Is the section of the serial input basics tutorial that shows how to do what you want.

ichimo:
I know, I did change it to a slash, but I still don't know how to put each separated piece into a variable.

Post the program that represents your best attempt.

...R

Robin2:
Post the program that represents your best attempt.

…R

This is the closest I’ve gotten with it. It works as long as I put a start and end marker but since I’m stuck to the incoming format without the markers it doesn’t work how I need it.

#include "FastLED.h"
#define NUM_LEDS 300
CRGB leds[NUM_LEDS];
const byte numChars = 100;
char receivedChars[numChars];
char tempChars[numChars];      
char messageFromPC[numChars] = {0};
int red = 0;
int green = 0;
int blue = 0;
boolean newData = false;

//============

void setup() {
    Serial.begin(9600);
    Serial.println("Enter data in this style <C1/255/255/255>  ");
    Serial.println();
    FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS);
}

//============

void loop() {
    recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(tempChars, receivedChars);
        parseData();
        showParsedData();
        RGBSelection();
        newData = false;
    }
}

//============

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

//============

void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars,"/");      // get the first part - the string
    strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
 
    strtokIndx = strtok(NULL, "/"); // this continues where the previous call left off
    red = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, "/");
    green = atoi(strtokIndx);   
     
    strtokIndx = strtok(NULL, "/");
    blue = atoi(strtokIndx);  
}

//============

void showParsedData() {
    Serial.print("Side ");
    Serial.println(messageFromPC);
    Serial.print("Red ");
    Serial.println(red);
    Serial.print("Green ");
    Serial.println(green);
    Serial.print("Blue ");
    Serial.println(blue);
}

//============

void RGBSelection() {
fill_solid(leds, NUM_LEDS, CRGB(red,green,blue)); FastLED.show();
}

If not '>' does the serial data end with an end of line (/r/n)? Or just a line feed (\n)?

Add the indicated line to your code in the recvWithStartEndMarkers() function and Run the program with the incoming format that you are stuck with. Copy and post the results from the serial monitor so we can see the format of the data.

 while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        Serial.print(rc, HEX);  Serial.print(',');  // add this line to see exactly what is incoming

        if (recvInProgress == true) {

groundFungus:
If not '>' does the serial data end with an end of line (/r/n)? Or just a line feed (\n)?

Add the indicated line to your code in the recvWithStartEndMarkers() function and Run the program with the incoming format that you are stuck with. Copy and post the results from the serial monitor so we can see the format of the data.

63,31,2F,32,35,35,2F,32,35,35,2F,32,35,35,D,A,

OK, see the D and A at the end? That is 0x0d and 0x0a which are the carriage return (0x0d = \r) and line feed (0x0a = \n) characters. So change the end marker to '\n'. You may need to insert a line to ignore the carriage return (if you don't want to keep that character).

Does the data always begin with 'c'? If so you could use that as the start marker.
Edit: Now that I think about it that is not a good idea as the start market is not saved to the receivedChars array. Use the example with the end marker only.

The reason to print the data in HEX is that the normally invisible (non printing) characters will show up so you know exactly what is coming in.

Yeah the '\r' for the end marker is letting it work now. I was originally trying to add an actual space cause I thought that was meant for blank.

ichimo:
It works as long as I put a start and end marker but since I'm stuck to the incoming format without the markers

Have you tried removing the function recvWithStartEndMarkers() and replacing it with recvWithEndMarker()

...R