Go Down

Topic: Serial Communication from Processing TO Arduino producing errors after some time (Read 1 time) previous topic - next topic

Ron04317

Hi Guys,

I am working on a drawing-machine, using processing for sending coordinates to my arduino due via serial.
Currently, I am having some trouble with the communication-part.
I built my code basing largely on common tutorials for this kind of usage (serial communication from processing->arduino)

The code I got so far for both sides is basicallys doing what I want, BUT:

After a certain point, usually around the 12th coordinate beeing send from processing to arduino,
the recieved values start to have errors and then the whole communication seems to get out of sync.


The fact, that the code works at the beginning but fails after some repetitions gives me the impression,
that the error must lie in some kind of data overflow. (mabye some kind of buffer at the arduino?)
Unfortunately, I do not know enough about the details of serial-communication to figure that one out for myself.


Maybe you guys could help me? That would be awesome.

My questions would be:

-is there some kind of input-buffer that would need to be cleared to prevent it from overflowing?

-is the handshake-communication-method done the right way in my code?

-what other reasons could there be for this kind of errors by time?

If you find something awfully stupid in my code, I am also happy to get hints of course,
always eager to learn something ;)

Thank you all!

You find my code here:
(FYI: as you will see, the current processing-code sends a set of 15 x/y-coordinates in a loop-> thats the placeholder for the actual coordinate-routine, which is working and therefore of no concern here)


Processing-Code

Code: [Select]
import processing.serial.*; //import the Serial library

Serial myPort;  //the Serial port object
String val;

boolean firstContact = false; // since we're doing serial handshaking,
                              // we need to check if we've heard from the microcontroller
                             
int dataX[]={10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150};
int dataY[]={15, 25, 35, 45, 55, 65, 75 ,85 , 95, 105, 115, 125, 135, 145, 155};



void setup()
{
  size(500, 500); //make our canvas 200 x 200 pixels big
  myPort = new Serial(this, Serial.list()[1], 9600); //  initialize your serial port and set the baud rate to 9600
  delay(2000);
  myPort.bufferUntil('\n'); //This let's us store the incoming data into a buffer, until we see a specific character we're looking for.
}

void draw()
{
  //we can leave the draw method empty,
  //because all our programming happens in the serialEvent (see below)
}

void serialEvent( Serial myPort)
{
  val = myPort.readStringUntil('\n');    //put the incoming data into a String - the '\n' is our end delimiter indicating the end of a complete packet
  if (val != null)    //make sure our data isn't empty before continuing
  {
    val = trim(val);    //trim whitespace and formatting characters (like carriage return)
    println(val);
    if (firstContact == false)
    {
      if (val.equals("A"))  //look for our 'A' string to start the handshake,
      {
        myPort.clear();     //if it's there, clear the buffer, and send a request for data
        firstContact = true;
        myPort.write("A");
        println("contact");
       }
    }
    else
    { //if we've already established contact, keep getting and parsing data
      println(val);
      for(int i= 0;i<=14;i++)
      {
        myPort.write("B"); 
        myPort.write("X");
        myPort.write(dataX[i]);
        delay(10);
        myPort.write("Y");
        myPort.write(dataY[i]);
        delay(10);
      }
    }
    myPort.write("A");// when you've parsed the data you have, ask for more:
 }
}


Arduino-Code

Code: [Select]

char val; // Data received from the serial port
int ledPin = 13; // Set the pin to digital I/O 13
boolean ledState = LOW; //to toggle our LED

int newX;
int newY;

int counter = 0;

void setup()
{
  pinMode(ledPin, OUTPUT); // Set pin as OUTPUT
  //initialize serial communications at a 9600 baud rate
  Serial.begin(9600);
  establishContact();  // send a byte to establish contact until receiver responds
}

void loop()
{
  if (Serial.available() > 0) // If data is available to read,
  {
    val = Serial.read(); // read it and store it in val
    if(val == 'B') //if we get a B
    {
      val = Serial.read();
      if(val == 'X')
      {
        newX = Serial.read();
        Serial.println("New X = ");
        Serial.println(newX);
      }
      val = Serial.read();
      if(val == 'Y')
      {
        newY = Serial.read();
        Serial.println("New Y = ");
        Serial.println(newY);
      }
      Serial.print("counter = ");
      Serial.println(counter);
      Serial.println("moving .......");
      counter++;
     
      delay(300);
           
     
    }
   
  }
  else
  {
    Serial.println("Arduino Waiting for Input!"); //send back a hello world
    delay(50);
  }
}

void establishContact()
{
  while (Serial.available() <= 0)
  {
  Serial.println("A");   // send a capital A
  delay(300);
  }
}




Robin2

Your system for receiving data is not robust - relying on delay()s is not a good idea. The Arduino needs to have a means of knowing when the data starts and ends without relying on time.

Look at the third example in the Thread serial input basics and also, possibly, the code for parsing input.

As a more general comment, a program for a drawing machine should not use the delay() function anywhere. Use millis() to manage timing as illustrated in several things at a time.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Ron04317

Hi Robin,

thank you, thats good input. I will check out your tutorials soon!
And thanks for reminding me at the delay() vs. millis() issue. I already thought about that.

Go Up