Data getting cut off in serial read

Hi,

I'm trying to control 30+ servos using Processing. Once I calculate the appropriate angle for each servo, I'm writing the angle to the serial port, but I'm only receiving about 15-20 of them in Arduino. My Arduino code is very similar to the one found in the example, though I'm not sure why I'm losing so much data. I've tried adding delays in both Arduino and Processing, but to no avail.

Any thoughts on this?

Thanks.

If the buffer inside the Serial library (in the Arduino) is full, the next incoming data is discarded.

The buffer size is 64 or so (I'm not sure).

If you post your code (in code tags) for both parts of the system, you might get better help.

-br

Below is my code. It seems like random chunks of data are being cut off - it’s not like it’s reading the first x values and discarding the rest.

Processing:

for(int i=0; i<n; i++){
   port.write("s"+n);
}

Arduino:

static int v = 0;

while(Serial.available()){
   char ch = Serial.read();

   switch(ch){
      
      case '0'...'9':
        v = v*10 + ch - '0';
        break;

      case 's':
        Serial.println(v);
        v=0;
        break;
   }
}

FYI, even if I set n to a fraction of n (like n/3), chunks are still missing. n is usually around 30 in my code.

Thanks for posting in code tags. It makes it much easier to read.

I think you're going to have to post all your code. These fragments do not reveal an obvious problem.

-br

Arduino:

void setup(){
   Serial.begin(19200);
   Serial.println("Ready");
}

void loop(){
   (see previous post for loop code)
}

Processing:

Serial port;

void setup(){
   port = new Serial(this, Serial.list()[0], 19200);
}

I think that's all the relevant code. I'm printing out the array in question in Processing and everything looks fine. I've also tried casting to char in Arduino (not that that would make a huge difference), but to no avail.

It is considered polite to post all the code without modifications when requesting help. Neither of those is your compete code.

-br

Apologies.

Arduino:

void setup(){
  Serial.begin(19200);
  Serial.println("Ready");
}

void loop(){
  static int v = 0;

  while(Serial.available()) {
    char ch = (char) Serial.read();

    switch(ch) {
      case '0'...'9':
        v = v * 10 + ch - '0';
        break;
      
      case 's':

        Serial.print(v);

        Serial.println();
        v = 0;
        break;
    }
 }
}

Processing:

import processing.serial.*;
import cc.arduino.*;

int[] servoAngles = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35};
Serial port;

void setup(){
  port = new Serial(this, Serial.list()[0], 19200);
}

void keyPressed(){
  if(key=='s'){
    for(int i=0; i<servoAngles.length; i++){
      println(servoPins[i]);
      port.write("s"+servoPins[i]);
    }
  }
}

void draw(){
  
}

For further clarification, upon pressing ‘s’, the following appears in the Arduino serial monitor:

4
5
6
7
8
9
10

18
19
20
21
22
23
231
32
33
34

Each time it’s run, a different subset of the 35 numbers appears, but there are always chunks missing.

Thank you for your help.

It looks to me like the processing side is over-pressuring the arduino's serial buffer, perhaps overrunning it and causing characters to be dropped. Remember the Arduino only buffers 64 characters ahead on the serial port.

This is a rare case where a delay might help. If the above theory is right, a short delay on the Processing side after each 's' to allow the arduino to catch up might help.

-br

Thanks for the thought. I've unfortunately already tried that, to no avail. Any other ideas?

Oh, cool. Where did you put the delay, what values did you try, and what did you see as a result?

-br

I put delay(50) right after port.write() in my Processing code. I got the following result in the Serial monitor:

Ready
0
1
4

7

0111
1
1


92
22325
26

89331
233

I also tried separating the ‘s’ and the angles:

port.write("s");
delay(20);
port.write(servoAngles[i]);

This gave me a bunch of 0’s in the Serial monitor.

Puzzled here, but the next thing I would try is to wait longer after 's', since that's when the arduino side is going to try to print, and hang in serial, inviting the overrun. Make it absurdly high, like 1000ms, and see if it works, and then tweak it down, maybe?

br

No luck - just a 1 second delay between 0’s. Many of the 0’s didn’t line break either. I’m puzzled as well.

Still puzzled here.

What do you see on the serial monitor if you have the Arduino serial.print the character it receives?

Does it work any better if you test it without the serial monitor open at the same time?

-br

Just tried that, but with a byte instead of a character. Same result/problem. Here’s the modified code I was using:

void loop() {
  delay(10);
  // Temporary buffer
  byte incoming_byte;
  // check if the something is pending
  if (Serial.available() > 0)
  {
    // read the pending byte;
    incoming_byte = Serial.read();
    
    // Sending it back;
    Serial.println(incoming_byte);
  }
}

I wonder if what you are seeing is contention between the serial monitor and Processing.

Anyway, a couple thoughts:

Delete the delay() in that arduino sketch and try it again without?

Try driving your original sketch from serial monitor. Does it work any differently?

-br

Unfortunately the problem persists. Not quite sure what the next steps are here. I recall having similar issues in the past, but I remember always being able to "debounce" it by adding a small delay.

Is it possible to control servos from Processing using analogWrite? This would allow me to bypass sending information over the Serial to Arduino…

You still have to send the servo id and angle via serial for the arduino to do the servo.write().

-br