MIDI input

This commit is contained in:
Dejvino 2026-02-21 21:12:30 +01:00
parent 94ade20143
commit 8ef4371711
4 changed files with 78 additions and 2 deletions

View File

@ -2,19 +2,83 @@
// MIDI UART Pins (GP0/GP1) // MIDI UART Pins (GP0/GP1)
#define PIN_MIDI_TX 0 #define PIN_MIDI_TX 0
#define PIN_MIDI_RX 1
MidiDriver midi; MidiDriver midi;
MidiDriver::MidiDriver() { MidiDriver::MidiDriver() : lastInputNote(-1), lastInputVelocity(0), _runningStatus(0), _byteIndex(0), _data1(0), _data2(0) {
} }
void MidiDriver::begin() { void MidiDriver::begin() {
mutex_init(&_mutex); mutex_init(&_mutex);
Serial1.setTX(PIN_MIDI_TX); Serial1.setTX(PIN_MIDI_TX);
Serial1.setRX(PIN_MIDI_RX);
Serial1.begin(31250); Serial1.begin(31250);
Serial.println(F("MIDI Serial initialized on GP0/GP1")); Serial.println(F("MIDI Serial initialized on GP0/GP1"));
} }
void MidiDriver::update() {
while (Serial1.available()) {
uint8_t b = Serial1.read();
Serial1.write(b); // Soft THRU: Merge input with output
// Realtime messages don't affect running status
if (b >= 0xF8) continue;
if (b >= 0x80) {
_runningStatus = b;
_byteIndex = 0;
} else if (_runningStatus) {
if (_byteIndex == 0) {
_data1 = b;
_byteIndex++;
// Handle 2-byte messages (Program Change 0xC0, Channel Pressure 0xD0)
uint8_t type = _runningStatus & 0xF0;
if (type == 0xC0 || type == 0xD0) {
_byteIndex = 0; // Message complete
}
} else if (_byteIndex == 1) {
_data2 = b;
_byteIndex = 0; // Message complete
uint8_t channel = (_runningStatus & 0x0F) + 1;
uint8_t type = _runningStatus & 0xF0;
if (type == 0x90) {
if (_data2 > 0) {
// Serial.print(F("Note On CH"));
// Serial.print(channel);
// Serial.print(F(": "));
// Serial.print(_data1);
// Serial.print(F(" Vel: "));
// Serial.println(_data2);
lastInputNote = _data1;
lastInputVelocity = _data2;
} else {
// Serial.print(F("Note Off CH"));
// Serial.print(channel);
// Serial.print(F(": "));
// Serial.println(_data1);
if (lastInputNote == _data1) {
lastInputNote = -1; // Note On vel 0 is Note Off
lastInputVelocity = 0;
}
}
} else if (type == 0x80) {
// Serial.print(F("Note Off CH"));
// Serial.print(channel);
// Serial.print(F(": "));
// Serial.println(_data1);
if (lastInputNote == _data1) {
lastInputNote = -1;
lastInputVelocity = 0;
}
}
}
}
}
}
void MidiDriver::lock() { void MidiDriver::lock() {
mutex_enter_blocking(&_mutex); mutex_enter_blocking(&_mutex);
} }

View File

@ -8,6 +8,10 @@ class MidiDriver {
public: public:
MidiDriver(); MidiDriver();
void begin(); void begin();
void update();
volatile int lastInputNote;
volatile int lastInputVelocity;
void sendNoteOn(uint8_t note, uint8_t velocity, uint8_t channel); void sendNoteOn(uint8_t note, uint8_t velocity, uint8_t channel);
void sendNoteOff(uint8_t note, uint8_t channel); void sendNoteOff(uint8_t note, uint8_t channel);
@ -19,6 +23,10 @@ public:
private: private:
mutex_t _mutex; mutex_t _mutex;
uint8_t _runningStatus;
uint8_t _byteIndex;
uint8_t _data1;
uint8_t _data2;
}; };
extern MidiDriver midi; extern MidiDriver midi;

View File

@ -129,6 +129,7 @@ static void handlePlayback() {
} }
void loopPlayback() { void loopPlayback() {
midi.update();
if (needsPanic) { if (needsPanic) {
for (int i=0; i<NUM_TRACKS; i++) { for (int i=0; i<NUM_TRACKS; i++) {
midi.panic(midiChannels[i]); midi.panic(midiChannels[i]);

View File

@ -50,13 +50,16 @@ Make sure to establish a **common ground** by connecting the ground from your ex
| GND | External 5V Supply - | External Power Ground | | GND | External 5V Supply - | External Power Ground |
| (Matrix GND) | GND (Pin 18) | Common Ground with Pico | | (Matrix GND) | GND (Pin 18) | Common Ground with Pico |
+----------------------+------------------------+-----------------------------+ +----------------------+------------------------+-----------------------------+
| MIDI DIN (Serial) | | | | MIDI OUT (Serial) | | |
| TX (MIDI OUT) | GP0 (Pin 1) | To DIN Pin 5 (via 220 ohm) | | TX (MIDI OUT) | GP0 (Pin 1) | To DIN Pin 5 (via 220 ohm) |
| MIDI IN (Serial) | | (optional!) |
| RX (MIDI IN) | GP1 (Pin 2) | To DIN Pin 3 (optoisolator) |
+----------------------+------------------------+-----------------------------+ +----------------------+------------------------+-----------------------------+
**MIDI Hardware Note**: **MIDI Hardware Note**:
* **MIDI OUT**: Connect **GP0** to DIN Pin 5 via a 220Ω resistor. Connect DIN Pin 4 to 3.3V (3V3) via a 220Ω resistor. Connect DIN Pin 2 to GND. * **MIDI OUT**: Connect **GP0** to DIN Pin 5 via a 220Ω resistor. Connect DIN Pin 4 to 3.3V (3V3) via a 220Ω resistor. Connect DIN Pin 2 to GND.
* **MIDI IN**: Optional! Uses a 6N137 optocoupler based on [this guide](https://www.kieranreck.co.uk/MIDI-6N137-vs-6N138-vs-6N139/). Connect the optocoupler output to **GP1**.
Once everything is wired up, you can upload the code and your tracker should be ready to go! Once everything is wired up, you can upload the code and your tracker should be ready to go!