david alexander currie

Teachable Machine: Sound x Color

April 08, 2021

This project uses Teachable Machine to train an audio classifier to recognise the sound of my voice saying different colors. I trained the model to identify the following colors (white, red, yellow, blue, and green) with 20 voice samples per color. The model is run on ml5 and sends the result of the classification process (via Serial) to an Arduino, which prints the color on a ST7789 display.

p5 code:

const mySoundModelURL =
  "https://teachablemachine.withgoogle.com/models/aT-fLciJP/"
let mySoundModel
let resultDiv
let serial // variable to hold an instance of the serialport library
let portName = "/dev/tty.usbmodem14201" // fill in your serial port name here
let outByte = 0 // for outgoing data

function preload() {
  mySoundModel = ml5.soundClassifier(mySoundModelURL + "model.json")
}

function setup() {
  resultDiv = createElement("h1", "...")
  serial = new p5.SerialPort() // make a new instance of the serialport library
  serial.on("error", serialError) // callback for errors
  serial.open(portName) // open a serial port
  mySoundModel.classify(gotResults)
}

function serialError(err) {
  console.log("Something went wrong with the serial port. " + err)
}

function gotResults(err, results) {
  if (err) console.log(err)
  if (results) {
    console.log(results)
    if (results[0].confidence < 0.7) return
    resultDiv.html("Result is: " + results[0].label)
    if (results[0].label === "white") {
      outByte = 0
    } else if (results[0].label === "red") {
      outByte = 1
    } else if (results[0].label === "yellow") {
      outByte = 2
    } else if (results[0].label === "green") {
      outByte = 3
    } else if (results[0].label === "blue") {
      outByte = 4
    }
    // send it out the serial port:
    console.log("outByte: ", outByte)
    serial.write(outByte)
  }
}

Arduino Code:

int color = 0;

#include <SPI.h>

// ST7789 (Display) Libraries
#include <Adafruit_GFX.h>
#include <Arduino_ST7789.h>

#define TFT_DC    8
#define TFT_RST   9
#define TFT_MOSI  11
#define TFT_SCLK  13

Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST);

void setup() {

  tft.init(240, 240);
  tft.fillScreen(BLACK);
  Serial.print("Screen!");
  delay(1000);
}

void loop() {

  if (Serial.available() > 0) { // if there's serial data available
    color = Serial.read();   // read it
    delay(200);                // waits
  }

  if (color == 0) {
    tft.fillScreen(WHITE);
    Serial.print("0 = White");
  } else if (color == 1) {
    tft.fillScreen(RED);
    Serial.print("1 = Red");
  } else if (color == 2) {
    tft.fillScreen(YELLOW);
    Serial.print("2 = Yellow");
  } else if (color == 3) {
    tft.fillScreen(GREEN);
    Serial.print("3 = Green");
  } else if (color == 4) {
    tft.fillScreen(BLUE);
    Serial.print("4 = Blue");
  }
}

Written by David Currie, a current student at NYU ITP. Follow me on Twitter