Learning how to store chars in arrays... (newbie)

Hi I am trying to learn how to store chars in arrays and for this purpose I have created a simple code. Unfortunately it doesn’t work as it should :’( . Could you please have a look and let me know what is wrong? The goal is to intercept and store a string into an array and print it in serial monitor at the end. Thank you in advance!

char message[20];
int i = 0;
char c;

void setup() 
{
  Serial.begin(9600);
  while (!Serial);   
}

void loop()
{
if(Serial.available() >0)
  for (i=0; i<100; i++)
  {
  c=Serial.read();
  message [i] = c;
  i=i+1;
  }
message [i] = '\0';
i=0;
Serial.println(message);
}

MarJanPol:

char message[20];


  for (i=0; i<100; i++)
  {
  c=Serial.read();
  message [i] = c;
  i=i+1;
  }

You create a 20 byte array and then write up to index 99 in it. When you write off the end of an array you corrupt some other memory. That could cause any sort of strange, hard to diagnose bugs. This is one of the most important things to understand when working with arrays.

Second problem is that you increment i in the for statement, then you increment it again in the for loop. So that means i increases by 2 with every fime through the for loop.

You check if there is more than 0 bytes available, then read 50 times, even though there may not be that much data available.

You assume that all bytes are available at the moment that Serial.available() indicates that possibly only one is / two are available.

Serial communication is slow. One byte takes 1 millisecond. You type in serial monitor e.g. two characters. The first one is received, read and stored at location 0 in the array. The next one is still being transmitted from the PC to the Arduino.

Next you write hunderd bytes in the array that is only 20 bytes long; you overwrite memory that doe not belong to the array; this might e.g. be the integer i (if it’s stored in memory after the array) and in that case corrupts your counter.

Now loop is finished, runs 100 times or so and only then sees the second character that is transmitted.

This will be more in line with what is needed; this assumes a fixed message from the PC of 19 characters.

void loop()
{
  if (Serial.available() > 0)
  {
    message[i] = Serial.read();
    i++;
  }

  if (i == 20)
  {
    mesaage[19] = '\0';
    Serialprintln(message);
    i = 0;
  }
}

Once you understand the above, you can take it a step up and read Serial Input Basics - updated

pert:
Second problem is that you increment i in the for statement, then you increment it again in the for loop. So that means i increases by 2 with every fime through the for loop.

OOPS, missed that one.

pert: Second problem is that you increment i in the for statement, then you increment it again in the for loop. So that means i increases by 2 with every fime through the for loop.

Thank you for your help!!! Now I understand what was wrong however I don't understand the above sentence. In my code there was i=0; after FOR statement so why you wrote that I increased by 2 every time going through the loop?

sterretje: This will be more in line with what is needed; this assumes a fixed message from the PC of 19 characters.

Many thanks for your help!!!! M.

Unfortunately the code that you proposed doesn't work and I have no idea why... :(

Maybe you haven't entered enough characters

CtrlAltElite: Maybe you haven't entered enough characters

Yes, exactly. My mistake. Thank you! m

MarJanPol: Thank you for your help!!! Now I understand what was wrong however I don't understand the above sentence. In my code there was i=0; after FOR statement so why you wrote that I increased by 2 every time going through the loop?

i++ isn't just there for pretty, it does exactly the same thing as i = i+1; so...

dougp: i++ isn't just there for pretty, it does exactly the same thing as i = i+1; so...

Ok. Now I understand... Thanks a lot!!! M.

Dear Robin2, you advised me some time ago using this procedure for catching a string: http://forum.arduino.cc/index.php?topic=396450.0

I used that. However I’ve found recently some idea which seams to be more simple. What do you think? :

char message[100];
int i = 0; 
int ilosc; 

void setup() 
{
 Serial.begin(9600);
 while (!Serial); 
}

void loop()
{
if (Serial.available() > 0) 
{
delay(20);  
if (i==0)
     {
     ilosc = Serial.available();
     Serial.println("chars in memory buffer: ");
     Serial.println(ilosc); 
     i=i+1;
     }
   else
     {
     i=0;
     for (i=0; i<ilosc; i++)
{
message = Serial.read(); 
   }  
message[ilosc] ='\0';
     Serial.println(message); 
     i = 0;
     ilosc=0;
}
}
}

BR,
Marek

MarJanPol: I used that. However I've found recently some idea which seams to be more simple. What do you think? :

I don't like the use of delay() and your code cannot guarantee that it has received a complete message.

...R

char message[100];
int i = 0; 
int ilosc; 

void setup() 
{
 Serial.begin(9600);
 while (!Serial); 
}

void loop()
{
if (Serial.available() > 0) 
{
delay(20);                             // this does nothing for you
if (i==0)
     {
     ilosc = Serial.available();
     Serial.println("chars in memory buffer: ");
     Serial.println(ilosc); 
     i=i+1;
     }
   else
     {
     i=0;
     for (i=0; i<ilosc; i++)
{
message = Serial.read();                // message needs an index
   }  
message[ilosc] ='\0';
     Serial.println(message); 
     i = 0;                             // i is redundant here...
     ilosc=0;                           // ...ilosc already does what you have 'i' doing
}
}
}

You could set the monitor to use newline, then you could capture full strings.
You would have to ensure that other input sources you use also attach newline.

Thank you Robin2 and Boolrules!

Could you also advise me please what is the best way to catch values coming from a mobile phone accelerometer? I use RoboRemo App. Should I use strtok()?
When I see accelerometer data comming from UART on Serial monitor they usually look like:

Y 0
X 128
Y 108
Y 108
Y 109
X 129
X 128

Mar

MarJanPol: Could you also advise me please what is the best way to catch values coming from a mobile phone accelerometer? I use RoboRemo App. Should I use strtok()?

You use the appropriate example from Serial Input Basics to "catch" the data.

After you have caught the data you can use the parse example to extract the "values" from it. The parse example illustrates the use of strtok() inter alia.

...R

Thank you Robin2. I adapted your code and it works perfect. M.