This is my code and sorry if it looks a mess. The code is setup to use the serial monitor to receive commands that i type in to help debug. Am have a problem with this bit of code
//Reads data from the ELM IC.
//For example 41 0C 7B 7B>.
byte STN_Read(char *str)
{
byte i = 0;
char temp;
while((temp = Serial.read()) != '>')
{
if(temp >= ' ' && temp <= '~')
{
str[i++] = temp;
}
}
if(i > 16)
{
Serial.println(i);
Serial.flush();
return 0;
}
else
{
str[i] = '\0';
return 1; //No data to read or buffer full.
}
}
. If i send data that is more then 16 bytes long the code above detects this and prints out byte i but then it crashes and will not continue. All is fine if i send data less then 16 bytes. The reason i want to do this is because if for some reason i don't get the ">" at the end of my received strings i want the function to bail out when the str buffer gets to 16.
Thats what am thinking. Am thinking that the code is putting more then 16 bytes in the str_rx buffer but am trying to get the code to only put 16 bytes in the buffer.
Yes thank you. The code below stops the skectch from crashing but when i type in the serial monitor 123456789123456789> (longer then 16 bytes) i then got the sketch to print out what it just received in the str and i get this 1234567891234567** (the * is garbage) but i think this tells me the code is still putting more then 16 bytes in the buffer.
//Reads data from the ELM IC.
//For example 41 0C 7B 7B>.
byte STN_Read(char *str)
{
byte i = 0;
char temp;
while((temp = Serial.read()) != '>')
{
if(temp >= ' ' && temp <= '~')
{
Serial.println(i);
Serial.println(temp);
str[i++] = temp;
}
if(i == 16)
{
return 0;
}
}
str[i] = '\0';
return 1; //No data to read or buffer full.
}
Does anyone know a better way to collect data with error handling for what am trying to do?
//Reads data from the ELM IC.
//For example 41 0C 7B 7B>.
byte STN_Read(char *str)
{
byte i = 0;
char temp;
while((temp = Serial.read()) != '>')
{
if(temp >= ' ' && temp <= '~')
{
str[i++] = temp;
}
if(i == 16)
{
return 0;
}
}
str[i] = '\0';
return 1; //No data to read or buffer full.
}
Am wanting it to terminate the read when the 16 byte buffer gets full if no '>' is found and then flush out out anydata remaining before it starts again.
You seem to be confused about how NULL termination of strings occurs. There is nothing magic about it. YOU must NULL terminate the array. The best time to do that is after EVERY character is added to the array.
Thanks PaulS and yes i am. Am still learning how functions work but unfortunately it doesn't come over night. I will give that a try and see how i get on.
Ok i have better results now with strings under 16 bytes long but still can't work out what is going on when i type 1234567891234567> in the serial monitor. The sketch reboots with the code below. I thought that if i gets to 16 then the function is meant to exit with that if statment. Can you tell me what is going wrong? Am i correct in thinking that the last number in the string is placed into buffer location 16> Thank you.
//Reads data from the ELM IC.
//For example 41 0C 7B 7B>.
byte STN_Read(char *str)
{
byte i = 0;
char temp;
while((temp = Serial.read()) != '>')
{
if(temp >= ' ' && temp <= '~')
{
str[i++] = temp;
str[i] = '\0';
}
if(i == 16)
{
return 0;
}
}
return 1; //Read is probably good.
}
If you got a valid character, write it into the array, and append a NULL. If the NULL was written into the 17th element of a 16 element array, return 0. Do you see where this is a problem?
Yes i can see that is the problem now but the way that am understanding it is that is that a string of 1234567891234567> the last 7 is placed into the 15th element then incremented to the 16th element (NULL is placed into that) and then the if stament of if(i == 16) should exit the loop and byte i goes back to 0 when the functhion is called again so at the min i can't see that "i" gets to the 17th. Hope you understand me. My understanding must be wrong.
This code to increment the character index executes every time a character is received, regardless of whether the buffer is already full. I suggest you add a check along these lines:
if(i < MAXLEN)
{
str[i++] = temp;
str[i] = 0;
}
Note that the size of the array needs to be MAXLEN+1 to include space for the null terminator. You could declare it like this:
Think i get it now. I was under the impression that a 16byte array is 1 to 16 but it's not, it's 0 to 15 so the when the counter gets to 16 (as in my code) no such element exists so problems happen. Is this correct?
Yes. Keep in mind that the NULL takes up one of the elements in the array. The cutoff for not writing any more to the array is when the NULL was just written to the last position (position 15 in a 16 element array).