https://wnoadiarwb.us/machines/S39

S39 is a PCB for driving up to 39 solenoids or other high-current actuators with USB-MIDI control.

SAFETY WARNING
This device is capable of potentially fatal electrical current up to 3 Amps. According to OSHA, if you are electrocuted with 1 to 4.3 Amps, “rhythmic pumping action of the heart ceases. Muscular contraction and nerve damage occur; death is likely” (https://www.osha.gov/sites/default/files/2019-04/Basic_Electricity_Materials.pdf)
Build at your own risk! I am not responsible for any accidents, injuries, or damage to personal property caused by this device.

CURRENT RELEASE - 20240310 a.k.a “Quick N’ Dirty”
Download KiCad Project
Download Gerber + Drill Files

This version uses a Teensy 3.6 or 4.1 microcontroller. It is nicknamed “Quick N’ Dirty” because, while it works, it was made hastily with many imperfections. For example, the footprint for R1 and R2 are too small so you’re going to have to jam larger resistors in there. But this is the version I’ve been traveling, performing, and recording with for the past several months. So I felt it needed to be shared regardless.

Note: Each output is wired in parallel such that the device is technically capable of driving multiple actuators simultaneously. However, it is really only meant to comfortably drive one at a time due to the high load of solenoids. You might burn something up if you actuate multiple at once.

The following code is for controlling a 33-note MIDI glockenspiel. Velocity is mapped to the duration of each hit. Use or modify freely for your own application!

//adapted from https://learn.adafruit.com/midi-solenoid-drummer/software


#include "MIDIUSB.h"

//maps full range 0-127 midi notes to the 33 glockenspiel notes
int pitchToSolenoid[] = {7,8,9,10,11, //C-2 to E-2
0,1,2,3,4,5,6,7,8,9,10,11, //F-2 to E-1
0,1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19,20,21,22,23,24, //f-1 to E1
0,1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, //F1 to C4
8,9,10,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, //c#4 to C6
8,9,10,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, //C#6 to C8
20,21,22,23,24,25,26}; //C#8 to G8


//re-orient the pins due to the ergonomiic restrictions on the board
//delete or make a new version depending on your needs
int solenoidToPin[] = {10,11,12,14,15,16,17,18,19,20,21,22,23, //0-12
9,9,8,7,6,5,4,3,2,1,0, //13-22
24,25, //23,24
26,27,28,29,30,31,32,33}; //25-31


int hitDur = 30; //duration for each hit (ms)
int coolDown = 0; //cooldown time for each hit (ms)


void setup() {
  int i = 0;
  while (i<=32)
  {
    pinMode(i, OUTPUT);
    i++;
  }
}

void loop() {
  digitalWrite(13, HIGH);
  midiEventPacket_t rx = MidiUSB.read();
  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) {
  hitDur = map(velocity, 0, 127, 2, 30);
  hit(solenoidToPin[pitchToSolenoid[pitch]]);
}

void hit(int drum) {
  digitalWrite(drum, HIGH);  //turn solenoid all the way on
  delay(hitDur);                                      // wait
  digitalWrite(drum, LOW);  //turn solenoid all the way off
  delay(coolDown);
}

Last Updated: 20240909

---------------
© wnoadiarwb
← Back to Machines
← ← Back to Index