tttapa / Control-Surface

Arduino library for creating MIDI controllers and other MIDI devices.
GNU General Public License v3.0
1.27k stars 140 forks source link

Need help to add the led with button #68

Closed 4dvn closed 4 years ago

4dvn commented 4 years ago

I want to add LEDs that light up when a button is pressed with 64 buttons matrices method, can you help me with wiring schematic of 8x8 button matrix adding led ? Here is my code: https://drive.google.com/file/d/1YqwD8hrNIjD1ZXY6R81CUqa7pewemvzq/view?usp=drivesdk Is that important to add the diodes with this code?

tttapa commented 4 years ago

The buttons are separate from the LEDs. First get the buttons working as shown in this example: https://tttapa.github.io/Control-Surface-doc/Doxygen/d4/d53/NoteButtonMatrix_8ino-example.html
You need diodes if you want to be able to correctly register multiple button presses at the same time.

You could edit the onButtonChanged callback function to turn on/off the LEDs: https://github.com/tttapa/Control-Surface/blob/ec1382b126bd420c2c0330af87245cea5a4979cd/src/MIDI_Outputs/Abstract/MIDIButtonMatrix.hpp#L38-L44

For wiring, it's probably easiest to use a MAX7219 to drive the 64 LEDs. This chip is supported by the library: https://tttapa.github.io/Control-Surface-doc/Doxygen/de/de9/classAH_1_1MAX7219.html#details

4dvn commented 4 years ago

Maybe i use the 64 rgb strip, the one thing make me stuck that how to control led similar to launchpad

tttapa commented 4 years ago

You can use the NoteRangeFastLED class. By default, it uses the Launchpad color mapping.

Examples:

4dvn commented 4 years ago

I need help to add the 2 buttons change the octave of 64 buttons matrices can you add the example of 64 button matrices with change bank?

tttapa commented 4 years ago

Something like this?

#include <Control_Surface.h>

USBMIDI_Interface midi;

// Transposer that transposes one octave (12 semitones) at a time,
// from -2 to +2 octaves.
Transposer<-2, +2> transposer(12);

// Push buttons on pins 7 and 8 to transpose up/down.
IncrementDecrementSelector<5> selector = {transposer, {7, 8}};

AddressMatrix<2, 3> notes = {{
  {0, 1, 2},
  {3, 4, 5},
}};

Bankable::NoteButtonMatrix<2, 3> buttons = {
  transposer, // bank/transposer
  {2, 3},     // row pins (outputs, driven low-Z low !)
  {4, 5, 6},  // column pins (inputs, hi-Z)
  notes,      // note numbers
  CHANNEL_1,  // MIDI channel / cable
};

void setup() {
  Control_Surface.begin();
}

void loop() {
  Control_Surface.loop();
}

Also here.

4dvn commented 4 years ago
Can i map the led color of rgb of 64 leds( or 128 WS2812 leds)with ableton script? 

 I can't add the note C#2 of this code:

RainbowColorMapper> midiled = {leds, note(C, 2)};

I made the similar to this video: 

https://store.djtechtools.com/products/midi-fighter-64-b-stock

The board i use is arduino and pro micro, maybe the ocatve need to move to arduino mega with WS2812
tttapa commented 4 years ago

The color is determined by the velocity of the note event and the color mapper you use. If you change the velocity in Ableton, you change the color.

What do you mean you can't add the note C#2? C#2 == Db2.

tttapa commented 4 years ago

Note that it's much more efficient to use a range of notes than an array with many notes:

NoteRangeFastLED

4dvn commented 4 years ago

Here is my code for 2 leds from 64 buttons:

test.txt

tttapa commented 4 years ago

I don't understand what you're trying to do. Please elaborate.

The CRGB array is an array of colors, not an array of notes.
You cannot create overlapping LED ranges (a range starting at C2 with a length of 64 semitones overlaps with a range starting at C#2 with length 64).

4dvn commented 4 years ago

I want to create the 64 WS2812 leds, when push the buttons with note from 36 to note 99 and the leds is bright follow from the note 36 to 99. So i can map the led with ableton drumrack color and the rainbow effect. Can you help to fix the code?

tttapa commented 4 years ago

You just specify the start note and the length for the NoteRange class. A single instance handles all notes in that range.

#include <FastLED.h>
// Must be before Control Surface to enable FastLED features of Control Surface
#include <Control_Surface.h>

// Define the array of leds.
Array<CRGB, 64> leds = {};

// The data pin with the strip connected.
constexpr uint8_t ledpin = 0;

USBMIDI_Interface midi;

// The note numbers corresponding to the buttons in the matrix
const AddressMatrix<8, 8> addresses = {{
  {36, 37, 38, /* ... */ },
  { /* ... */ },
  { /* ... */ 97, 98, 99},
  // (fill in yourself)  
}};

NoteButtonMatrix<8, 8> buttonmatrix = {
  {2, 3, 4, 5, 6, 7, 8, 9}, // row pins
  {10, 11, 12, 13, A0, A1, A2, A3},    // column pins
  addresses,    // address matrix
  CHANNEL_3,    // channel and cable number
};

// Create a functor that maps the velocity and the index of a note to a color.
struct RainbowColorMapper {
  CHSV operator()(uint8_t velocity, uint8_t index) const {
    return CHSV(255 * index / leds.length, 255, 2 * velocity);
  }
};

// Range from note 36 to 99 (= 36 + leds.length - 1)
NoteRangeFastLED<leds.length, RainbowColorMapper> midileds = {leds, 36};

void setup() {
  // See FastLED examples and documentation for more information.
  FastLED.addLeds<NEOPIXEL, ledpin>(leds.data, leds.length);
  FastLED.setCorrection(TypicalPixelString);
  midileds.setBrightness(128);
  Control_Surface.begin();
}

void loop() {
  Control_Surface.loop();
  FastLED.show();
}
4dvn commented 4 years ago

I use this map of midi fighter note is that true for the code and the usb edge? I made the wood case finished 😍 CCDE524A-AD4F-4C50-9E3B-BE2F92FA3A44 DD837BA8-5C0E-4DF7-A795-9AB87A2D65C9

const AddressMatrix<8, 8> addresses = {{
{64, 65, 66, 67, 96, 97, 98, 99},
{60, 61, 62, 63, 92, 93, 94, 95},
{56, 57, 58, 59, 88, 89, 90, 91},
{52, 53, 54, 55, 84, 85, 86, 87},
{48, 49, 50, 51, 80, 81, 82, 83},
{44, 45, 46, 47, 76, 77, 78, 79},
{40, 41, 42, 43, 72, 73, 74, 75},
{36, 37, 38, 39, 68, 69, 70, 71},
}};

NoteButtonMatrix<8, 8> buttonmatrix = { {2, 3, 4, 5, 6, 7, 8, 9}, // row pins {10, 11, 12, 13, A0, A1, A2, A3}, // column pins addresses, // address matrix CHANNEL_3, // channel and cable number };

tttapa commented 4 years ago

You can change the mapping for the button matrix relatively easily by changing the address matrix. However, the LEDs are a bit harder. You have to map the index in this function to the correct LED:

https://github.com/tttapa/Control-Surface/blob/55066c642f9169a3f2d07c729adcb4df85cb1219/src/MIDI_Inputs/LEDs/FastLED.hpp#L56-L60

By default, it assumes that the LEDs are in order. If the range begins at 36, note 36 corresponds to index 0, which corresponds to the first LED of the strip (ledcolors[0]). Note 37 maps to index 1, which corresponds to the second LED of the strip (ledcolors[1]), etc.
You could create a lookup table to map the index (i.e. note number - first note) to the number of the LED.

4dvn commented 4 years ago
Can you give me the fix code of FastLed.hpp, so i can add the next index, i'll test with this 8x8: 

https://www.amazon.co.uk/Matrix-WS2812-Integrated-Drivers-Arduino/dp/B07SPJTR3J

After that i plan to wire the 64 single ws2812 to the bottom of case.

tttapa commented 4 years ago

I added the necessary functionality to map the index in the FastLED strip.

For now, you can try the code I posted in https://github.com/tttapa/Control-Surface/issues/68#issuecomment-568773209, but you can use your custom address matrix if you want to.
The LEDs will be out of order, but I'll explain how to fix that once the first test is working.

4dvn commented 4 years ago

I got this old 8x8 ws2812b from my friend, it can use 49 leds because the 15 leds is die, i use the #68 yesterday code but when i sent the note from ableton is not bright, so i use the example of Note-FastLED is working:

https://www.youtube.com/playlist?list=PLM73Vxl0lUzYDwQaUVTjygPYLP4thouRw

tttapa commented 4 years ago

code but when i sent the note from ableton is not bright, so i use the example of Note-FastLED is working

I'm not sure I understand what you mean.

4dvn commented 4 years ago

When i touch the note C4 from ableton keyboard, the led is not working ( i tested with midiox ) So i use the example without matrix button, the led is light when press the note (C, 4) work with midiox but ableton not working 😔

tttapa commented 4 years ago

I'm afraid I can't help you with that. What channel are you using? How are you routing and mapping the MIDI in Ableton?

4dvn commented 4 years ago

I use the channel 3, the midi mapping i follow to this drumrack note: 8F92753F-8FD9-4F1F-9A08-E3E4F39DD4B8 I think this line have error: // Range from note 36 to 99 (= 36 + leds.length - 1) NoteRangeFastLED<leds.length, RainbowColorMapper> midileds = {leds, 36};

tttapa commented 4 years ago

If you're using channel 3, you have to use

NoteRangeFastLED<leds.length, RainbowColorMapper> midileds = {leds, {36, CHANNEL_3}};
4dvn commented 4 years ago

Can i change the velocity of button matrix? The note black C#4 on the video i pressed it running some effect but the another note is single color, i wanna add this Led effect after plugin the power cable https://youtu.be/-K63lNxeVx4 Maybe this is the effect i need: https://youtu.be/ug6-c_dUtxM And it turn off to normal when press the button with my own RainbowColorMapper

tttapa commented 4 years ago

You can pass the velocity as an optional parameter to the constructor or use the setter:
https://tttapa.github.io/Control-Surface-doc/Doxygen/d2/daf/classNoteButtonMatrix.html#ade241eb36c7f772da1cb9f6e5245cc66

You have full control over the LEDs if you want to, so you can create any effect you want.

4dvn commented 4 years ago

I adding the velocity 127 but this line is not working:

NoteRangeFastLED<leds.length, RainbowColorMapper> midileds = {leds, {36, CHANNEL_3}};

I press the note 36 from button matrix the led not bright, and i adding the basic

NoteRangeFastLED<leds.length, RainbowColorMapper> midileds = {leds, note (C, 2)};  Is working

I think the light just recive the note (C, 2) and the 36 not work

tttapa commented 4 years ago

The LEDs won't react to button presses unless your DAW loops back the note messages, there's no direct link between the button matrix and the LEDs.

Please try to understand the parameters you use, they are explained in the documentation.

NoteRangeFastLED<leds.length, RainbowColorMapper> midileds = {leds, {36, CHANNEL_3}};

This is note 36 on channel 3.

NoteRangeFastLED<leds.length, RainbowColorMapper> midileds = {leds, note (C, 2)};

This is note 36 on the default channel (CHANNEL_1).

https://tttapa.github.io/Control-Surface-doc/Doxygen/d8/d73/classNoteRangeFastLED.html#aa45475bc04abc41964f8bee00994783b

https://tttapa.github.io/Control-Surface-doc/Doxygen/d3/d10/classMIDICNChannelAddress.html#af01126768cafcda0d97f3297c65222c7

4dvn commented 4 years ago

I found the solution: https://github.com/mat1jaczyyy/teensy-underlights

Can you adding to the library for arduino and teensy 2.0 ?

tttapa commented 4 years ago

All functionality of the repo you linked to is supported by the Control Surface library, I don't understand what you mean.

4dvn commented 4 years ago

If is supported, how can i add with button matrix? :(

tttapa commented 4 years ago

I think you have a misconception somewhere. The button matrix and the LEDs are completely separate.

The button matrix sends messages to Ableton when you press a button.

The LED range listens for messages from Ableton, and turns on/off the LED accordingly.

Try to get the buttons and the LEDs to work separately first, the code has already been posted, you just have to select the correct address (note number and channel).

tttapa commented 4 years ago

It's very hard to help you like this. You have to keep in mind that I don't have Ableton, I don't have the same hardware, I have no idea what code you've tried or what you're doing in Ableton.

Try to ask specific questions, and carefully explain what you're doing.

4dvn commented 4 years ago

How can i use this code with matrix button to your library?

include "MIDIUSB.h"

const byte _NLED = 64; const byte _DPIN = 6;

include

Adafruit_NeoPixel _LED = Adafruit_NeoPixel(_NLED, _DPIN, NEO_GRB + NEO_KHZ800);

const byte _R[128] = {0, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 45, 93, 142, 223, 190, 28, 61, 93, 190, 125, 12, 28, 45, 158, 61, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 12, 28, 45, 158, 61, 28, 61, 93, 190, 125, 45, 93, 142, 223, 190, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 36, 73, 109, 146, 182, 219, 255}; const byte _G[128] = {0, 0, 0, 0, 125, 0, 12, 28, 45, 158, 61, 28, 61, 93, 190, 125, 45, 93, 142, 223, 190, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 45, 93, 142, 223, 190, 28, 61, 93, 190, 125, 12, 28, 45, 158, 61, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 36, 73, 109, 146, 182, 219, 255}; const byte _B[128] = {0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 12, 28, 45, 158, 61, 28, 61, 93, 190, 125, 45, 93, 142, 223, 190, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 45, 93, 142, 223, 190, 28, 61, 93, 190, 125, 12, 28, 45, 158, 61, 36, 73, 109, 146, 182, 219, 255}; const byte _PStart = 36; // First note in array

void setup() { _LED.begin(); _LED.show(); }

void loop() { midiEventPacket_t rx; do { rx = MidiUSB.read(); if(rx.header == 0x9) setLED(rx.byte2,rx.byte3); } while (rx.header == 0); // hold until a MIDI message is received }

void setLED(byte pitch, byte velocity) { if (pitch >= 28) { _LED.setPixelColor(pitch - _PStart, _R[velocity], _G[velocity], _B[velocity]); } else { _LED.show(); if(velocity>64){ wipe(); } } }

void noteOff(byte channel, byte pitch, byte velocity) { _LED.setPixelColor(pitch - _PStart, 0, 0, 0); _LED.show(); }

void wipe(){ for(int i = 0; i< _NLED; i++){ _LED.setPixelColor(i, 0, 0, 0); } }