# serialEvent for high frequency for closed loop control - Arduino & Processing

**URL:** <https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883>\
**Category:** Electronics (Arduino, etc.)\
**Created:** [August 4, 2024, 7:02am UTC](https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883 "2024-08-04T07:02:20Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rouno](https://avatars.discourse-cdn.com/v4/letter/r/ecae2f/32.png) [@Rouno](https://discourse.processing.org/u/Rouno)\
**Post date:** [August 4, 2024, 7:02am UTC](https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883/1 "2024-08-04T07:02:20Z")

</div>

Hi guys, (reposting from [my issue in Arduino Forum](https://forum.arduino.cc/t/serial-high-frequency-for-closed-loop-control-arduino-processing/1288164))

I’m writing some code in Processing that interacts with an Arduino to control a robot arm. I need the closed-loop control code to run Processing with the highest frequency possible, reaching the Arduino side’s physical limit.

For that purpose, I want to use serialEvent once a data frame from Arduino is received which will trigger calculations and commands to be sent on serial back to the Arduino. The principal is illustrated in the code below (Arduino + Processing)

My problem is that somehow serialEvent is no longer triggered after several seconds and I don’t know why

Arduino Code:

```auto
char pcOutBuffer[] = "Motorboard:Present_Posistion 1 20093774343;Present_Posistion 2 20093774343;Present_Posistion 3 20093774343;"; //typical payload

void setup() {
  SerialUSB.begin();
  while (!Serial);
}

void loop() {
  SerialUSB.readStringUntil('\n');
  delay(1); //here the arduino would apply commands from PC and fill pcOutBuffer with motor data
  SerialUSB.write(pcOutBuffer);
  SerialUSB.write('\n');
}

```

Processing Code:

```auto
import processing.serial.*; //Include Processing Serial

Serial myPort;                       

void setup() {
  size(256, 256);
  printArray(Serial.list());
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
  myPort.bufferUntil('\n');
  myPort.write('\n');
}

void draw() {
}

void serialEvent(Serial myPort) {
  String strIn = myPort.readString();
  print(strIn);
  //close loop control would happen here
  println(second());
  myPort.write('\n');//command to arduino would fit here as well
}

```

I would like to understand what is going on to implement the highest-performance approach for my needs.

My setup :  
Target is OpenCM9.04 from Robotis  
Arduino IDE is the lastest 1.8 version  
Processing IDE 4.3

I there anything I’m doing wrong?

Many thanks for your help

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [August 4, 2024, 9:50am UTC](https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883/2 "2024-08-04T09:50:58Z")

</div>

> [@Rouno](#):
>
> I would like to understand what is going on to implement the highest-performance approach for my needs.

You may not be keeping up at the receiving end.  
Do the math for your BAUD rate and the size of your payload.  
It is worthwhile to do some research on this.

I tested your code with a hardware serial port (not SerialUSB) and it worked with a BAUD as high as 2000000 (for testing only!)

If you want higher performance, throughout and control:

- Increase BAUD rate. Only as high as required and testing!
- Reduce size of your _payload_
- Optimize code on receiving end
- Consider handshaking between Arduino and Processing
- print() to console can impact performance; only use for development

```auto
//char pcOutBuffer[] = "Motorboard:Present_Posistion 1 20093774343;Present_Posistion 2 20093774343;Present_Posistion 3 20093774343;"; //typical payload

char pcOutBuffer[] = "20093774343,20093774343,20093774343"; //typical payload

```

_Payload_ can be reduced further if necessary but work on above first.

_serialEvent()_ that I tested with:

```auto
int t, tLast;

void serialEvent(Serial myPort) 
  {
  String strIn = myPort.readString();
  print(strIn);

  //close loop control would happen here
  
  t=millis();
  println(t-tLast);
  tLast = t;
  myPort.write('\n');//command to arduino would fit here as well
  }

```

At some point you may need these:

- [trim() / Reference / Processing.org](https://processing.org/reference/trim_.html)
- [split() / Reference / Processing.org](https://processing.org/reference/split_.html)

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/6/d/6d55938127262812fde656d1c3b3fb2eaf7bb1db.png)

`:)`

---

<div class="post-metadata">

**Author:** ![Rouno](https://avatars.discourse-cdn.com/v4/letter/r/ecae2f/32.png) [@Rouno](https://discourse.processing.org/u/Rouno)\
**Post date:** [August 4, 2024, 10:19am UTC](https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883/3 "2024-08-04T10:19:34Z")

</div>

Hi @glv,

Thanks a lot for your feedback! What is weird though is that my code is working fine on your setup using hardware serial instead of SerialUSB

Is there anyway you could test with SerialUSB to reproduce my error? That will defenitely pinpoint a bug in SerialUSB on Arduino side

Kind regards

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [August 4, 2024, 10:26am UTC](https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883/4 "2024-08-04T10:26:09Z")

</div>

> [@Rouno](#):
>
> Is there anyway you could test with SerialUSB to reproduce my error?

Which Arduino board (other board?) are you using?

I do not have a board with native USB.

You could send me one of these and I will test it:

> **[Arduino Due](https://store-usa.arduino.cc/products/arduino-due)**
>
> The Arduino Due is a microcontroller board based on the Atmel SAM3X8E ARM Cortex-M3 CPU. It is the first Arduino board based on a 32-bit ARM core microcontroller. It has 54 digital input/output pins (of which 12 can be used as PWM outputs), 12...

`:)`

---

<div class="post-metadata">

**Author:** ![Rouno](https://avatars.discourse-cdn.com/v4/letter/r/ecae2f/32.png) [@Rouno](https://discourse.processing.org/u/Rouno)\
**Post date:** [August 4, 2024, 10:53am UTC](https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883/5 "2024-08-04T10:53:05Z")

</div>

Hi @glv, I’m using the OpenCM9.04 from Robotis : [OpenCM 9.04](https://emanual.robotis.com/docs/en/parts/controller/opencm904/)

Thanks for your proposal, I’ll defenitely consider it if I don’t manage to find someone on either forums 😊

I will also try with one of my HW serial once I get a USB ftdi cable

---

<div class="post-metadata">

**Author:** ![Rouno](https://avatars.discourse-cdn.com/v4/letter/r/ecae2f/32.png) [@Rouno](https://discourse.processing.org/u/Rouno)\
**Post date:** [August 4, 2024, 1:29pm UTC](https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883/6 "2024-08-04T13:29:34Z")

</div>

@glv I think I found where the problem comes from (on my side) :

I did some experiment and if have no problem sending any buffer up to 63 bytes (including ‘\n’) like :

```auto
char pcOutBuffer[] = "this is an example of a 62 characters payload which works fine";

```

However when reaching 64 bytes, no serialEvent are triggered on Processing side and above 64 bytes then my problem appears

Now I think can implement a proper workaround but I’m still unsure about the real explanation.

What do you think of that @glv ?

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [August 4, 2024, 4:27pm UTC](https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883/7 "2024-08-04T16:27:26Z")

</div>

Would it be possible to send data as comma separated values without redundant text? For example, have Processing split string to positionArray[3] ; To reinforce what has already been stated there is a lot of redundancy in

```auto
char pcOutBuffer[] = "Motorboard:Present_Posistion 1 20093774343;Present_Posistion 2 20093774343;Present_Posistion 3 20093774343;"; //typical payload

```

and could be shortened with comma separated values and sent as a much shorter string, eg

```auto
value1,value2,value3 followed by a line feed(accomplished by println())

```

The following is example Processing code which **will run on an Arduino Due R3** :

```auto
import processing.serial.*;

Serial myPort; // The serial port
String inStr; // Input string from serial port
int lf = 10; // ASCII linefeed
String[] dataStr = new String[2];
int[] data = new int[2];

void setup() {
  surface.setVisible(false); // Output is in console at bottom of editor
  // List all the available serial ports:
  printArray(Serial.list());
  // Enter device number for your system
  myPort = new Serial(this, Serial.list()[1], 115200);
  myPort.bufferUntil(lf);
}

void draw() {
}

void serialEvent( Serial myPort) {
  //'\n' (line feed) is delimiter indicating end of packet
  inStr = myPort.readStringUntil('\n');
  //make sure our data isn't empty before continuing
  if (inStr != null) {
    //trim whitespace and formatting characters (like carriage return and/or line feed)
    inStr = trim(inStr); //Data is sent as a string
    println("inStr =", inStr);
    String[] myData = split(inStr, ','); // String is split into array at comma
    println("array:");
    printArray(myData);
    for (int i = 0; i < myData.length; i++) {
      try {
        int parsedInt = Integer.parseInt(myData[i]);
        data[i] = parsedInt;
      }
      catch (NumberFormatException e) {
        println("Failed to parse the string as an integer.");
      }
    }
  }
}

```

**Arduino code:**

```auto
int num[2];

void setup() {
  Serial.begin(115200);
  SerialUSB.begin(115200);
}

void loop() {
  num[0] = random(255);
  num[1] = random(300, 900);
  SerialUSB.print(num[0]);
  SerialUSB.print(","); // Comma separated values
  SerialUSB.println(num[1]); // Has a line feed.
  //Wait for a bit to keep serial data from saturating
  delay(10);
}

```

Note that there is no SerialUSB.write().

By the way, your code does run if you declare a baud rate on the Arduino side, eg

```auto
SerialUSB.begin(115200);

```

**Output in my console log (macos):**

 ![usbs](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/b/6/b6fe1b5cf68b6dadc12e3b35054913a093ce0242.png)

And it didn’t hang; went to 59 and then reset to zero.

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [August 4, 2024, 7:12pm UTC](https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883/8 "2024-08-04T19:12:43Z")

</div>

> [@Rouno](#):
>
> What do you think of that @glv ?

Great to see experimentation!  
`:)`

> [@Rouno](#):
>
> However when reaching 64 bytes, no serialEvent are triggered on Processing side and above 64 bytes then my problem appears

Share the smallest version of code that you can so we are on the same page.  
Would like to know the BAUD rate, delay between writes, etc.  
Still SerialUSB?

There are _Notes and Warnings_ here at the bottom of the page related to Serial:

> **[Serial.write() - Arduino Reference](https://www.arduino.cc/reference/tr/language/functions/communication/serial/write/)**
>
> The Arduino programming language Reference, organized into Functions, Variable and Constant, and Structure keywords.

I get the same results with an _Arduino Uno R3_ and _Arduino Mega 2560 R3_:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/7/b/7b4226fe23a61cac42af264509cc20d48eac55bb.png)

The above may not apply directly to SerialUSB and can’t test it.

> [@Rouno](#):
>
> Now I think can implement a proper workaround but I’m still unsure about the real explanation.

I am sure you can! Serial communications can be a challenge at times.

Related:  
[Due - SerialUSB.write() issue - Programming Questions - Arduino Forum](https://forum.arduino.cc/t/due-serialusb-write-issue/1087424) \< some excellent suggestions in here!  
Also take a look at Related Topics in topic above.

`:)`

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [August 5, 2024, 3:16pm UTC](https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883/9 "2024-08-05T15:16:31Z")

</div>

Hello @Rouno,

Can you try this with your SerialUSB:

> **[Serial.availableForWrite() - Arduino Reference](https://www.arduino.cc/reference/tr/language/functions/communication/serial/availableforwrite/)**
>
> The Arduino programming language Reference, organized into Functions, Variable and Constant, and Structure keywords.

Just curious!

And I am getting an Arduino Due! Not any time soon but for future projects that would benefit from an upgrade.

`:)`

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [August 5, 2024, 7:06pm UTC](https://discourse.processing.org/t/serialevent-for-high-frequency-for-closed-loop-control-arduino-processing/44883/10 "2024-08-05T19:06:44Z")

</div>

> [@glv](#):
>
> Can you try this with your SerialUSB:

I get 511 on my system.
