Program slower when I send data to Arduino

Hello,
I make turning 5 motors with a potar with Arduino. It works perfectly, I make turning them with a simulation from Processing, it all turn but the simulation is slower than if I don’t send datas to Arduino.
What did I do wrong?
I send datas from Processing like this ( my program is lightened)

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.
      
 
  }  
}   

And in Arduino i read my 5 ints separately like this

//***********  Variable de Processing
int w0, w1, w2, w3, w4; // speed in number step /seconde

#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() { 
   

 //testPotarMotor(); // work perfectly
  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();
    }
  }

void testPotarMotor ()  {

   analog_in = analogRead(ANALOG_IN);
   positionX= map ( analog_in, 0, 1023, -200, 200); // 5V

    for(uint8_t i = 0; i < NBMOTEURS; i++) {      
  stepper[i].setMaxSpeed(100);
  stepper[i].setSpeed(100);
  stepper[i].setAcceleration(10);
  stepper[i].moveTo(positionX);
  stepper[i].run();
 // stepper[i].runSpeed();
//  stepper[i].runSpeedToPosition();

  Serial.println (positionX);
  }

  
}
1 Like

Hi bking!

I have not a solution for your problem, so sorry :(. But I’m a lot interested in your example, I’m trying to communicate a Processing Sketch and an Arduino Sketch, to send some data from the first to the second through Serial port.

Maybe you could revolve my code, I think that I’ve near the solution but, at the moment, I can not resolve it :s.
I’m looking your Sketches but I can not see how you resolve this communication.

You can find my codes here :: [SOLVED] Problems sending data from Processing to Arduino through serial port

Thanks in advance!
Best.

Hi @bking, In general there are two ways to solve the problem. The easy way is to reduce your requirement, the more complicated solution is to understand exactly what’s happening and maybe you can fix it. Easy way first, to get it out of the way, send to the Arduino less often, e.g.

if (frameCount % 10 == 0) {arduinoPos();}

Your frameRate is 80, I wonder if it is achieving that, but assume it is for the moment. In arduinoPos function you have for loop sending 5 times? why? What is the length of the message? Looks like 25 chars to me. How many bits per second? = chars * bits/char * num/sec = 25 * 11 * 5 * 80 = 110000. and the baud rate is 115000. So you are very close to the theoretical maximum rate. This is without thinking whether the PC or Arduino are limiting things.

Processing’s console (where the prints() go) has it’s limitations. If you print too much or too fast it can hang up. I think you are near/beyond it’s limits.

1 Like

Hello Richard,
I have tested to send very slowly or very quickly datas from Processing.

If I send the data 500 to one motor, It should go the position 500 with the speed set in the Arduino Program.
But, I I set frameRate(1) and if(frameCount%2 == 0); the motor goes step by step to its position frame by frame. One step / 2 secondes.

Why my motor don’t go to 500 at the speed set in Arduino?
My processing program

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

int i; // to send different speed by multipling i

String time = "";

//  String positions ;

void setup() {
  
    frameRate(120); // by changing frame Rate , i change speed .
   //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() {
  background (0);
    if(frameCount%2 == 0)  {//slow. But with frameCount%1 == 0, motors bug and they don't go faster.
       
        thread("requestData");
        
           textSize(32);
          text(time, 10, 50);
 arduinoPos ( );
  }
}

void arduinoPos () {  
//  delay (1); // delay (20); motors don't bug
//  delay (10); // delay (20); motors don't bug
    i+=1;

   //   String positions ="<"+ int (i)+","+ int ((2*i))+","+ int (i)+","+ int (i)+","+ int (i)+","+ ">";//
//   String positions ="<"+ int (i)+","+ int ((1000))+","+ int (-500)+","+ int (1000)+","+ int (i)+","+ ">";//

    String positions ="<"+ int (i)+","+ int ((-i))+","+ int (-500)+","+ int (-i)+","+ int (i)+","+ ">";//
    
//     if(frameCount%1 == 0)  
       println(frameCount + ": " + (positions) ); 
       arduinoport.write(positions); // Send data to Arduino.       
} 

void requestData() {
  
//   println(frameCount + ": " + (pos));
//   arduinoPos ();
 //  arduinoport.write(pos); // Send data to Arduino.
  JSONObject json = loadJSONObject("http://time.jsontest.com/");
  time = json.getString("time");
}

And my Arduino program with marker to receive the begin and the end of the 5 ints from Processing


//***********  Variable de Processing
long w0, w1, w2, w3, w4; // position in step
boolean dataReady = false;
int i; // test speed of motor




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

// Example 5 - Receive with start- and end-markers combined with parsing

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing

      // variables to hold the parsed data
char messageFromPC[numChars] = {0}; //or 5 doesn't change anything
int integerFromPC0 = 0;
int integerFromPC1 = 0;
int integerFromPC2 = 0;
int integerFromPC3 = 0;
int integerFromPC4 = 0;


float floatFromPC = 0.0;

boolean newData = false;

//============



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(400);
  stepper[i].setAcceleration(50);
  stepper[i].setSpeed(200);
   }
}

void loop() { 

   recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(tempChars, receivedChars);
            // this temporary copy is necessary to protect the original data
            //   because strtok() used in parseData() replaces the commas with \0
        parseData();
        showParsedData();
        newData = false;
    }
  
 //testStepMotors();
// testPotarMotor(); // work perfectly
//  receiveData(); // receive data from Processing
//SendDataToMax ();


}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

//============

void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars,",");      // get the first part - the string
 
    integerFromPC0 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC1 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC2 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC3 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC4 = atoi(strtokIndx);     // convert this part to an integer
}

//============

void showParsedData() {
 


  SerialUSB.print(integerFromPC0);
  SerialUSB.print(integerFromPC1);
  SerialUSB.print(integerFromPC2);
  SerialUSB.print(integerFromPC3);
  SerialUSB.println(integerFromPC4);

  
       
       stepper[4].moveTo(integerFromPC4);
       stepper[4].run();
       stepper[3].moveTo(integerFromPC3);
       stepper[3].run();
       stepper[2].moveTo(integerFromPC2);
       stepper[2].run();
       stepper[1].moveTo(integerFromPC1);
       stepper[1].run();
       stepper[0].moveTo(integerFromPC0); // premiere donnée envoyée dansla chaine de String de Processing = virtualPositon4
       stepper[0].run();
       
}
void receiveData() {

  if (Serial.available() > 0) { // 

    w0 = Serial.parseInt(); //
    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

    dataReady = true;
    }

  if (dataReady)
  
    {  // i++;
      //move motor to i. DON'T WORK AT THE GOOD SPEED
      /*
       stepper[4].moveTo(i);
       stepper[3].moveTo(i);
       stepper[2].moveTo(-i);
       stepper[1].moveTo(i);
       stepper[0].moveTo(i); // premiere donnée envoyée dansla chaine de String de Processing = virtualPositon4
      */
      
      
       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[4].runSpeedToPosition();
        stepper[3].runSpeedToPosition();
        stepper[2].runSpeedToPosition();
        stepper[1].runSpeedToPosition();
        stepper[0].runSpeedToPosition();
 */       
/*
        stepper[4].runSpeed();
        stepper[3].runSpeed();
        stepper[2].runSpeed();
        stepper[1].runSpeed();
        stepper[0].runSpeed();
  */

       stepper[4].run();
       stepper[3].run();
       stepper[2].run();
       stepper[1].run();
       stepper[0].run();
     
      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); 
    dataReady = false;
    }
      
  }
  
void testStepMotors() {
  

    for(uint8_t i = 0; i < NBMOTEURS; i++) {      
     stepper[i].setCurrentPosition(0);

 
  // Run the motor forward at 400 steps/second until the motor reaches 600 steps (3 revolutions):
  while (stepper[i].currentPosition() != 400)  {
      stepper[i].setMaxSpeed(300);
 
    stepper[i].setSpeed(200);
       stepper[i].setAcceleration(150);
    stepper[i].runSpeed();
}
  
 //delay(1);
  // Reset the position to 0:
  stepper[i].setCurrentPosition(0);
  // Run the motor backwards at 600 steps/second until the motor reaches -200 steps (1 revolution):
  while (stepper[i].currentPosition() != -400)   {
    stepper[i].setSpeed(-200);
        stepper[i].setAcceleration(1);
    stepper[i].run();
  // stepper[i].runSpeedToPosition(); /NE FONCTIONNE PAS
  }
  }
   Serial.print (stepper[0].currentPosition());
}

void testPotarMotor ()  {

   analog_in = analogRead(ANALOG_IN);
   positionX= map ( analog_in, 0, 1023, -400, 400); // 5V

  stepper[4].moveTo(positionX);
  stepper[4].run(); // work perfectly
  
  stepper[3].moveTo(positionX);
  stepper[3].run(); // work perfectly
   
  stepper[2].moveTo(positionX);
  stepper[2].run(); // work perfectly

  stepper[1].moveTo(positionX);
  stepper[1].run(); // work perfectly
  
  stepper[0].moveTo(positionX);
  stepper[0].run(); // work perfectly

  SerialUSB.println (positionX);
}

void SendDataToMax () {

// Arduino--Max--Processing  

   i++;

   // WORK VERY WEELL. 
       stepper[4].moveTo(i);
       stepper[3].moveTo(i/3);
       stepper[2].moveTo(i/2);
       stepper[1].moveTo(i/4);
       stepper[0].moveTo(i);

       stepper[4].run();
       stepper[3].run();
       stepper[2].run();
       stepper[1].run();
       stepper[0].run();
   
      Serial.print ("A "); Serial.println (i);     
      Serial.print ("B "); Serial.println (-i+2);        
      Serial.print ("C "); Serial.println (i+3);  
      Serial.print ("D "); Serial.println (i+4);
      Serial.print ("E "); Serial.println (i*4);
      Serial.println (i-2);

      SerialUSB.print ("A "); SerialUSB.println (-i);     
      SerialUSB.print ("B "); SerialUSB.println (-i+2);        
      SerialUSB.print ("C "); SerialUSB.println (-i+3);  
      SerialUSB.print ("D "); SerialUSB.println (-i+4);
      SerialUSB.print ("E "); SerialUSB.println (-i*4);
      SerialUSB.println (i-2);

       delay (1);
       


   
}
 
 

Here datas send with Processing

2020: <1010,-1010,-500,-1010,1010,>
2022: <1011,-1011,-500,-1011,1011,>
2024: <1012,-1012,-500,-1012,1012,>

Here datas receive with Arduino
15:49:06.601 -> 1010-1010-500-10101010
15:49:06.645 -> 1011-1011-500-10111011
15:49:06.645 -> 1012-1012-500-10121012

Thank you, I’m totally lost.

1 Like

@bking, in your original post you said ‘working perfectly…slows down’. Now you say ‘why motor don’t go at the speed’? Is this because of the changes I suggested?

In your Arduno sketch what is USBSerial? (Lots of times I’ve used normal Serial which goes via USB to the PC). What type of Arduino? What is the physical arrangement?

PC–usb-cable—Arduino----10-wires----Stepper-Controller ?

I’m studying your sketches…

I’ve think you’re using an Arduino Due, it has USB serial. One small problem in your program is calling thread(“requestData”) at every draw(). With frameRate(120) this is not practical. I suggest you call this only every second or so.

Not sure if this is a problem, you’re transmitting on USBSerial at 9600, much slower than receiving on Serial, but your not transimitting as much. There has to be time for each transmission channel to keep up with what’s expected. Another confusion for me is the baud rate discussion here.

I have your sketch in and Arduino Mega, and tomorrow I intend to connect a ttl-usb-serial module to Serial2 so I can see what you are printing on USBSerial.

Hi @bking,

Now I have your sketches running using a Mega with output on Serial2 va ttl-to-usb and Putty window on the PC.

With the Processing frameRate < 5 the comms worked fine. With comms running and Ard reset it never recovered. I tried various changes inside recvWithStartEndMarkers to throw away any chars arriving faster than it could use, but nothing made it better. I added Serial2.prints to see what was doing and it went into recvWithStartEndMarkers and hung up. It seems like the Arduino or serial really can’t handle over-run. In fact I have a note about this on a project.

So I tried making the Ard send a char when it’s ready, and Processing sends. This works, runs with frameRate = 120 and recovers from pressing the reset button. I think it’s sending to the Ard every other draw. To use this idea put this at the end of the Ard loop() function.


  Serial.print("X");
}

In Processing send to Ard only when it asks:

    char in_ch;
    while (arduinoport.available() > 0)
    {
      in_ch = (char) arduinoport.read();
      if (in_ch == 'X')
      {
        while (arduinoport.available() > 0) {arduinoport.read();}
        arduinoPos();
        iXmtCount++;
      }
      break;
    }
1 Like

Hi Richard.

It works perfectly now. With all frameRate.
Thank you as much as I can do. :star_struck:

1 Like