Midiusb solenoid driver

I have been working on a 8 relay solenoid driver that responds to midiusb messages. I am a newbie when it comes to some of the ins and outs of the programming. I have created a bodged together piece of code that manages to write the pins corresponding to the relays LOW when specific note on messages are received but I would also like the corresponding note off messages to write the pins HIGH. Can anyone help me with adding this functionality? Thanks!

Here is my sketch:

#include "MIDIUSB.h"

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup()
{
  pinMode(2, OUTPUT); // set arduino pin to output mode
  pinMode(3, OUTPUT); // set arduino pin to output mode
  pinMode(4, OUTPUT); // set arduino pin to output mode
  pinMode(5, OUTPUT); // set arduino pin to output mode
  pinMode(6, OUTPUT); // set arduino pin to output mode
  pinMode(7, OUTPUT); // set arduino pin to output mode
  pinMode(8, OUTPUT); // set arduino pin to output mode
  pinMode(9, OUTPUT); // set arduino pin to output mode

  Serial.begin(9600);
}

void loop() {

  midiEventPacket_t rx = MidiUSB.read();  //listen for new MIDI messages

  switch (rx.header) {
    case 0x9:            //Note On message
      handleNoteOn(
        rx.byte1 & 0xF,  //channel
        rx.byte2,        //pitch
        rx.byte3         //velocity
      );
      break;
    default:
      break;
  }
}

void handleNoteOn(byte channel, byte pitch, byte velocity) {

  switch (pitch) {
    case 24:      //kick = C1/24
      digitalWrite(2, LOW);
      break;
    case 25:      //snare = C#1/25
      digitalWrite(3, LOW);
      break;
    case 26:      //shake = D1/26
      digitalWrite(4, LOW);
      break;
    case 27:      //cymbal = D#1/27
      digitalWrite(5, LOW);
      break;
    case 28:      //? = D#1/27
      digitalWrite(6, LOW);
      break;
    case 29:      //? = D#1/27
      digitalWrite(7, LOW);
      break;
    case 30:      //? = D#1/27
      digitalWrite(8, LOW);
      break;
    case 31:      //? = D#1/27
      digitalWrite(9, LOW);
      break;        
    default:
      break;
  }
}

Can't you just add a handleNoteOff() function?

You should also handle the "velocity=0" method of signaling Note Off:

    case 0x9:            //Note On message
      if (rx.byte3 != 0)
        handleNoteOn(
          rx.byte1 & 0xF,  //channel
          rx.byte2,        //pitch
          rx.byte3         //velocity
          );
      else
         handleNoteOff(
          rx.byte1 & 0xF,  //channel
          rx.byte2,        //pitch
          rx.byte3         //velocity
          );
      break;

Thanks so much for the reply! I know it is a lot to ask but would you mind showing me where those cases should fit in my code example? Thanks!

In switch (rx.header) {

Got it! Works like a charm, Thanks!

You really should shorten and tidy up that code!

Like this:

#include "MIDIUSB.h"

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

const byte numRelays = 8;
const byte relayPin[numRelays] = {2, 3, 4, 5, 6, 7, 8, 9 };

void setup()
{
  for (byte p=0; p<numRelays; p++)
    pinMode(relayPin[p], OUTPUT); // set arduino pin to output mode
  Serial.begin(9600);
}

void loop() {

  midiEventPacket_t rx = MidiUSB.read();  //listen for new MIDI messages

  switch (rx.header) {
    case 0x9:            //Note On message
      if (rx.byte3 != 0)
        handleNoteOn(
          rx.byte1 & 0xF,  //channel
          rx.byte2,        //pitch
          rx.byte3         //velocity
          );
      else
         handleNoteOff(
          rx.byte1 & 0xF,  //channel
          rx.byte2,        //pitch
          rx.byte3         //velocity
          );
      break;
  }
}

void handleNoteOn(byte channel, byte pitch, byte velocity) {
  if (pitch >= 24 && pitch <= 31)
    digitalWrite(relayPin[pitch - 24], LOW);
}

void handleNoteOff(byte channel, byte pitch, byte velocity) {
  if (pitch >= 24 && pitch <= 31)
    digitalWrite(relayPin[pitch - 24], HIGH);
}

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