I am working on a project where I need to split incoming data from serial (time to be exact, so aa:bb:cc) and need to split it into aa then bb and cc, ideally into an array. I know I could use readStringUntil and make 3 separate variables, but I would prefer it is in arrays. Here is the code that supposed to do this. It works with predefined string (eg. 00:00:00), but with reading serial it says that the initializer fails to determine size of "input". Thank you in advance for helpful suggestions.
Here is the code:
void setup() {
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
Serial.begin(9600);
while(!Serial.available()){} //wait until Serial data received
String vst = Serial.readString();
char buf[vst.length()+1];
vst.toCharArray(buf, vst.length());
char input[] = vst;
char delic[] = ":";
char* sub = strtok(input, delic);
while(sub != NULL){
Serial.println(ptr);
sub = strtok(NULL, delic);
}
}
1 Answer 1
Your main problem is this:
char buf[vst.length()+1];
You can't initialize an array with the return value of a function.
Instead you would need to use alloca
to perform the same function:
char *buf = alloca(vst.length()+1);
However, the way you're doing it is wasteful. You don't need buf
at all. You can directly access and manipulate the internal char
buffer inside the string using vst.c_str();
.
For convenience you can point buf
at it:
char *buf = vst.c_str();
To complete the picture here's a routine that takes the string and gives you three integers. Since we expect a specific format with only 3 sections to it we don't really need a loop.
// Use readStringUntil to avoid the 1 second delay.
String vst = Serial.readStringUntil('\n');
char *buf = vst.c_str();
char *hourString = strtok(buf, ":");
char *minuteString = strtok(NULL, ":");
char *secondString = strtok(NULL, ":");
if (secondString != NULL) { // Will only be true if we have two colons
int hours = atoi(hourString);
int minutes = atoi(minuteString);
int seconds = atoi(secondString);
Serial.print("It is ");
Serial.print(minutes);
Serial.print(" and ");
Serial.print(seconds);
Serial.print(" seconds past ");
Serial.println(hours);
} else {
Serial.println("Invalid time format");
}
vst.toCharArray()
(which copies the data) just directly usevst.c_str()
which is a char array already. You don't needbuf