Extra Char in Serial.Print (Array too small?)

char incomingbyte = 'A';
int ReadLength = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Hello Computer");
}

void loop() {
   ReadLength = Serial.available();
   if (ReadLength > 0){
     char ReadStr[ReadLength - 1];
     for (int i = 0; Serial.available() > 0 ; i++) {
       delay(1);
       ReadStr[i] =  Serial.read();     
     }
     
     Serial.println(ReadStr);
     Serial.flush();
   }
}

That gives my entered characters in the serial code along with some extra characters. Is it just me?

You’ve allocated space to hold some characters:

   ReadLength = Serial.available();
   if (ReadLength > 0){
     char ReadStr[ReadLength - 1];

That should be a +1, by the way, not a -1, in there. The value in the brackets is the number of elements, not the upper index, and you need to allow for the trailing NULL (that you need to add). Suppose ReadLength is 4. You are allocating space to hold 3 characters, when you should be allocating space to hold 5 characters (the 4 to be read and the NULL).

Now, you read until there are no more characters:

     for (int i = 0; Serial.available() > 0 ; i++) {

This may not be the same number of times that you planned for, if more data arrives before the loop is complete. You should loop while i < ReadLength;.

Now, you try to print a string:

     Serial.println(ReadStr);

But, the definition of a string is a NULL terminated array of characters. You haven’t NULL terminated the array of characters, so println prints until it encounters a NULL somewhere in memory.

Aha. Thanks.

There seemed to be a myriad of problems.

char incomingbyte = 'A';
int ReadLength = 0;
int Buffer = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Hello Computer");
}

void loop() {
  Buffer = Serial.available();
   if (Serial.available() > 0){
     delay(1);
     while(Serial.available() > Buffer){
       Buffer = Serial.available();
       delay(5);
     }
     ReadLength = Serial.available();
     char ReadStr[ReadLength + 1];
     for (int i = 0; i < ReadLength; i++) {
       delay(1);
       ReadStr[i] =  Serial.read();     
     }
     ReadStr[ReadLength] = '\0';

     Serial.println(ReadStr);
   }
}

That is some god-dammned ugly code up there, but I guess it works.

Eh, anyway to read the size of an array?

There seemed to be a myriad of problems.

There still are.

First, names like buffer or Buffer usually refer to arrays, not the number of values in the array.

  Buffer = Serial.available();
   if (Serial.available() > 0){
     delay(1);
     while(Serial.available() > Buffer){
     Buffer = Serial.available();
     delay(5);
     }
     ReadLength = Serial.available();

How many times do you need to see whether or not there is serial data to read? There are 5 calls here to that function here.

If you want loop() to do something only when there is serial data to process, do this:

void loop()
{
   if(Serial.available() > 0)
   {
      // Read and process all the data here
      int readLength = Serial.available();
      char buffer[readLength+1];
      for(int i=0; i<readLength; i++)
      {
         buffer[i] = Serial.read();
         buffer[i+1] = '\0'; // NULL terminate the array
      }

      // Now do something with the serial data
   }
}

There is no reason to have the delay in the for loop. You KNOW that there is data to read. There is no reason to wait for anything.

void loop()
{
   if(Serial.available() > 0)
   {
      // Read and process all the data here
      int readLength = Serial.available();
      char buffer[readLength+1];
      for(int i=0; i<readLength; i++)
      {
         buffer[i] = Serial.read();
         buffer[i+1] = '\0'; // NULL terminate the array
      }

      // Now do something with the serial data
   }
}

I tried something very identical to that.

The problem is, with very long strings, that the program goes straight to collecting the chars together while there are still some in the buffer.

So, if you use “ReadLength = Serial.Available()”, then ReadLength in the for loop, in longer strings, Serial.Available has increased already. So, that loop up there is to wait until serial.available has stopped increasing for 5 milliseconds.

Alternately, just made this.

String InputBuffer = String();

void setup() {
  Serial.begin(9600);
  Serial.println("Hello Computer, This is Arduino 1");
}

void loop() {
  while (Serial.available() > 0) {
    InputBuffer.concat(Serial.read());
    delay(2);
  }
  if (InputBuffer.length() > 0) {
    Serial.println(InputBuffer);
    InputBuffer = String();
  }
  
}

Quite a bit more elegant, if a bit big bytes wise. (4k+ instead of 2k+ for the other one)

If you are not reading to the end of the string, when the serial data being transmitted is long, that is a clear indication that you need to change HOW you are sending the data, to include an end-of-packet marker.

Then, the Arduino code should read serial data until it receives that end-of-packet marker.

The various delays that you are using simply mask the problem. They don't solve it.

That above delay could be removed without affecting the program.

But yes, I see your point. though, one additional question.

Assuming I use your suggestion to use a end-of-packet char, such as the pound sign.

It'll be a while loop until Serial.Read hits a pound sign, wouldn't it? But how could I extend the array while i'm doing it without using a String object? Is it even possible because the size of incoming isn't known?

But, regardless, thanks for the tip about the EOF symbol.

String InputBuffer = String();

void setup() {
  Serial.begin(9600);
  Serial.println("Hello Computer, This is Arduino 1");
}

void loop() {
  while (Serial.available() > 0) {
    InputBuffer.concat(char(Serial.read()));
    if (InputBuffer.endsWith('

)){      Serial.println(InputBuffer);      break;    }    }

  } ```

It'll be a while loop until Serial.Read hits a pound sign, wouldn't it? But how could I extend the array while i'm doing it without using a String object? Is it even possible?

Yes, you would use a while loop. You can't dynamically change the size of an array.

A String object dynamically allocates more space than it needs. If that space fills up, it dynamically allocates more space, in another location, and then copies the data it has to that new space, adds the new data, and frees the original space it was using. This is why strings carry so much overhead.

You could use a String object, and suffer the overhead, or use a fixed size global array that is sized to hold the longest string that you think you will ever encounter.

Hm, that's a shame.

I guess i'll suffer the overhead. Eh, sorry. How do you clear a string object anyway? And thanks for the help - it really is very educational.

Edit: I'm a moron InputBuffer = "";

Alright, thanks. I'll be back soon with more idiotic questions.

EDIT: Hm, just re-read the Reference Manual. Theoretically, can't I use Sizeof, then redefine the array everytime it reads another character with "Sizeof + 1"? Am I doing something silly again?

If you put the array declaration inside the while loop, so that you can (try to) resize it, it goes out of scope as soon as the end of the while loop is reached (not when the while loop ends) resulting in complete data loss.

And then copy the array into a global array after you’re done. But yeah. Regardless, i’m here with another stupid question.

Why won’t this code work? Skip all the complicated functions - all that matters is the setup and the loop, as everything is stripped out.

Arduino 1:

String InputBuffer = String();
int Pins[6] = {3,5,6,9,10,11};
boolean Direction[6] = {1,2,4,7,8,12};

void setup() {
  Serial.begin(9600);
//  Serial.println("Arduino ROV reporting for Duty");
//  for(int i = 0; i > 5; i++){
//    pinMode(Pins[i], OUTPUT);
//    pinMode(Direction[i], OUTPUT);
//  } //Init Pins to Output
  
  
}

boolean ReadIncoming(){
  while (Serial.available() > 0) {
    InputBuffer.concat(char(Serial.read())); //Read until Pound sign
    if (InputBuffer.endsWith('

Arduino 2:

#include <NewSoftSerial.h>

String InputBufferComp = String();
String BitBuffer = String();
NewSoftSerial BitSerial(2,3);

boolean ReadIncomingSerial(){
  while (Serial.available() > 0) {
    InputBufferComp.concat(char(Serial.read())); //Read until Pound sign
    if (InputBufferComp.endsWith('

Arduino 1 is powered by a 9 volt battery, and the Tx pin is connected to pin 2 of Arduino 2, and Rx pin is connected to pin 3 of the Arduino 2.

As you can see, Arduino two initializes Serial and NewSoftSerial. It then repeatedly tries to send something to Arduino 1, and Arduino one is supposed to reply with “received”, which will make arduino two print “Received!” in serial monitor.

It isn’t. It loops, keeps sending 1234$, but nothing’s coming back.

)){ //Note, Infinite loop if Pound not found
     InputBuffer = InputBuffer.replace(’


Arduino 2:

§DISCOURSE_HOISTED_CODE_1§


Arduino 1 is powered by a 9 volt battery, and the Tx pin is connected to pin 2 of Arduino 2, and Rx pin is connected to pin 3 of the Arduino 2.

As you can see, Arduino two initializes Serial and NewSoftSerial. It then repeatedly tries to send something to Arduino 1, and Arduino one is supposed to reply with "received", which will make arduino two print "Received!" in serial monitor.

It isn't. It loops, keeps sending 1234$, but nothing's coming back.

,' ');
      InputBuffer = InputBuffer.trim(); //Input Buffer is a global Var  
      return true;  //True if Pound sign returned, remove Pound sign
    } 
  }
}

boolean ControlMotor(){
  char TempArray[5];
  if (InputBuffer.length() == 4){
    InputBuffer.toCharArray(TempArray, sizeof(TempArray));
    int InputSpeed = atoi(TempArray); //Bad C code right here
    int PinRef = InputSpeed;
    while(PinRef >= 10)
      PinRef /= 10;
    InputSpeed = InputSpeed - (PinRef * 1000); //Minus first digit
    if ((PinRef <= 5) && (InputSpeed > 0) && (InputSpeed < 512)){
      Serial.print("Motor Control Init: Motor Pin ");
      Serial.println(Pins[PinRef]); //Lookup PinRef within Pins Array
      Serial.print("Motor Direction: ");
      Serial.println(InputSpeed <= 255);
      Serial.print("Motor Speed: ");
      Serial.println(InputSpeed);
      Serial.print("$");
//      if (InputSpeed <= 255)
//        digitalWrite(Direction[PinRef], HIGH);
//      else{
//        digitalWrite(Direction[PinRef], LOW);  
//        InputSpeed = InputSpeed - 255;
//      }    
//      analogWrite(Pins[PinRef], InputSpeed);
//      return true;        
    }      
  }
 return false;
}


void loop() {
 
   if (Serial.available()) Serial.println("Received");   
      
}

Arduino 2:

§_DISCOURSE_HOISTED_CODE_1_§

Arduino 1 is powered by a 9 volt battery, and the Tx pin is connected to pin 2 of Arduino 2, and Rx pin is connected to pin 3 of the Arduino 2.

As you can see, Arduino two initializes Serial and NewSoftSerial. It then repeatedly tries to send something to Arduino 1, and Arduino one is supposed to reply with “received”, which will make arduino two print “Received!” in serial monitor.

It isn’t. It loops, keeps sending 1234$, but nothing’s coming back.

)){ //Note, Infinite loop if Pound not found
     return true;  //True if Pound sign returned, remove Pound sign
   }
 }  
}

boolean ReadBitSerial(){
 while (BitSerial.available() > 0) {
   BitBuffer.concat(char(BitSerial.read())); //Read until Pound sign
   if (BitBuffer.endsWith(’


Arduino 1 is powered by a 9 volt battery, and the Tx pin is connected to pin 2 of Arduino 2, and Rx pin is connected to pin 3 of the Arduino 2.

As you can see, Arduino two initializes Serial and NewSoftSerial. It then repeatedly tries to send something to Arduino 1, and Arduino one is supposed to reply with "received", which will make arduino two print "Received!" in serial monitor.

It isn't. It loops, keeps sending 1234$, but nothing's coming back.

)){ //Note, Infinite loop if Pound not found
      InputBuffer = InputBuffer.replace('

Arduino 2:

§_DISCOURSE_HOISTED_CODE_1_§

Arduino 1 is powered by a 9 volt battery, and the Tx pin is connected to pin 2 of Arduino 2, and Rx pin is connected to pin 3 of the Arduino 2.

As you can see, Arduino two initializes Serial and NewSoftSerial. It then repeatedly tries to send something to Arduino 1, and Arduino one is supposed to reply with “received”, which will make arduino two print “Received!” in serial monitor.

It isn’t. It loops, keeps sending 1234$, but nothing’s coming back.

,’ ');
     InputBuffer = InputBuffer.trim(); //Input Buffer is a global Var  
     return true;  //True if Pound sign returned, remove Pound sign
   }
 }
}

boolean ControlMotor(){
 char TempArray[5];
 if (InputBuffer.length() == 4){
   InputBuffer.toCharArray(TempArray, sizeof(TempArray));
   int InputSpeed = atoi(TempArray); //Bad C code right here
   int PinRef = InputSpeed;
   while(PinRef >= 10)
     PinRef /= 10;
   InputSpeed = InputSpeed - (PinRef * 1000); //Minus first digit
   if ((PinRef <= 5) && (InputSpeed > 0) && (InputSpeed < 512)){
     Serial.print("Motor Control Init: Motor Pin ");
     Serial.println(Pins[PinRef]); //Lookup PinRef within Pins Array
     Serial.print("Motor Direction: ");
     Serial.println(InputSpeed <= 255);
     Serial.print(“Motor Speed: “);
     Serial.println(InputSpeed);
     Serial.print(”$”);
//      if (InputSpeed <= 255)
//        digitalWrite(Direction[PinRef], HIGH);
//      else{
//        digitalWrite(Direction[PinRef], LOW);  
//        InputSpeed = InputSpeed - 255;
//      }    
//      analogWrite(Pins[PinRef], InputSpeed);
//      return true;        
   }      
 }
return false;
}

void loop() {

if (Serial.available()) Serial.println(“Received”);  
     
}


Arduino 2:

§DISCOURSE_HOISTED_CODE_1§


Arduino 1 is powered by a 9 volt battery, and the Tx pin is connected to pin 2 of Arduino 2, and Rx pin is connected to pin 3 of the Arduino 2.

As you can see, Arduino two initializes Serial and NewSoftSerial. It then repeatedly tries to send something to Arduino 1, and Arduino one is supposed to reply with "received", which will make arduino two print "Received!" in serial monitor.

It isn't. It loops, keeps sending 1234$, but nothing's coming back.

)){ //Note, Infinite loop if Pound not found
      return true;  //True if Pound sign returned, remove Pound sign
    } 
  }
}

void setup() {
  Serial.begin(9600);
  BitSerial.begin(9600);
  Serial.println("Arduino Shore reporting for Duty");
}

void loop() {
//  if (ReadIncomingSerial()){
//    Serial.println("Incoming data from Computer.");
//    BitSerial.println(InputBufferComp);
//    Serial.println(BitSerial.available(), DEC);
//    Serial.println(InputBufferComp);
//    InputBufferComp = "";
//  }
//  if (ReadBitSerial()){
//    Serial.println("Incoming data from ROV.");
//    Serial.print(BitBuffer);
//    Serial.println(" :Rov");
//    BitBuffer = "";
//  }
  BitSerial.println("1234$");
  if (BitSerial.available()) Serial.println("Received!");
}

Arduino 1 is powered by a 9 volt battery, and the Tx pin is connected to pin 2 of Arduino 2, and Rx pin is connected to pin 3 of the Arduino 2.

As you can see, Arduino two initializes Serial and NewSoftSerial. It then repeatedly tries to send something to Arduino 1, and Arduino one is supposed to reply with “received”, which will make arduino two print “Received!” in serial monitor.

It isn’t. It loops, keeps sending 1234$, but nothing’s coming back.

)){ //Note, Infinite loop if Pound not found
     InputBuffer = InputBuffer.replace(’


Arduino 2:

§DISCOURSE_HOISTED_CODE_1§


Arduino 1 is powered by a 9 volt battery, and the Tx pin is connected to pin 2 of Arduino 2, and Rx pin is connected to pin 3 of the Arduino 2.

As you can see, Arduino two initializes Serial and NewSoftSerial. It then repeatedly tries to send something to Arduino 1, and Arduino one is supposed to reply with "received", which will make arduino two print "Received!" in serial monitor.

It isn't. It loops, keeps sending 1234$, but nothing's coming back.

,' ');
      InputBuffer = InputBuffer.trim(); //Input Buffer is a global Var  
      return true;  //True if Pound sign returned, remove Pound sign
    } 
  }
}

boolean ControlMotor(){
  char TempArray[5];
  if (InputBuffer.length() == 4){
    InputBuffer.toCharArray(TempArray, sizeof(TempArray));
    int InputSpeed = atoi(TempArray); //Bad C code right here
    int PinRef = InputSpeed;
    while(PinRef >= 10)
      PinRef /= 10;
    InputSpeed = InputSpeed - (PinRef * 1000); //Minus first digit
    if ((PinRef <= 5) && (InputSpeed > 0) && (InputSpeed < 512)){
      Serial.print("Motor Control Init: Motor Pin ");
      Serial.println(Pins[PinRef]); //Lookup PinRef within Pins Array
      Serial.print("Motor Direction: ");
      Serial.println(InputSpeed <= 255);
      Serial.print("Motor Speed: ");
      Serial.println(InputSpeed);
      Serial.print("$");
//      if (InputSpeed <= 255)
//        digitalWrite(Direction[PinRef], HIGH);
//      else{
//        digitalWrite(Direction[PinRef], LOW);  
//        InputSpeed = InputSpeed - 255;
//      }    
//      analogWrite(Pins[PinRef], InputSpeed);
//      return true;        
    }      
  }
 return false;
}


void loop() {
 
   if (Serial.available()) Serial.println("Received");   
      
}

Arduino 2:

§_DISCOURSE_HOISTED_CODE_1_§

Arduino 1 is powered by a 9 volt battery, and the Tx pin is connected to pin 2 of Arduino 2, and Rx pin is connected to pin 3 of the Arduino 2.

As you can see, Arduino two initializes Serial and NewSoftSerial. It then repeatedly tries to send something to Arduino 1, and Arduino one is supposed to reply with “received”, which will make arduino two print “Received!” in serial monitor.

It isn’t. It loops, keeps sending 1234$, but nothing’s coming back.

Are the Gnd pins connected between the two Arduinos?

EDITED POST:

Thanks for the point about the groudn pins.

They're currently fine. Now, I get this strange error with NewSoftSerial, as if the baud rate for one is not exactly correct.

I'm currently using two arduinos. One is constantly transmiting "CHECK!" at the TX pin, which is connected to pin 2 of the second arduino. This pin 2 is a new soft serial.

I have set the program to repeat exactly whatever's received on pin 2.

So, now, i'm getting absolutely nothing. However, when I move the jumper contact against the "side" of the female header pin on the arduino, I get something "CHECK!". But only while i'm moving it up and down, around 40% of the time.

Any ideas?

If it helps, the first arduino which is transmitting "CHECK!" is powered using a 9v battery.