Files
purrChestrion/purrChestrion-arduino/purrChestrion-arduino.ino
T

141 lines
3.6 KiB
Arduino
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// include libraries
#include <Adafruit_MCP23X17.h>
#include <MIDI.h>
// Instantiate libraries
Adafruit_MCP23X17 mcp1; // First MCP23017
Adafruit_MCP23X17 mcp2; // Second MCP23017
// Default hardware MIDI. SoftwareSerial is too slow...
MIDI_CREATE_DEFAULT_INSTANCE();
// A7 A6 A5 A4 A3 A2 A1 A0 <-- GPIO A
// MCP pins 28 27 26 25 24 23 22 21 20 19 18 17 16 15
// 8 = pin 1 ╔══════════════════════════════════════════╗
// 9 = pin 2 ╠ MCP23017 ║
// 10 = pin 3 ╚══════════════════════════════════════════╝
// 01 02 03 04 05 06 07 08 9 10 11 12 13 14
// B0 B1 B2 B3 B4 B5 B6 B7 <-- GPIO B
// Default MIDI channel
byte currentMidiChannel = 8; // Default MIDI channel
// Struct for 2 MCP chips.
struct MCPOutput {
uint8_t chip; // 0 = mcp1, 1 = mcp2
uint8_t pin; // 015
};
// LED shows MIDI activity
unsigned long ledOnTime = 0;
bool ledActive = false;
const unsigned long ledDuration = 50; // flash for 50ms
// Note to pin mapping. {chip, pin}
// One would be able to add up to 8 MCPs, but 2 is plenty for a Meowsic.
MCPOutput noteToMCP[32] = {
// MCP1 MIDI 57 to 72
{0, 0}, // 57 A3
{0, 1}, // 58 A#3
{0, 2}, // 59 B3
{0, 3}, // 60 C4
{0, 4}, // 61 C#4
{0, 5}, // 62 D4
{0, 6}, // 63 D#4
{0, 7}, // 64 E4
{0, 8}, // 65 F4
{0, 9}, // 66 F#4
{0, 10}, // 67 G4
{0, 11}, // 68 G#4
{0, 12}, // 69 A4
{0, 13}, // 70 A#4
{0, 14}, // 71 B4
{0, 15}, // 72 C5
// MCP2 MIDI 73 to 88
{1, 0}, // 73 C#5
{1, 1}, // 74 D5
{1, 2}, // 75 D#5
{1, 3}, // 76 E5
{1, 4}, // 77 F5
{1, 5}, // 78 F#5
{1, 6}, // 79 G5
{1, 7}, // 80 G#5
{1, 8}, // 81 A5
{1, 9}, // 82 A#5
{1, 10}, // 83 B5
{1, 11}, // 84 C6
{1, 12}, // 85 C#6
{1, 13}, // 86 D6
{1, 14}, // 87 D#6
{1, 15} // 88 E6
};
void setup() {
// LED debug
pinMode(LED_BUILTIN, OUTPUT);
// Initialize MCP23017s
mcp1.begin_I2C(0x20);
mcp2.begin_I2C(0x21);
// Initialize MIDI
MIDI.begin(MIDI_CHANNEL_OMNI);
MIDI.setHandleNoteOn(handleNoteOn);
MIDI.setHandleNoteOff(handleNoteOff);
for (int i = 0; i < 16; i++) {
mcp1.pinMode(i, OUTPUT);
mcp1.digitalWrite(i, LOW);
mcp2.pinMode(i, OUTPUT);
mcp2.digitalWrite(i, LOW);
}
}
void loop() {
MIDI.read();
// LED feedback
if (ledActive && millis() - ledOnTime >= ledDuration) {
digitalWrite(LED_BUILTIN, LOW);
ledActive = false;
}
// if (MIDI.read()) {
// digitalWrite(LED_BUILTIN, HIGH);
// delay(50);
// digitalWrite(LED_BUILTIN, LOW);
// }
}
void handleNoteOn(byte channel, byte pitch, byte velocity) {
if (channel == currentMidiChannel) {
if (pitch >= 57 && pitch <= 88) {
MCPOutput out = noteToMCP[pitch - 57];
if (out.chip == 0) {
mcp1.digitalWrite(out.pin, HIGH);
} else if (out.chip == 1) {
mcp2.digitalWrite(out.pin, HIGH);
}
}
}
// Flash LED on any valid Note On
digitalWrite(LED_BUILTIN, HIGH);
ledOnTime = millis();
ledActive = true;
}
void handleNoteOff(byte channel, byte pitch, byte velocity) {
if (channel == currentMidiChannel) {
if (pitch >= 57 && pitch <= 88) {
MCPOutput out = noteToMCP[pitch - 57];
if (out.chip == 0) {
mcp1.digitalWrite(out.pin, LOW);
} else if (out.chip == 1) {
mcp2.digitalWrite(out.pin, LOW);
}
}
}
}