7

I'm starting to build my first Arduino project but I'm running into some problems with serial communication.

I get serial data from the console and store it in a char array called "data".

Then, when I send a new console message to the Arduino, I want it to clear the existing "data" array and store only the new data in that array.

I don't understand exactly what's wrong with my code: I believe those nested Serial.available() statements don't work but I have no ideas on how to fix the code.

Data is correctly stored by the Arduino but it concatenates the newer string to the old one.

int count = 0;
char data[30];
boolean dataComplete = false;

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


void loop() {

  if (Serial.available() > 0){
    if (dataComplete == true){
    Serial.println("There is data already, clearing...");
    char data[30];
    dataComplete = false;
  }
    if (dataComplete == false){
      Serial.println("New command, collecting...");
      while (Serial.available()>0){
        char character = Serial.read();
        data[count] = character;
        count++;
      }
     dataComplete = true;
    }
  }
  Serial.print("Command received: ");
  Serial.println(data);
  delay(1000);
}

Thanks in advance!

5 Answers 5

18

To clear an array you would do:

for( int i = 0; i < sizeof(data);  ++i )
   data[i] = (char)0;

or

memset(data, 0, sizeof(data));

, which does the same thing using a library function.

However, because strings of characters (not referring to 'String' objects here) are terminated by a zero byte, only the first byte needs to be zeroed:

data[0] = (char)0;

will do it.

0
2

First of all, this is an excellent example why whitespace matters. Your code is really hard to read as it is, as skimming over it, it seems as the second if statement is outside of the first one.

Fixed code:

int count = 0;
char data[30];
boolean dataComplete = false;

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

void loop() {
  if (Serial.available() > 0){
    if (dataComplete == true){
      Serial.println("There is data already, clearing...");
      char data[30];
      dataComplete = false;
    }
    if (dataComplete == false){
      Serial.println("New command, collecting...");
      while (Serial.available()>0){
        char character = Serial.read();
        data[count] = character;
        count++;
      }
     dataComplete = true;
    }
  }
  Serial.print("Command received: ");
  Serial.println(data);
  delay(1000);
}

Also, it seems as it prints "Command received:" every iteration, regardless of if there's new data or not (although, this could be the intended feature).

Like mentioned, you don't clear the variable, you just create a new one. You'll need to clear and reset count to fix this issue. However, just resetting count won't work if the second command is shorter than the one before.

Also, why do you complicate the code with the dataComplete variable? I simplified the code below:

int count = 0;
char data[30];
boolean dataComplete = false;

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

void loop() {
  if (Serial.available()){
    Serial.println("New command, collecting...");
    count = 0;
    data[] = "";
    while (Serial.available()){
      char character = Serial.read();
      data[count] = character;
      count++;
    }
  }
  Serial.print("Command received: ");
  Serial.println(data);
  delay(1000);
}
1

This probably doesn't do what you intend it to do:

Serial.println("There is data already, clearing...");
char data[30];

Your output says you are clearing the data array, but you're doing no such thing. In fact, you are declaring a new local variable called data, which is independent of the global data you already have declared at the top of your program. Local variables only exist within the scope in which they are declared (inside their nearest enclosing { }).

Instead, your count variable keeps track of how much data you have received. So perhaps do the following:

Serial.println("There is data already, clearing...");
count = 0;

This is not the only thing that might cause your program to operate unexpectedly, but it should at least fix the problem stated in your question.

3
  • Also a null terminator is needed for data: Add data[count]='\0'; after dataComplete = true;
    – Craig
    Commented Jul 3, 2014 at 21:47
  • Yes, that's true, but the larger problem is that there is no way for the sender to indicate the end of a data transmission other than to pause. And since this is serial, there is going to be a long enough pause in between every character transmitted. Commented Jul 3, 2014 at 21:49
  • Thanks to both of you guys. My code was wrong and changing it to "count = 0" worked. I also added a delimiter to indicate the end of an input command and it works as intended now. However, the only way that worked to empty the "data" array was using a for loop as indicated by @JRobert: this way newer commands work even if they are shorter than older ones.
    – squeck
    Commented Jul 4, 2014 at 22:51
0

To speak to the point of the question, and what the author was attempting to accomplish.

None of this code actually works as a whole. The data would get over written and just keep looping continuously... anyway here is a working example of the original code.

This method I prefer to clear an array:

    for( int i = 0; i < sizeof(data);  ++i )
    data[i] = (char)0;

Here is working example. ( Make sure to select Carriage Return on the serial monitor )

    char message[32];
    uint8_t incomingByte = 0; 
    uint8_t BufferPos = 0;
    int clearbyte = 0;


    void setup() {
    Serial.begin(9600);
    Serial.println("\n String conversion testing");

    }

    void loop() {

       if (BufferPos >= 32) {
              Serial.print("Buffer Full\n");
              BufferPos = 00;
              incomingByte = 0;

       }  

      if (Serial.available()) {
             incomingByte = Serial.read();
             message[BufferPos++]= incomingByte;   

         switch(incomingByte)
      {
           case '\n':
           case ' ':
             break;
           case '\r':
              Serial.println(message); 

          for( int i = 0; i < sizeof(message);  ++i )
         message[i] = (char)0;
              BufferPos= 0;
              incomingByte= 0;

      }
      }
    }
0

I was read all comments on this question, but all codes was share so verbosing. After that, i create a code with simple functions and less of line. in this case, i think this code will working fine

if you set baudrate under 115200, must be add delay() for saving message to char array

void loop() {
    char data[255];
    uint8_t k = 0;
    while (Serial.available()) {
        data[k] = Serial.read();
         k++;
    }
    for (int i = 0; i < k; i++) {
        Serial.print(data[i]);
        data [i] = '\0';
    }
    //delay(50);
}
3
  • 1
    char data[] = {}; will give you a zero-length array. Trying to put data into it is a bad idea.
    – Nick Gammon
    Commented Jan 17, 2019 at 6:47
  • I agree with @NickGammon . Please edit your answer to replace "I think... will work fine" with a definitive yes/no, once you have tested the code.
    – MichaelT
    Commented Jan 17, 2019 at 8:17
  • @NickGammon thanks for the correction, i was revision my code Commented Jan 17, 2019 at 9:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.