Skip to content

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.

Individual assignment:

  • Write an application that interfaces a user with an input and/or output device(s) on a board that you made.

Download Design Files

Click here to download my design files folder

Group Work Reflection

The group work helped me to better understand multiple types of interfacing platforms and ways to achieve interfacing and application programming. It was very confusing at first but the group work helped me to better understand the benefits of different platforms. Although we did try to interface with eachn other’s chosen platform(s) (time constraints had us with little room to stray off what we needed to accomplish), we did talk through the experience of using the platform/the ease, or difficulty, of its use.

Personally, through talking with Landon and seeing how he used each platform, I learned many things! For instance, I learned that Lopaka is helpful in more efficiently creating OLED displays. Through my struggles of constantly having to re-upload code to see if it works/changes what I want it to, I think having something like Lopaka to help see how the OLED would display without having to upload over and over again would be extremely nice. Additionally, I learned about Matplotlib from Landon. Matplotlib takes information from a sensor and graphs the x and y values. Although I did think this was cool, I was a bit confused about its practical use in terms of Landon’s final project. But then he reminded me that he wanted to make a ski mask that displayed stats related to your skiing. With this in mind, Matplotlib seemed like a wonderful thing for Landon to use and would be awesome to encoroprate in some of my future projects! And also great to use for seeing how consistently a sensor is performing which would help eliminate possible questions as to what is and what isn’t working when debugging!

Link to Group Work Page

Research

I wasn’t quite sure what to do to start this week. The video helped, however, I was still a bit confounded on where to start and what I could even realistically do. I checked out many of my peer’s documentation and eventually decided that Collin Kanofsky’s documentation made the most sense to me and seemed most plausible. I am not very versatile in software and things of such sort so I wasn’t very confident in my abilities going into this week.

I downloaded the software Processing 4 and started by exploring some of their examples. From there, I read through another Fab Academy Student’s Documentation, Nicole Stancampiano.

  • In my own words, I would describe Processing as a clean, easy to use environment that aids users in figuring out how to interface and create software. Its minimalistic style allows for challenging, and oftentimes overwhelming coding to appear more inviting and helps to encourage those new to the programming world to create, try new things, and experiment!

  • Processing “includes a text editor, a compiler, and a display window and enables the creation of software within a carefully designed set of constraints” (source). These features, along with the large amount of resources and examples and tutorials make Processing a very, very nice application!

I then used ChatGPT to experiment with coding in Processing and had it write this cool code that made a bunch of circles appear on the screen when you clicked a button on the screen:

import processing.serial.*;

Serial port;
Button b;

void setup() {
size(600, 400);
// Modify the port name based on your system (check in Arduino IDE)
// Commenting out serial initialization for the sake of simplicity in this example
// port = new Serial(this, "/dev/cu.usbmodem11301", 9600);

// Create a button
b = new Button(width/2 - 100, height/2 - 50, 200, 100, "Click for Fun");
}

void draw() {
// Display random circles when button is clicked
if (b.isClicked()) {
    background(random(255), random(255), random(255)); // Change background color
    for (int i = 0; i < 50; i++) {
    float x = random(width);
    float y = random(height);
    float diameter = random(10, 100);
    fill(random(255), random(255), random(255)); // Random circle color
    ellipse(x, y, diameter, diameter);
    }
}

// Draw the button
b.drawButton();
}

void mousePressed() {
// Check if the mouse is pressed over the button
b.clicked();
}

class Button {
float x, y, w, h;
String label;
boolean clicked = false;

Button(float x, float y, float w, float h, String label) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.label = label;
}

void drawButton() {
    PFont f;
    f = createFont("Arial", 24);
    rectMode(CENTER);
    rect(x, y, w, h, 10);
    fill(255);
    textFont(f);
    textAlign(CENTER, CENTER);
    fill(0);
    text(label, x, y);
}

void clicked() {
    if (mouseX > x - w/2 && mouseX < x + w/2 && mouseY > y - h/2 && mouseY < y + h/2) {
    clicked = true;
    } else {
    clicked = false;
    }
}

boolean isClicked() {
    return clicked;
}
}

Feeling a bit more comfortable with what lied ahead of me, I decided to experiment with the codes Collin and Nicole Stancampiano used.

Hardware

For this week, I used a XIAO-RP2040 and the board I designed and made in Week 11: Input Devices.

Coding

I then used ChatGPT to help me understand Collin Kanofsky’s interfacing code

ChatGPT said:

This code is a simple Processing sketch that interfaces with an Arduino or any other microcontroller connected via a serial port. Let's break it down step by step:

1. Import Serial Library: `import processing.serial.*;`
This line imports the serial library, which provides functionality for communicating with serial ports.

2. Declare Serial Port Object: `Serial port;`
This line declares a variable `port` of type `Serial`, which will be used to communicate with the serial port.

3. Declare Button Object: `Button b;`
This line declares a variable `b` of type `Button`, which represents a clickable button in the sketch.

4. Setup Function: `void setup()`
This function is called once when the sketch starts. It initializes the sketch, sets the canvas size, and initializes the serial port object.

5. Initialize Serial Port: `port = new Serial(this, "/dev/cu.usbmodem11301", 9600);`
This line initializes the serial port object `port` with the specified port name ("/dev/cu.usbmodem11301" in this case) and baud rate (9600).

6. Create Button: `b = new Button(width/2 - 100, height/2 - 50, 200, 100, "Click for Blinks");`
This line creates a new button object `b` with the specified position, dimensions, and label.

7. Draw Function: `void draw()`
This function is called continuously in a loop after `setup()`. In this sketch, it's empty because we don't need to draw anything continuously.

8. Mouse Pressed Event: `void mousePressed()`
This function is called whenever the mouse is pressed. It checks if the mouse is pressed over the button and calls the `clicked()` method of the button object.

9. Button Class: `class Button`
This is a nested class that represents a clickable button. It has properties like position, dimensions, and label.

10. Constructor: `Button(float x, float y, float w, float h, String label)`
    This is the constructor of the `Button` class. It initializes the button with the specified parameters and draws it on the canvas.

11. drawButton() Method: `void drawButton()`
    This method draws the button on the canvas using the `rect()` and `text()` functions.

12. clicked() Method: `void clicked()`
    This method is called when the button is clicked. It checks if the mouse coordinates are within the button boundaries and sends a command ('H') to the Arduino via the serial port if the conditions are met.

This sketch essentially creates a graphical interface with a clickable button. When the button is clicked, it sends a command to an Arduino or similar microcontroller via the serial port to trigger some action, like blinking an LED.

From here, I uploaded the following code that Collin had used to my Seeed Studio XIAO-RP2040 in Arduino:

#include <Adafruit_NeoPixel.h>      // includes the Adafruit NeoPixel library, providing functions to control neopixels

int PIN  = LED_BUILTIN;        // declares & initializes "PIN" as a constant integer for the built-in LED pin

#define NUMPIXELS 1     // defines a preprocessor macro "NUMPIXELS" with a value of 1, indicating that the number of neopixels being controlled is 1

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);     // creates object "Adafruit_Neopixel" named "pixels", initialized to control "NUMPIXELS" LEDs connected to the specified "PIN"; the LEDs are configured to use the GRB color format and communicate at 800 kHz

const int ledPin1 = 
int ledState = LOW;     // declares & initializes "ledState" as an integer to track the LED's state (initially off)
int buttonState = 0;        // declares & initializes "buttonState" as an integer to track the buttons state (initially 0)

void setup() {
pixels.begin();     // initializes the neopixel library
Serial.begin(9600);     // initializes serial communication at baud rate 9600
Serial.println("Arduino is ready");     // prints a message to the serial monitor indicating that the Arduino is ready
}

void loop() {
if (Serial.available() > 0) {       // checks if there is data available on the serial port
    char command = Serial.read();       // if data is available, it reads the incoming bute into the "command" variable
    Serial.print("Received command: ");     
    Serial.println(command);        // prints the received command to the serial monitor

    if (command == 'H') {       // If the command is 'H', it toggles the "ledState" and calls the "flashLED()" function
    ledState = !ledState;  // Toggle LED state
    flashLED();
    }
}
}


void flashLED() {       // the "flashLED()" function controls the neopixel
Serial.println("Flashing LED");     // prints "Flashing LED" to the serial monitor
pixels.clear();     // clears any previous color from the neopixel
pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // sets the neopixel to red
delay(500);     // 500 millisecond delay between color change
pixels.show();      // updates the neopixel to display the set color
delay(500);     // 500 millisecond delay between color change
pixels.clear();     // clears any previous color from the neopixel
pixels.setPixelColor(0, pixels.Color(0, 255, 0)); // sets the neopixel to green
delay(500);     // 500 millisecond delay between color change
pixels.show();      // updates the neopixel to display the set color
delay(500);     // 500 millisecond delay between color change
pixels.clear();     // clears any previous color from the neopixel
pixels.setPixelColor(0, pixels.Color(0, 0, 255)); // sets the neopixel to blue
delay(500);     // 500 millisecond delay between color change
pixels.show();      // updates the neopixel to display the set color
delay(500);     // 500 millisecond delay between color change
pixels.clear();     // clears any previous color from the neopixel
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // sets the neopixel to OFF (black technically)
delay(500);     // 500 millisecond delay between color change
pixels.show();      // updates the neopixel to display the set color
delay(500);     // 500 millisecond delay between color change

}

I summarized this code with the help of ChatGPT as follows:

  1. Setup:

    • Initializes the NeoPixel library and serial communication.

    • Sets up the power pin for the NeoPixel.

  2. Loop:

    • Continuously checks for incoming serial commands.

    • Toggles the built-in LED state and calls flashLED() when the ‘H’ command is received.

  3. flashLED():

    • Cycles through red, green, blue, and off colors on the NeoPixel with 500 millisecond delays.

Then, I used ChatGPT’s information to help me understand and edit the code and came up with the following interfacing blink code:

import processing.serial.*;     // import serial library, allowing the Processing sketch to communicate with serial devices (like Arduino)

// The serial port
Serial myPort;      // declare variable "myPort" of type "Serial" for handling serial communication
Serial port;        // declare variable "port" of type "Serial" for handling serial communication
Button b;       // declare variable "b" of type "Button" for the button object

void setup() {      
    size(300, 200);     // sets the size of the window to 300 x 200 pixels 
// Modify the port name based on your system (check in Arduino IDE)
port = new Serial(this, "/dev/cu.usbmodem11301", 9600);     // initializes the "port" object for serial communication; connecting to the specified port at a baud rate of 9600

// Create a button
b = new Button(width/2 - 100, height/2 - 50, 200, 100, "Click for Blinks");     // creates a new "Button" object "b" positioned at the center of the window with a size of 200 x 100 pixels labeled "Click for Blinks"
}

void draw() {       // the "draw()" function runs continuously and is empty in this case as there is nothing to draw 
    // Nothing to draw here
}

void mousePressed() {       // "mousePressed()" function called whenever the mouse is pressed; checking if the button "b" is clicked by calling the "clicked()" method of the "Button" class
    // Check if the mouse is pressed over the button
    b.clicked();
}

class Button {      // defines the "Button" class with four float variables (x, y, w, & h) for the button's position and dimensions and a "String" variable "label" for the button's text
    float x, y, w, h;
    String label;

Button(float x, float y, float w, float h, String label) {      // the constructor for the "Button" class; it initializes the button's position, size, and label, then calling "drawButton()" to draw the button
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.label = label;
    drawButton();
}

void drawButton() {     // The "drawButton()" function draws the button on the screen, creating a font, drawing a rectangle for the button, and finally drawing the button's label centered within the rectangle
    PFont f;
    f = createFont("arial", 24);
    rect(x, y, w, h);
    fill(0);
    textFont(f);
    textAlign(CENTER, CENTER);
    text(label, x + w/2, y + h/2);
}

void clicked() {        // the "clicked()" function checks if the mouse click was withi the button's boundaries. If it eas and the "port" is not null ('null' meaning having no value), it sends character "H" to the Arduino via the serial port and prints a confirmation message "Sent command 'H' to Arduino" to the console 
println("Button Clicked");
if (mouseX > x && mouseX < x + w && mouseY > y && mouseY < y + h) {
    if (port != null) {
    port.write('H');  // Send 'H' to Arduino
    println("Sent command 'H' to Arduino");
    }
}
}

}
  • To summarize: this code creates a window with a button. When the button is clicked, it sends a command ‘H’ to an Arduino via a serial connection.

To summarize what this code does and what it means, I had ChatGPT help me by explaining the code to mean line-by-line

Video of the interfacing:

How is this interfacing possible? Well, the “interfacing blink code” can control an LED connected to an Arduino or similar microcontroller, like the XIAO RP2040 I used, through serial communication.

I had ChatGPT help me in coming up with this step-by-step explanation of how this works:

  1. Serial Communication Setup:

    • The Processing sketch sets up a serial connection to the XIAO RP2040.

    • “port = new Serial(this, “/dev/cu.usbmodem11301”, 9600);” opens the serial port at a baud rate of 9600. The specific port name (“/dev/cu.usbmodem11301”) might be different on your system and needs to be updated accordingly.

  2. Button Creation and Interaction:

    • The Processing sketch creates a button on the screen.

    • When you press the mouse button, the “mousePressed()” function is triggered, which checks if the button was clicked.

    • If the button is clicked, the “clicked()” method of the “Button” class sends the character ‘H’ over the serial connection: “port.write(‘H’);”.

  3. Microcontroller (XIAO RP2040) Code:

    • On the XIAO RP2040, you have a separate program (typically written in Arduino code or CircuitPython) that listens for serial communication.

    • When the XIAO RP2040 receives the character ‘H’ over the serial connection, it toggles the state of the LED.

In Summary,

  • The Processing Sketch: Displays a button on the screen and sends the character ‘H’ to the XIAO RP2040 over a serial connection when the button is clicked.

  • The XIAO RP2040 Code: Listens for serial communication. When it receives the character ‘H’, it toggles the state of an LED.

And, by combining the Processing sketch with the XIAO RP2040 code, you create a system where pressing a button on your computer sends a command to the XIAO RP2040, which in turn controls an LED.

Reflection

This week mainly served as a reminder to me not to look down upon myself too much. Even as someone who definitely struggles with software-related things, I was able to complete this week’s assignment. Also, I was reminded of the wonderful powers of Artificial Intelligence (when used properly and prompted well).

References

https://fabacademy.org/2024/labs/charlotte/students/collin-kanofsky/Week%2014/

https://processing.org/reference/PFont.html

https://fabacademy.org/2023/labs/vancouver/students/nicole-stancampiano/assignments/week14.html


Last update: September 6, 2024