Send multiple commands or an array over serial to process?

Hi All,

One of my modules back in University almost 10 years ago was C++, and I thought I'd got away from it...oh well!

What I am trying to replicate is the functionality similar to the NZXT Hue+ PC Case LEDs. In short, they let you control an addressable RGB strip and can let you do a number of things:

  • Rainbow wave the LEDS
  • Create patterns & animations
  • Set single colours
  • Address each LED individually

Now, I've pretty much got the understanding on how to do most of the above, but what I am struggling with is how to tie this all together into 1 package.

For now, I am using the Serial Monitor to send the data, but eventually this will be via some custom program.

For example, I have the following function that takes a HEX string from Serial and converts it into an RGB colour profile to change the colour of the strip.

void executeSerialCommands() {
  while(Serial.available()) {
    String incomingString = Serial.readString();
    Serial.println(incomingString);

    long number = (long) strtol(&incomingString[0], NULL, 16);
    int r = number >> 16;
    int g = number >> 8 & 0xFF;
    int b = number & 0xFF;
  
    colourRun(strip.Color(r,g,b));
  }
}

What I am struggling to do though is say what function to execute and what code. So I'd like to send something that would say "Solid Colour - 6aa6ba" which would go to my function above and send that HEX value.

I'm fairly well versed in Javascript, and I know if I was doing this in JS, I would send over an array or something like the below and process it on the Arduino

{ 
    "function":"SolidColour", 
    "hex": "6aa6ba" 
}

I don't believe this is possible, so im a little stumped on how to do this

Very possible. Probably easier to do than the structure you have proposed.

See Serial Input Basics Updated

Have a look at the parse example in Serial Input Basics

You could send data in the format

"function":"SolidColour", "hex": "6aa6ba"

but I suggest that would make the interpretation on the Arduino very complex.

My approach would be to send a message that always contains all the data elements - even if they have not changed - in the same order. For your example it could be

"<SolidColour, 6aa6ba>"

The Arduino would know that the first item is the “function” and the second item is the hex value.

And I would simplify it further to

<S,6aa6ba>

…R

Robin2:
Have a look at the parse example in Serial Input Basics

You could send data in the format

"function":"SolidColour", "hex": "6aa6ba"

but I suggest that would make the interpretation on the Arduino very complex.

My approach would be to send a message that always contains all the data elements - even if they have not changed - in the same order. For your example it could be

"<SolidColour, 6aa6ba>"

The Arduino would know that the first item is the “function” and the second item is the hex value.

And I would simplify it further to

<S,6aa6ba>

…R

Ah thanks, that 3rd example explains what I was trying to do perfectly. I thought that maybe there was a simple way to do it, but seems you have to parse it yourself!

Now its just a case of breaking receivedChars down into comma separated values and interpreting them how I see fit

K20Evo:
Now its just a case of breaking receivedChars down into comma separated values and interpreting them how I see fit

if you have several sets of data for different items - for example 3 pairs of colour data for 3 different items

SolidColour, 6aa6ba, SolidColour, 3bb3aa, SolidColour, 1dd1dd

then it can be useful to use two different delimiters like this

<S, 6aa6ba; S, 3bb3aa; S, 1dd1dd>

and first parse on the semi-colons to break out the different groups and subsequently parse each group based on the comma to get the two parts for each item.

(Hope that makes sense)

…R

That does make sense, however I don’t think that’s required.
What I am doing is essentially controlling an addressable LED strip, so for example I might have the following functions:

  1. Solid Colour
  • Light up the strip one colour by taking a hex code
  • <s, 4286f4>
  1. Pixel Selector
  • Light individual pixels a certain colour
  • <p, ffffff, ff0000, 000000, 001dff>
  • Would light up the first 4 pixels as white, red, off, blue
  1. Rainbow
  • Run a rainbow effect

Where I am getting a bit confused is how to access each part of the array.

char* chars_array = strtok(receivedChars, ",");


if(chars_array == c) {
    Serial.println("Ran colour mode");
    colourRun(strip.Color(255,0,0));
}
        
while(chars_array) {
    Serial.println(chars_array);
    chars_array = strtok(NULL, ",");
}

The while loops prints out each part of the array, however chars_array is always the first part of the array. I thought if I did chars_array[1] it might give me the 2nd part of the array, but it gives the second letter:

<hello,world> gives me e, rather than world, but printing chars_array gives me hello

I suggest (for simplicity) that you identify the longest message - perhaps

<p, ffffff, ff0000, 000000, 001dff>

and make all your messages that size so that

<s, 4286f4>

becomes

<s, 4286f4, 0, 0, 0>

And would be

<r,0,0,0,0>

Then your Arduino code can call a different function depending on the value of the first character. Some functions will use all 4 data elements, others will only use one or none

…R