Open jmym opened 4 years ago
There are certainly cleaner ways to do the integration, but if you just want to reuse the code you posted, you can do something like this:
#include <Control_Surface.h>
#include <Adafruit_MCP23017.h>
typedef void (*rotaryActionFunc)(bool clockwise, int id);
class RotaryEncOverMCP {
public:
RotaryEncOverMCP(Adafruit_MCP23017* mcp, byte pinA, byte pinB, rotaryActionFunc actionFunc = nullptr, int id = 0) {}
// ...
};
// --------------------------------------------------------------------------
USBMIDI_Interface midi;
Bank<3> bank(4);
Bankable::SingleAddress encAddresses[8] = {
{bank, 16},
{bank, 17},
{bank, 18},
{bank, 19},
{bank, 20},
{bank, 21},
{bank, 22},
{bank, 23},
};
void handler(bool clockwise, int id) {
MIDIAddress address = encAddresses[id].getActiveAddress();
RelativeCCSender::send(clockwise ? +1 : -1, address);
}
Adafruit_MCP23017 mcp;
RotaryEncOverMCP rotaryEncoders[] = {
{&mcp, 0, 1, handler, 0}, // Pins GPA0,GPA1, register with encAddresses id 0
{&mcp, 2, 3, handler, 1},
{&mcp, 4, 5, handler, 2},
// ...
};
IncrementDecrementSelector<3> selector = {bank, {2, 3}};
void setup() {
Control_Surface.begin();
// Initialize mcp here and attach interrupt
// see https://github.com/maxgerhardt/rotary-encoder-over-mcp23017/blob/master/examples/Interrupt/InterruptExample.cpp
}
void loop() {
Control_Surface.loop();
// Update mcp and rotaryEncoders here if interrupt occured
// see https://github.com/maxgerhardt/rotary-encoder-over-mcp23017/blob/master/examples/Interrupt/InterruptExample.cpp
}
Thank you, I'll try your code in my project.
Thanks for your help.
Best regards. JMY
El jue., 26 mar. 2020 22:28, tttapa notifications@github.com escribió:
There are certainly cleaner ways to do the integration, but if you just want to reuse the code you posted, you can do something like this:
include
include
typedef void (rotaryActionFunc)(bool clockwise, int id); class RotaryEncOverMCP { public: RotaryEncOverMCP(Adafruit_MCP23017 mcp, byte pinA, byte pinB, rotaryActionFunc actionFunc = nullptr, int id = 0) {}
// ...
}; // --------------------------------------------------------------------------
USBMIDI_Interface midi;
Bank<3> bank(4);
Bankable::SingleAddress encAddresses[8] = { {bank, 16}, {bank, 17}, {bank, 18}, {bank, 19}, {bank, 20}, {bank, 21}, {bank, 22}, {bank, 23}, }; void handler(bool clockwise, int id) { MIDIAddress address = encAddresses[id].getActiveAddress(); RelativeCCSender::send(clockwise ? +1 : -1, address); }
Adafruit_MCP23017 mcp;
RotaryEncOverMCP rotaryEncoders[] = { {&mcp, 0, 1, handler, 0}, // Pins GPA0,GPA1, register with encAddresses id 0 {&mcp, 2, 3, handler, 1}, {&mcp, 4, 5, handler, 2}, // ... };
IncrementDecrementSelector<3> selector = {bank, {2, 3}}; void setup() { Control_Surface.begin(); // Initialize mcp here and attach interrupt // see https://github.com/maxgerhardt/rotary-encoder-over-mcp23017/blob/master/examples/Interrupt/InterruptExample.cpp } void loop() { Control_Surface.loop(); // Update mcp and rotaryEncoders here if interrupt occured // see https://github.com/maxgerhardt/rotary-encoder-over-mcp23017/blob/master/examples/Interrupt/InterruptExample.cpp }
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/tttapa/Control-Surface/issues/147#issuecomment-604696450, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHZPWCYDRTET4TN7SR6E7I3RJPCJHANCNFSM4LUPB42A .
Hello again, my volume encoders works with pitchbends values, in channels from 1 to 8, How I could send a pitchbend value in a specific channel from banks?
MIDIAddress address = encAddresses[id].getActiveAddress();
PitchBendSender<RESOLUTION>::send(val, addr);//clockwise ? +1 : -1
What kind of pitch bend messages does your DAW expect? Relative or absolute?
Could you explain me the difference? I send the pitchbendsender and only work in the first fader from my daw. I use the Mackie control driver to send the data from Arduino to my daw.
El sáb., 28 mar. 2020 16:33, tttapa notifications@github.com escribió:
What kind of pitch bend messages does your DAW expect? Relative or absolute?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/tttapa/Control-Surface/issues/147#issuecomment-605463186, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHZPWC2TNFQI2RX2HJBG6YLRJYKELANCNFSM4LUPB42A .
In absolute mode, you send a value between 0 and 16,384, which represents a value between 0% and 100%. This is how potentiometers work.
For encoders, relative messages are often used. Instead of sending an absolute value, you send relative deltas, e.g. "+1" or "-1". This adds or subtracts one from the current value in the DAW, there's no way to set the absolute value of a control.
If you want to go from the (relative) input of an encoder to an absolute value, you'll have to keep track of the absolute position on the Arduino, so you'll have to add an array, one position variable for each encoder.
I send the pitchbendsender and only work in the first fader from my daw.
If you want to use pitch bend, you have to specify the channels:
Bankable::SingleAddress encAddresses[8] = {
{{bank, BankType::CHANGE_CHANNEL}, CHANNEL_1},
{{bank, BankType::CHANGE_CHANNEL}, CHANNEL_2},
{{bank, BankType::CHANGE_CHANNEL}, CHANNEL_3},
{{bank, BankType::CHANGE_CHANNEL}, CHANNEL_4},
{{bank, BankType::CHANGE_CHANNEL}, CHANNEL_5},
{{bank, BankType::CHANGE_CHANNEL}, CHANNEL_6},
{{bank, BankType::CHANGE_CHANNEL}, CHANNEL_7},
{{bank, BankType::CHANGE_CHANNEL}, CHANNEL_8},
};
Thank you again. The Daw works in absolute mode. I write my code to increment or decrement values and work correctly. But, when change the bank (in the DAW has got more than 8 tracks), the channels start in 9 and ends in 16 in my controller (don't work in studio one). I test with TouchDaw app in my tablet and emulates a Mackie for Studio One, and when I press the bank, send the tablet "noteOn A# 127-0" or "noteOn B 127-0" (two buttons bank) and the channels begins the next 8 channels in channel 1 to 8. I don't know, how it's work internally my DAW or the "mackie emulator" but, could you help me, please?
The MCU protocol has banking functionality built-in. This is different from the banking implemented by Control Surface.
You can change the MCU banks using the note numbers MCU::BANK_LEFT
and MCU::BANK_RIGHT
. IIRC, BANK_LEFT
/BANK_RIGHT
shift the bank by 8 tracks, and CHANNEL_LEFT
/CHANNEL_RIGHT
shift the bank by 1 track. These can be used with the NoteButton
class, for instance.
If you use MCU banks, you probably don't need Control Surface banks, the encoders always send on the same track.
You'll need some extra housekeeping in your sketch to determine what bank you're in, and to keep track of the encoder value for each track (which doesn't necessarily correspond to the physical encoder).
Another approach is to use the Control Surface BankType::CHANGE_CABLENB
, but this only works if your MIDI interface has multiple cables (such as Teensy boards). In that case, you can bank to Mackie Control Extenders.
I'm just leaving this here for reference, it won't work with your Arduino Mega.
Thank you for you quickly response. I'm trying your comment, but I don't know how to put all the ideas in the code. I write the code below, but i don't know how to insert MCU::BANK_LEFT:
NoteButton noteButton[2]={
14, // Push button on pin 14
{note(Ab, 1), CHANNEL_1}, // Note Ab on MIDI channel 1
15, // Push button on pin 15
{note(B, 1), CHANNEL_1}, // Note B on MIDI channel 1
};
And but after that, how could I write my code to work, with my encoders in your banks, please?
Best regards, JMY
You can do it like this:
NoteButton noteButton[]={
{
14, // Push button on pin 14
MCU::BANK_LEFT,
},
{
15, // Push button on pin 15
MCU::BANK_RIGHT
},
};
Note that there's one pair of braces around the entire array, and another pair of braces around each element.
And but after that, how could I write my code to work, with my encoders in your banks, please?
If you're using MCU banks, you don't need, Control Surface banks.
How Could I link my RotaryEncOverMCP to your MIDIsend or PitchBendSender? I'm trying all the options, without asking you. But I still, don't know how it's work MCU, and your code.
I use MCU banks, and in the code bellow, i write MCU::Bankable::VPotRing
array. But how could I update the rotary encoders with the vpotRing.
#include <Control_Surface.h> // Include the Control Surface library
#include <Wire.h>
#include <Adafruit_MCP23017.h> // https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library
#include <Rotary.h>
#include "RotaryEncOverMCP.h"
USBMIDI_Interface midi;
void RotaryEncoderChanged(bool clockwise, int id);
// setup the port expander
Adafruit_MCP23017 mcp0;
Adafruit_MCP23017 mcp1;
//Array of pointers of all MCPs if there is more than one
Adafruit_MCP23017* allMCPs[] = { &mcp0, &mcp1 };
constexpr int numMCPs = (int)(sizeof(allMCPs) / sizeof(*allMCPs));
#define addr1 7 // 7 = A1 high, A2 high, A3 high
#define addr2 0
Bank<4> bank(8);
NoteButton noteButton[]={
{
14, // Push button on pin 14
MCU::BANK_LEFT,
},
{
15, // Push button on pin 15
MCU::BANK_RIGHT
},
};
// VPot rings
MCU::Bankable::VPotRing<4> vpot[] = {
{bank,1,CHANNEL_1},
{bank,2,CHANNEL_2},
{bank,3,CHANNEL_3},
{bank,4,CHANNEL_4},
{bank,5,CHANNEL_5},
{bank,6,CHANNEL_6},
{bank,7,CHANNEL_7},
{bank,8,CHANNEL_8}
};
RotaryEncOverMCP rotaryEncoders[] = {
// outputA,B on GPA7,GPA6, register with callback and ID=1
RotaryEncOverMCP(&mcp0, 0, 1, &RotaryEncoderChanged, 1),
RotaryEncOverMCP(&mcp0, 3, 4, &RotaryEncoderChanged, 2),
RotaryEncOverMCP(&mcp0, 8, 9, &RotaryEncoderChanged, 3),
RotaryEncOverMCP(&mcp0, 11, 12, &RotaryEncoderChanged, 4),
RotaryEncOverMCP(&mcp1, 0, 1, &RotaryEncoderChanged, 5),
RotaryEncOverMCP(&mcp1, 3, 4, &RotaryEncoderChanged, 6),
RotaryEncOverMCP(&mcp1, 8, 9, &RotaryEncoderChanged, 7),
RotaryEncOverMCP(&mcp1, 11,12, &RotaryEncoderChanged, 8)
};
void RotaryEncoderChanged(bool clockwise, int id) {
if(clockwise){
RotarysValues[id-1] = RotarysValues[id-1]+1;//0.2;
}else{
RotarysValues[id-1] = RotarysValues[id-1]-1;//0.2;
}
digitalWrite(led, !digitalRead(led));
RotarysValues[id-1] = constrain(RotarysValues[id-1], 0, 127);
// MIDIAddress address = vpot[id-1].getActiveAddress(); //??????????????????????????
// PitchBendSender<RESOLUTION>::send(RotarysValues[id-1], address);//???????????????????
}
void setup(){
//light.blink(50,50);
RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
Control_Surface.begin(); // Initialize Control Surface
Wire.begin();
mcp0.begin(); // use default address 0
mcp1.begin(7);
//Initialize input encoders (pin mode, interrupt)
for(int i=0; i < numEncoders; i++) {
rotaryEncoders[i].init();
}
}
void loop() {
Control_Surface.loop(); // Update the Control Surface
pollAll();
}
Thank you for your patience, but I think we are all going to learn something from all this.
I don't have the time to write and test code right now, but it might be useful to read the MCU specification regarding banks.
https://images.thomann.de/pics/prod/151261_manual.pdf
The interesting part is "Fader Bank Zone" on page 64.
You need an array of encoder positions for all tracks in your DAW, let's say 24.
If you're on the first MCU bank, tracks 1-8 are active, so when the encoders are turned, you update elements 0-7 in the array. Then when you receive a "Bank Right" message, tracks 9-16 are active, so when the encoders are turned, you update elements 8-15 in the array. If you receive a "Channel Left" message, tracks 8-15 are active, so you update elements 7-14 in the array.
If you are using MCU Banks, you don't need Control Surface banks, so use MCU::VPotRing
, not MCU::Bankable::VPotRing
.
The addresses of the pitch bend messages don't change, they are tied to one of the encoder IDs. (They are independent of the MCU Bank or active tracks.)
PitchBendSender<10>::send(RotarysValues[id-1], Channel(id-1));
You'll also need to clamp the RotarysValues
to match the resolution of the PitchBendSender
. In this case, the resolution is 10 bits, so you need to make sure that the values are between 0 and 1023 = 210 - 1.
Thank you very much.
Best regards, JMY
El mar., 31 mar. 2020 12:02, tttapa notifications@github.com escribió:
I don't have the time to write and test code right now, but it might be useful to read the MCU specification regarding banks.
https://images.thomann.de/pics/prod/151261_manual.pdf
The interesting part is "Fader Bank Zone" on page 64.
You need an array of encoder positions for all tracks in your DAW, let's say 24. If you're on the first MCU bank, tracks 1-8 are active, so when the encoders are turned, you update elements 0-7 in the array. Then when you receive a "Bank Right" message, tracks 9-16 are active, so when the encoders are turned, you update elements 8-15 in the array. If you receive a "Channel Left" message, tracks 8-15 are active, so you update elements 7-14 in the array.
If you are using MCU Banks, you don't need Control Surface banks, so use MCU::VPotRing, not MCU::Bankable::VPotRing.
The addresses of the pitch bend messages don't change, they are tied to one of the encoder IDs. (They are independent of the MCU Bank or active tracks.)
PitchBendSender<10>::send(RotarysValues[id-1], Channel(id-1));
You'll also need to clamp the RotarysValues to match the resolution of the PitchBendSender. In this case, the resolution is 10 bits, so you need to make sure that the values are between 0 and 1023 = 210 - 1.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/tttapa/Control-Surface/issues/147#issuecomment-606525201, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHZPWCY4LB4JG6Z7LDIL5ATRKG5T7ANCNFSM4LUPB42A .
I'have the code below, for use multiples MCP23017, with rotary encoders and switches, and work correctly, but i'm interested about the integration with your system and my code. I use an Arduino Mega, 16 Encoders, a fews MCPs and i like to use with my Presonus Studio One DAW, I would like to use 8 volumen, and 8 pan with the encoders. And integrate with your banks, etc.