Visits

Sunday, December 15, 2024

Arduino Midi True Bypass Looper

I have a midi foot controller but only a few midi enabled pedals, so it was begging for more utility. 
Seeing as I have a several pedals that negatively impact the tone in their off state, I wanted a way to bypass them entirely.

A loop swichter would be easy enough to do and I have the avaailable parts already, but I wanted something a little more interesting. I'd seen a few commercially available units, but the price was prohibitive & none that I'd read up on were equipped to deal with stereo pathways.

I kept seeing relays pop up, so I decided to see if Arduino was capable of triggering them and in about 10 minutes I had ordered a midi shield and a pile of relays.

Anyway, long story short, people had done midi and done relays, but nobody (that I could find) had shared code that blended the two. I've pretty much forgotten what little C# that I knew and had to start from scratch.

Cheating with AI did me no good as even though the code Copilot spat out would compile(Chat GPT would not), it wouldn't do what it said it would. So I cobbled it together old fashioned way (reading the reference material (References below the Sketch)).

I'll be working on this over the summer and have yet to design the enclosure & schematic.
I have 8 relay pairs modules that are mounted on a 3d printed base of my own (poor) design.
This could support 8 mono or 4 stereo true bypass loops (depending on the wiring scheme).

Hopoefully there is enough memory left to run a display of some sort.


Basic Part List:

Arduino Leonardo (others will work).


Generic Midi Shield (this works fine, but get one with sockets on top if you can).


5v 2 Channel relay module (Can be configured like an SPST switch).

The relay modules can also be purchased in larger banks (wish I had known this before I got trigger happy with the order).
Here's the Sketch to control 8 Relays:

#include 

MIDI_CREATE_DEFAULT_INSTANCE();

// -----------------------------------------------------------------------------

// Configuration
#define LED 13                   // LED pin on Arduino Uno
const int relayPins[8] = {2, 3, 4, 5, 6, 7, 8, 9}; // Pins connected to the 8 relays
const int midiCCNumbers[8] = {1, 2, 3, 4, 5, 6, 7, 8}; // MIDI CC numbers to listen for

// Timer for LED control
unsigned long lastLedTime = 0;
const unsigned long ledDelay = 100; // LED on time in milliseconds

// -----------------------------------------------------------------------------

void BlinkLed(byte num)         // Basic blink function
{
    for (byte i = 0; i < num; i++)
    {
        digitalWrite(LED, HIGH);
        delay(50);
        digitalWrite(LED, LOW);
        delay(50);
    }
}

// -----------------------------------------------------------------------------

void setup()
{
    pinMode(LED, OUTPUT);

    // Initialize relay pins
    for (int i = 0; i < 8; i++) {
        pinMode(relayPins[i], OUTPUT);
        digitalWrite(relayPins[i], LOW); // Relays off initially
    }

    MIDI.begin(16);           // Launch MIDI, listening to channel 16
}

void loop()
{
    if (MIDI.read())                // Is there a MIDI message incoming?
    {
        switch (MIDI.getType())      // Get the type of the message we caught
        {
            case midi::ControlChange:       // If it is a Control Change,
                BlinkLed(MIDI.getData1());  // Blink the LED a number of times corresponding to the program number

                // Relay control
                for (int i = 0; i < 8; i++) {
                    if (MIDI.getData1() == midiCCNumbers[i]) {
                        if (MIDI.getData2() > 63) {
                            digitalWrite(relayPins[i], HIGH); // Turn relay on
                        } else {
                            digitalWrite(relayPins[i], LOW); // Turn relay off
                        }
                    }
                }
                lastLedTime = millis(); // Reset the LED timer
                break;

            // See the online reference for other message types
            default:
                break;
        }
    }

    // Control LED timing non-blocking approach
    if (millis() - lastLedTime > ledDelay) {
        digitalWrite(LED, LOW); // Turn off the LED after the delay
    }
}

Reference Material:
Arduino 4 Relays Shield Basics
Relay Module with Arduino
Arduino Relay
Midi Shield
Send and Receive MIDI With Arduino
Notes & Volts Youtube Tutorials