‹ anneVideotracking4OpenBCI WiFi Shield DIY ›

MIDI Pedals

2019-01-16 14:01 electronics

Here's how I built a USB foot pedal that sends out MIDI CC messages as well as note on/off messages when crossing some threshold.

To get a rugged pedal I bought a sewing machine foot pedal/speed control. For converting to MIDI and connecting to a computer I used a Digispark module. The two other parts needed are a 3.5mm socket and a 4K7 resistor.

pedal photo 1 pedal photo 0

The code for the Digispark is really simple and I programmed it from the Arduino IDE. THRESH_HI and THRESH_LO together with the state variable implement hysteresis, and lastVal is used to filter out any repeating values.

//with Digispark (Default - 16.5MHz)
//connect 4.7K resistor between tip and 5V, tip to P2 and sleeve to GND

//usb yellow or red     5V
//usb white             data-
//usb green             data+
//usb grey or black     GND

#define USB_CFG_DEVICE_NAME     'm','i','d','i','P','e','d','a','l'
#define USB_CFG_DEVICE_NAME_LEN 9
#include <DigiMIDI.h>

#define PINLED 1      //onboard led
#define PINSENSOR A1  //foot controller sensor (P2)
#define PINGND 0      //ground
#define CTRL 7        //midi controller (cc)
#define NOTE 99       //midi note
#define VELO 64       //midi velocity
#define CHAN 9        //midi channel
#define THRESH_HI 100 //0-127
#define THRESH_LO 50  //0-127

DigiMIDIDevice midi;
int lastVal = 0;
int state = 0;

void setup() {
  pinMode(PINLED, OUTPUT);
  pinMode(PINGND, OUTPUT);
  digitalWrite(PINGND, LOW);
  midi.sendNoteOff(NOTE, VELO, CHAN);
}

void loop() {
  midi.update();
  int val = analogRead(PINSENSOR);
  val = constrain(val, 9, 900);
  val = map(val, 9, 900, 127, 0);
  if (val != lastVal) {
    midi.sendControlChange(CTRL, val, CHAN);
    if (state == 0 && val > THRESH_HI) {
      midi.sendNoteOn(NOTE, VELO, CHAN);
      digitalWrite(PINLED, HIGH);
      state = 1;
    } else {
      if (state == 1 && val < THRESH_LO) {
        midi.sendNoteOff(NOTE, VELO, CHAN);
        digitalWrite(PINLED, LOW);
        state = 0;
      }
    }
    lastVal = val;
  }
  midi.delay(100);
}

Some SuperCollider test code...

MIDIClient.init;
MIDIIn.connectAll;
MIDIdef.cc(\pedalCont, {|...args| [\pedalCont, args].postln}, 7, 8);
MIDIdef.noteOn(\pedalOn, {|...args| [\pedalOn, args].postln}, 99);
MIDIdef.noteOff(\pedalOff, {|...args| [\pedalOff, args].postln}, 99);

MIDIdef.trace;

For another project, I also made a 3D printed variant. This one is not so rugged and only acts as an on/off switch. It's based on Adafruit's USB_Foot_Switch_Controller but modified to fit a Digispark.

pedal photo 2

Arduino code for this discrete pedal (only note on/off)...

//with Digispark (Default - 16.5MHz)
//modified Adafruit's USB_Foot_Switch_Controller

#define USB_CFG_DEVICE_NAME     'm','i','d','i','P','e','d','a','l'
#define USB_CFG_DEVICE_NAME_LEN 9
#include <DigiMIDI.h>

#define PINLED 1  //onboard led
#define PINSENSOR 2 //switch
#define NOTE 89  //midi note
#define VELO 64  //midi velocity
#define CHAN 9  //midi channel

DigiMIDIDevice midi;

int state = 0;

void setup() {
  pinMode(PINSENSOR, INPUT_PULLUP);
  pinMode(PINLED, OUTPUT);
  midi.sendNoteOff(NOTE, VELO, CHAN);
}

void loop() {
  midi.update();

  if (digitalRead(PINSENSOR) == 0) {
    if (state == 0) {
      digitalWrite(PINLED, HIGH);
      midi.sendNoteOn(NOTE, VELO, CHAN);
      state = 1;
    }
  } else {
    if (state == 1) {
      digitalWrite(PINLED, LOW);
      midi.sendNoteOff(NOTE, VELO, CHAN);
      state = 0;
    }
  }
  midi.delay(100);
}
‹ anneVideotracking4OpenBCI WiFi Shield DIY ›