My program getting slower when I write datas on Serial Port

Hello,
I think there is a problem with my Processing program to write datas to the Serial Port. Or there is a problem with my Arduino code to read datas from the serial Port.

I give you both program. Thank you.

import java.util.Arrays;
import sync.*;
// MANAGE ARDUINO
import processing.serial.*;
Serial arduinoport;


void setup() {
  
    frameRate(80); 
   //perspective setting
  size(1000, 800, P3D);
  
  //********to send value to Arduino
  String[] ports = Serial.list();
 // printArray(ports);
   printArray(Serial.list());
  arduinoport = new Serial(this,ports[6],115200);//Carefull: chosse the port matching to the serial list
    
}

void draw() {
 arduinoPos ( );
}

void arduinoPos () {
  
  
    for (int i = 0; i < 5; i++) {
 
   
    String pos = (-232) +"*"+(4232) +"*"+(1111)+"*"+(56232)+"*"+(-222)+"*"; 
    
 // String pos = (int (i*2))+"*"+ (int (10))+"*"+ (int (-i))+"*"+ (int (12))+"*"+ (int (314))+"*";//
       
       print ("  pos   ");println (pos);
       
       arduinoport.write(pos); // Send data to Arduino.
      
  }  
}   

The Arduino program below

#include <AccelStepper.h>

// Define a stepper and the pins it will use
#define NBMOTEURS 5

#define NBPASPARTOUR 200

// Define a stepper and the pins it will use
#define STEP 1//-->Mode pas complet

#define PINDIRECTION0  12
#define PINSPEED0  13

#define PINDIRECTION1  10
#define PINSPEED1  11

#define PINDIRECTION2  8
#define PINSPEED2  9

#define PINDIRECTION3  6
#define PINSPEED3  7

#define PINDIRECTION4  4
#define PINSPEED4  5

/*
const uint8_t PINDIRECTION[NBMOTEURS] =  {8, 12};
const uint8_t PINSPEED[NBMOTEURS] =  {9, 13};
*/
//int stepper[] = NBMOTEURS;
//AccelStepper stepper[i](STEP, PINSPEED0, PINDIRECTION0);  


AccelStepper stepper[ NBMOTEURS] = {
AccelStepper (STEP, PINSPEED0, PINDIRECTION0), 
AccelStepper (STEP, PINSPEED1, PINDIRECTION1), 
AccelStepper (STEP, PINSPEED2, PINDIRECTION2), 
AccelStepper (STEP, PINSPEED3, PINDIRECTION3), 
AccelStepper (STEP, PINSPEED4, PINDIRECTION4),  
};

#define ANALOG_IN A0

int analog_in;
int positionX;

void setup()
{  
   //     pinMode(LED_BUILTIN, OUTPUT);
    Serial.begin (115200);
    SerialUSB.begin (9600); // it doesn't make any sens but i prefer

      SerialUSB.print ("A "); SerialUSB.println (-4);     
      SerialUSB.print ("B "); SerialUSB.println (-3);        
      SerialUSB.print ("C "); SerialUSB.println (-2);  
      SerialUSB.print ("D "); SerialUSB.println (-1);
      SerialUSB.print ("E "); SerialUSB.println (-10);

      Serial.print ("A "); Serial.println (4);     
      Serial.print ("B "); Serial.println (3);        
      Serial.print ("C "); Serial.println (2);  
      Serial.print ("D "); Serial.println (1);
      Serial.print ("E "); Serial.println (10);

    
  for(uint8_t i = 0; i < NBMOTEURS; i++) {      
  stepper[i].setMaxSpeed(500);
  stepper[i].setAcceleration(150);
   }
}

void loop() { 
   
  receiveData(); // receive data from Processing

     for(uint8_t i = 0; i < NBMOTEURS; i++) {    

  stepper[i].setMaxSpeed(300);
  stepper[i].setAcceleration(150);
  stepper[i].setSpeed(250);
  

  stepper[4].moveTo(w4);
  stepper[3].moveTo(w3);
  stepper[2].moveTo(w2);
  stepper[1].moveTo(w1);
  stepper[0].moveTo(w0); // premiere donnée envoyée dansla chaine de String de Processing = virtualPositon4

  stepper[i].setSpeed(100);
  stepper[i].setAcceleration(10);
  stepper[i].runSpeedToPosition();
 //  stepper[i].run(); // turn without stop
 /*
      SerialUSB.print ("A "); SerialUSB.println (w4);     
      SerialUSB.print ("B "); SerialUSB.println (w3);        
      SerialUSB.print ("C "); SerialUSB.println (w2);  
      SerialUSB.print ("D "); SerialUSB.println (w1);
      SerialUSB.print ("E "); SerialUSB.println (w0);
    //  Serial.print ("F "); Serial.println (i-2);
  */  

  }  
}
void receiveData() {

  if (Serial.available() > 0) { // Ne pas redeclarer w1

    w0 = Serial.parseInt(); // FONCTIONNE AVEC SPEED0 dans Processing et le reste commenté dans Arduino
    w1 = Serial.parseInt(); 
    w2 = Serial.parseInt();
    w3 = Serial.parseInt();
    w4 = Serial.parseInt(); // La dernière donné qui figure sur le serial de Processing arrive en premier sur Arduino

    Serial.read();
    }
  }
1 Like

Hello,

Please do not duplicate post.

Related post:

I wrote some quick code to:

  • Send data from Processing to Arduino (Serial)
  • Send data received to another serial port (Serial1) to monitor incoming data on Arduino monitor (or other terminal software).

It was sending and receiving just fine.

Some observations about your code below.

Processing:

  • It is set to 80 fps.
  • Sending the same data string 5 times in a loop every frame.

Is this necessary? If not slow things down.

I will post code when I clean it up

Arduino *updated*
long w0, w1, w2, w3, w4; // speed in number step /second
boolean dataReady = false;

void setup()
  {
  Serial.begin (9600);  // From Processing
  Serial1.begin (9600); // Arduino Monitor

  Serial1.print ("A "); Serial1.println (-4);
  Serial1.print ("B "); Serial1.println (-3);
  Serial1.print ("C "); Serial1.println (-2);
  Serial1.print ("D "); Serial1.println (-1);
  Serial1.print ("E "); Serial1.println (-10);
  }

void loop()
  {
  receiveData(); // receive data from Processing
  Serial1.println ("loop"); // Mostly for debugging to see of receivData() was blocking code.
  }

void receiveData()
  {
  if (Serial.available() > 0)
    {
//    String inString = Serial.readStringUntil('*');
//    Serial1.println(inString);
//    
//    int inByte = Serial.read();
//    Serial1.print(char(inByte));

    w0 = Serial.parseInt();
    w1 = Serial.parseInt();
    w2 = Serial.parseInt();
    w3 = Serial.parseInt();
    w4 = Serial.parseInt();
    dataReady = true;
    }

  if (dataReady)
    {
    Serial1.println(w0);
    Serial1.println(w1);
    Serial1.println(w2);
    Serial1.println(w3);
    Serial1.println(w4);  
    //dataReady == false; //Arduino flagged this as an error!
    dataReady = false; // Correction
    
}
  }

  
Processing
import processing.serial.*;
Serial arduinoPort;

void setup() 
  {
  frameRate(60); 
  size(500, 500, P3D);
  
  String[] ports = Serial.list();
  printArray(Serial.list());
  arduinoPort = new Serial(this, ports[4],9600);//Carefull: chosse the port matching to the serial list  
  delay(2000); //Arduino reboots when making a serial connection; this gives it some time to be ready. 
  }

void draw() 
  {
  if(frameCount%30 == 0) //Does a write every .5 sec
    arduinoPos( );
  }

void arduinoPos () 
  {
  //for (int i = 0; i < 5; i++) //Why?
    {
    String pos = (-232) +"*"+(4232) +"*"+(1111)+"*"+(56232)+"*"+(-222)+"*"; 
    print ("  pos   ");
    println (pos);
    arduinoPort.write(pos); // Send data to Arduino.
    //arduinoPort.write('\n'); //Use if you want this to end string
    }  
  }   

:)

1 Like

Hey!
Sending data to serial can get really slow. It seems to me that you’re writing 80 x 5 times per seconds (framerate x for loop in arduinoPos() ).
Do you need to send you data that fast?
You could also try reducing the Baud Rate.
Cheers,
Geoffroy

1 Like

We made the same observation and posted at same time!

Good catch!

:)

1 Like

Thank so much Glv, it works now.
I’m sorry for the duplicate post. As I didn’t see it in my diary, I believed I didn’t ask the question.

If I want to keep sending data at 115200 baud at 60 frame rate, which calcul should I do, I want to send 5 datas each .1 sec. And so, how set this if(frameCount%30 == 0) //Does a write every .5 sec.

Thanks so much. :smiling_face_with_three_hearts:

Hello,

The draw cycle has a frame rate of 60 fps (default).
That means each frame is 1/60 second which is 16.66667 ms

Every 6 frames would be 100 ms; you can do the math.

You can review the modulo operator to see how the frameCount timer works.
Write some simple examples of code with println() statements and you will understand it quickly.

However…
The frameRate can vary from frame to frame and frameCount may not serve as the best timer. :)

millis() is always counting in the background and can be read anytime.

You can write some code to display your counter output to see if it suits your application; there will timing errors to consider because you are still sending data during a draw() cycle.

Here is an example of a simple timer that can be adapted:

int timeStart;
int timeIncrement;
int timeNow;

int count = 0;

void setup() 
  {
  size(100, 100);
  timeStart = millis();
  println(timeStart);    
  }

void draw() 
  {
  background(0);
  timeIncrement = 1000;
  timeNow = millis();
  if(timeNow >= timeStart + timeIncrement)
    {
    //Do something
    println(count);
    count++;
    
    timeStart = millis();  // reset for next cycle
    }
  }

There are other discussions out there about precise timing. I only linked one as an example; do some research and see what is out there.

I will be looking in to the use of thread() for this; you inspired that.

It is important that you do some research on this.
I just got you started.

:)

2 Likes