Go Down

Topic: Serial.print incomplete string ? (Read 1 time) previous topic - next topic

Rizzla

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.

billroy

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

-br

Rizzla

#2
Dec 14, 2012, 01:43 pm Last Edit: Dec 14, 2012, 01:49 pm by AWOL Reason: 1
Arduino:

Code: [Select]
#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

HazardsMind

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

delay(50); should do it.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

Rizzla

Where should i put this delay code ?

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

HazardsMind

Actually, you should try to increase the baud rate to 115200, and make sure the serial monitor is set to the same.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

Rizzla

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

HazardsMind

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

Code: [Select]
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?
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

PeterH

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 only provide help via the forum - please do not contact me for private consultancy.

liudr

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.

Rizzla

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 ;)

Thanks y'all

robtillaart


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.

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

zoomkat


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.

Code: [Select]
globalString = "";
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

HazardsMind

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.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

PeterH


should eliminate any problems with the string.


Does that also resolve the memory leak problem?
I only provide help via the forum - please do not contact me for private consultancy.

Go Up