[Solved]

I’m making a project that allows a RGB LED to be controlled through Serial using a C# program I have written.

This is and example of the string I am sending to the Arduino from my C# app: 064,128,255

I use this wrote this code to store it in a buffer so I could be read as a whole.

char* GetStringFromSerialData()
{ 
  char charBuffer[11];
  char newChar;
  int index = 0;
  
  while (Serial.available() > 0)
   {
     if (index < 10)
     {
       newChar = Serial.read();
       charBuffer[index] = newChar;
       index++;
       charBuffer[index] = '\0';
     }
   }
     
  return charBuffer;
}

It returns the stored array of chars received through the Serial port.

But I need to write a method where I can take that buffer, split it into substrings (RGB values extracted) and then use them as a PWM value.

Is anyone able to help me with this, I’ve searched a lot but I didn’t find anything and I’m not very well acquainted with pointers which I think plays a part.

Any help is appreciated :slight_smile:

One thing that you need to be careful about is that charBuffer is a local variable. It goes out of scope when the GetStringFromSerialData() function ends. You are returning a pointer to space that will no longer exist.

For the time being, you should make charBuffer a global variable, and make GetStringFromSerialData() a void function.

As for parsing the string, you really haven't given us anything to go on. We have no idea what delimiters, if any, you are using.

The strtok function can extract a token from a string, when the delimiters are known.

Thank you, that stuff about the pointers made a lot of sense.

The type of data I want to parse is arriving in this form: 064,128,255 So the delimiter is ','.

So how would I split this data into segments, eg "064, 128, 255" would be split into "064" and "128" and "255" and stored into separate variables.

Then I need to convert them to int values, would I use atoi() for this?

You can parse the code like this:

char *rStg = strtok(charArray, ",");
char *gStg = strtok(NULL, ",");
char *bStg = strtok(NULL, "\0");

Notice, though, that the whole packet may not arrive before GetStringFromSerialData() is called, or ends. You really should be using start-of-packet and end-of-packet markers, so that GetStringFromSerialData() can return only when the end-of-packet marker has arrived.

If you always know the format and size of what is being sent to the arduino, you probably could do something like below (you could skip the servo part). If the sent string is 064,128,255 then you could just parce out the three different values, convert them to a number and use them for the PWM.

// zoomkat 11-22-10 serial servo (2) test
// for writeMicroseconds, use a value like 1500
// for IDE 0019 and later
// Powering a servo from the arduino usually DOES NOT WORK.
// two servo setup with two servo commands
// send eight character string like 15001500 or 14501550

#include <Servo.h> 
String readString, servo1, servo2;
Servo myservo1;  // create servo object to control a servo 
Servo myservo2;

void setup() {
  Serial.begin(9600);
  myservo1.attach(6);  //the pin for the servo control 
  myservo2.attach(7);
  Serial.println("servo-test-21"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(10);  
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    } 
  }

  if (readString.length() >0) {
      Serial.println(readString); //see what was received
      
      // expect a string like 07002100 containing the two servo positions      
      servo1 = readString.substring(0, 4); //get the first four characters
      servo2 = readString.substring(4, 8); //get the next four characters 
      
      Serial.println(servo1);  //print ot serial monitor to see results
      Serial.println(servo2);
      
      int n1; //declare as number  
      int n2;
      
      char carray1[6]; //magic needed to convert string to a number 
      servo1.toCharArray(carray1, sizeof(carray1));
      n1 = atoi(carray1); 
      
      char carray2[6];
      servo2.toCharArray(carray2, sizeof(carray2));
      n2 = atoi(carray2); 
      
      myservo1.writeMicroseconds(n1); //set servo position 
      myservo2.writeMicroseconds(n2);
    readString="";
  } 
}

Awesome I got it all working :)

Thanks for the help.

I suggest you correct the name of the discussion back to the origional, as "solved" provides no help for the next person researching the same issue.