MIDI Signal to/from Serial Bridge

Hi there, thank you in advance for any help. I am very new to using these microcomputer, codes, relays etc. I am trying to build a synchronized light show.

Hardware:

  • ESP32 development board
  • 8 channel relay
  • Computer

Software:

  • Arduino IDE
  • Hairless MIDI
  • LoopMIDI
  • DAW software
    Steps taken so far:
  1. Set up the ESP32 board in the Arduino IDE and uploaded a sketch.
  2. Connected the MIDI controller components to the ESP32 board and wrote a code to read the inputs from the components and send MIDI signals out through the MIDI interface or cable.
  3. Set up the Hairless MIDI software and created a virtual MIDI port using LoopMIDI to receive and send MIDI signals to the ESP32 board.
  4. Configured the DAW software to recognize the virtual MIDI port and route the MIDI signals to the desired tracks

I created a MIDI arrangement that syncs to the beat of a song. Uploaded that at the song to DAW. Created virtual MIDI port and in the DAW and loaded that to the hairless MIDI bridge.
I think it's close, but I am not getting a signal from serial port in hairless midi bridge and also nothing on the output from the relay. I know I am probably missing some info to help solve the problem, please let me know any additional info needed.

#include "notes_bits.h"

const int relayPins[] = {4, 5, 6, 7, 8, 9, 10, 11}; // pins connected to the relay channels
const int numRelays = sizeof(relayPins) / sizeof(relayPins[0]); // calculate number of relays based on array size

int pitch, cmd, velocity;
boolean state;
byte relayData = 0;

void setup() {
  for (int i = 0; i < numRelays; i++) {
    pinMode(relayPins[i], OUTPUT);
    digitalWrite(relayPins[i], HIGH); // set relay to initial state (off)
  }
  Serial.begin(38400);
}

void loop() {
  if (Serial.available() > 2) {
    cmd = Serial.read();
    pitch = Serial.read();
    velocity = Serial.read();

    if (cmd == 144) { // note on
      state = true;
    } else if (cmd == 128) { // note off
      state = false;
    }

    // set the corresponding bit in relayData
    int relayIndex = getBit(pitch);
    if (relayIndex < numRelays) {
      bitWrite(relayData, relayIndex, state);
    }

    // turn on/off the relays according to the new data
    for (int i = 0; i < numRelays; i++) {
      digitalWrite(relayPins[i], bitRead(relayData, i));
    }
  }
}

notes.bits.h

#define C8 0b00000001
#define Cs8 0b00000010
#define D8 0b00000100
#define Ds8 0b00001000
#define E8 0b00010000
#define F8 0b00100000
#define Fs8 0b01000000
#define G8 0b10000000

byte getBit(int pitch) {
  switch(pitch) {
    case 96: return C8; // C8
    case 97: return Cs8; // C#8/Db8
    case 98: return D8; // D8
    case 99: return Ds8; // D#8/Eb8
    case 100: return E8; // E8
    case 101: return F8; // F8
    case 102: return Fs8; // F#8/Gb8
    case 103: return G8; // G8
    default: return 0; // default case for silence
  }
}


Hello jmiller1283

Use a logic analyzer to see what happens.

Insert Serial.println()´s at points of interrest.

HTH

Have a nice day and enjoy coding in C++.

This code cannot parse MIDI correctly, not all messages are three bytes long. You'll need a better parser that can at least discriminate between status and data bytes. See the MIDI standard, and compare to existing implementations, e.g. https://github.com/tttapa/Control-Surface/blob/main/src/MIDI_Parsers/SerialMIDI_Parser.cpp.

If you just want to turn on/off some GPIO pins based on MIDI note messages, see Control Surface: 1.Note-LED.ino or Control Surface: 2.Note-Range-LEDs.ino.

Thank you so much for getting back to me and for the suggestion.

Can I use the MIDI control surface to turn GPIO pins on and off without the use of a relay? Also, do I still use the MIDI file that is synced to the music to send the signals to the pins to turn on and off?

Sure, the library just uses digitalWrite to turn on/off the appropriate GPIO pin. What you do with that GPIO pin is up to you.

Yes, the GPIO pin is turned on/off when receiving MIDI note on/off messages for the selected notes.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.