drmpf:
Coming from Matlab you will expect strings to be well behaved.
To get similar behaviour in Arduino, you need to use Arduino Strings
Avoid low level c-string methods (even though they have similar names to the matlab fns) as in Arduino (C/C++) they work on fixed length char[] not Strings. They are very pone to coding errors, so much so that Microsoft has banded their use and text books have been written on why they should not be used.
Here is some sample code that reads a line of comands and executes them.
Because Strings are being used here, it does not matter if the length of your command line increases. The String inputLine will just expand as necessary, as in matlab. The strInput_RESERVE is just a hint.
// sample input
// L,R,D',B,U,D,F',R,B',L',B2,R,F2,D2,F,L',U2,L,U2,L,B2,L',B2,L2,U2,L2,R2,U2,B2,U2
// terminated with a NewLine char '\n' or CR NL
String inputLine;
unsigned int strInput_RESERVE = 120; // an estimate of the input line length no need to be exact
// stopC is the char to stop at
// returns true when get stopC and input contains the input up to then
// else return false
bool readStrUntil(char stopC, String& input) {
while (Serial.available()) {
char c = Serial.read();
if (c == stopC) {
return true; // input has char upto stopC
}
// else
input += c;
if (input.length() >= strInput_RESERVE) {
// prevent re-allocation and fragmenation
return true; // input has char upto stopC
}
}
return false;
}
void runL() {
Serial.println("run cmd L");
}
void runR() {
Serial.println("run cmd R");
}
/// etc
void unknownCmd(String& cmd) {
Serial.print("cmd:"); Serial.print(cmd); Serial.println(" not programmed yet.");
}
void execute(String& cmd) {
cmd.trim();
if (cmd.length() == 0) {
return;
}
if (cmd == "L") {
runL();
} else if (cmd == "R") {
runR();
// . . . etc
} else {
unknownCmd(cmd);
}
}
void parseInput(String& data) { // note the String&
Serial.print(F("Data :")); Serial.println(data);
data.trim();
if (data.length() == 0) { //no data just return
return;
}
data += ','; // add a trailing , to simplify the logic
int idx = data.indexOf(',');
while (idx >= 0) { // not -1 i.e found ,
String cmd = data.substring(0, idx);
execute(cmd);
data = data.substring(idx + 1); // step over the , and remove the cmd just processed
idx = data.indexOf(',');
}
}
void setup() {
Serial.begin(115200);
for (int i = 10; i > 0; i--) {
Serial.print(i); Serial.print(' ');
delay(500);
}
Serial.println();
inputLine.reserve(strInput_RESERVE); // allow some initial space
}
void loop() {
if (readStrUntil('\n', inputLine)) { // got a line of input
parseInput(inputLine);
inputLine = ""; // clear for next input
}
}
Collecting the whole line and processing it in one go is the simplest solution and avoids execution timing problems.
In the sketch above I am sending some debug output back to the Serial. Test this code out from the Arduino IDE first.
When connected to matlab, the debug output will go back there.
The SafeString references I gave above can be used for whole line processing, but use char[] and so will not expand as needed. You can use the SafeStringReader to read a field at a time, but then you will be reading and executing 'at the same' time. It can be done but takes a bit more care. See my tutorial on [Multi-tasking in Arduino](https://www.forward.com.au/pfod/ArduinoProgramming/RealTimeArduino/index.html)
Thank you all for your responses. It will help me in trying to get to my end goal. A couple of questions.
When I connect the arduino to matlab, I need to specify a COM port and baud rate. I can do this, but the COM port can only be used by one thing at a time? So I couldnt run the arduino code and the Matlab at the same time?
I am liking your idea with collecting the whole line and then processing it. How long do you think it would be to transfer a line like that. Would it be easier for me to covert it to numbers in matlab, then send it over? Once it gets the code, i need the execution to be quick, so I dont mind about waiting for it to process.