Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I need help to transfer from leonardo to esp32-s3 #1078

Open
DRCRecoveryData opened this issue Sep 23, 2024 · 1 comment
Open

I need help to transfer from leonardo to esp32-s3 #1078

DRCRecoveryData opened this issue Sep 23, 2024 · 1 comment

Comments

@DRCRecoveryData
Copy link

DRCRecoveryData commented Sep 23, 2024

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:

#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;
  }
}
@tttapa
Copy link
Owner

tttapa commented Sep 23, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants