isaac pierre racine

Home
Next project
Previous project
12 - Interface and application programming

Assignment: A_ Interface and application programming

A_write an application that interfaces with an input and/or output device that you made.
comparing as many tool options as possible

This week's assignment is a big challenge for me as programming is still my weakest point so I start from the very beginning.

What is an interface?

An interface can be described as the mean to visualize datas from a computer program. It is in it-self a program that transforms datas into objects (visuals, sounds, etc.) that users or other devices can interact with.

For this assignment I will use the simplest applications - Arduino/Processing, starting with simple exercices using an Arduino board and finally interfacing the datas from a board I created for my final project which has a potentiometer input and an output to a Neopixel led strip.

I used this Serial Communication with Processing tutorial to understand the workflow and relationship between Arduino IDE and Processing. Both applications uses a similar language, syntax and logic. This compatibility makes it very easy to have them work together. While Arduino code is the program that is loaded onto the board the Processig code represents the instructions that translates the datas generated by the board into digital objects (sounds, images, interaction, etc).

Understanding the basics with a push botton (Arduino + Processing)

In this first exercise I want Processing to read the datas of a push botton that is connected to an Arduino UNO.

I started by connecting a push button to Arduino Analog port A4 and made shure the Arduino send the data input through the serial communication port.

//serial communication button
// Code for sensing a switch status and writing the value to the serial port.
int button = 4;// Switch connected to pin 4
void setup() {
pinMode(button, INPUT);// Set pin 4 as an input
Serial.begin(9600);// Start serial communication at 9600 bps
}

void loop() {
if (digitalRead(button) == HIGH) { // If button is pressed
Serial.print(1);// Prints data (1) to the serial port as human-readable ASCII text
} else { // If button not pressed
Serial.print(0);// Prints data (0) to the serial port as human-readable ASCII text
}
delay(100); // Wait 100 milliseconds
}

As seen in the following image, when the botton is pressed the 0 cahnge to 1, comfirming the serial communication port is reading the datas.

In this case the Arduino is programmed to send "characters" (0 and 1) to the serial communication port but for Processing to translate the data into objects (graphics, sound, etc) ) the Arduino needs to send bytes instead of characters. For this we need replace the function "digital print" by "digital write" (sends bytes) in the Arduino Ide sketch, than compile and load the board with this program.

//serial communication button
// Code for sensing a switch status and writing the value to the serial port.
int button = 4;// Switch connected to pin 4
void setup() {
pinMode(button, INPUT);// Set pin 4 as an input
Serial.begin(9600);// Start serial communication at 9600 bps
}

void loop() {
if (digitalRead(button) == HIGH) { // If button is pressed
Serial.write(1);// writes binary data to the serial port
} else { // If button not pressed
Serial.write(0);// writes binary data to the serial port
}
delay(100); // Wait 100 milliseconds
}

Now we need to write the Processing sketch that will read the data and convert it into an image - in this case a black square will change to dark yellow when the botton is pressed. The processing code is a little bit more complex but it obeys same logic as Arduino.

Download and Open the Processing application and go to:
file/examples/library/serial/simpleread
This opens a generic serial communication sketch. The first line of code define the serial class library Processing needs to commmunicate through the serial port:
import processing.serial.*; // import the serial class processing library

The next 2 lines initialize and declare variables
Serial myPort; //create an object from Serial class
int val; //variable that will hold the information the serial port is collecting

I added a line to declare the fill color to brownish yellow:
color c1 = color(255, 204, 0); //set the fill color (deep darkish yellow)

Refer to this link for further documentation on color with Processing js.

In the void setup we define the size of the interface window
void setup()
{
size(300, 500) //the size of the interface window will be 300px x 500px

Finally we need to define the port Porcessing will use to communicate with the Arduino board.
As oppose to Arduino IDE, the serial communication port in Processing is not defined in the tool menu but in the code directly. By default the simpleread Processing sketch is set to use PORT0 (notice the 0 in the square bracket)
String portName = Serial.list()[0];
But we need to set Processing to use the same port Arduino is using to serial communicate the datas which in my case is:
/dev/cu.usbmodem641.

To figure which port number to put between the square bracket we add a line of code that will tell Processing to list the available ports:
println(Serial.list());
Running the Processing sketch with this line in the code a window at the bottom of the main window opens listing the serial communication ports available. They are listed as items in an array mode which means that:
the 1st item on the list = 0, the 2nd on the list = 1, etc. etc.

As we can see in the prevous image the "/dev/cu.usbmodem641" port is the second item listed which means it corresponds to PORT1, therefore I changed the 0 to 1 in the square bracket.
String portName = Serial.list()[1];

Than we need to add a line for processing to initialize an instance of the serial class:
myPort = new Serial(this, portName, 9600);// set the class for the port, port name and baudrate

The next step is to create the function that will make the object interact with the data input. For this we use "void draw" (which is in Processing what "void loop" is to Arduino) and write the program following the same logic as in Arduino.

Here is the complete Processing sketch that makes a 300px x 500px black square change to dark yellow when the botton is pressed:
import processing.serial.*; //import serial library from processing
Serial myPort; // Create object from Serial class
int val; // Data received from the serial port
color c1 = color(255, 204, 0); //set the color (deep darkish yellow)

void setup() {
size(300, 500); //set the size of the interface window
println(Serial.list());//lists the ports in the serial list on my mac
String portName = Serial.list()[1]; // assign the port arduino is using for serial comunication.
myPort = new Serial(this, portName, 9600);// set the class for the port, port name and baudrate
}
void draw()//draw is to processing what loop is to Arduino
{
if ( myPort.available() > 0) // If data is available
{
val = myPort.read(); // read it and store it in val
}
background(0); // Set background to black
if (val == 0) // If the serial value is 0
{
fill(0); // set fill to black
}
else // If the serial value is not 0
{
fill(c1); // set fill to brownish yellow
}
rect(10, 10, 280, 480); // set the position and the dimension of the rectangle to be drawn
}

Graphs Arduino + Processing

Next exercise consists of interfacing a graph with the datas collected from a light sensor connected to an Arduino board. The script visualize the values collected by the light sensor and map it into an X and Y position on a graph. I used a template and adapted some of the graphic aspects. The resistance I use is too high for the LRD sensor making the minimum never reaching O - not using full potential range. With this exercise I used new Processing functions such xPos, SerialEvent and inByte.

Going a little further adding complexity (Arduino + processing)

Next I created a sketch in Arduino and wired a board with 3 leds (Red, Blue and Green) and wrote a Processing script that makes colored squares in different position of the screen interact with the mouse position and buttons (left and right).
1º- left mouse button pressed fills the frame with black + all leds are off
2º- a 200 x 200 px blue square pop up when mouse is over the right end side of the window (between 0 and 200 and no button pressed) + blue led turns on.
3º- when mouse is not over the blue square a 600 px green square popups from the right end limit of the window and stays even if mouse scroll over + green led turns on.
4º- when right mouse botton is pressed 2 red square pop up on each side of the green square which disappears + red led turns on. This Processing- Interactivity page was very helpful to learn how to create this program.

Reading from a potentiometer (Arduno + Processing)

For the next exercise I connected a potentiometer on the Arduino board and downloaded a Processing script that slides a yellow circle from left to right as the potentiometer value increases. Here I introduce more complex functions and datatype such as float, maps and padding - some to do with the graphic aspect of the interface but others with the functonality.
Here is the Arduino + processing program that I used as a start point.

I wired the potentiometer to the Arduino board and ran the script as is but it took only 1/4 of potentiomemnter turn(90º) for the yellow circle to travel from one extreme to the other of the screen . The circle would go 4 times from one end to the other when turning the potentiometer knob 360º, and the value read by Processing would range between 0 and 255 also 4 times.

Bytes range from 0 to 255 as opposed to ASCII characters which range from o to 1023. For the yellow circle to travel only once from one side to the other when potentiometer is turned 360º the ASCII characters needs to be converted into strings (sequence) of bytes and map the bytes to a proportion where o-1023 is equivalent to 0-255). The program needs to be adapted so the conversion happens outside the "void draw" function by adding a "serial.event"function in which the string value in bytes is mapped.
I picked some bits of codes from different sources, and with my instructor managed to get the program to do what I was intending. It's a bit of a patching and far from elegant but it worked.

Reading potentiometer data from Attiny84 board (Arduino + Processing)

The next and final step of this assignment is to make the same interface work on an Attiny84 board I made for my final project.

The board has 3 Analog I/O pin but for this exercise I will use only one of the output pin - a potentiometer.
Arduino board comes by default with Serial communication library but when writing a serial communication sketch for Attiny board we need to tell the Arduino IDE to link it to a SoftwareSerial library. This is done by including and declaring the library in the first lines of code:
#include <SoftwareSerial.h>

The rest of the Arduino Sketch is very simple and worked perfectly well. But I wanted to make a further iteration of the processing program to have the ball change color as it slides from one end to the other.

Basically what I did is to insert in the serial draw function:
int g = int(reading*255.0); //create an integrer g which corresponds to the reading multiplied x 255
fill(0, g, 0); //set the fill color as int g
float x = reading*1023.0 +100; //define x as decimal numerical number which equal to: reading* decimal ASCII character +100 - (100 set the start position of the yellow circle equivalent to padding value)
println("drawing ellipse at x=" + x); //translate reading in the range 0 to 1 to x that has a value between 100 and 1123.

And in the serial event function:
reading = float(inString)/1023.0; //convert 0 to 1023 range to 0 to 1.0
println("normalized arduino value: " + reading); // print in the processing monitor the value read by arduino

And finally I canceled the last line of code:
reading = map(reading, 0, 255, 0, height);

With this I managed to slick my code and get the yellow circle to change from black to bright green as it slides along the potentiometer, and have the Arduino reading printed on the Processing monitor. Here is the entire code:

import processing.serial.*;
Serial myPort;
int value;
int padding = 100;
float m;
String myString;
float val;
int[] pin_val;
int lf = 10;
boolean received;
float reading = 0;

void setup()
{
size(1200, 200); // println("Available serial ports:");
println(Serial.list());
myPort = new Serial(this, Serial.list()[1], 9600);

smooth();
strokeWeight(10);
stroke(10);
}

void draw()
{
background(#FFFFF0);
line(padding, height/2, width-padding, height/2);
noStroke();
int g = int(reading*255.0);
fill(0, g, 0);
float x = reading*1023.0 +100;
println("drawing ellipse at x=" + x);
ellipse(x, height/2, 100, 100);
stroke(10);
}

void serialEvent (Serial myPort)
{
String inString = myPort.readStringUntil('\n');
if (inString!= null){
inString = trim(inString);// trim off any whitespace;
reading = float(inString)/1023.0;//convert to an int and map to the screen height and convert 0 to 1023 to 0 to 1.
println("normalized arduino value: " + reading);//reading = map(reading, 0, 255, 0, height);
}
}

Links and referecens

Here a series of links and references I used and were very helpful:
Processign potentiometer
Processign potentiometer
Processign references
serial print arduino
Processing: serial data
graphing data from Arduino sensor

Connecting Arduino to processing- Handshake.

And other references about interfacing with Python which I did not have tome to explore:
Arduino Matlab
Pythn to plot graph of serial data from arduino Uno analog pin
Python to Arduino

Conclusion

This week I learned a lot but I will need a long time and lots of practice to assimilate all I got acquainted to. Nevertheless it is a big step in getting more confident with actually writing programs. Unfoertunatly I got really involved with Processing and did not get around to try Python but I feel it was better to go deeper into one language than try scratching a few. The reason is simply that I think getting better at one will give the skills, knowledge and confidence to challenge more language in the future.
I am also very happy that this exercise will also serve my final project.

Access original files here.


Back to top
Next project
Previous project