Week 14. Interface and Application Programming¶
Group Assignment:¶
- Compare as many tool options as possible.
- Document your work on the group work page and reflect on your individual page what you learned.
Link to Group Assignment Page.
Some take-aways:
- MicroPython introduces a new programming language to learn, offering versatility for various projects.
- Remember to flash the board before use, and ensure you have two essential files: boot.py (similar to Arduino’s setup) and main.py (akin to Arduino’s loop).
- Despite differences, coding in MicroPython shares similarities with Arduino, such as variable declarations and basic control structures like if and else statements.
Individual Assignment:¶
- Write an application that interfaces a user with an input and/or output device(s) on a board that you made.
Processing¶
- To start with processing, I downloaded processing software from here.
- Processing communicates with a Microcontroller (like Arduino) via a serial connection.
- This connection enables two-way communication between Processing and the Microcontroller.
- Processing can send control signals to the Microcontroller, acting as an Input interface. For example, a graphical ON button on a Processing canvas can activate an LED connected to the Microcontroller.
- Processing can receive data from the Microcontroller, acting as a Data Visualizing Display. For instance, it can receive temperature sensor data from a sensor connected to the Microcontroller and display it visually.
- The Processing program runs on a PC while the Microcontroller is connected via Serial Communication. This setup allows for interactive control and visualization, with Processing both sending commands to the Microcontroller and receiving data from it.
Riko’s Tutorial¶
To get started with Processing! Riko’s tutorials are very helpful.
- Make a Colorful Canvas
This is the processing code for red, 400px by 400px square canvas with background(90R, 0G, 0B)
void setup(){
size(400,400); //pixels
}
void draw() {
background(90,0,0); //RGB
}
- Draw Shapes & Text!
void setup(){
size(400,400); //pixels
}
void draw(){
background(0); //0 is black, 255 is white
stroke(0,0,200);
strokeWeight(2);
fill(200, 10, 10);
circle(width/2, height/2, 200);
stroke(100,100,100);
fill(255, 255, 255);
textSize(30);
text("Click me!", width/2-50, height/2);
}
This Processing code creates a simple interactive visual. Upon execution, a black window with a red circle at its center and the text “Click me!” displayed inside appears. The circle serves as a clickable element. When the user clicks anywhere within the circle, the background turns black again, essentially refreshing the screen. This basic interactive display encourages user engagement by prompting them to interact with the circle element.
- Creating a Custom Pointer: Utilizing Mouse Events and Positioning in Processing
void setup(){
size(500,500); //pixels
noCursor();
}
void draw(){
background(100); //greyscale...0 is black, 255 is white
//Button
//Conditional statement...button color depends mouse click
if (mousePressed) {
fill(0, 200, 50);
} else {
fill(200, 0, 0);
}
stroke(0,0,200);
strokeWeight(5);
circle(width/2, height/2, 200);
//Pointer
fill(200,100,0);
noStroke();
circle(mouseX, mouseY, 30);
}
This Processing code creates an display with a button and a custom pointer. Upon running, it initializes a 500x500 pixel window with no system cursor visible. The background color is set to a mid-grey tone. The button’s color changes based on mouse click events: when the mouse is pressed, the button turns green; otherwise, it remains red. The button is drawn at the center of the window as a circle with a diameter of 200 pixels, outlined with a blue stroke.
Arduino (Sender) > Processing (Receiver)…the OUTPUT scenario¶
Remember to Execute the Arduino code followed by the Processing sketch to complete the workflow seamlessly.
For Arduino:
- Start serial communication:
Serial.begin(9600)
Arduino Code:
void setup(){
//initialised the serial port for data upload
Serial.begin(9600);
}
void loop(){
//capture data in arduino
int variable1 = int(random(100));
//put the data onto the serial port
Serial.println(variable1);
delay(100);
}
For Processing:
- Import serial library:
import processing.serial.*;
- Create a Serial object:
Serial portName;
- Define portName:
String portName = Serial.list()[0];
- Initialize Serial object:
portName = new Serial(this, portName, 9600);
Processing Code:
import processing.serial.*;
Serial mySerial; //create local serial object from serial library
//useful variables for serial communication
String myString = null; //variable to capture string data being transmitted over serial port
int nl = 10; //'nl' variable to represent a carriage return (end of line)...represented by '10' in this case
float myVal; //'float' are non-whole numbers
void setup() {
size(200,400); //canvas size
//initialize serial communication
String portName = Serial.list()[0];
mySerial = new Serial(this,portName,9600); //initialize and configure serial port...match baud rate with arduino
}
void draw() {
//check to see if data available in serial port
while(mySerial.available() > 0) {
myString = mySerial.readStringUntil(nl); //read string until carriage return received
//check data validity
if (myString != null) {
background(0); //refresh background color...no trace
myVal = float (myString);
//scale and map myVal value to screen Y-position
myVal = myVal/100 * height; //divide by 100 to match range set in Arduino code
//draw a rectangle representation of the data...variable Y height
rectMode(CENTER);
rect(width/2, height-(myVal/2), 100, myVal); //x,y, xpos, ypos
}
}
}
Processing (Sender) > Arduino (Receivers)…the INPUT scenario¶
Interactive Button Control: Arduino - Processing for Mouse-Activated LED Blinking¶
This Arduino program establishes a serial communication connection with a Processing program, receiving characters to trigger actions via pin 1 of the MCU, which is connected to an LED.
//Arduino-processing blink LED at GPIO1 XiaoEsp32S3
char val;
int ledPin = 1;
void setup() {
Serial.begin(9600); //initialise serial communication at 9600 baud rate
pinMode(1, OUTPUT); //set pin 1 as output
}
void loop() {
if (Serial.available()){
val = Serial.read(); //create character type data variable 'val'
if (val == '1'){ //if '1' received over serial
digitalWrite(ledPin, HIGH); //turn ON LED
} else{
digitalWrite(ledPin, LOW); //turn OFF LED
}
delay(10);
}
}
In this Processing program, the Serial library is imported to facilitate communication with the Arduino. A Serial variable ‘port’ is created to establish a connection. To trigger a transmission event, the ‘port.write(“1”);’ command is utilized, sending the character ‘1’ through the serial connection to the Arduino program.
import processing.serial.*;
Serial port;
void setup(){
size(500,500); //pixels
noCursor();
String portName = Serial.list()[0];
port = new Serial(this, portName, 9600); //set port variable equal to new seria
}
void draw(){
background(100); //greyscale...0 is black, 255 is white
//Button
//conditional statement....button color depends on pointer position
if (mouseX > 150 && mouseX < 350 && mouseY > 150 && mouseY < 350 && mousePressed){
fill(0, 200, 50);
port.write('1');
} else {
fill(200, 0, 0);
port.write('0');
}
stroke(0,0,200);
strokeWeight(5);
circle(width/2, height/2, 200);
//pointer
fill(200,100,0);
noStroke();
circle(mouseX, mouseY, 30);
}
Control Arduino Using GUI (Arduino + Processing)¶
I followed a comprehensive document and a step-by-step YouTube tutorial from this link to guide me through the process.
- To integrate the ControlP5 GUI library into Processing, navigate to “Sketch” in the menu, select “Import Library,” and then choose “Add Library.” ControlP5, authored by Andreas Schlegel, enriches the Processing programming environment with advanced graphical user interface capabilities.
Here’s the Processing code:
import controlP5.*;
import processing.serial.*;
Serial port;
ControlP5 cp5; //create ControlP5 object
PFont font;
void setup(){ //same as arduino program
size(300, 450); //window size, (width, height)
printArray(Serial.list()); //prints all available serial ports
port = new Serial(this, "COM4", 9600); //i have connected arduino to COM4, it would be different in linux and mac os
//lets add buton to empty window
cp5 = new ControlP5(this);
font = createFont("calibri light bold", 20); // custom fonts for buttons and title
cp5.addButton("A") //"A" is the name of button
.setPosition(100, 50) //x and y coordinates of upper left corner of button
.setSize(120, 70) //(width, height)
.setFont(font)
;
cp5.addButton("B") //"B" is the name of button
.setPosition(100, 150) //x and y coordinates of upper left corner of button
.setSize(120, 70) //(width, height)
.setFont(font)
;
cp5.addButton("C") //"C" is the name of button
.setPosition(100, 250) //x and y coordinates of upper left corner of button
.setSize(120, 70) //(width, height)
.setFont(font)
;
cp5.addButton("alloff") //"alloff" is the name of button
.setPosition(100, 350) //x and y coordinates of upper left corner of button
.setSize(120, 70) //(width, height)
.setFont(font)
;
}
void draw(){ //same as loop in arduino
background(150, 0 , 150); // background color of window (r, g, b) or (0 to 255)
//lets give title to our window
fill(0, 255, 0); //text color (r, g, b)
textFont(font);
text("LED CONTROL", 80, 30); // ("text", x coordinate, y coordinat)
}
//lets add some functions to our buttons
//so whe you press any button, it sends perticular char over serial port
void A(){
port.write('1');
}
void B(){
port.write('2');
}
void C(){
port.write('3');
}
void alloff(){
port.write('0');
}
- This Processing code sets up a graphical user interface (GUI) using the ControlP5 library, allowing user interaction to control an Arduino-connected LED. Upon running, it displays a window with buttons labeled A, B, C, and “alloff”.
- Each button corresponds to a specific action: pressing A sends the character ‘1’ over the serial port, B sends ‘2’, C sends ‘3’, and “alloff” sends ‘0’.
- These characters trigger actions on the Arduino side, controlling the state of an LED.
- The GUI window also includes a title “LED CONTROL” at the top. The program continuously runs in a loop and enables users to control the LED’s behavior by simply clicking the corresponding buttons in the graphical interface.
Now for Arduino, I wrote a code that listens for incoming characters through serial communication, and based on the received character, it toggles the state of specific LEDs connected to pins 1, 43, and 44 accordingly, turning them on or off.
Arduino Code:
void setup() {
pinMode(1, OUTPUT); //set pin as output LED1
pinMode(43, OUTPUT); //set pin as output LED2
pinMode(44, OUTPUT); //set pin as output LED3
Serial.begin(9600); //start serial communication @9600 bps
}
void loop(){
if(Serial.available()){ //id data is available to read
char val = Serial.read();
if(val == '1'){ //if 1 received
digitalWrite(1, HIGH); //turn on LED1
}
if(val == '2'){ //if 2 received
digitalWrite(43, HIGH); //turn on LED2
}
if(val == '3'){ //if 3 received
digitalWrite(44, HIGH); //turn on LED3
}
if(val == '0'){ //if 0 received
digitalWrite(1, LOW); //turn off all led
digitalWrite(43, LOW);
digitalWrite(44, LOW);
}
}
}
Here’s the working video: