Serial Com : stream data, too fast ?

hello everybody,

i want to dim some leds with processing and arduino. so i found a great code on arduino cookbook about sending datas from processing to arduino. this works fine by sending message one after the other simply by clicking, but leds become crazy at higher rate. indeed if i send datas from the void draw() function it doesn’t work well but with mousePressed it’s good. is processing going too fast for arduino ?
here the code :

PROCESSING PART

import processing.serial.*;
Serial myPort;
String val;
int cpt;

void setup(){
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
  }

void draw(){
  //counter for led brightness
  if(frameCount%5==0){
  cpt++;
  val = cpt+","+cpt+","+cpt+"\n";
  //to arduino
  myPort.write(val);
  println("cpt "+cpt);
  println("val "+val);
  if (cpt>253)cpt=0;
  }}

void mousePressed(){
  //led brightness control by hand
  if(mouseButton == LEFT){
  cpt+=10;
  val = cpt+","+cpt+","+cpt+"\n";
  myPort.write(val);
  if(cpt>254)cpt = 0;  
}
  if(mouseButton == RIGHT){
  cpt-=10;
  val = cpt+","+cpt+","+cpt+"\n";
  myPort.write(val);
  }
  println(cpt);
  println("val "+val);
}

ARDUINO PART

/*
 * SerialReceiveMultipleFields sketch
 * This code expects a message in the format: 12,345,678
 * This code requires a newline character to indicate the end of the data
 * Set the serial monitor to send newline characters
 */
#define LEDR 9
#define LEDJ 10
#define LEDV 11
const int NUMBER_OF_FIELDS = 3; //how many comma separated field we expect
int fieldIndex = 0;
int values[NUMBER_OF_FIELDS];
byte r, j, v=0;

void setup(){
  Serial.begin(9600); //initialize serial port to send and receivedata at 9600 bits per seond
  pinMode(LEDR, OUTPUT);
  pinMode(LEDJ, OUTPUT);
  pinMode(LEDV, OUTPUT);
 }
 
 void loop(){
   if(Serial.available()){
   char ch = Serial.read();
   if(ch >= '0' && ch <= '9'){// is this an ASCII digit between 0 and 9 ?
   //yes accumulate the value
   values[fieldIndex] = (values[fieldIndex] *10) + (ch - '0'); 
   }
   else if(ch == ','){//comma is our separator, so move on the next field
   if(fieldIndex < NUMBER_OF_FIELDS-1)fieldIndex++;//increment field index
   }
   else {
     // any character not a digit or comma ends the acquisition of fields
     // in this example it's the newline character sent by the Serial Monitor
   //Serial.print( fieldIndex +1);
     // Serial.println(" fields received:");
//LEDS value      
r = values[0];
      j = values[1];
      v = values[2];
      
      for(int i=0; i <= fieldIndex; i++)
      {
        //on stoke la valeur avant qu'elle ne soit remise à zero
        //val[i] = values[i];
        //Serial.println(values[i]);
        values[i] = 0; // set the values to zero, ready for the next message
      }
      fieldIndex = 0;  // ready to start over
    }
blink();  
delay(20);
}
 
 
 }
 
//my LEDS
void blink(){
analogWrite(LEDR, r);
analogWrite(LEDJ, j);
analogWrite(LEDV, v);

}

thank you in advance :slight_smile:

There are coding styles that call for the curly brace on the same line as the if/for/while statement, like so:

if(someValue == someOtherValue) {

There are coding styles that call for the curly brace on the next line, like so:

if(someValue == someOtherValue)
{

There are NONE that call for the curly brace to be jammed tight up against the end of the statement and then followed by a comment withnospacesanywhere.

I prefer the second style. I also prefer that people use Tools + Auto Format to properly indent code before posting.

Your blink() function does not cause the LEDs to blink, so that's a pretty poor choice of names.

Your biggest problem, though is this:

delay(20);

Why are you calling the heyImGoingToDoNothingForAWhileFeelFreeToDiscardSerialDataWhenTheBufferOverflows() function?

:astonished: wahoo ! ok i'm sorry for all... i will try to do my best

so now what can i do ? i've tried several delay value but it's doesn't change a lot of things... maybe i have to send a message to P5 after each \n ?

how can i synchronized arduino and p5 ? how do you choose the value of delay ?

i've tried several delay value but it's doesn't change a lot of things...

Have you tried the most obvious one? None. Do not call delay at all.

how can i synchronized arduino and p5 ?

You could have the Arduino send a message to Processing each time it is ready to receive data. There is an example (SerialCallResponse IIRC) that shows how.

ok i thought that the delay function was compulsory because i've seen a lot sketch with it or with millis()...

thank you for your fast reply !

ok i thought that the delay function was compulsory because i've seen a lot sketch with it or with millis()...

If you want things to happen after predefined periods of time, that is true. Blinking an LED requires some way to periodically turn it on or off. Fading a LED also requires periodically changing the PWM value.

Your changes are not happening at regular intervals. They happen when the PC tells (actually, when it finishes telling) the Arduino to do something.

That can happen once a week, once a day, once an hour, at unpredictable intervals, or as fast as possible as the mouse moves.

Once thing that you need to keep in mind is that serial data delivery follows the USPS model, not the UPS model.

UPS guarantees to deliver your package. USPS guarantees to try to deliver your package. Send it via UPS and it will get there. Send it via USPS and it might or might not get there, and it might or might not arrive undamaged.

Only undamaged packages are accepted at the serial port and put into the buffer. Now, this does not imply that what is in the buffer constitutes a complete, undamaged packet, since there are no "I'm a start of packet marker", "I'm an end of packet marker", "I define how big a packet is", or "I define how to tell that the packet is correct" type of data in your packets.

What you are doing is fine for coloring LEDs, but it is a long ways from robust code needed for more complex communications. In your case, the next iteration of draw() corrects the color, if the color was misinterpreted due to data loss.

i understand what you mean about paquet checking. with some conditions you keep only complete paquets. but it may kill the sending rate, no ?

another question : message in my code are something like this : 125,155,56\n arduino receive this message in byte, isn't it ?

my message -> ASCII transposition -> byte transposition -> arduino reception -> ASCII transposition...

so one byte for the first value, one byte for ',' one for the second value etc... we've got a byte for each element, isn't it ? so my message is 7 bytes long, am i wrong ?

so my message is 7 bytes long, am i wrong ?

Yes, you are.

message in my code are something like this : 125,155,56\n

Count the number of characters. 1, 2, 3, 4 (comma), 5, 6, 7, 8 (comma), 9, 10, 11 (carriage return).

By the way, your messages are NOT like that.

  val = cpt+","+cpt+","+cpt+"\n";

You are sending the same value 3 times, with commas between them and carriage return at the end.

yes i know that it's the same value, i code this quickly.

ok 125,155,56\n is equal to 12 bytes, isn't it ?

and i think about something, if i choose to add a value in my message to choose a blinking rate for an extra led like for example the led 13. so i will be able to choose brightness for my 3 leds and the blink rate of the led 13 with one message. how can i use the delay function for blinking led 13 without creating trouble in the data reception ?

ok 125,155,56\n is equal to 12 bytes, isn't it ?

No. \n is one byte.

how can i use the delay function for blinking led 13 without creating trouble in the data reception ?

You can't. That's what the blink without delay example is for.