MIDI controller help

Hello, I'm trying to help my son with his end of year 6th grade project. His design vision was "color to sound".

The hardware implementation is

||TCS3200 Color Sensor > SparkFun MIDI Shield mounted on Arduino R4 WiFi > 5 pin DIN from the SparkFun MIDI Out > MPC Key 61 MIDI In||

The color sensor is wired per this schematic:

and the MIDI shield is mated directly to the R4 with headers.

On the software side, we've attempted to use a mishmash of sample code piece by piece to get things going. This library is referenced; This is the code:

// TCS230 or TCS3200 pins wiring to Arduino
#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define sensorOut 8
#include <MIDI.h>
MIDI_CREATE_INSTANCE(HardwareSerial, Serial, MIDI);


// Stores frequency read by the photodiodes
int redFrequency = 0;
int greenFrequency = 0;
int blueFrequency = 0;

// Stores the red. green and blue colors
int redColor = 0;
int greenColor = 0;
int blueColor = 0;

void setup() {
  // Setting the outputs
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);

  
  pinMode(LED_BUILTIN, OUTPUT);
  MIDI.begin(4);                      // Launch MIDI and listen to channel 4

  
  // Setting the sensorOut as an input
  pinMode(sensorOut, INPUT);
  
  // Setting frequency scaling to 100%
  digitalWrite(S0,HIGH);
  digitalWrite(S1,HIGH);
  
  // Begins serial communication
  Serial.begin(31250);
}

void loop() {
  // Setting RED (R) filtered photodiodes to be read
  digitalWrite(S2,LOW);
  digitalWrite(S3,LOW);
  
  // Reading the output frequency
  redFrequency = pulseIn(sensorOut, LOW);
  // Remaping the value of the RED (R) frequency from 0 to 255
  // You must replace with your own values. Here's an example: 
  // redColor = map(redFrequency, 70, 120, 255,0);
  redColor = map(redFrequency,1150,100,0,127);
  
  // Printing the RED (R) value
  Serial.print(" R = ");
  Serial.print(redColor);
  delay(100);
  
  // Setting GREEN (G) filtered photodiodes to be read
  digitalWrite(S2,HIGH);
  digitalWrite(S3,HIGH);
  
  // Reading the output frequency
  greenFrequency = pulseIn(sensorOut, LOW);
  // Remaping the value of the GREEN (G) frequency from 0 to 255
  // You must replace with your own values. Here's an example: 
  // greenColor = map(greenFrequency, 100, 199, 255, 0);
  greenColor = map(greenFrequency, 8000, 127, 0, 127);
  
  // Printing the GREEN (G) value  
  Serial.print(" G = ");
  Serial.print(greenColor);
  delay(100);
 
  // Setting BLUE (B) filtered photodiodes to be read
  digitalWrite(S2,LOW);
  digitalWrite(S3,HIGH);
  
  // Reading the output frequency
  blueFrequency = pulseIn(sensorOut, LOW);
  // Remaping the value of the BLUE (B) frequency from 0 to 255
  // You must replace with your own values. Here's an example: 
  // blueColor = map(blueFrequency, 38, 84, 255, 0);
  blueColor = map(blueFrequency, 1000, 74, 0, 127);
  
  // Printing the BLUE (B) value 
  Serial.print(" B = ");
  Serial.print(blueColor);
  delay(100);

  // Checks the current detected color and prints
  // a message in the serial monitor
  if(redColor > greenColor && redColor > blueColor){
      Serial.println(" - RED detected!");
  }
  if(greenColor > redColor && greenColor > blueColor){
    Serial.println(" - GREEN detected!");
  }
  if(blueColor > redColor && blueColor > greenColor){
    Serial.println(" - BLUE detected!");
  }
  {
      MIDI.sendNoteOn(42, 127, 1);    // Send a Note (pitch 42, velo 127 on channel 1)
      delay(1);		            // Wait for a second
      Serial.print("note played!");
      MIDI.sendNoteOff(42, 0, 1);     // Stop the note
  }
}


as it stands; at this point I'm just trying to get any message to come from the MIDI out on the shield to the MPC with no luck. I think I'm missing something with declaring/configuring the serial port, but I am short on time and losing faith. Any help would be great; my messages in the discord are instantly flagged as spam so I'm trying this, thank you in advance!

Start by reading the pinned post re 'How to get the most from the forum'. Remember we can't see what you see so you must show us. We dont chase links, post the Auto formatted code in a < CODE/ > block or use IDE->Edit->Copy for forum.
For the wiring diagram a photo of a hand drawn diagram is suffiucient as long as we can see every wire start to finish, labels, datasheets (can be linked) to uncommon parts.

Your code is 404. What is a MPC?

edited to embed the code. an MPC is a standalone digital audio workstation with its own internal OS and lots of hardware.

Closer. Editing an earlier post is frowned upon.
The circuit you posted is your instructions, we need to see where you really connected the wires to. Do NOT assume because you looked at it 17 times that it is correct.
That so called library is not a library. Did you not notice the error when trying to install it?

BUT the samples it contains is where you want to begin.

Next I used one of the samples in the not-a-library file that is for the shield. There are a few examples I picked MIDI-sniffer.ino. That is when I discovered I needed the following library.

Unfortunatly this is where we learned the following

I then used an UNO and it worked fine.
Screenshot 2026-05-17 at 13.18.04

I installed the library using the onboard library manager in the IDE.

I don't get any errors related to the library, neither when installing it nor during compiling/uploading

I will make a new sketch with the sniffer and see if that pops any lightbulbs in my head.

We are talking about two different things. I also had to get the MIDI library I am using from Github, it was not in the Library Manager.

At the end of your sketch you have the final few lines wrapped in braces. Perfectly valid, but is that what you intended, oir should there be an if preceding it?

I intended for it to just execute repeatedly with no if condition with the hopes that simply sending a straight up MIDI message would enable me to confirm connectivity with the receiving device; no luck. My 5 pin DIN has confirmed continuity with a multimeter on pins 2, 4, and 5, as well as visual confirmation pulling back the shield and inspecting the solder joints. I'm just not convinced that on the software side I am correctly sending a MIDI message to the MIDI out port on the MIDI shield.

Argh, confused myself, didn't notice the library changed names.

OK, agreed your sketch and the following library compiles.
In library manager you will notice 3 dots ... beside the lib name. Click and find an example that most closely functions the way you want. Let us know when you are successfull.

On a very superficial level, my initial thought was Basic_IO should suit my needs. I want to generate values from a color sensor and output them as MIDI messages. That was what led me to pull the last portion of code out of that sketch specifically and use it in my sketch. I've combed through each of the other sketches and can't glean that any of them would be useful for what I'm trying to achieve, but I am completely out of my depth here.

Tell me if I get this wrong.
When you say Basic_IO you mean the example sketch?
If so, what happens when you upload and run it? You will need to 'read a MIDI message', I do not know how to do that. However, you want to replace that with color input so I assume that small board attached to the UNO is a color sensor?
If all that is true, you will need to lok at the tutorials re how to do many things at once. I STRONGLY suggest you look at at least 3 variations to get a feel for what works for you. They also go by 'state machine', blinking multiple leds and so on. Plan on a few hours of study.
Now that you are educated, build in pieces and slowly. Before makig sound, just print that a sound was sent.
Your code will have 3 components (logically) a control function with setup and loop, and a color read function and a send midi function.
Good luck

Thanks for your time

The problem is that the real answer is to use Hairless to form a serial bridge to read and control MIDI messages. Hairless MIDI Serial bridge](GitHub - projectgus/hairless-midiserial: Lightweight cross-platform GUI-based MIDI/Serial bridge · GitHub) program stopped working with OS X Catalina. While Hairless still works on some PCs it will not work with a Mac.

So I devised a program that will work with a Mac, but it involves writing a program in Python. It has only very low latency (probably less than 5ms) so far.

Requirements / Installation

This script needs python-rtmidi, PySerial and Python 3.

  1. Install Python 3
  2. Install pip
  3. pip install python-rtmidi
  4. pip install pyserial
  5. Download serialmidi.py

Quickstart

MAC OS X example
$ python3 serialmidi.py --serial_name=/dev/cu.SLAB_USBtoUART --midi_in_name="IAC Bus 1" --midi_out_name="IAC Bus 2"

WINDOWS example
$ python.exe .\serialmidi.py --serial_name=COM4 --midi_in_name="loopMIDI Port IN 0" --midi_out_name="loopMIDI Port OUT 2"

setup

  1. Run serialmidi.py -h to see this help.
$ python3 serialmidi.py -h
usage: serialmidi.py [-h] --serial_name SERIAL_NAME [--baud BAUD]
                     [--midi_in_name MIDI_IN_NAME]
                     [--midi_out_name MIDI_OUT_NAME] [--debug]

Serial MIDI bridge

optional arguments:
  -h, --help            show this help message and exit
  --serial_name SERIAL_NAME
                        Serial port name. Required
  --baud BAUD           baud rate. Default is 115200
  --midi_in_name MIDI_IN_NAME
  --midi_out_name MIDI_OUT_NAME
  --debug               Print incoming / outgoing MIDI signals
  1. Figure out serial port name and baud rate. Baud rate default is 115200.
  2. Run serialmidi.py --serial_name=[serial_port] --baud=[baud]. Make sure it doesn't say "Serial port opening error.".
  3. The script prints recognized MIDI devices. Use one of listed name as argument of --midi_in_name and --midi_out_name. Here is an example on OS X.
INFO:root:IN : 'IAC Bus 1','IAC Bus 2'
INFO:root:OUT : 'IAC Bus 1','IAC Bus 2'

You may want to use MIDI loop bus such as IAC Bus for OS X, or loopMIDI for Windows. Also, you need to use different bus in order to avoid signal loop.

  1. If it is not working, try --debug option. It will dump all incoming / outgoing MIDI messages. Or create an issue on the GitHub page.

Tested environment

  • Tested with OS X Catalina with ESP32 board, and Windows10 with loopMIDI.

Other notes

  • It's made for my ESP32 based synthesizer, so I tested MIDI IN a lot, but MIDI OUT. MIDI OUT message processing might have some bugs. Please let me know if you find it.

Requirements / Installation

This script needs python-rtmidi, PySerial and Python 3.

  1. Install Python 3
  2. Install pip
  3. pip install python-rtmidi
  4. pip install pyserial
  5. Download serialmidi.py

Quickstart

MAC OS X example
$ python3 serialmidi.py --serial_name=/dev/cu.SLAB_USBtoUART --midi_in_name="IAC Bus 1" --midi_out_name="IAC Bus 2"

WINDOWS example
$ python.exe .\serialmidi.py --serial_name=COM4 --midi_in_name="loopMIDI Port IN 0" --midi_out_name="loopMIDI Port OUT 2"

setup

  1. Run serialmidi.py -h to see this help.
$ python3 serialmidi.py -h
usage: serialmidi.py [-h] --serial_name SERIAL_NAME [--baud BAUD]
                     [--midi_in_name MIDI_IN_NAME]
                     [--midi_out_name MIDI_OUT_NAME] [--debug]

Serial MIDI bridge

optional arguments:
  -h, --help            show this help message and exit
  --serial_name SERIAL_NAME
                        Serial port name. Required
  --baud BAUD           baud rate. Default is 115200
  --midi_in_name MIDI_IN_NAME
  --midi_out_name MIDI_OUT_NAME
  --debug               Print incoming / outgoing MIDI signals
  1. Figure out serial port name and baud rate. Baud rate default is 115200.
  2. Run serialmidi.py --serial_name=[serial_port] --baud=[baud]. Make sure it doesn't say "Serial port opening error.".
  3. The script prints recognized MIDI devices. Use one of listed name as argument of --midi_in_name and --midi_out_name. Here is an example on OS X.
INFO:root:IN : 'IAC Bus 1','IAC Bus 2'
INFO:root:OUT : 'IAC Bus 1','IAC Bus 2'

You may want to use MIDI loop bus such as IAC Bus for OS X, or loopMIDI for Windows. Also, you need to use different bus in order to avoid signal loop.

  1. If it is not working, try --debug option. It will dump all incoming / outgoing MIDI messages. Or create an issue on the GitHub page.

Tested environment

  • Tested with OS X Catalina with ESP32 board, and Windows10 with loopMIDI.

Other notes

  • It's made for my ESP32 based synthesiser, so I tested MIDI IN a lot, but MIDI OUT. MIDI OUT message processing might have some bugs. Please let me know if you find it.

serialmidi.py (5.0 KB)