Control-Surface
Control-Surface copied to clipboard
adding mute mcu 9 10 11...16
hi Pieter I need to have mutes for 16 tracks, I just saw that you implemented that only for track 1 to 8, I tried modifying mcu.hpp and keywords.txt but that seems to not be enough, is there a reason for you didn't it for the 16 tracks or just because nobody needed that?
I can have the 8 first track mute showing on the screen but when I switch bank I only see my tracks number and mute doesn't t show anything maybe I made a mistake in the code?
#include <Control_Surface.h>
#include <Encoder.h> // Include the Encoder library.
#include "Control_Surface.h"
#include <Display/DisplayInterfaces/DisplayInterfaceSSD1306.hpp>
//#include <name.c>
// celà doit etre écrit avant la library control surface
//USBDebugMIDI_Interface midi = 115200; // enlever les // en début de ligne pour entrer en mode debug usb et voir dans le panneau de control si vos controler envoient bien les infos
//auto &serial = Serial1;// Selectionne le port série à utiliser remplacer par serial pour une arduino
//SerialMIDI_Interface<decltype(serial)> midi = {serial, MIDI_BAUD};// démarre une interface midi serial au midi baud rate par defaut
USBMIDI_Interface usbmidi;// enlever les / en debut de ligne pour activer l'interface usb, penser à désactiver l'interface série(din)
HardwareSerialMIDI_Interface midiser = Serial1;
MIDI_PipeFactory<8> pipes;
// ----------------------------- Display setup ------------------------------ //
// ========================================================================== //
/*
Instantiate and initialize the SSD1306 OLED display
*/
constexpr uint8_t SCREEN_WIDTH = 128;
constexpr uint8_t SCREEN_HEIGHT = 64;
constexpr int8_t OLED_DC = 19; // Data/Command pin of the display
constexpr int8_t OLED_reset = -1; // Use the external RC circuit for reset
constexpr int8_t OLED_CS = 10; //wired on 13
constexpr uint32_t SPI_Frequency = SPI_MAX_SPEED;
// Instantiate the displays
Adafruit_SSD1306 ssd1306Display = {
SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, OLED_DC,
OLED_reset, OLED_CS, SPI_Frequency,
};
// --------------------------- Display interface ---------------------------- //
// ========================================================================== //
// Implement the display interface, specifically, the begin and drawBackground
// methods.
class MySSD1306_DisplayInterface : public SSD1306_DisplayInterface {
public:
MySSD1306_DisplayInterface(Adafruit_SSD1306 &display)
: SSD1306_DisplayInterface(display) {}
void begin() override {
// Initialize the Adafruit_SSD1306 display
if (!disp.begin())
FATAL_ERROR(F("SSD1306 allocation failed."), 0x1306);
// If you override the begin method, remember to call the super class method
SSD1306_DisplayInterface::begin();
}
void drawBackground() override { disp.drawLine(1, 8, 126, 8, WHITE); }
} display = ssd1306Display;
/*
CD74HC4067 mux1 = {
14, // numéro de broche de l'arduino
{9, 3, 4, 5} // numéro de pins de l'arduino sur lesquels sont branchés tous les multiplexeurs apellés mux S0, S1, S2
};
CD74HC4067 mux2 = {
15,
{9, 3, 4, 5},
};
CD74HC4067 mux3 = {
16,
{9, 3, 4, 5}
};
CD74HC4067 mux4 = {
17,
{9, 3, 4, 5}
};
CD74HC4067 mux5 = {
18,
{9, 3, 4, 5}
};
*/
Bank<2> bank = {8}; // active 2 bank avec 8 adresses par bank
IncrementDecrementSelector<2> selector = {
bank, // Bank to manage
{5, 6}, // push button pins (increment, decrement)
Wrap::Wrap, // Wrap around
};
// -------------------------- MIDI Input Elements --------------------------- //
// ========================================================================== //
/*
Define all elements that listen for MIDI messages.
*/
// Time display keeps track of the bar counter
MCU::TimeDisplay timedisplay = {};
// Play / Record
NoteValue play = {MCU::PLAY};
NoteValue record = {MCU::RECORD};
// Mute
Bankable::NoteValue<2> mute[] = {
{bank, MCU::MUTE_1},
{bank, MCU::MUTE_2},
{bank, MCU::MUTE_3},
{bank, MCU::MUTE_4},
{bank, MCU::MUTE_5},
{bank, MCU::MUTE_6},
{bank, MCU::MUTE_7},
{bank, MCU::MUTE_8},
};
// Solo
Bankable::NoteValue<2> solo[] = {
{bank, MCU::SOLO_1},
{bank, MCU::SOLO_2},
};
NoteValue rudeSolo = {MCU::RUDE_SOLO};
// Record arm / ready
Bankable::NoteValue<2> recrdy[] = {
{bank, MCU::REC_RDY_1},
{bank, MCU::REC_RDY_2},
};
// VU meters
MCU::Bankable::VU<2> vu[] = {
{bank, 1, MCU::VUDecay::Hold},
{bank, 2, MCU::VUDecay::Hold},
};
// ---------------------------- Display Elements ---------------------------- //
// ========================================================================== //
/*
Define all display elements that display the state of the input elements.
*/
// Time display
MCU::TimeDisplayDisplay timedisplaydisplay = {
// position (0, 0), font size (1)
display, timedisplay, {0, 0}, 1, WHITE,
};
// Play / Record
NoteBitmapDisplay playDisp = {
display, play, XBM::play_7, {16 + 64, 0}, WHITE,
};
NoteBitmapDisplay recordDisp = {
display, record, XBM::record_7, {26 + 64, 0}, WHITE,
};
// Mute
NoteBitmapDisplay muteDisp[] = {
{display, mute[0], XBM::mute_10B, {10, 13}, WHITE},
{display, mute[1], XBM::mute_10B, {42, 13}, WHITE},
{display, mute[2], XBM::mute_10B, {74, 13}, WHITE},
{display, mute[3], XBM::mute_10B, {106, 13}, WHITE},
{display, mute[4], XBM::mute_10B, {10, 38}, WHITE},
{display, mute[5], XBM::mute_10B, {42, 38}, WHITE},
{display, mute[6], XBM::mute_10B, {74, 38}, WHITE},
{display, mute[7], XBM::mute_10B, {106, 38}, WHITE},
};
/*
// Solo
NoteBitmapDisplay soloDisp[] = {
{display, solo[0], XBM::solo_10B, {14, 50}, WHITE},
{display, solo[1], XBM::solo_10B, {14 + 64, 50}, WHITE},
};
NoteBitmapDisplay rudeSoloDisp = {
display, rudeSolo, XBM::solo_7, {36 + 64, 0}, WHITE};
// Record arm / ready
NoteBitmapDisplay recrdyDisp[] = {
{display, recrdy[0], XBM::rec_rdy_10B, {14 + 14, 50}, WHITE},
{display, recrdy[1], XBM::rec_rdy_10B, {14 + 14 + 64, 50}, WHITE},
};
// VU meters
MCU::VUDisplay vuDisp[] = {
// position (32+11, 60), width (16), bar height (3) px, bar spacing (1) px
{display, vu[0], {32 + 11, 60}, 16, 3, 1, WHITE},
{display, vu[1], {32 + 11 + 64, 60}, 16, 3, 1, WHITE},
};
// VPot rings
/*MCU::VPotDisplay vpotDisp[] = {
// position (0, 10), outer radius (16) px, inner radius (13) px
{display, vpot[0], {0, 10}, 4, 2, WHITE},
{display, vpot[1], {32, 10}, 4, 2, WHITE},
};
*/
// Bank seting
BankDisplay bankDisp[] = {
// first track of the bank (1), position (0, 50), font size (2)
{display, bank, 1, {3, 10}, 1, WHITE},
{display, bank, 2, {35, 10}, 1, WHITE},
{display, bank, 3, {67, 10}, 1, WHITE},
{display, bank, 4, {99, 10}, 1, WHITE},
{display, bank, 5, {3, 35}, 1, WHITE},
{display, bank, 6, {35, 35}, 1, WHITE},
{display, bank, 7, {67, 35}, 1, WHITE},
{display, bank, 8, {99, 35}, 1, WHITE},
};
void setup() {
SPI.setMOSI(11);
// Correct relative mode for MCU rotary encoders
RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
Control_Surface.begin(); // Initialize Control Surface
Control_Surface.begin(); // initialise la library surface de control
usbmidi >> pipes >> midiser; // all incoming midi from USB is sent to serial
usbmidi << pipes << midiser; // all incoming midi from Serial is sent to USB
usbmidi >> pipes >> usbmidi; // all incoming midi from USB is looped back
midiser << pipes << midiser;
Control_Surface >> pipes >> usbmidi;
Control_Surface << pipes << usbmidi;
Control_Surface >> pipes >> midiser;
Control_Surface << pipes << midiser;
usbmidi.begin();
midiser.begin();
// The default SPI MOSI pin (11) is used for I²S, so we need to use the
// alternative MOSI pin (7)
SPI.setMOSI(11);
// Correct relative mode for MCU rotary encoders
RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
Control_Surface.begin(); // Initialize Control Surface
}
void loop() {
Control_Surface.loop(); // Update the Control Surface
usbmidi.update();
midiser.update();
}
The standard MCU protocol only supports 8 tracks. If you want more, you either have to use MCU XT (Extenders) by using MCU::MUTE_1 on the second virtual MIDI USB cable, or you have to use the MCU banks (not the Control Surface banks).
See https://github.com/tttapa/Control-Surface/issues/147#issuecomment-605671653.
There's nothing magical about the MCU constants, and changing them won't work, because then they won't match the MCU protocol anymore, so your DAW gets confused.
hi, i m back to this project! could you show me how to use cable please? I didn't t found example using this. i d like to send mute from tracks 9 to 16 to my teensy
The cable is just an additional argument in the MIDI address, see https://tttapa.github.io/Control-Surface-doc/Doxygen/d3/df7/midi-tutorial.html#midi_md-midi-addresses.
For instance:
NoteValue mute[] = {
{{MCU::MUTE_1, CABLE_2}}, // Mute track #9
// ...
};
You'll have to enable multiple MIDI cables in the Tools > USB type menu in the Arduino IDE, and then map this as an MCU Extender (XT) in your DAW.
I am on the Arduino IDE > Tools but can't see USB type menu there. The closest thing I see is Port. I guess that's not the right thing?
Is there a way within the same board to have the first 8 channels and then another 8 on CABLE_2 and an expander to act as the whole controller of 16 channels, MCU and MCU XT altogether?
Are you using a teensy? Not sure arduino are able to act as teensy on different USB port a t a time
That's right, the wrong board was selected. By selecting the Midi Cable it means MIDIx4 and MIDIx16 right?
Midix4 will show 4 différent controllers in any midi application on your computer and midix16 will show 16 controllers so midi x4 will be enough if you only need two cables
Hey Benwadub, have been testing what I have done with my previous Leonardo Board. The PBPotentiometer is not working in full, it does start working after the 25%/30% while on the Leonardo worked in full from 0%. Do you happen to have solve that?
Not sure to understand what you mean sorry, but I think that for pitch bend you have to send absolute value instead of relative for many daw, maybe that could help you finding your problem?
That’s exactly what I though. Not sure what the difference is between a teensy and a leonardo as with the Leonardo everything worked correctly except for not having CABLE_ which I need
You use exactly the same code and same schematic? I m not an expert but I think that if that is working on the Leonardo the exact same thing would work on the teensy.
Yes. That’s what I thought too unless with the LC the absolute value needs to be specified. I haven’t seen if that’s possible with PBPotentiomenters and MCU and couldn’t figure it out
Found the solution. The voltage on the pins of the Teensy LC is 3.3v rather than 5v and this shouldn't be applied. As the voltage is divided being the lowest value 5V it only starts working around the 3.3V (at 33% of the actual potentiometer)
I can only make My Teensy LC work with cables on Serial+MIDIx4 and can't find the solution to not having the serial on the USB type