I want to send commands to the arduino. I've seen examples that check for the '\0' character to indicate an end to the input string. But I've had no luck trapping that. I have had luck trapping other characters like '#'. I'd like to be able to send a string command, then a comma, then a number, followed by a terminating character... e.g. "PinOn,13#" where terminating character is # (or \0 if I can figure out how.
The following code is what I've tested, but the command-string cmd never gets concatenated together. So the ch is printed but not the msg. Any one have an idea on how I can get this done.... (I've tried about 20 different things, with no luck...
String GetCommand()
{
String msg=""; //the message starts empty
byte ch; // the character that you use to construct the Message
byte d='#';// the separating symbol
if(Serial.available())// checks if there is a new message;
{
while(Serial.available() && Serial.peek()!=d)// while the message did not finish
{
ch=Serial.read();// get the character
Serial.print(ch);
Serial.print(" = ");
Serial.print(char(ch));
msg += String((char)ch);//add the character to the end message
Serial.print("Message = ");
Serial.println(msg);
delay(10);//wait for the next character
}
ch=Serial.read();// pop the '#' from the buffer
if(ch==d) // id finished
{
Serial.println(msg);
return msg;
} else {
return "NA";
}
}
else
{
return "NA"; // return "NA" if no message;
}
}
Well I just discovered why I wasn't responding to the '\n' part of the serial.read . In the lower right of the monitor window is a place to set how the data entered is terminated. The default is "no line ending", and other selections are 'newline', 'Carriage return', 'Both NL & CR". I hadnt seen that mentioned before. Part of being new to this environment etc.
Now still trying to figure out why my code readString.length is always 0 and readString += c doesn't concatenate the character c to my string readString....
This stuff should be easy, but WOW it is driving me crazy.
Thanks I will play with this. Although I am getting some odd results...
I changed the Start Marker to "[" and stop marker to "]". I'm not quite getting the results I would have expected, but I need to look at the code/script more closely. It is still an improvement over what I was getting on my own.
Send
[This is first line]
Arduino monitor shows
[ start received] & [hhis is first linh]
Send
[ This is the 2nd line]
...
Arduino monitor shows....
[ start received] & [hhis is first linh] & [ss is first linh s is]
Send
[ this is the 3rd line]
...
Arduino monitor shows...
[ start received] & [this is 3rd line]
So seems to strip off the first character in the string, and is not very consistent for some reason... looking at code again!
Simple serial code that captures a string sent from the serial monitor that is ended with a comma , as a delimiter. The captured String is then evaluated for desired data.
//zoomkat 3-5-12 simple delimited ',' string parse
//from serial port input (via serial monitor)
//and print result out serial port
//send on, or off, from the serial monitor to operate LED
int ledPin = 13;
String readString;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
Serial.println("serial LED on/off test with , delimiter"); // so I can keep track
}
void loop() {
if (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
Serial.println(readString); //prints string to serial port out
//do stuff with the captured readString
if(readString.indexOf("on") >=0)
{
digitalWrite(ledPin, HIGH);
Serial.println("LED ON");
}
if(readString.indexOf("off") >=0)
{
digitalWrite(ledPin, LOW);
Serial.println("LED OFF");
}
readString=""; //clears variable for new input
}
else {
readString += c; //makes the string readString
}
}
}
I think I the differences between a string and a character array are finally starting to sink in. I've seen many posts saying strings may produce memory leaks, and other "disasters" so I've been trying to program and avoid them. Thank you for the help here.
Your algorithm also seems to assume that an entire message will arrive during the execution of one iteration of the loop( ) function. In general, this is a somewhat unwise assumption. It isn't called "asynchronous" communication for nothing, although most people have forgotten that. For short messages from a known source, you can probably get away with using that delay(10) that you have there. As long as you can be sure that the sending end doesn't start sending messages very quickly - and then you get other problems. It is not a very robust solution.
The whole b/s problem of where a "newline" character is a CR, a LF, or a CR and a LF, goes back to antique hardware requirements and some kind of dispute between MS-DOS and the Unix universe 30 years ago. It still seems to annoy me every day when I open some text readme,txt file using Notepad and the whole contents come up on a single line thousands of characters long. A pox on both their houses.
ltetzner:
I think I the differences between a string and a character array are finally starting to sink in. I've seen many posts saying strings may produce memory leaks, and other "disasters" so I've been trying to program and avoid them. Thank you for the help here.
Just don't forget that a string is a null-terminated character array, and a String is a different beast all together.
I believe that you're are actually talking about Strings, not strings, when you talk about memory leaks and other problems. Strings are to be avoided and strings are how you do so.
It may seem picky but there is a huge difference between the two.
And just for fun, here is zoomkat's example hacked to not use the String class. Is it really that hard?
//zoomkat's example hacked to not use String
//
//zoomkat 3-5-12 simple delimited ',' string parse
//from serial port input (via serial monitor)
//and print result out serial port
//send on, or off, from the serial monitor to operate LED
const byte MAX_STRING_LEN = 30;
const byte LED_PIN = 13;
char readString[MAX_STRING_LEN];
byte strLen = 0;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
Serial.println("serial LED on/off test with , delimiter"); // so I can keep track
}
void loop() {
if (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
Serial.println(readString); //prints string to serial port out
//do stuff with the captured readString
if(strstr(readString, "on") != NULL)
{
digitalWrite(ledPin, HIGH);
Serial.println("LED ON");
}
if(strstr(readString, "off") != NULL)
{
digitalWrite(ledPin, LOW);
Serial.println("LED OFF");
}
readString[0] = '\0';
strLen = 0;
}
else {
if (strLen < (MAX_STRING_LEN - 1)) {
readString[strLen++] = c;
readString[strLen] = '\0';
}
}
}
}
Probably not too hard for a more experienced programmer, but I have to admit confusing for me. I didn't realize there are "Strings" vs "strings". I did understand that a character array is terminated with a null character. But when writing any kind of code I admit to spending a lot of time debugging why I'm not getting the results I expect. ...
It is usually incorrect usage of some time of variable. integer vs float, long vs other, etc. Wish this fully supported the sprintf() function. But as I code more, look at other code, and ask questions here I will improve. Thanks for the feedback from everyone!