After 4 years i made button and leds working like novation launchpad now, but i need you help to transfer for me from leonardo to working esp32-s3 as Control-Surface library of:
#include <Adafruit_NeoPixel.h>
#include "MIDIUSB.h"
// LED Strip definition
const byte _NLED = 16; // Number of LEDs
const byte _DPIN = 10;
Adafruit_NeoPixel _LED = Adafruit_NeoPixel(_NLED, _DPIN, NEO_GRB + NEO_KHZ800);
// Color Palette (example values; modify as needed)
const byte _R[128] = {0, 65, 130, 255, 255, 255, 130, 65, 255, 255, 130, 65, 255, 255, 130, 65, 134, 81, 40, 20, 73, 0, 0, 0, 73, 0, 0, 0, 73, 0, 0, 0, 73, 0, 0, 0, 73, 0, 0, 0, 73, 0, 0, 0, 45, 0, 0, 0, 105, 45, 24, 12, 255, 255, 130, 65, 255, 255, 130, 65, 255, 150, 117, 32, 0, 0, 0, 0, 0, 16, 125, 28, 255, 186, 174, 97, 12, 0, 0, 0, 24, 89, 174, 40, 255, 134, 113, 0, 57, 85, 53, 89, 49, 105, 210, 255, 255, 182, 142, 130, 57, 0, 12, 20, 20, 101, 130, 219, 215, 255, 158, 101, 20, 219, 125, 154, 142, 61, 113, 223, 158, 53, 24, 4, 182, 61, 178, 73};
const byte _G[128] = {0, 65, 130, 255, 61, 0, 0, 0, 186, 61, 32, 16, 174, 255, 130, 65, 255, 255, 130, 65, 255, 255, 130, 65, 255, 255, 130, 65, 255, 255, 130, 65, 255, 255, 130, 65, 194, 166, 85, 45, 134, 85, 45, 24, 36, 0, 0, 0, 53, 0, 0, 0, 61, 0, 0, 0, 65, 0, 0, 0, 12, 53, 81, 53, 57, 73, 20, 0, 69, 0, 125, 28, 0, 255, 235, 255, 138, 255, 166, 40, 0, 0, 24, 16, 49, 223, 255, 255, 255, 255, 255, 138, 81, 81, 28, 0, 69, 166, 255, 89, 40, 73, 77, 20, 28, 57, 0, 65, 73, 190, 223, 178, 20, 210, 235, 150, 101, 61, 113, 255, 0, 0, 206, 65, 174, 49, 81, 20};
const byte _B[128] = {0, 65, 130, 255, 61, 0, 0, 0, 105, 0, 0, 0, 45, 0, 0, 0, 49, 0, 0, 0, 73, 0, 0, 0, 93, 24, 12, 4, 89, 85, 45, 24, 182, 150, 73, 36, 255, 255, 130, 65, 255, 255, 130, 65, 255, 255, 130, 65, 251, 255, 130, 65, 255, 255, 130, 65, 109, 81, 40, 20, 0, 0, 0, 4, 0, 24, 109, 255, 77, 202, 125, 28, 0, 45, 4, 8, 0, 93, 255, 255, 255, 255, 121, 0, 0, 4, 20, 0, 36, 109, 202, 255, 194, 231, 255, 89, 0, 0, 0, 4, 0, 12, 32, 40, 89, 24, 0, 40, 16, 36, 45, 12, 45, 105, 138, 255, 255, 61, 113, 255, 0, 0, 0, 0, 0, 0, 0, 0};
// Brightness control (0 to 100)
byte brightness = 10;
// Map MIDI notes to LED indices (4x4 grid)
const byte noteToLED[4][4] = {
{36, 37, 38, 39},
{40, 41, 42, 43},
{24, 25, 26, 27},
{60, 61, 62, 63}
};
// For controlling LED updates based on time
unsigned long lastUpdate = 0;
const unsigned long updateInterval = 5; // LED update every 5ms
bool update = false;
// Adjust color by brightness level (0-100)
byte applyBrightness(byte colorValue) {
return (colorValue * brightness) / 100;
}
// Send MIDI note on/off messages
void sendMidiMessage(byte pitch, byte velocity) {
midiEventPacket_t event;
event.header = (velocity > 0) ? 0x9 : 0x8; // Note On or Note Off
event.byte1 = 0x90; // Channel 1
event.byte2 = pitch; // Note number
event.byte3 = velocity; // Velocity
MidiUSB.sendMIDI(event);
MidiUSB.flush(); // Ensure the message is sent
}
// Convert MIDI note to LED index using the noteToLED array
void updateLEDs(byte pitch, byte velocity) {
byte ledIndex = 0;
bool noteFound = false;
for (byte row = 0; row < 4; row++) {
for (byte col = 0; col < 4; col++) {
if (noteToLED[row][col] == pitch) {
ledIndex = row * 4 + col; // Calculate the 1D index
noteFound = true;
break;
}
}
if (noteFound) break;
}
if (noteFound) {
if (velocity > 0) {
// Set the LED color based on the received velocity
_LED.setPixelColor(ledIndex,
applyBrightness(_R[velocity]),
applyBrightness(_G[velocity]),
applyBrightness(_B[velocity]));
} else {
// Turn off the LED
_LED.setPixelColor(ledIndex, _LED.Color(0, 0, 0)); // Set to off
}
update = true;
}
}
// Pins for the rows and columns of the button matrix
const int rowPins[4] = {2, 3, 4, 5};
const int colPins[4] = {6, 7, 8, 9};
// Matrix button setup
void setup() {
Serial.begin(115200); // Start serial communication
_LED.begin();
_LED.show();
// Initialize button pins
for (byte i = 0; i < 4; i++) {
pinMode(rowPins[i], OUTPUT);
digitalWrite(rowPins[i], HIGH);
pinMode(colPins[i], INPUT_PULLUP);
}
}
// Keep track of the previous button state
bool previousButtonState[4][4] = {false};
void loop() {
midiEventPacket_t rx;
// Read MIDI messages
do {
rx = MidiUSB.read();
if (rx.header == 0x9) updateLEDs(rx.byte2, rx.byte3); // Note on, update LEDs
if (rx.header == 0x8) updateLEDs(rx.byte2, 0); // Note off, turn off color
} while (rx.header != 0);
// Check matrix buttons
for (byte row = 0; row < 4; row++) {
digitalWrite(rowPins[row], LOW); // Activate the row
for (byte col = 0; col < 4; col++) {
bool currentButtonState = (digitalRead(colPins[col]) == LOW); // Button pressed
if (currentButtonState && !previousButtonState[row][col]) {
// Button pressed: Send Note On with max velocity
sendMidiMessage(noteToLED[row][col], 127);
previousButtonState[row][col] = true; // Update the previous state
} else if (!currentButtonState && previousButtonState[row][col]) {
// Button released: Send Note Off
sendMidiMessage(noteToLED[row][col], 0); // Note Off
previousButtonState[row][col] = false; // Update the previous state
// Turn off the LED
byte ledIndex = row * 4 + col; // Calculate the 1D index
_LED.setPixelColor(ledIndex, _LED.Color(0, 0, 0)); // Set to off
update = true;
}
}
digitalWrite(rowPins[row], HIGH); // Deactivate the row
}
// Update LEDs if needed
unsigned long currentTime = millis();
if (update && currentTime - lastUpdate >= updateInterval) {
_LED.show();
lastUpdate = currentTime; // Update time
update = false;
}
}
I'd recommend having a look at the MIDI tutorial. Your sendMidiMessage function and the MidiUSB.read() do-loop should be trivial to convert to Control Surface's MIDI interface API.
Hi,
After 4 years i made button and leds working like novation launchpad now, but i need you help to transfer for me from leonardo to working esp32-s3 as Control-Surface library of: