Components and supplies
CD74HC4067 16-Kanal Analog Digital Multiplexer
hall sensor
seeeduino xiao
Foot Pistons
Tools and machines
Osciloscope
Multimeter
Apps and platforms
Arduino IDE
MidiView
Project description
Code
Controller Code
c
Tested with seeduino Xiao SAMD21.
1/* Organ Pedalboard Midi Controler: 2 * Reads Hall sensors signals ánd/or foot pistons switches connected to 3 Multiplexer and sends the corresponding midi note via midi usb. 3 * tested with seeduino Xiao SAMD21. 4 * 5 * Autor: Benjamin Ahlin Sanvee 6 * Use, share, and modify !!! 7 */ 8 9 10#include <Arduino.h> 11#include <Adafruit_TinyUSB.h> 12#include <MIDI.h> 13 14#define TOTAL_MUX_CHANNELS 48 // Number of total channels 15#define PER_MUX_CHANNELS 16 // Channels per mutiplexer 16 17#define MIDI_NOTE_OFF_STATE HIGH // --> open collector setting 18#define MIDI_NOTE_ON_STATE LOW 19#define MIDI_CHANNEL 1 20#define LOWEST_NOTE_NUMBER 36 // --> C2 Midi Note number of the lowest pedal on the organ 21#define MIDI_VELOCITY_ON 127 22#define MIDI_VELOCITY_OFF 0 23 24//mux control pins 25const int pin_s0 = 5; 26const int pin_s1 = 4; 27const int pin_s2 = 3; 28const int pin_s3 = 2; 29 30// comon sig pin of the 3 multiplexers 31const int pin_sig0 = 1; 32const int pin_sig1 = 10; 33const int pin_sig2 = 9; 34 35//enable pins 36const int pin_en = 6; 37 38//const int testpin = 7; // uncomment and connect oszilocope to test pin for performance testing 39 40//Declare Midi instance 41Adafruit_USBD_MIDI usb_midi; 42MIDI_CREATE_INSTANCE(Adafruit_USBD_MIDI, usb_midi, MIDI); 43 44int last_midi_state[TOTAL_MUX_CHANNELS] = { 0 }; 45const uint32_t DEBOUNCE_TIME_MILLIS = 50; 46uint32_t last_debounce_time[PER_MUX_CHANNELS] = { 0 }; // Debouce time for foot pistons 47 48//----------SETUP----------// 49 50void setup() { 51 // Pin initialisation: 52 pinMode(pin_s0, OUTPUT); 53 pinMode(pin_s1, OUTPUT); 54 pinMode(pin_s2, OUTPUT); 55 pinMode(pin_s3, OUTPUT); 56 57 // Sig pins 58 pinMode(pin_sig0, INPUT_PULLUP); 59 pinMode(pin_sig1, INPUT_PULLUP); 60 pinMode(pin_sig2, INPUT_PULLUP); 61 62 // Common en pin 63 pinMode(pin_en, OUTPUT); 64 digitalWrite(pin_en, LOW); 65 66 //uncomment and connect oszilocope to test pin for performance testing 67 //pinMode(testpin, OUTPUT); 68 69 70 // Initialize the MIDI interface so it's ready to be used 71 MIDI.begin(MIDI_CHANNEL_OMNI); 72 Serial.begin(9600); 73 Serial.print("Setup Done"); 74} 75 76//----------LOOP----------// 77 78void loop() { 79 80 for (int i = 0; i < 16; i++) { 81 82 //Dial multiplex channel 83 digitalWrite(pin_en, HIGH); // disable the multiplexer to avoid inter channel leaks due to non simultanous write operations 84 digitalWrite(pin_s0, (i & 0x01)); 85 digitalWrite(pin_s1, (i & 0x02) >> 1); 86 digitalWrite(pin_s2, (i & 0x04) >> 2); 87 digitalWrite(pin_s3, (i & 0x08) >> 3); 88 digitalWrite(pin_en, LOW); 89 90 //Get state off the 3 Sig Pins 91 delayMicroseconds(20); // Delay is nneded due to delay in volatge raise 92 93 //if (i == 0) { 94 // digitalWrite(testpin, HIGH); 95 //} 96 97 int current_midi_state1 = digitalRead(pin_sig0); 98 int current_midi_state2 = digitalRead(pin_sig1); 99 int current_midi_state3 = digitalRead(pin_sig2); 100 101 //digitalWrite(testpin, LOW); 102 103 if (current_midi_state1 != last_midi_state[i]) { 104 if (current_midi_state1 == MIDI_NOTE_OFF_STATE) { 105 MIDI.sendNoteOff(LOWEST_NOTE_NUMBER + i, MIDI_VELOCITY_OFF, MIDI_CHANNEL); 106 last_midi_state[i] = MIDI_NOTE_OFF_STATE; 107 } else { 108 MIDI.sendNoteOn(LOWEST_NOTE_NUMBER + i, MIDI_VELOCITY_ON, MIDI_CHANNEL); 109 last_midi_state[i] = MIDI_NOTE_ON_STATE; 110 } 111 } 112 113 if (current_midi_state2 != last_midi_state[i + 16]) { 114 if (current_midi_state2 == MIDI_NOTE_OFF_STATE) { 115 MIDI.sendNoteOff(LOWEST_NOTE_NUMBER + i + 16, MIDI_VELOCITY_OFF, MIDI_CHANNEL); 116 last_midi_state[i + 16] = MIDI_NOTE_OFF_STATE; 117 } else { 118 MIDI.sendNoteOn(LOWEST_NOTE_NUMBER + i + 16, MIDI_VELOCITY_ON, MIDI_CHANNEL); 119 last_midi_state[i + 16] = MIDI_NOTE_ON_STATE; 120 } 121 } 122 // The last 16 ports are used for footpistons and therefore we implement a primitive software debounce 123 if (current_midi_state3 != last_midi_state[i + 32]) { 124 if (abs(millis() - last_debounce_time[i]) > DEBOUNCE_TIME_MILLIS) { 125 last_debounce_time[i] = millis(); 126 if (current_midi_state3 == MIDI_NOTE_OFF_STATE) { 127 MIDI.sendNoteOff(LOWEST_NOTE_NUMBER + i + 32, MIDI_VELOCITY_OFF, MIDI_CHANNEL); 128 last_midi_state[i + 32] = MIDI_NOTE_OFF_STATE; 129 } else { 130 MIDI.sendNoteOn(LOWEST_NOTE_NUMBER + i + 32, MIDI_VELOCITY_ON, MIDI_CHANNEL); 131 last_midi_state[i + 32] = MIDI_NOTE_ON_STATE; 132 } 133 } 134 } 135 } /* The sampling rate of this loop is approx 1600Hz 136 * this is more than enough !!! 137 */ 138}
Comments
Only logged in users can leave comments