14. Interface and application programming

1.1 Assignments of the Week

  1. 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.
  2. Individual assignments:
    • Write an application that interfaces a user with input and/or output device(s) on a board that you made.

1.2 Group Assignment

This is the link of our group assignment.

1.3 Individual Assignment

1.3.1 Light a LED: Serial Communication Between Arduino and Processing

To begin with, I created an interface in Processing where I could left-click to light up the LED on my Fab-Xiao development board and right-click to turn off the LED. I followed the tutorial on Youtube. Here is the hero shot video below:

When I left-click the mouse, the square turned pink (the LED on my board is pink) and turn on the LED.
When I right-click the mouse, the square turned black and turn off the LED.


Arduino Code:


        void setup() {
          // put your setup code here, to run once:
        pinMode(D6,OUTPUT);
        Serial.begin(9600);
        }

        void loop() {
          // put your main code here, to run repeatedly:
        if(Serial.available()>0){
          char ledPinState = Serial.read();
          if(ledPinState == '1'){
            digitalWrite(D6,HIGH);
          }
          if(ledPinState == '0'){
            digitalWrite(D6,LOW);
          }
        }
        }
      

I encountered an issue where I attempted to abbreviate the "D6" pin as "6," similar to how it's done in Arduino. However, this approach did not yield the desired results when working with the Seeed Xiao board. It's crucial to note that omitting the "D" prefix for digital pins on the Seeed Xiao board will result in functionality problems.

Processing Code:


        import processing.serial.*;
        Serial myPort;

        void setup(){
          size(200,200);
          background(255);
          rect(80,80,40,40);
          myPort=new Serial(this, "COM12", 9600);
        }

        void draw(){
          if(mousePressed && (mouseButton == LEFT)){
            fill(255,106,160);
            rect(80,80,40,40);
            myPort.write('1');
          }
          if(mousePressed && (mouseButton == RIGHT)){
            fill(0);
            rect(80,80,40,40);
            myPort.write('0');
          }
        }
      

It is important to note that in the line of code "myPort=new Serial(this, "COM12", 9600);", you need to identify the right serial port number that corresponds to your development board and ensure the matching baud rate is set in Arduino.

1.3.2 RGB-LED: Serial Communication Between Fab-XIAO and Processing

Then I tried to use Processing to create an interface that can control RGB-LED. I borrowed the sample code of Scrollbar from the official website of processing. I created 3 scrollbars to control the three colors of red, green, blue respectively. Now I can move the scrollbar left and right to change the color of the RGB-LED.

Arduino Code:


        char charbuf[20];
        int color[3];

        void setup() {
          // put your setup code here, to run once:
          pinMode(D0, OUTPUT);  //red
          pinMode(D1, OUTPUT);  //green
          pinMode(D2, OUTPUT);  //blue
          Serial.begin(9600);
        }

        void loop() {
          while (Serial.available() > 0) {
            Serial.readBytesUntil('s', charbuf, 20);
            if (charbuf[0] == 'a') {
              color[0] = 100 * (charbuf[1] - '0') + 10 * (charbuf[2] - '0') + charbuf[3] - '0';
              color[1] = 100 * (charbuf[4] - '0') + 10 * (charbuf[5] - '0') + charbuf[6] - '0';
              color[2] = 100 * (charbuf[7] - '0') + 10 * (charbuf[8] - '0') + charbuf[9] - '0';
            }
            analogWrite(D0, color[0]);
            analogWrite(D1, color[1]);
            analogWrite(D2, color[2]);
          }
        }
      

Processing Code:


        import processing.serial.*;
        Serial colorfulLed;

        boolean firstMousePress = false;
        HScrollbar hs1, hs2, hs3;
        PImage imgred, imggreen, imgblue;
        int r, g, b;
        String strRed,strGreen,strBlue;
        String message;

        void setup() {
          size(1000, 600);
          noStroke();

          hs1 = new HScrollbar(0, height/4, width, 16, 16);
          hs2 = new HScrollbar(0, height*2/4, width, 16, 16);
          hs3 = new HScrollbar(0, height*3/4, width, 16, 16);

          imgred = loadImage("w14_red_led.jpg");
          imggreen = loadImage("w14_green_led.jpg");
          imgblue = loadImage("w14_blue_led.jpg");

          colorfulLed = new Serial(this, "COM12", 9600);
        }

        void draw() {
          background(255);

          // Get the position of the img1 scrollbar
          // and convert to a value to display led images
          float imgredPos = hs1.getPos()-width/2;
          fill(255);
          image(imgred, width/2 + imgredPos-25, height/4-50,50,50);

          float imggreenPos = hs2.getPos()-width/2;
          fill(255);
          image(imggreen, width/2 + imggreenPos-25, height*2/4-50,50,50);

          float imgbluePos = hs3.getPos()-width/2;
          fill(255);
          image(imgblue, width/2 + imgbluePos-25, height*3/4-50,50,50);

          hs1.update();
          hs2.update();
          hs3.update();
          hs1.display();
          hs2.display();
          hs3.display();

          //map scroll bar positions to values of 3 colors
          r=int(map(hs1.getPos(),0,640,0,255));
          g=int(map(hs2.getPos(),0,640,0,255));
          b=int(map(hs3.getPos(),0,640,0,255));

          //convert values of 3 colors into strings
          strRed =r+"";
          if(r<100){
            strRed ="0"+r;
          }
          if(r<10){
            strRed ="00"+r;
          }

          strGreen =g+"";
          if(g<100){
            strGreen ="0"+g;
          }
          if(g<10){
            strGreen ="00"+g;
          }

          strBlue =b+"";
          if(b<100){
            strBlue ="0"+b;
          }
          if(b<10){
            strBlue ="00"+b;
          }

          //concatenate strings and send to my FAB-XIAO
          message ='a'+strRed+strGreen+strBlue+'s';
          colorfulLed.write(message);

          //After it has been used in the sketch, set it back to false
          if (firstMousePress) {
            firstMousePress = false;
          }
        }

        void mousePressed() {
          if (!firstMousePress) {
            firstMousePress = true;
          }
        }

        class HScrollbar {
          int swidth, sheight;    // width and height of bar
          float xpos, ypos;       // x and y position of bar
          float spos, newspos;    // x position of slider
          float sposMin, sposMax; // max and min values of slider
          int loose;              // how loose/heavy
          boolean over;           // is the mouse over the slider?
          boolean locked;
          float ratio;

          HScrollbar (float xp, float yp, int sw, int sh, int l) {
            swidth = sw;
            sheight = sh;
            int widthtoheight = sw - sh;
            ratio = (float)sw / (float)widthtoheight;
            xpos = xp;
            ypos = yp-sheight/2;
            spos = xpos + swidth/2 - sheight/2;
            newspos = spos;
            sposMin = xpos;
            sposMax = xpos + swidth - sheight;
            loose = l;
          }

          void update() {
            if (overEvent()) {
              over = true;
            } else {
              over = false;
            }
            if (firstMousePress && over) {
              locked = true;
            }
            if (!mousePressed) {
              locked = false;
            }
            if (locked) {
              newspos = constrain(mouseX-sheight/2, sposMin, sposMax);
            }
            if (abs(newspos - spos) > 1) {
              spos = spos + (newspos-spos)/loose;
            }
          }

          float constrain(float val, float minv, float maxv) {
            return min(max(val, minv), maxv);
          }

          boolean overEvent() {
            if (mouseX > xpos && mouseX < xpos+swidth &&
              mouseY > ypos && mouseY < ypos+sheight) {
              return true;
            } else {
              return false;
            }
          }

          void display() {
            noStroke();
            fill(204);
            rect(xpos, ypos, swidth, sheight);
            if (over || locked) {
              fill(0, 0, 0);
            } else {
              fill(102, 102, 102);
            }
            rect(spos, ypos, sheight, sheight);
          }

          float getPos() {
            // Convert spos to be values between
            // 0 and the total width of the scrollbar
            return spos * ratio;
          }
        }
      
To send three different color values, you'll need to first convert them into strings ("strRed", "strGreen", and "strBlue" in the processing code). Next, concatenate the three strings into a single string (the "message" in processing code), and finally send the "message" to the development board. In the development board, you'll need to split the string and convert them into integers.