Serial with Hardware Flow Control

Every now and then you need to interface with a device via the computer serial port that asks for Hardware Flow Control (RTS/CTS).

I had a look at the documentation: https://processing.org/reference/libraries/serial/Serial.html
and it looks like it is not provided.

I also had a search online and found an old post on the old Processing forum from 2010 that asked about this. Here it confirmed that this was never provided even though there appears to be a relatively simple fix.

So I thought to ask here in the forum in case the documentation is out of date.

Also I see Processing 4 is in alpha testing at the moment so thought to throw this request in the pot to get it changed as I need it for an application.

Thanks.

Hello,

See here:
https://processing.github.io/processing-javadocs/libraries/processing/serial/Serial.html

I edited the Serial example code and can setRTS() and getCTS():

Serial Write
import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;        // Data received from the serial port

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

void draw() 
  {
  background(255);
  if (frameCount%60 == 0)
    {
    myPort.write('1');              // send an H to indicate mouse is over square
    myPort.setRTS(true);
    }
  if (frameCount%120 == 0)
    {    
    myPort.write('0');              // send an L otherwise
    myPort.setDTR(false);
    }
  }

Serial Read
import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;        // Data received from the serial port

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

void draw()
  {
  if (myPort.available() > 0)     // If data is available
    {  
    val = myPort.read();         // read it and store it in val
    println(char(val));
    println(myPort.getCTS());
    }
  
  background(255);               // Set background to white
  if (val == '0')                // If the serial value is 0,
    {                          
    fill(0);                     // set fill to black
    }   
  else if (val == '1')           // If the serial value is not 0,
    {                          
    fill(204);                   // set fill to light gray
    }
  rect(50, 50, 100, 100);
  }

I did not have a “real” hardware serial port and used a virtual COM port to communicate between sketches.

Example above was just to try those methods and will have to be integrated in your code to work for your specific requirements.

:)

1 Like

Hi, I have computer(s) with real serial ports. This test program derived from one of @glv’s above, is reduced to just testing RTS+CTS on one PC. RTS and CTS are the middle two pins on the row of 4 pins in the 9-pin d-socket usually used for COM1. If those two pins are connected the program prints alternating bursts of # or dot.

I’ll try to develop this to flow controlled comms between 2 PCs.

@gerrikoio What are you connecting to the the PC serial?


  /*
  
  This switches RTS on and off. It reads back the RTS 
  state as CTS and prints the result as a line of characters 
  in the console window.
  
  Assumes RTS and CTS pins are connected on COM1.
  
  */

  
  import processing.serial.*;
  
  final boolean F = false;
  final boolean T = true;
  
  Serial myPort;
  
  void setup() 
  {
    String portName = "COM1";
    myPort = new Serial(this, portName, 9600);
    frameRate(20);
  }
  
  void draw()
  {
    if (frameCount % 40 ==  0) {myPort.setRTS(T);}  
    if (frameCount % 40 == 20) {myPort.setRTS(F);}     
    print(myPort.getCTS() ? "#" : "."); print("");
  }

Output:

...###################....................####################.............

Two programs below.

‘Read’ reads and prints everything that comes in by serial. It sets RTS high and low alternately to tell the sender to wait.

‘Write’ writes date to serial only when CTS is true. So you can see the effect, this depends on the mouse. Mouse above window centre: send only when CTS is true, below centre: send continuously.

I’m running these on two PCs, connected by serial cable. The console windows show the data in bursts or continuously depending on mouse position.

// Read
import processing.serial.*;

final boolean F = false;
final boolean T = true;

Serial myPort;
int val;

void setup() 
{
  size(200, 200);
  String portName = "COM1";
  myPort = new Serial(this, portName, 9600);
  frameRate(20);
}



void draw()
{
  int val;
  // Set RTS for half the time to tell 
  // the sender to wait.
  if (frameCount %  40 ==  0) {myPort.setRTS(T);}  
  if (frameCount %  40 == 20) {myPort.setRTS(F);}  

  // Print all that arrives by serial. 
  while (myPort.available() > 0)
  {
    val = myPort.read();
    print(char(val));
  }
}
// Write 
import processing.serial.*;

final boolean T = true;
final boolean F = false;

Serial myPort;
int val;

void setup() 
{
  size(200, 200);
  frameRate(20);
  String portName = "COM1"; // Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
}

  char ch = ' ';
  String str;

void draw() 
{
  if (myPort.getCTS() || mouseY > height / 2)
  {
    myPort.write(ch);
    str = ch + "";
    print(str);
    ch++;
    if (ch > '~'){ch = ' ';};
  }
}

What am I connecting - I’ve got an ARM Cortex M4 dev board which uses an FTDI USB driver and has a 802.15.4 wireless module connected too. This receives / transmits small packets of data (bidirectional comms) and the available firmware uses hardware flow control. I believe max throughput from wireless bridge is 150kbps. Wanted to plot some data / visualise the data using Processing.

On this FTDI page, see “How does RTS/CTS flow control work in an FTDI chip?”.

You could run my program from post-3 on your PC to switch RTS on and off regularly. If your program on the ARM can read CTS and see it switching then you can use it for flow control.