Serial.print incomplete string ?

Hello everyone,

I made a controller with 12 buttons, and when each button is pressed its send a string over to actionscript.
The strings that i send are "A1","A2" and so on.
But sometimes the string i receive is "2" instead of "A2".

How can i fix this, because this is very annoying because sometimes the action trigged by the button never fires because of the incomplete string.

It is hard to give advice without seeing the code for both transmit and receive. Does the problem get worse under load?

-br

Arduino:

#include <Button.h>

Button button2(2, BUTTON_PULLUP_INTERNAL);
Button button3(3, BUTTON_PULLUP_INTERNAL);
Button button4(4, BUTTON_PULLUP_INTERNAL);
Button button5(5, BUTTON_PULLUP_INTERNAL);
Button button6(6, BUTTON_PULLUP_INTERNAL);
Button button7(7, BUTTON_PULLUP_INTERNAL);
Button button8(8, BUTTON_PULLUP_INTERNAL);
Button button9(9, BUTTON_PULLUP_INTERNAL);
Button button10(10, BUTTON_PULLUP_INTERNAL);
Button button11(11, BUTTON_PULLUP_INTERNAL);
Button button12(12, BUTTON_PULLUP_INTERNAL);
Button button13(13);

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

void loop() {
  
  if(button2.uniquePress()){
    Serial.print("D1");
  }
  if(button3.uniquePress()){
    Serial.print("D2");
  }
  
  if(button4.uniquePress()){
    Serial.print("D3");
  }
  if(button5.uniquePress()){
    Serial.print("C1");
  }
  
  if(button6.uniquePress()){
    Serial.print("C2");
  }
  if(button7.uniquePress()){
    Serial.print("C3");
  }
  
  if(button8.uniquePress()){
    Serial.print("B1");
  }
  if(button9.uniquePress()){
    Serial.print("B2");
  }
  
  if(button10.uniquePress()){
    Serial.print("B3");
  }
  if(button11.uniquePress()){
    Serial.print("A1");
  }
  if(button12.uniquePress()){
    Serial.print("A2");
  }
  if(button13.uniquePress()){
    Serial.print("A3");
  }
  
}

Actionscript:

private function socketDataHandler(event:Event):void{
var socket:Socket = event.currentTarget as Socket;
var data:String = socket.readUTFBytes(socket.bytesAvailable);
trace(data);
playSoundArduino(data);
}

Moderator edit: CODE TAGS

You could add a delay in your code, to give it some time to process the data

delay(50); should do it.

Where should i put this delay code ?

And is this a good idea ?
Because the buttons are pressed rapidly (beatbox machine)

Actually, you should try to increase the baud rate to 115200, and make sure the serial monitor is set to the same.

I notice that it happens less frequent now, but it still happens.
What's the maximum you can crank this up ?

I think that is the max, you may need to add the delay between here:

if(button2.uniquePress()){
    delay(50);    // try this for all of them
    Serial.print("D1");
  }

Also, you dont want to make them println, because they will be printed back to back with no space?

I suspect the problem is that on the actionscript side you are reading all available bytes from the serial stream and assuming you have got a complete message, but you may only have received a partial message. It would be better to have the actionscript code explicitly determine the end of each message, for example by putting a newline separator between messages and having the actionscript detect that to know that it has received a complete message.

I share PeterH's view. You should use arduino serial monitor to confirm that all button pushes generate complete messages they intend to generate. If you can confirm it, then the problem resides with actionscript. I don't think the delay and max baud rate suggestions are relevant to your problem, especially not knowing what this button.h is.

This is the solution

private function inputReceived(inputOfArduino:String):void {
globalString += inputOfArduino;
while(globalString.length > 1) {
var chord:String = globalString.substr(0, 2);
trace("play chord: " + chord);
globalString = globalString.substr(2);

playSoundArduino(chord);
}

}

The chord is the right String, just bu building a buffer :wink:

Thanks y'all

using the String class is considered a bad idea as there are problems with the dynamic nature of the class.

Serial baudrate can be up to 500.000baud however the standard IDE will not support it. You must use another terminal program.

robtillaart:
using the String class is considered a bad idea as there are problems with the dynamic nature of the class.

I've read the String class arguments and including simple cleanup like below might be solution.

globalString = "";

I agree with Zoomkat, when your writing to a string, as so (globalString += inputOfArduino;), you write to it, make it do it's job, then you have to clear it.
If you don't clear it, it will continue to build up and slow down the processor. I learned this the hard way, with my project.
adding this "globalString = "";" after "globalString = globalString.substr(2);" should eliminate any problems with the string.

HazardsMind:
should eliminate any problems with the string.

Does that also resolve the memory leak problem?

How would you know if you are having memory leakage problems, how do I test this?

Because I use strings a lot but, I never noticed any problems.

Fellows, I think you may have the String thing mixed up. The OP is only using String in actionscript. Isn't that run on a computer instead of on Arduino? 8)

Regarding memory leak, I heard from experts that is a problem with free(). HazardsMind, you may not have experienced a problem possibly because you are not defining String in subroutines or loop (did you just define String outside functions?). There are plenty of others that did get into trouble and fixed the problem by not using String. The problem is if you have a String in functionX then every time the function quits free() should clean up the String but it doesn't, that's what I heard.

@liurd

I'll post a sample from my robot code when I get home, I don't have it on me right now.

It there a way to see the memory leakage?

HazardsMind:
It there a way to see the memory leakage?

I used this:

http://playground.arduino.cc/Code/AvailableMemory

This also pertains to String objects too, right?