Emilio Méndez- Fab Lab CiDi 2024

14. Interface and application programming

Assignment:
Group assignment:
Compare as many tool options as possible

Individual assignment:
Write an application that interfaces a user with an input &/or output device that you made

Planning

For this week, I decided to use a SiSonic SPU0414HR5H-SB microphone, which utilizes MEMS (micro-electromechanical system) technology. To build the electronic board, I based it on a design presented by Neil in the input devices class. This will allow me to convert an analog sound signal to digital and interact with that signal. For the interface, I decided to use Processing, which uses Java language for programming.
The components of the board are:
  • 1 ATtiny45 microcontroller
  • 1 Mic MEMS Anolog OMNI -42 db SPU0414HR5H-SB
  • 1 1K Ω resistor
  • 1 10K Ω resistor
  • 3 cap 1uF
  • 1 cap 10uF
  • 1 FTDI connector
  • J1 ISP connector
  • IC reg linear 3.3V
This is my finished electronic board:

Programming and Testing

First, I programmed the Attiny45 using Arduino IDE 1.8.18, using an Atmel ICE as a programmer. I loaded a code to print the word "Hello" in the serial monitor. Here is the code and the Hello video:

            #include <SoftwareSerial.h>
            
            int rx = 3;    
            int tx = 2;    
            
            SoftwareSerial mySerial(rx, tx); //Setting up the RX/TX pins as a SoftwareSerial
            
            
            void setup(){
             mySerial.begin(9600);       //Start the serial communication and select the its speed that deppends of the frequency that it will be program the attiny
            
             
            
            }
            
            void loop() {
            
            
            
                  mySerial.println("hello \n");         //Prints in the screen the actual state
                
            
                delay(1000);
             
            
            }
            
            


"Next, I used a code that allowed me to visualize the variations in sound captured by the microphone on the serial plotter. This way, I could verify that the microphone works correctly, as soldering it was quite a challenge.
            la#include <SoftwareSerial.h>
            
            int rx = 3;    
            int tx = 2;    
            int analogPin = A2;  // Analog input pin for receiving signal
            
            SoftwareSerial mySerial(rx, tx); // Setting up the RX/TX pins as a SoftwareSerial
            
            void setup(){
              mySerial.begin(9600);       // Start the serial communication and select the speed
              
              pinMode(analogPin, INPUT);  // Set the analog pin as input
            }
            
            void loop() {
              // Read the analog value from the analog pin
              int sensorValue = analogRead(analogPin);
              
              // Print the analog value to the serial monitor
              //mySerial.print("Analog Value: "); 
              mySerial.println(sensorValue);
              
              delay(10);
            
            



Finally, I proceeded to download Processing and used a code that allowed me to visualize the variation of sound frequencies in a graph. In all my codes, I used ChatGPT as a basis to generate them, then I modified them according to my interests and preferences.
import processing.serial.*;

Serial myPort;  // Create object from Serial class
static String val;    // Data received from the serial port
int sensorFreq = 0; // Frequency of the sound
int[] freqHistory; // Array to store frequency history
int historyLength = 500; // Length of history to display
int graphWidth = 800; // Width of the graph
int graphHeight = 400; // Height of the graph

void settings() {
  size(graphWidth, graphHeight);
}

void setup() {
  background(0);
  stroke(255);
  noFill();
  freqHistory = new int[historyLength];
  String portName = "COM11"; // Change the port name to match your setup
  myPort = new Serial(this, portName, 9600);
}

void draw() {
  if (myPort.available() > 0) {  // If data is available from the serial port
    val = myPort.readStringUntil('\n'); 
    try {
      if (val != null) { // Check if val is not null before using it
        sensorFreq = Integer.valueOf(val.trim());
        updateHistory(sensorFreq);
        drawGraph();
      }
    } catch(Exception e) {
      println("Error reading serial data: " + e);
    }
  }  
}

void updateHistory(int newFreq) {
  // Shift the frequency history array to the left
  for (int i = 0; i < historyLength - 1; i++) {
    freqHistory[i] = freqHistory[i + 1];
  }
  // Add the new frequency to the end of the history array
  freqHistory[historyLength - 1] = newFreq;
}

void drawGraph() {
  // Clear the background
  background(0);
  // Draw the graph lines
  for (int i = 0; i < historyLength - 1; i++) {
    float x1 = map(i, 0, historyLength - 1, 0, width);
    float x2 = map(i + 1, 0, historyLength - 1, 0, width);
    float y1 = map(freqHistory[i], 0, 1023, height, 0);
    float y2 = map(freqHistory[i + 1], 0, 1023, height, 0);
    line(x1, y1, x2, y2);
  }
}


To visualize the frequency variation graph, I used the song 'The Great Gig in the Sky' by Pink Floyd.


To make it a bit more interactive, I used a program to add two buttons: one to change the background color and the other to turn sound detection on and off. I used Pink Floyd's "Money" for the music.

            import processing.serial.*;
            
            Serial myPort;  // Create object from Serial class
            static String val;    // Data received from the serial port
            int sensorFreq = 0; // Frequency of the sound
            int[] freqHistory; // Array to store frequency history
            int historyLength = 500; // Length of history to display
            int graphWidth = 800; // Width of the graph
            int graphHeight = 400; // Height of the graph
            boolean soundDetectionOn = true; // Flag to control sound detection
            boolean isBlackBackground = true; // Flag to control background color
            Button soundButton, backgroundButton; // Buttons for sound detection and background color
            
            void settings() {
              size(graphWidth, graphHeight);
            }
            
            void setup() {
              background(0);
              stroke(255);
              noFill();
              freqHistory = new int[historyLength];
              String portName = "COM11"; // Change the port name to match your setup
              myPort = new Serial(this, portName, 9600);
              
              // Initialize buttons
              soundButton = new Button(20, 20, 100, 40, "Sound");
              backgroundButton = new Button(140, 20, 200, 40, "Background");
            }
            
            void draw() {
              if (soundDetectionOn && myPort.available() > 0) {  // If sound detection is on and data is available from the serial port
                val = myPort.readStringUntil('\n'); 
                try {
                  if (val != null) { // Check if val is not null before using it
                    sensorFreq = Integer.valueOf(val.trim());
                    updateHistory(sensorFreq);
                  }
                } catch(Exception e) {
                  println("Error reading serial data: " + e);
                }
              }  
              
              // Draw graph
              drawGraph();
              
              // Draw buttons
              drawButtons();
            }
            
            void updateHistory(int newFreq) {
              // Shift the frequency history array to the left
              for (int i = 0; i < historyLength - 1; i++) {
                freqHistory[i] = freqHistory[i + 1];
              }
              // Add the new frequency to the end of the history array
              freqHistory[historyLength - 1] = newFreq;
            }
            
            void drawGraph() {
              // Set background color
              if (isBlackBackground) {
                background(0);
              } else {
                background(0, 0, 255); // Blue background
              }
              
              // Draw the graph lines
              for (int i = 0; i < historyLength - 1; i++) {
                float x1 = map(i, 0, historyLength - 1, 0, width);
                float x2 = map(i + 1, 0, historyLength - 1, 0, width);
                float y1 = map(freqHistory[i], 0, 1023, height, 0);
                float y2 = map(freqHistory[i + 1], 0, 1023, height, 0);
                line(x1, y1, x2, y2);
              }
            }
            
            void drawButtons() {
              fill(255);
              rect(20, 20, 100, 40);
              rect(140, 20, 200, 40);
              fill(0);
              textSize(16);
              textAlign(CENTER, CENTER);
              text("Sound", 70, 40);
              text("Background", 240, 40);
            }
            
            void mousePressed() {
              // Check if the mouse is over the sound button
              if (mouseX >= soundButton.x && mouseX <= soundButton.x + soundButton.w &&
                  mouseY >= soundButton.y && mouseY <= soundButton.y + soundButton.h) {
                soundDetectionOn = !soundDetectionOn; // Toggle sound detection
              }
                                                 
              // Check if the mouse is over the background button
              if (mouseX >= backgroundButton.x && mouseX <= backgroundButton.x + backgroundButton.w &&
                  mouseY >= backgroundButton.y && mouseY <= backgroundButton.y + backgroundButton.h) {
                isBlackBackground = !isBlackBackground; // Toggle background color
              }
            }
            
            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;
              }
            }
            
            


Downloads