Hey gang-
I'm hoping someone can educate me here where I am little unclear on how to go about/approach this.
I know/understand that we SHOULD NOT (ever) use the "S"tring clas (capital "S" here)... and should use string or char.
Its a shame the String class causes those stack/heap (whatever) errors... as it easier to understand/work with
*IMHO at least.. but what do I know.. I'm a spoiled web developer, so taking in to account memory/space issues is foreign to me.. and I'm having some difficulty wrapping my brain about how one goes doing the following.
Summary:
- I want to take some incoming serial data...
- It has start & ending packet (characters) to signify the start and end of the incoming data
- The data 'between' the SOP/EOP characters is varying length.
What I'd like to do (in a perfect world).. would be to take this incoming serial data, and chop the data between the SOP/EOP characters by the comma delimiter... and put each of these 'chunks' of data into an Array.
Here is where I get a little unclear on how to do things.
Strings are bad... so using an array of strings is also bad.....right?
If we use char arrays... each 'character' is an item/index in the array..... right?
So how do we 'store' several characters together as one 'index' in an array?
I have read serial basics...etc.. but I dont think that applies to what I am asking here.. I'm not asking how to collect the incoming serial data to some variable.
I'm not asking how to break it up by some delimiter (well sorta!..lol)...
I'm specifically asking about breaking it up and having those groups of values be stored 'together' in an array index?
Here is some code to perhaps help illustrate things.
//serial format examples
//<b=1:1,b=2:1,m=6:200>
//<b=1:1,b=2:1,b=5:2,m=6:100,m=2:300>
There is no telling how many 'snippets/chunks' there will be between the < & > characters..
There could be 2 or 3.. or up to maybe 10?
I would say that each 'chunk' would NOT be more than 8-10 chars (tops...probably not more than 8)..
But for the same of planning..lets say 10 'chunks' of no more than 10 characters each.. so 100 character (max) on any incoming serial 'command'.
I'd like to get each:
b=1:1,
b=2:1,
b=5:2,
m=6:100,
m=2:300
into an array... so I can just loop through the array and parse each 'action'.. and when the array is done.. there are no more 'actions/steps' to be performed...etc..
fake example:
parse...parse
actionArray[counter] = (add delimited chunk here,,blah blah);
*(but this would need to be a String array...right? (which we do not want?)
in the end left with something like:
actionArray['b=1:1','b=2:1','b=5:2','m=6:100','m=2:300'];
*(but this would need to be a String array...right? (which we do not want?)
Then loop through the above array:
for(int z=0; z<30; z++) {
if(actions[z] != "0") {
parseAction(actions[z]);
}
}
So the above (for now) is my intended goal... but understanding how to go about WITHOUT using the String class has me a bit stumped.
In the code example below..
The parsing part is still assuming an older format.... (but even that was just to practice breaking up the string at specific delimiter).... the same question holds true.. how can I get each snippet into an array to be parsed (acted upon) later on?
//example recipie format (old format)
//<b=1:1><b=2:1><m=6:200> = bottle#1/1 shot, bottle#2/1 shot, mixer#6/200ms
//example recipie format (new format)
//<b=1:1,b=2:1,m=6:200> = bottle#1/1 shot, bottle#2/1 shot, mixer#6/200ms
#define SOP '<'
#define EOP '>'
bool hasStarted = false;
bool hasEnded = false;
char incomingSerialData[100];
byte index;
int positionValue = 0;
int amountValue = 0;
void setup() {
//serial monitor output
Serial.begin(9600);
}
//example recipie format (old format)
//<b=1:1><b=2:1><m=6:200> = bottle#1/1 shot, bottle#2/1 shot, mixer#6/200ms
//example recipie format (new format)
//<b=1:1,b=2:1,m=6:200> = bottle#1/1 shot, bottle#2/1 shot, mixer#6/200ms
void loop(){
// Read all serial data available, as fast as possible
while(Serial.available() > 0){
char incomingCharacter = Serial.read();
//Serial.println(incomingCharacter);
if(incomingCharacter == SOP){
index = 0;
incomingSerialData[index] = '\0';
hasStarted = true;
hasEnded = false;
}else if (incomingCharacter == EOP){
hasEnded = true;
break;
}else{
if (index < 100) {
incomingSerialData[index] = incomingCharacter;
index++;
incomingSerialData[index] = '\0';
}
}
}
// Packet data done...parse/evaluate data
if(hasStarted && hasEnded){
Serial.print("TOTAL COMMAND PACKET (CP) CHECK: ");
Serial.println(incomingSerialData);
char *actionToken = strtok(incomingSerialData, "="); //split action value from location/amount values
if(actionToken){
Serial.print("ACTION COMMAND: ");
Serial.println(actionToken);
//check if bottle 'action' data coming over
if(strcmp(actionToken, "b") == 0){
//grab position value
char *positionToken = strtok(NULL, ":");
if(positionToken){
Serial.print("BOTTLE #: ");
Serial.println(positionToken);
positionValue = atoi(positionToken);
//now grab 'amount' value
char *amountToken = strtok(NULL, "\0");
if(amountToken){
Serial.print("SHOT COUNT: ");
Serial.println(amountToken);
amountValue = atoi(amountToken);
}
}
}
//check if mixer action data coming over
if(strcmp(actionToken, "m") == 0){
char *positionToken = strtok(NULL, ":");
if(positionToken){
Serial.print("VALVE #: ");
Serial.println(positionToken);
positionValue = atoi(positionToken);
//now grab 'amount' value
char *amountToken = strtok(NULL, "\0");
if(amountToken){
Serial.print("OPEN TIME: ");
Serial.println(amountToken);
amountValue = atoi(amountToken);
}
}
}
}
Serial.println("");
// Reset for the next packet
hasStarted = false;
hasEnded = false;
index = 0;
incomingSerialData[index] = '\0';
}
So for now.. we can ignore the innards of the:
if(hasStarted && hasEnded){}
conditional... and just use that break things up into an array.
Or at least that is my goal here.
Maybe there is a different better approach to be had for this scenario?
I know the serial 'format' could be changed to make it easier to parse..etc.. and when I get further along and I'll regroup and refactor that..but for now.. I am just concerned/curious about how to get those comma delimited values (strings?) into an array?
Especially if we a NOT supposed to be using the String class? Maybe its my thinking/understanding of the char arrays that is flawed?
Maybe this is a situation where the String class may be acceptable? (although that incoming serial data >> array will happen over and over and over and over)
Basically a touch screen 'menu' will be sending this command/action (serial string) over, anytime someone uses the touch screen menu.
So to re-cap:
How can I parse incoming serial data by a comma delimiter and store those values into an array.. if we are NOT supposed to use the String class?
Thanks.