BeatCanvas – a BLE MIDI Controller : 5 Steps (with Pictures)
CODE
#include
#include
#include
BLEMIDI_CREATE_INSTANCE(“ESP32_KOALA_CTRL”, MIDI)
// —- CONFIG —-
const int potPin = 34; // potentiometer pin (ADC1 channel)
// Button pins (adjust these as per your wiring)
const int buttonPins[8] = {13, 14, 15, 5, 22, 18, 19, 21};
// MIDI note numbers for each pad
int midiNotes[8] = {36, 38, 42, 46, 49, 51, 45, 47};
// (Kick, Snare, HiHat Closed, HiHat Open, Crash, Ride, Tom1, Tom2)
int lastPotValue = -1;
bool padState[8] = {0}; // track button state
// —- WS2812 LED CONFIG —-
#define LED_PIN 23 // Data pin for WS2812 LEDs
#define NUM_LEDS 64 // 8×8 matrix (or adjust if using a strip)
#define BRIGHTNESS 3 // 0–255 brightness
Adafruit_NeoPixel leds(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
// —- Rainbow animation variables —-
uint16_t rainbowOffset = 0;
// —- SETUP —-
void setup() {
Serial.begin(115200);
MIDI.begin();
// Configure button pins with internal pull-ups
for (int i = 0; i < 8; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
// Initialize LED matrix
leds.begin();
leds.setBrightness(BRIGHTNESS);
leds.show(); // Initialize all pixels to ‘off’
Serial.println(“ESP32 MIDI Controller with Rainbow Animation Ready!”);
}
// —- MAIN LOOP —-
void loop() {
handlePot();
handleButtons();
rainbowAnimation(10); // continuous rainbow effect (non-blocking)
delay(5);
}
// —- POTENTIOMETER HANDLER —-
void handlePot() {
int potValue = analogRead(potPin); // 0-4095
int ccValue = map(potValue, 0, 4095, 0, 127); // scale to 0-127
if (ccValue != lastPotValue) {
MIDI.sendControlChange(21, ccValue, 1); // CC 21 on channel 1
Serial.print(“Pot: “);
Serial.println(ccValue);
lastPotValue = ccValue;
}
}
// —- BUTTON HANDLER —-
void handleButtons() {
for (int i = 0; i < 8; i++) {
int val = digitalRead(buttonPins[i]);
if (val == LOW && !padState[i]) {
MIDI.sendNoteOn(midiNotes[i], 127, 1);
Serial.print(“Pad “);
Serial.print(i);
Serial.println(” Note On”);
padState[i] = true;
}
else if (val == HIGH && padState[i]) {
MIDI.sendNoteOff(midiNotes[i], 0, 1);
Serial.print(“Pad “);
Serial.print(i);
Serial.println(” Note Off”);
padState[i] = false;
}
}
}
// —- RAINBOW ANIMATION —-
void rainbowAnimation(uint8_t wait) {
for (int i = 0; i < leds.numPixels(); i++) {
int pixelHue = rainbowOffset + (i * 65536L / leds.numPixels());
leds.setPixelColor(i, leds.gamma32(leds.ColorHSV(pixelHue)));
}
leds.show();
rainbowOffset += 256; // Move rainbow forward
delay(wait);
}
Read more here: Source link
