Tuesday, April 15, 2014

RedBoard Tutorial 2: Simple Continuous MIDI Controller

This tutorial series is intended for people that attended the Arduino / RedBoard Beginner's Workshop at Square Sounds Festival in Melbourne in April, 2014 (though it may be of use to others). This particular tutorial deals with how to make a very simple continuous MIDI controller.

Red Board Hardware

This is the Red Board. Different pins are marked as having different functions - including 5V and ground for power, analog in (for sensors) and digital (for buttons, LEDs, anything that goes ON and OFF).

The Red Board is programmed using the Arduino IDE, which can be downloaded from http://arduino.cc/.

In this tutorial, a sensor (potentiometer, flex, light and touch) is connected to an analog in. The analog in can take a voltage between 0V(ground) and 5V, and converts this to a number between 0 and 1023 (relative to the voltage). The resulting data is sent to a music program to control a parameter. Let's build the hardware first, and then set up and program the Red Board.

Connecting up the Hardware

This is a bread board. The breadboard has two columns (which in the above image are horizontal), divided up into many rows per column. Each row has five holes. Each row of five holes are electrically connected, so that placing the leg of one component (or a breadboard jumper wire) in one hole connects that component to the four other holes in that row.

This is a pot. The pot can turn approximately 270˚. The pot has three legs.

Place the pot onto the breadboard, so that each leg of the pot occupies a different, separate row.

Connect the ground pin of the Red Board to one of the outside legs of the pot, by putting it in the appropriate row.

Connect the 5V pin of the Red Board to the other outside leg of the pot.

Voltage Divider
Connect analog in 0 to the middle leg of the pot. This type of configuration is called a voltage divider, and is a very common circuit. Two resistive components sit in-between a voltage rail (in this case 5V0 and ground. At the junction where the two resistive components meets, the output voltage will be equal to the ratio of one resistive component compared to the other in respect to the voltage rail.

For example, if resistive component A is 3kΩ and resistive component B is 2kΩ, then the output voltage where A and B meet will be 2V. if A is 4kΩ and B is 16kΩ, then the voltage output will be 4V.

A number of different components act as a resistor in this scenario. A common one is the pot. Essentially, from one outer leg to the middle leg is resistive component A, and from the middle leg to the other outer leg is resistive component B.

Red Board Code
To actually read the value of the pot, the Red Board must be programmed in some way. Let's summarise what the program should do:
• Read the value of the analog input
• Send the value of the analog input as a message that a music program can understand (MIDI)
• Repeat indefinitely

The most straightforward way of achieving this is with the following code, or something similar:

Let's go through this code line by line, structure by structure. Every Arduino program (a "sketch") is made up of at least two main structures - a setup() function and a loop() function.

The setup() function is block of code that is executed once when the Arduino is powered up and turned on.

The loop() function is  block of code that is repeated on loop forever until the Arduino is powered down and turned off. Of course, conditioning branches and structures can be written as part of loop() to create complex programs and actions, depending on various factors.

The only line in the setup() function is:

This line of code opens up a serial port - in this case via the USB bus - using a baud rate (speed) of 57600.

The loop() function is a set of four lines:
Serial.write(analogRead(0) / 8);

The Serial.write() command sends a single byte of data to the serial port. Keep in mind that the data needs to be formatted in a way that our music software will eventually understand. To this end, the data from the analog input is formatted as a continuous controller MIDI message.

This type of message is typically used for faders, knobs and buttons on a USB MIDI controller. If you are unfamiliar with MIDI and continuous controllers, it is suffice to say that:
• Part of MIDI is a language, with "room" for 16 channels with notes, volumes, etc etc
• A continuous controller message is one type of MIDI message that can be sent
• A continuous controller message will have a channel number from 1 - 16
• A continuous controller message will be one of 128 different controller path ways for that particular channel
• A continuous controller message will have a value of 0 - 127

One way of thinking about continuous controller messages is to imagine a theoretical MIDI console that has 128 different physical faders. Each fader needs its own "pathway" to send data along - and thus, a continuous controller message can be used to send the value of a particular fader to a computer. More information about MIDI can be found here.

The format for this type of message is as follows:

byte 1: the value 176 plus the channel number from 0 to 15 (note: 176 as hexadecimal is 0xb0)
byte 2: the controller number (i.e. which "fader" is it that is being controlled) from 0 to 127
byte 3: the controller value (i.e. what is the value of the fader as defined in byte 2) from 0 to 127

Back to our Red Board Arduino code, the first two lines of the loop() function are:

These two lines correspond directly with byte 1 and byte 2 of the continuous controller message. Serial.write(0xb0) indicates that we are sending a continuous controller message via channel 1. Serial.write(0x01); indicates that we are sending a continuous controller message via controller number 1.

The third line of code is:
Serial.write(analogRead(0) / 8);

Here, the voltage that is present at analog input pin 0 is read as a data value. The number that is returned is somewhere between 0 and 1023. As the value range of a continuous controller message is limited to 0 to 127, the range 0 - 1023 is divided by 8 to always guarantee a value between 0 - 127. Serial.write(analogRead(0) / 8); indicates that we are sending a continuous controller value between 0 - 127, depending on the position of the pot.

The final line of the loop() function is delay(5);, which is simply a short delay of five milliseconds before the loop is repeated. 

Software Setup and Mapping
Once the code has been uploaded to the Red Board, make sure to launch and set up the SerialThing app. A stream of controller values will be sent out of the app and can be used to control a parameter in music software, as shown below.

The basic software setup is:
• Upload code to Red Board
• Set up SerialThing
• Open music software and map controller 1 channel 1 to a parameter
• The method for the step above is different for various music software packages

In Ableton Live, the process is simple:
• Enter MIDI mapping mode by pressing command M
• Click on the onscreen parameter that is to be mapped
• Move the pot
• Confirm the channel and continuous controller number
• Exit MIDI mapping mode by pressing command M
• Move the pot to confirm that the mapping works, and that the pot is controlling the onscreen parameter

Component Replacement and Experimentation
Note that the exact same code and circuit can be used with other components, as shown below:

Light dependent resistor and 10kΩ resistor. The light dependent resistor goes to 5V and analog in. The 10kΩ resistor goes to analog in and ground.

Flex sensor and 10k resistor. The flex sensor goes to 5V and analog in. The 10kΩ resistor goes to analog in and ground.

Touch slider. The three legs of the touch slider go to 5V, analog in and ground respectively (equivalent to a potentiometer).