Control-Surface
Control-Surface copied to clipboard
Incrément Button
bonjour, je tiens tout d'abord a te remercier pour cette fabuleuse librairie. Parmi plusieurs controle midi je souhaite utiliser un switch momentary pour incrementer un CC midi de 35 valeurs. Au debut value = 0 , puis lorsque jappuie une premiere fois value=35, une deuxieme fois value=70, une troisième fois value= 105, une quatrième fois retour à value= 0.
j'imagine que cela est possible mais je ne vois pas comment proceder, peut-être que tu aurais quelques piste ?
merci beaucoup hello, first of all I want to thank you for this fabulous bookstore. Among several midi controls I want to use a momentary switch to increment a midi CC of 35 values. At the beginning value = 0, then when I press for the first time value = 35, a second time value = 70, a third time value = 105, a fourth time return to value = 0.
I imagine that this is possible but I do not see how to proceed, maybe you would have some leads?
thank you so much
A possible approach would be to use something similar to the CCSelection class introduced here: https://github.com/tttapa/Control-Surface/issues/136#issuecomment-602223025
#include <Control_Surface.h>
template<setting_t N>
class CCValueSelection : public Selectable<N> {
public:
CCValueSelection(MIDIAddress address, uint8_t delta = 1, uint8_t base = 0)
: address{ address }, delta{ delta }, base{ base } {}
void select(setting_t setting) override {
setting = Selectable<N>::validateSetting(setting);
Control_Surface.sendCC(address, base + setting * delta);
}
private:
MIDIAddress address;
uint8_t delta, base;
};
CCValueSelection<4> ccsel{ MIDI_CC::Channel_Volume, 35, 0 };
IncrementSelector<4> incbtn{ ccsel, 2 }; // pin number
USBDebugMIDI_Interface midi;
void setup() {
Control_Surface.begin();
}
void loop() {
Control_Surface.loop();
}
Thank you for your quick reply,
the code is compiling, I will try it for real soon. I have several incremental buttons, 2 with 4 values and 10 with 3 values. For the 3 value buttons I tried to set up a "for" loop with arrays, but the code does not compile.
I have another question, I have several potentiometers which I want to put in 14 bits, I used "CC14Potentiometer" (issues # 202). To generate the 14bits at noon is sent on 2 control change 1-31, 2-32, 3-33, ...?
#include "Adafruit_TLC5947.h"
#include <Control_Surface.h>
#define NUM_TLC5974 4
#define data 11
#define clock 13
#define latch 10
#define oe -1
Adafruit_TLC5947 tlc = Adafruit_TLC5947(NUM_TLC5974, clock, data, latch);
char incSEL3[2] = {incbtn3, incbtn4};
char SEL3[2] = {selx, selxx};
constexpr size_t numbuttons = 13;
uint8_t tlcpins[numbuttons] = {5, 24, 25, 23,
3, 15, 22, 19,
6, 4, 3, 23, 0
};
CD74HC4067 mux1 = { A0, {20, 21, 22, 23},};
CD74HC4067 mux7 = { A15, {20, 21, 22, 23},};
CD74HC4067 mux8 = { A16, {20, 21, 22, 23},};
class CC14Potentiometer : public MIDIFilteredAnalog<ContinuousCCSender14<10>> {
public:
CC14Potentiometer(pin_t analogPin, MIDIAddress address)
: MIDIFilteredAnalog(analogPin, address, {}) {}
};
CC14Potentiometer potentiometer[] = {
{mux1.pin(0), {11, CHANNEL_1}},
{mux1.pin(4), {10, CHANNEL_1}},
{mux1.pin(5), {26, CHANNEL_1}},
{mux1.pin(7), {7, CHANNEL_1}},
{mux1.pin(8), {9, CHANNEL_1}},
{mux1.pin(9), {25, CHANNEL_1}},
{mux1.pin(13), {8, CHANNEL_1}},
{mux1.pin(14), {23, CHANNEL_1}},
{mux7.pin(1), {4, CHANNEL_1}},
{mux7.pin(13), {5, CHANNEL_1}},
{mux7.pin(15), {6, CHANNEL_1}},
{mux8.pin(0), {2, CHANNEL_1}},
{mux8.pin(3), {3, CHANNEL_1}},
{mux8.pin(6), {22, CHANNEL_1}},
{mux8.pin(8), {1, CHANNEL_1}},
{mux8.pin(12), {24, CHANNEL_1}},
{mux8.pin(15), {0, CHANNEL_1}},
};
template<setting_t N>
class CCValueSelection : public Selectable<N> {
public:
CCValueSelection(MIDIAddress address, uint8_t delta = 1, uint8_t base = 0)
: address{ address }, delta{ delta }, base{ base } {}
void select(setting_t setting) override {
setting = Selectable<N>::validateSetting(setting);
Control_Surface.sendCC(address, base + setting * delta);
}
private:
MIDIAddress address;
uint8_t delta, base;
};
for (int k = 0; k < 2 ; k++) {
CCValueSelection<3> SEL3{{82, CHANNEL_1}, (127 / 3), 0 };
IncrementSelector<3> incSEL3{ SEL3, mux1.pin(3) }; // pin number
}
CCValueSelection<4> cutoff{{112, CHANNEL_1}, (127 / 4), 0 };
IncrementSelector<4> incbtn1{ cutoff, mux1.pin(6) }; // pin number
CCValueSelection<4> bend{{90, CHANNEL_1}, (127 / 4), 0 };
IncrementSelector<4> incbtn2{ bend, mux7.pin(14) }; // pin number
CCButtonLatched button[] = {
{ mux1.pin(1), {111, CHANNEL_1}},
// { mux1.pin(3), {82, CHANNEL_1}},39&40,
// { mux1.pin(6), {112, CHANNEL_1}}, 34&35&36&37
{ mux1.pin(10), {84, CHANNEL_1}},
{ mux1.pin(12), {106, CHANNEL_1}},
{ mux1.pin(15), {86, CHANNEL_1}},
// { mux7.pin(0), {92, CHANNEL_1}}, 17&18,
{ mux7.pin(3), {99, CHANNEL_1}},
{ mux7.pin(5), {101, CHANNEL_1}},
{ mux7.pin(8), {98, CHANNEL_1}},
{ mux7.pin(11), {96, CHANNEL_1}},
// { mux7.pin(14), {90, CHANNEL_1}},20&21
{ mux8.pin(1), {100, CHANNEL_1}},
{ mux8.pin(4), {87, CHANNEL_1}},
{ mux8.pin(5), {83, CHANNEL_1}},
{ mux8.pin(9), {97, CHANNEL_1}},
{ mux8.pin(13), {84, CHANNEL_1}},
};
void setup() {
tlc.begin();
Control_Surface.begin();
}
void loop() {
Control_Surface.loop();
for (uint8_t i = 0; i < numbuttons; ++i) {
if (button[i].getButtonState() == Button::Falling) {
tlc.setPWM(tlcpins[i], 4095 * button[i].getState());
}
}
tlc.write();
}
For the 3 value buttons I tried to set up a "for" loop with arrays, but the code does not compile.
You can't use for-loops for declarations. Try this:
CCValueSelection<3> SEL3[] {
{ {82, CHANNEL_1}, 127 / 3, 0 },
{ {83, CHANNEL_1}, 127 / 3, 0 },
{ {84, CHANNEL_1}, 127 / 3, 0 },
};
IncrementSelector<3> incSEL3[] {
{ SEL3[0], mux1.pin(3) },
{ SEL3[1], mux1.pin(4) },
{ SEL3[2], mux1.pin(5) },
};
I have another question, I have several potentiometers which I want to put in 14 bits, I used "CC14Potentiometer" (issues # 202). To generate the 14bits at noon is sent on 2 control change 1-31, 2-32, 3-33, ...?
CC messages only carry 7 bits of data, so if you want 14 bits of precision you have to send 2 CC messages. IIRC, the MIDI standard specifies CC 0-31 for the most significant bits and CC 32-63 for the least significant bits, so you should see CC#1 and CC#33 used together, not CC#1 and CC#31.
at noon
Feel free to answer in French, you don't have to translate it.
Ca compile ! Merci encore ! Cependant comme le dit le fameux dicton " jamais deux sans trois", il me reste une ultime requête.
Le bouton incrémentateur doit allumer et éteindre en fonction de la valeurs MIDI des leds.
led 1= on si value<= 127.1/3
led 2 =on si value> 127.2/1 && <= 127.2/3
led 3 =on si value> 127.2/3
Mon idée initiale était de transférer dans une variable (CUTOFF) l' état du bouton sélecteur ( 0 , 1 , 2 ), puis utilisé cette variable pour sélectionner dans un tableau la sortie correspondante pour mon drivers led. tlc.setPWM(tlc3[CUTOFF], 4095);
J'ai tenté de recupéréer cet état dans plusieurs variable ( SEL3, incSEL3) avec la l'operateur A = CUTOFF, mais ça ne marche pas...
#include "Adafruit_TLC5947.h"
#include <Control_Surface.h>
#define NUM_TLC5974 4
#define data 11
#define clock 13
#define latch 10
#define oe -1
Adafruit_TLC5947 tlc = Adafruit_TLC5947(NUM_TLC5974, clock, data, latch);
byte CUTOFF ;
uint8_t tlc3[3] = {34, 35, 36};
CD74HC4067 mux1 = { A0, {20, 21, 22, 23},};
CD74HC4067 mux7 = { A15, {20, 21, 22, 23},};
CD74HC4067 mux8 = { A16, {20, 21, 22, 23},};
class CC14Potentiometer : public MIDIFilteredAnalog<ContinuousCCSender14<10>> {
public:
CC14Potentiometer(pin_t analogPin, MIDIAddress address)
: MIDIFilteredAnalog(analogPin, address, {}) {}
};
template<setting_t N>
class CCValueSelection : public Selectable<N> {
public:
CCValueSelection(MIDIAddress address, uint8_t delta = 1, uint8_t base = 0)
: address{ address }, delta{ delta }, base{ base } {}
void select(setting_t setting) override {
setting = Selectable<N>::validateSetting(setting);
Control_Surface.sendCC(address, base + setting * delta);
}
private:
MIDIAddress address;
uint8_t delta, base;
};
CCValueSelection<3> SEL3[] {
{ {82, CHANNEL_1}, 127 / 3, 0 },
{ {92, CHANNEL_1}, 127 / 3, 0 },
};
IncrementSelector<3> incSEL3[] {
{ SEL3[0], mux1.pin(3) },
{ SEL3[1], mux7.pin(0) },
};
void setup() {
tlc.begin();
Control_Surface.begin();
}
void loop() {
Control_Surface.loop();
tlc.setPWM(tlc3[CUTOFF], 4095);
tlc.write();
}
Re,
Bon, je me suis un peu creusé la tete, et finalement j'ai une piste ( je n'ai pas encore essayé).
#include "Adafruit_TLC5947.h"
#include <Control_Surface.h>
#define NUM_TLC5974 4
#define data 11
#define clock 13
#define latch 10
#define oe -1
Adafruit_TLC5947 tlc = Adafruit_TLC5947(NUM_TLC5974, clock, data, latch);
uint8_t tlc4[4] = {34, 35, 36, 37 };
CD74HC4067 mux1 = { A0, {20, 21, 22, 23},};
CD74HC4067 mux7 = { A15, {20, 21, 22, 23},};
CD74HC4067 mux8 = { A16, {20, 21, 22, 23},};
template<setting_t N>
class CCValueSelection : public Selectable<N> {
public:
CCValueSelection(MIDIAddress address, uint8_t delta = 1, uint8_t base = 0)
: address{ address }, delta{ delta }, base{ base } {}
void select(setting_t setting) override {
setting = Selectable<N>::validateSetting(setting);
Control_Surface.sendCC(address, base + setting * delta);
}
private:
MIDIAddress address;
uint8_t delta, base;
};
CCValueSelection<4> SEL4[] {
{ {112, CHANNEL_1}, 127 / 4, 0 },
{ {90, CHANNEL_1}, 127 / 4, 0 },
};
IncrementSelector<4> incSEL4[] {
{ SEL4[0], mux1.pin(6) },
{ SEL4[1], mux7.pin(14) },
};
void setup() {
tlc.begin();
Control_Surface.begin();
}
void loop() {
Control_Surface.loop();
tlc.write();
}
void myControlChange(byte channel, byte control, byte value) {
for (int i = 0; i < 4; i++) {
if ( control == 112 && value < 127 / 4 * i && value > 127 / 4 * i - 127 / 4) {
tlc.setPWM(tlc4[i], 4095);
}
}
}
It's not entirely clear what you're trying to do, but can't you update the LEDs here? You already have the setting:
void select(setting_t setting) override {
setting = Selectable<N>::validateSetting(setting);
// you can update the LEDs here, based on the value of `setting`, which will be 0, 1 or 2
Control_Surface.sendCC(address, base + setting * delta);
}
Thank you very much for your help Peter,
By dint of searching I ended up finding the solution. The goal was to light leds according to a midday value. Example: value of CC 82 <32 = led 1 on / led 2 & 3 & 4 = off value of CC 82 <64 & > 32 = led 2 on / led 1 & 3 & 4 = off value of CC 82 <96 & > 64 = led 3 on / led 1 & 2 & 4 = off value of CC 82 > 92 = led 4 on / led 1 & 2 & 3 = off `#include "Adafruit_TLC5947.h" #include <Control_Surface.h> USBMIDI_Interface midi;
#define NUM_TLC5974 2 #define data 11 #define clock 13 #define latch 10 #define oe 3
Adafruit_TLC5947 tlc = Adafruit_TLC5947(NUM_TLC5974, clock, data, latch);
byte adressCC = 112 ; byte cutoff;
byte tlc4[4] = {32 , 33, 34, 35 };
CD74HC4067 mux1 = { A0, // analog pin {20, 21, 22, 23}, // Address pins S0, S1, S2, S3 // 13, // Optionally, specify the enable pin };
CD74HC4067 mux7 = { A15, // analog pin {20, 21, 22, 23}, // Address pins S0, S1, S2, S3 // 13, // Optionally, specify the enable pin };
CD74HC4067 mux8 = { A16, // analog pin {20, 21, 22, 23}, // Address pins S0, S1, S2, S3 // 13, // Optionally, specify the enable pin };
template<setting_t N>
class CCValueSelection : public Selectable<N> { public:
CCValueSelection(MIDIAddress address, uint8_t delta = 32, uint8_t base = 0)
: address{ address }, delta{ delta }, base{ base } {}
void select(setting_t setting) override {
setting = Selectable<N>::validateSetting(setting);
Control_Surface.sendCC(address, base + setting * delta);
for (uint8_t i = 0; i < 3; ++i) {
if (address == adressCC) {
cutoff = setting ;
}
}
}
private: MIDIAddress address; uint8_t delta, base; };
CCValueSelection<4> SEL4[] {
{ {112, CHANNEL_1}, 32, 0 }, { {90, CHANNEL_1}, 32, 0 }, { {92, CHANNEL_1}, 32, 0 }, }; IncrementSelector<4> incSEL4[] {
{ SEL4[0], mux1.pin(6) }, { SEL4[1], mux7.pin(14) }, { SEL4[2], mux7.pin(0) }, };
void setup() {
tlc.begin(); if (oe >= 0) { pinMode(oe, OUTPUT); digitalWrite(oe, LOW); Control_Surface.begin(); } }
void loop() { Control_Surface.loop(); tlc.write(); delay(10);
for (uint8_t i = 0; i < 4; ++i) { if (i != cutoff ) { tlc.setPWM(tlc4[i], 0 ); } else tlc.setPWM(tlc4[i], 4092); } }`