Take the 2-minute tour ×
Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. It's 100% free, no registration required.

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!

share|improve this question

3 Answers 3

up vote 2 down vote accepted

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.

share|improve this answer
    
Thanks, the for loop idea worked! –  squeck Jul 4 at 22:54

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.

share|improve this answer
    
Also a null terminator is needed for data: Add data[count]='\0'; after dataComplete = true; –  Craig Jul 3 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. –  Greg Hewgill Jul 3 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 Jul 4 at 22:51

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);
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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