Processing Serial Port Number Programming and Selecting

Processing language applications that use the serial port to connect to serial devices such as Arduino need to use the correct serial port number that the serial device is connected to. Here are three methods for selecting and connecting to a serial device from a Processing application, namely, hard-coding, auto-detection and user selected Processing serial port.

Hard-coding a Processing Serial Port Number

Hard-coding the serial port number in the Processing application is the default way used in most Processing examples. In the library reference documentation for the Serial library, the hard-coded method is used.

Listing the Serial Ports and Connecting

Hard-coding examples usually print the list of serial ports on the computer to the text area at the bottom of the Processing IDE using the following line of code:

println(Serial.list());

This allows the programmer to determine which number the desired port is in the list of ports. The ports listed in the text area of the IDE are numbered from 0 in the list, so in the list of serial ports in the image below from a Linux computer, /dev/ttyACM0 would be 0 in the list, /dev/ttyS0 would be 1 in the list, etc.

Processing Serial Port List

Processing Serial Port List

 

 

 

 

 

On a Windows computer, these would typically be COM1, COM2, COM3, etc. which are also numbered in the list starting from 0.

After the correct serial port name from the list is found and the number of the serial port in the list has been determined, the serial port can be connected to in the Processing application code.

// Example by Tom Igoe

import processing.serial.*;

// The serial port:
Serial myPort;       

// List all the available serial ports:
println(Serial.list());

// Open the port you are using at the rate you want:
myPort = new Serial(this, Serial.list()[0], 9600);
  
// Send a capital A out the serial port:
myPort.write(65);

The above code is taken from the Processing Serial library documentation and first lists the available serial ports on the computer, then connects to the first serial port in the list. The following line of code is where the serial port number from the list is hard-coded in the application:

myPort = new Serial(this, Serial.list()[0], 9600);

The parameter Serial.list()[0] connects to the first serial port in the list of serial ports. In the above image, this would be /dev/ttyACM0. On my Windows PC, there is a default COM port, COM3. When an Arduino is plugged into the PC, it appears as COM4 or COM5, depending on which USB port the Arduino is plugged into. Processing code for the Windows PC must use Serial.list()[1] to connect to the second serial port on the PC which would be either COM4 or COM5 in this particular case.

Disadvantages of Hard-coding the Serial Port Number

If a Processing application that connects to a serial port is run on a different computer, or more than one serial device is connected to a computer, the desired port to connect to may change position in the list of ports. It would then be necessary to modify the Processing code to select the correct serial port. This means that the Processing IDE would need to be loaded onto every computer that the application is run on, in case the serial port number changes.

Auto-detecting a Processing Serial Port Number

A USB serial port can be auto-detected by a Processing application by starting with the USB serial device unplugged and then starting the Processing application. The Processing application can be programmed to store the list of serial ports before the desired USB serial device is plugged into the computer. When the device is plugged in, the Processing application can detect it and find it’s serial port name and number.

Code from the Processing application that auto-detects which serial port number an Arduino is plugged into uses the USB serial port auto-detect method and can be used as a starting point for any Processing project that is to use serial port auto-detect.

User Selected Processing Serial Port Number

Window controls in a Processing application can be used so that a user can scroll through the list of available serial ports and connect to the desired port. This method has the advantage that if the application is to run on different computers, the correct serial port can be selected by the user at run-time.

The image below shows controls in a Processing application window used to select and connect to a serial port.

Processing Serial Port Select Using Window Controls

Processing Serial Port Select Using Window Controls

Up and down buttons allow the list of serial ports to be scrolled through to select the desired port. When the Connect button is clicked, the application will connect to the selected (currently displayed) serial port.

A Disconnect button allows disconnecting from the serial port, so that the application can connect to a different serial port.

The Refresh button updates the list of available serial ports, which is useful in cases where a serial device is connected to the PC after the application is started. The new device will be added to the list when the refresh button is clicked.

A Simple Button for Processing Language Code

A button that can be placed in the application window of a Processing program (processing.org). The button code allows the button to be drawn and checked to see if it has been clicked by a mouse.

Processing button used in window of application

Buttons in a Procesing Application

At this point in time Processing does not have any button controls as part of the language or built in libraries. The code below is a class for a very simple button that should be easy for beginners in programming to understand, study and improve on. An example of using the button follows.

The image shows two buttons created in a Processing application window using the Button class.

Processing Button Class

This button class can be copied to any Processing sketch and then used in the sketch as demonstrated by the example that follows.

class Button {
  String label;
  float x;    // top left corner x position
  float y;    // top left corner y position
  float w;    // width of button
  float h;    // height of button
  
  Button(String labelB, float xpos, float ypos, float widthB, float heightB) {
    label = labelB;
    x = xpos;
    y = ypos;
    w = widthB;
    h = heightB;
  }
  
  void Draw() {
    fill(218);
    stroke(141);
    rect(x, y, w, h, 10);
    textAlign(CENTER, CENTER);
    fill(0);
    text(label, x + (w / 2), y + (h / 2));
  }
  
  boolean MouseIsOver() {
    if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
      return true;
    }
    return false;
  }
}

Processing Button Demonstration Example

This application uses the above Button class to create a button on the screen. When the mouse cursor is moved over the button, a square is drawn in the window, when the button is clicked, text is written to the text area console of the Processing IDE. This video shows the example code running:

// Processing application that demonstrates the Button class by creating a button
// Draws a square in the window when the mouse cursor is over the button
// Writes to the Processing IDE console pane when the button is clicked
// 3 July 2015    http://startingelectronics.org
Button on_button;  // the button
int clk = 1;       // number of times the button is clicked

void setup() {
  size (300, 150);
  smooth();
  
  // create the button object
  on_button = new Button("Click Me", 20, 20, 100, 50);
}

void draw() {
  // draw a square if the mouse curser is over the button
  if (on_button.MouseIsOver()) {
    rect(200, 20, 50, 50);
  }
  else {
    // hide the square if the mouse cursor is not over the button
    background(0);
  }
  // draw the button in the window
  on_button.Draw();
}

// mouse button clicked
void mousePressed()
{
  if (on_button.MouseIsOver()) {
    // print some text to the console pane if the button is clicked
    print("Clicked: ");
    println(clk++);
  }
}

// the Button class
class Button {
  String label; // button label
  float x;      // top left corner x position
  float y;      // top left corner y position
  float w;      // width of button
  float h;      // height of button
  
  // constructor
  Button(String labelB, float xpos, float ypos, float widthB, float heightB) {
    label = labelB;
    x = xpos;
    y = ypos;
    w = widthB;
    h = heightB;
  }
  
  void Draw() {
    fill(218);
    stroke(141);
    rect(x, y, w, h, 10);
    textAlign(CENTER, CENTER);
    fill(0);
    text(label, x + (w / 2), y + (h / 2));
  }
  
  boolean MouseIsOver() {
    if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
      return true;
    }
    return false;
  }
}

 

Sending an 8-bit Unsigned Char in Java using the Processing Language

In a Processing (which is basically Java) application that I am writing, I need to send a packet of data over the serial port that consists of unsigned bytes that are 8 bits long. In C programming, it would just be a matter of using unsigned char data types. Java or Processing does not have an unsigned char data type.

The requirements for the application are to send a packet of data from an array over the serial port. The first two bytes in the packet are header bytes, followed by various data and command bytes with a checksum at the end. The code already runs on an Arduino with the data packet stored in an array as follows:

byte tx_cmd[12] = { 0x55, 0xAA,             // header
                    0x01, 0x00,             // device ID
                    0x01, 0x00, 0x00, 0x00, // input parameter
                    0x01, 0x00,             // command code
                    0x02, 0x01              // checksum
                  };

In this Arduino code the byte type is an unsigned 8-bit byte  — equivalent of an unsigned char in C, as Arduino programming is basically C / C++.

Processing / Java Data Types Equivalent to C Unsigned Char

Two obvious candidates that look like they should be the equivalent of a C unsigned char are the Java char and Java byte data types. These two data types have the following problems:

Java Char

The Java char data type is 16 bits long. Trying to put the data packet to send over the serial port into a char array would send two 8-bit bytes for every char variable sent. The Java char is also intended for characters, so trying to pack two bytes into a char would be bad programming practice.

Processing char reference.

Java Byte

The Java byte data type is 8 bits long, however it is a signed data type, not unsigned. The range of the byte is from 127 to -128. This differs from the Arduino byte data type which is 8 bits long and unsigned with a range from 0 to 255 (same as a C unsigned char).

Processing byte reference.

Attempting to Use the Byte Data Type

The following Processing code shows the problem when using a data packet array of the byte data type.

void setup() {
  byte[] tx_cmd = new byte[12];
  tx_cmd[0] = 0x55;
  tx_cmd[1] = 0xAA;
  tx_cmd[2] = 0x01;
  tx_cmd[3] = 0x00;
  tx_cmd[4] = 0x01;
  tx_cmd[5] = 0x00;
  tx_cmd[6] = 0x00;
  tx_cmd[7] = 0x00;
  tx_cmd[8] = 0x12;
  tx_cmd[9] = 0x00;
  tx_cmd[10] = 0x13;
  tx_cmd[11] = 0x01;
  
  for (int i = 0; i < 12; i++) {
    println(hex(tx_cmd[i]));
  }
}

When trying to run the code in the Processing IDE, it gives the following error:

cannot convert from int to byte

Which refers to the code in the line:

tx_cmd[1] = 0xAA;

The problem is that the the hexadecimal value of AA which is the decimal value of 170 is too big for the positive range of the byte data type which can have a maximum value of 127. None of the other numbers assigned to the array elements give an error because they are all less than 127 decimal.

 Solution to Sending an Unsigned Byte Using Processing / Java

Although the byte data type is signed, it still stores binary values from 0000 0000b to 1111 1111b (or 0x00 to 0xFF hexadecimal) with the most significant bit (MSB) being the sign bit which is set when the number is negative. The code only treats the byte as negative because the data type of the language being used says that it is a signed number.

When data is sent over the serial port, it is sent as bytes. The device receiving the data bytes on the other side can choose whether to treat the bytes as signed or unsigned, so the solution to sending the bytes is to convert the data bytes with values above 127 to their negative equivalents.

This is actually done very simply by casting the input integer to the byte data type, which cuts off the top bytes of the integer and puts the least significant byte of the integer into the byte variable.

void setup() {
  byte[] tx_cmd = new byte[12];
  tx_cmd[0] = (byte)0x55;
  tx_cmd[1] = (byte)0xAA;
  tx_cmd[2] = (byte)0x01;
  tx_cmd[3] = (byte)0x00;
  tx_cmd[4] = (byte)0x01;
  tx_cmd[5] = (byte)0x00;
  tx_cmd[6] = (byte)0x00;
  tx_cmd[7] = (byte)0x00;
  tx_cmd[8] = (byte)0x12;
  tx_cmd[9] = (byte)0x00;
  tx_cmd[10] = (byte)0x13;
  tx_cmd[11] = (byte)0x01;
  
  // print the array in hexadecimal and decimal
  for (int i = 0; i < 12; i++) {
    print("0x");
    print(hex(tx_cmd[i]));
    print(" = ");
    println(tx_cmd[i]);
    
  }
  
}

The output from the above code:

0x55 = 85
0xAA = -86
0x01 = 1
0x00 = 0
0x01 = 1
0x00 = 0
0x00 = 0
0x00 = 0
0x12 = 18
0x00 = 0
0x13 = 19
0x01 = 1

The number stored in the byte array will be displayed as the desired value when printed as a hexadecimal number. When printed as an integer, it will be displayed as a negative value if it contains a number greater than 127.

As the code shows, it is much easier and more efficient to cast the input integer to a byte and truncate the integer, than to try and calculate the equivalent negative value for the input byte.

Software Voltmeter With History

This four channel Arduino software voltmeter with history was made by using an Arduino Uno and an application written in the Processing language that runs on a computer.

The Arduino reads analog values on four analog input pins connected through voltage dividers and then calculates the voltage. The Processing application displays the voltage reading and the voltage history is displayed on a graph for each channel.

This image shows the software voltmeter application:

Voltmeter Application Software

Voltmeter Application Software

Click the above link for the circuit diagram, Processing source code and Arduino source code for this project.

Processing Language System Requirements

The Processing language can be used in electronics applications for interfacing microcontroller circuits to a PC. The computer interface software can be written in Processing and allow a user to interact with the microcontroller circuit or embedded system. The Arduino can be interfaced to a computer in this way and there are many Arduino / Processing PC interfacing examples on the Internet (e.g. the Arduino relay shield project).

The article on the system requirements for the Processing language explains the hardware and software requirements for running Processing.