Skip to content

15. 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.

Getting Started

Just to preface, I struggled a lot with this week until I found Collin Kanofsky and Nicole Stancampiano’s documentation, so huge thanks to them for their help!

Creating the Interface

The first step I took for this week’s assignment was to download Processing, which can be found here. Processing is a simple application which allows people with limited programming knowledge to create interfaces, which is why I chose it. As for the code I used to create an interface, I modified the code Nicole Stancampiano displayed in her documentation which creates a button on the screen. The way this works is, if that button is clicked by a cursor, it sends a signal to Arduino by using “port.write(‘H’)”. When this ‘H’ is received by the board, the output device of the board will activate. The code I wrote in Arduino IDE will be shown later. For now, the interfacing code that I used is shown below.

What Communication Protocol was Used?

For the code in this week’s assignment, I used serial communication in order to communicate between my board and my computer. Both portions of code have embedded comments which will go more in depth when explaining how they work.

Processing Code

import processing.serial.*;

Serial port;
Button b;

void setup() {
  size(400, 200);
  // Modify the port name based on your system (check in Arduino IDE)
  port = new Serial(this, "COM7", 9600);

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

void draw() {
  // Nothing to draw here
}

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

class Button {
  float x, y, w, h;
  String label;

  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;
    drawButton();
  }

  void drawButton() {
    PFont f;
    f = createFont("Calibri", 20);
    rect(x, y, w, h);
    fill(0);
    textFont(f);
    textAlign(CENTER, CENTER);
    text(label, x + w/2, y + h/2);
  }

void clicked() {
  println("Button Clicked");
  if (mouseX > x && mouseX < x + w && mouseY > y && mouseY < y + h) { // Checks the position of the mouse to see if it is within the boundaries of the button
    if (port != null) {
      port.write('H');  // Send 'H' to Arduino
      println("Sent command 'H' to Arduino");
    }
  }
}

}

One important thing to note about the code above is that the Pfont f, textFont(f), and f = … parts of the code allow you to display a message on the button(in this case, “Activate”, which is defined in the b = … part of the code).

Explaining the Button in the Processing Code

As you can see above, this week, I used Processing to create a button as a GUI. In order to create the button, the code first uses everything in “class Button” to set the parameters for the button and create the float values it needs to set the button’s dimensions. Then, the “drawButton” function is called. This function first sets the font and font size that the text inside of the button will use (in this case Calibri and a font size of 20 were chosen), and then it uses the “rect()” function and fill(0) to actually create the rectangular button that the user sees. Finally, the textFont(), textAlign(), and text() functions are used to align and print the user’s chosen font inside of the button. This is how we end up with the final format of the button being a rectangle with font inside of it.

Now, I will explain how the code actually tells when you have clicked the button. Essentially, I used the “void mousePressed()” and “void clicked()” functions to check this, and you can check the comments in void clicked() for further details. Essentially, what void clicked() does is it checks the coordinates of the mouse when it is clicked. If the mouse is within the boundaries of the button when it is clicked, the rest of the code in the function triggers. If not, nothing happens. Compared to void clicked(), void mousePressed() is a much simpler function, as all it does is repeatedly run the line of code, “b.clicked”, which calls the clicked function. All mousePressed() does is repeatedly run the clicked() function. Using these two functions, the code can determine when the button is clicked.

Arduino Code

At the same time as when the code in Processing was being created, I was deciding what board to use as the output. I eventually settled on the Quentorres board I made early on in Fab Academy (found here), and I planned to blink 2 of its LEDs (alternating) after clicking on the button from the interface. To do this, I first created a new file in Arduino IDE. After seeing how Collin Kanofsky got his interfacing week assignment to work, I learned what I had to do to make my code run successfully (namely the void loop() portion of the program). The finished code is shown below.

#include <Adafruit_NeoPixel.h>

int ledState = LOW;

void setup() {
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
Serial.begin(9600);
Serial.println("Arduino is ready");
}

void loop() {
if (Serial.available() > 0) {
    char command = Serial.read(); // Checks for a serial message and assigns it to command
    Serial.print("Received command: ");
    Serial.println(command); // Prints a confirmation message for receiving the "command"

    if (command == 'H') { // Checks if the message received was the correct one (i.e. the one that is supposed to trigger the LED), which in this case is "H"
    ledState = !ledState;  // Toggle LED state
    flashLED(); // Flashes the LED repeatedly
    }
}
}

void flashLED() {
Serial.println("Flashing LED");
digitalWrite(0, HIGH);
delay(500);
digitalWrite(1, HIGH);
delay(500);
digitalWrite(0, LOW);
delay(500);
digitalWrite(1, LOW);
delay(500);
digitalWrite(0, HIGH);
delay(500);
digitalWrite(1, HIGH);
delay(500);
digitalWrite(0, LOW);
delay(500);
digitalWrite(1, LOW);
delay(500);
}

Problems Encountered

Although I was sure this code would work, when I actually began trying to upload it to my board, I kept encountering an error telling me that UPDI initialization had failed. After trying to figure out why this was happening for a few minutes, I settled on a possible explanation. Because I had turned my Xiao RP2040 into a programmer, I might no longer be able to upload code to it in the same way as with other chips. To test this theory, I opened file explorer and held down the ‘B’ and ‘R’ buttons on the chip so that it would appear under “This PC” on my computer. After doing this, I went back to Arduino IDE, and, sure enough, a port different to the one I was originally using now popped up. Instead of displaying “COM7” as an available port like before, Arduino IDE was now displaying “UF2_Board” as a port. After choosing this port, the code was uploaded successfully!

Running the Code

Now that I had successfully uploaded the code to my Xiao RP2040, I went back to processing and clicked on the start button to run the interfacing code. The video below shows my board successfully interfacing with my computer.

Group Assignment

The group assigment for this week was to compare different tool options that can be used for interface and application programming. I primarily used Processing, so that is mostly what I documented on our group assignment mage, found here.

Reflection

I feel like I learned a lot from this week, both from the struggles I experienced before finding Processing and when trying to figure out how to work with a Xiao RP2040 that had been turned into a programmer. I also learned how to adjust the different parts of my interface, such as the size of the button, what text it would display, what signal it would send out to my board, and more! My files for this week can be found here. I have pasted the processing code into a file in Arduino IDE. If you want to try it for yourself, just download Processing and paste that code into it instead of trying to run it directly from Arduino IDE.


Last update: July 5, 2024