This is what I want to achieve:
I am sending some data serially (currently from the serial monitor). I want it such that when I receive some particular codes such as "on1", "of1" the arduino should do some action. Otherwise it should print the data on the LCD.
This is how I am trying to achieve it right now (which is not correct in some way):
I am sending data from serial monitor. Receiving it in a character array. comparing it with the two command words I mentioned before by "==" ( Is it correct??) and then switching ON LED at pin 13 if the command is "on1", switching it off if its "of1" and printing on the serial terminal if it is neither.
This is the problem:
All the data that I am sending is being printed on the serial terminal including "on1", "of1" commands.
This is the code:
int ledPin = 13;
const int maxLength=140; //maximum length for textbox data
char char_in[maxLength]; //Create a buffer to input all incoming data
int i=0;
void setup() {
pinMode(ledPin, OUTPUT); //Configure pins as output
Serial.begin(9600); //begin serial communication
}
void loop() {
if (Serial.available() > 0) //Is any serial data available
{
for( i=0;i<maxLength && Serial.available();i++)
{
char_in[i] = Serial.read();
}
if (char_in=="on1")
{
digitalWrite(ledPin,HIGH);
}
else if(char_in == "of1")
{
digitalWrite(ledPin,LOW);
}
else
{
Serial.print(char_in);
}
}
}
I am a bit confused about how character arrays and strings are distinguished and I doubt the problem is because of that.
Hello Graynomad, thanks for your help
I have changed my program as you suggested. I have included a null terminator and used strcmp but still the output is same
Do you see any logical error in my code?
int ledPin = 13;
const int maxLength=140; //maximum length for textbox data
char char_in[maxLength]; //Create a buffer to input all incoming data
int i=0;
void setup() {
pinMode(ledPin, OUTPUT); //Configure pins as output
Serial.begin(9600); //begin serial communication
}
void loop() {
if (Serial.available() > 0) //Is any serial data available
{
for( i=0;i<maxLength && Serial.available();i++)
{
char_in[i] = Serial.read();
}
char_in[i+1]='\0';
if (!strcmp(char_in,"on1"))
{
digitalWrite(ledPin,HIGH);
}
else if(!strcmp(char_in,"of1"))
{
digitalWrite(ledPin,LOW);
}
else
{
Serial.print(char_in);
}
}
}
Now I think we are getting close, but I see something strange happening
When I added the line Serial.println(char_in[i]);, each character that was being stored in char_in got printed in a new line( like it should). But now the action that was to be performed is being done nicely (LEDs are turning on and off like they should). I cannot figure out why the program is running like it should after this line..
When I remove it the old behaviour starts.
The loop to give '0' values to each element is added to flush out the garbage values from previous serial input.
int ledPin = 13;
const int maxLength=140; //maximum length for textbox data
char char_in[maxLength]; //Create a buffer to input all incoming data
int i=0;
void setup() {
pinMode(ledPin, OUTPUT); //Configure pins as output
Serial.begin(9600); //begin serial communication
}
void loop() {
if (Serial.available() > 0) //Is any serial data available
{
for( i=0;i<maxLength;i++)
{
char_in[i] = 0;
}
for( i=0;i<maxLength && Serial.available();i++)
{
char_in[i] = Serial.read();
Serial.println(char_in[i]);
}
// Serial.print(char_in);
char_in[i+1]='\0';
if (!strcmp(char_in,"on1"))
{
digitalWrite(ledPin,HIGH);
}
else if(!strcmp(char_in,"of1"))
{
digitalWrite(ledPin,LOW);
}
else
{
Serial.print(char_in);
}
}
}
I cannot figure out why the program is running like it should after this line..
The act of printing the char is effectively adding a delay, so when the loop iterates again enough time has passed for another character to be received by the serial port. Remove the printing and the loop runs so fast that it's finished before the next character has arrived.
Given that it seems you will always have 3 characters I think the simplest thing to do is
while (Serial.available() < 3); // wait for three characters
for( i = 0 ; i < 3;) // stick them in the array, you could use memcpy() here
{
char_in[i++] = Serial.read();
}
char_in[i] = '\0';
(far from bullet proof but should work)
The for loop to clear the array is not necessary as the array will be overwritten anyway. However to be safe you can null the string by just placing a \0 in the first location.
Its a part of small proof-of-concept sort of project for college. So nothing critical. Also I have to display messages that are not command words on LCD so I cannot use the 3 character method( or any method with fixed number of characters ).
So, I think I will just cross my fingers and pray that it will work. After all, that'ss what programmers do
Do you have control over the sender? If so, then you should add start and end of packet markers to the packets you send. This way, you can read and store all the serial data as it arrives, as fast as it arrives, and only do something with the data when the end of packet marker arrives.
"PaulS SOP EOP" in the search field will get you code I post regularly that reads properly packet-ed data.
If you don't have control over the data stream, then you must determine what is in the stream that bounds a packet. Hopefully, it is not just a matter of timing. If it is, you should wait until near the end of the time between packets before reading all the data, with no delays. You will, of course, miss a few packets learning about the timing, if it is only timing that delimits packets. Your initial post indicates that you do have control, though.
The sort of thing we normally suggest is like this
Your code waits for the '<' character then starts accumulating characters until it sees the '>' character. Then it parses the data.
This provides a couple of mechanisms that make the code more robust.
Note that this only works if < and > will never appear in your data. If they might then use different characters that don't. This also means that this technique cannot be used for binary data.
I have had an arduino from a long time, but the real learning is starting now.
Thanks Graynomad, these characters are not going to be in my input so I will soon try what you and PaulS suggested.