Serial communication

This section introduces serial communication from and to the Arduino. Its use here is explained from the perspective of using Max or Pd as interfaces. An examples of how to connect to Supercollider can be found here.

jump to: led brightness
jump to: three motors

Arduino and simple Serial Communication

In order to establish communication with the Arduino, a serial protocol is used. This communication occurs when a script or program is uploaded to the Arduino, but is also possible as part of an interaction scheme, for instance when sensor values need to be visualized in a user interface. The serial communication can be explained in its most basic form as a transport line of individual characters between the Arduino and a computer. It is possible to deviate from this basic form; that will be explained later.

This section explains how to set up such simple communication between the Arduino board and the applications Max and Pd. Since these platforms are rather similar, patches for Max and Pd look somewhat similar. The Arduino can send data to Max/Pd, or it can receive data from it. In either case, data is represented by individual characters that are sent one at a time. Rather than the actual character, the transport line expects a numerical representation of that character. These representations are stored in a so called ASCII (pronounce: askey) table, which binds e.g. the letter ‘A’ to the value 65, or the character ‘7’ to the value 55. When sending data from Arduino, those ASCII representations remain obscure. All that is required is using the Serial.println command.

int x = 17;

The three lines above represents Arduino code that first sends the letters ‘a’ and ‘z’ over the serial port, and after that the value for x, which is 17, is sent. As said before, when sending, nothing shows that println uses ASCII representations. But at the receiving end, is will be ASCII that is received. The objects used are serial in Max and comport in Pd. The comport object is not vanilla and needs to be installed. Here is a how-to.

Max (left) and Pd (right) — connecting to a serial port

The connection to the serial port is created by providing a port reference. In Max this is a letter, and in Pd a number. With a specific message the information on available ports and their references can be printed. Arduino’s serial port is typically listed as ‘usbmodem’. The next step is to provide this identifier as argument, as well as the speed at which the communication is set up. The patches below show just this. The Max object that reads ‘poll’ is an attrui and is the easiest way to get data from serial.

Serial data sent to Max or Pd

The numbers that are printed out are in order: 97, 122, 13, 10, 49, 55, 13 and 10. After one second the exact same sequence appears. These values represent characters according to the before mentioned ASCII table. According to this table, the values 97 and 122 represent the characters ‘a’ and ‘z’, the values 49 and 55 the characters ‘1’ and ‘7’—indeed, numerical values are sent as individual characters. It is easy to see how this accords with the messages sent from the Arduino code. Twice, a combination of 13 and 10 appears. The ASCI table names these values ‘line feed’ (LF) and ‘carriage return’ (CR) respectively—terminology that suggests printer activity. These two values are inherent to the Arduino ‘println’ command and can be used in our patches as indicators that a complete message has been received.

Printing interpreted data from the serial connection

Max and Pd can transform the ascii values to the characters they represent using either the atoi or fudiparse object. Copy the code below into a Max patcher window to create the patch above.


Important to take into account is that only a single application at a time can connect with the Arduino board over the serial connection. In order to allow one application to open the connection, another must close it.

Telling apart multiple sensor values

When reading out multiple sensor values in Max or Pd, another approach than simply using println() must be adopted. In order to know which value represents the first sensor and which the second, the values are better send in such a way that they create a list. In Max/Pd a list can be specified as values separated by a space. The Arduino code shows how to create the spacing. Only after the last value has been sent, a println() is used to create a flag for the receiving end.

void setup() {

void loop() {
  int sensorValueOne = analogRead(A0);
  int sensorValueTwo = analogRead(A1);
  Serial.print(" ");

Set the brightness of an LED

The section above explains how Max or Pd receive values from the Arduino. Communication in the other directions is possible too; from Max/Pd to Arduino. The dimmer example shows how this communication can be used to adjust the brightness of an LED by sending a changing value in the range from 0 to 255. This value is used to change the setting of a PWM value. Not much coding is Max/Pd is required to achieve this, simply connect a number box to the serial/comport object. The Arduino example even includes Max code that can directly be pasted into an empty patcher window.

Sending values over serial

Serial fading an LED with potmeter

The fade example automatically fades the brightness of an LED between minimum and maximum. Closer examination reveals that although the pwm values used to fade are linearly increasing and decreasing, the change of light intensity appears not to be linear at all. If the left image below shows the linear change of pwm, the right image represents what the light intensity actually looks like; jumping rather quickly to high intensity and then slowing down while it reaches maximum value.

If linear intensity change is desired, it would be better to adjust the pwm values. Max provides a fine environment to prototype this. An audio rate oscillator provides the source of values. A potentiometer connected to A0, can provide a value for the speed of this oscillator. The patch below is an example of how to connect everything together. By raising the oscillator value to the power of three, we achieve a change of brightness that appears to linear.

A Max patch for adjusting speed of brightness change

Adjust the speed of three motors

Adjusting the brightness of an LED, as explained above, can be turned into adjusting the speed of a motor. But in order to extend this model to multiple motors, another approach needs to be taken. What we need to solve is how to connect multiple number boxes to equally as many PWM driven outputs.

The solution lies in creating a separate function for dealing with incoming serial data with serialEvent(). The Serial Event example demonstrates the use of this function. A Max or Pd patch now sends various values separated by spaces, using an ascii representation. In this representation the space and return values function as flags that trigger the pushing of values into an array and updating the values to be written to the outputs.

int motorPins[] = {9, 10, 11}; // pwm pins
int motorCount = 3;
byte motorSpeeds[3]; // reserve space for three bytes
int motorIndex = 0;
String inputString = "";
bool dataComplete = false;

void setup() {
  // declare all pins as outputs:
  for (int i=0; i<motorCount; i+=1) {
    pinMode(motorPins[i], OUTPUT);

void loop() {
  if (dataComplete) {
    for (int i=0; i<motorCount; i+=1) {
      analogWrite(motorPins[i], motorSpeeds[i]);
    dataComplete = false;

void serialEvent() {
  while (Serial.available()) {
    char inChar =;
    switch (inChar) {
      case 32: // space
        motorSpeeds[motorIndex] = inputString.toInt();
        motorIndex += 1; // increase index
        inputString = ""; // reset string
      case 13: // new line
        motorSpeeds[motorIndex] = inputString.toInt();
        dataComplete = true;
        motorIndex = 0; // reset index
        inputString = ""; // reset string
        inputString += inChar; // add character to string

The Pd patch below works with the above code. However, the fudiformat object generates additional data to the extent that a list selector is included in the ascii values. Although the ‘list trim’ object promises to strip off this selector, that appears not to work. In order to solve this issue, an object ‘list split 5’ is added.

Three values sent to the Arduino

Useful Links

Using Timers
Debounced Encoder