Control-Surface
Control-Surface copied to clipboard
ssd1306 and teensy 4.0
hi, again me, I d like to add the ssd 1306 display I just received to my controller but can t find how to adapt the exemple code to my teensy 4.0, no problem to wire and and vcc but how to wire the scl sda res and dc pins of the screen and how to write it in the code, I can t find in your exemple code the screen pins, I just see dc pin reset and cs that I don t have on my screen
/**
/**
* An example demonstrating the use of DisplayElement%s to display information
* from the DAW on a small OLED display.
*
* @boards Teensy 3.x
*
* Connections
* -----------
*
* - 5: Push button (to ground)
* - 6: Push button (to ground)
* - 7: OLED Data/D1 (SPI MOSI)
* - 13: OLED Clock/D0 (SPI SCK)
* - 17: OLED Data/Command
* - 10: OLED Cable Select
*
* Add a capacitor between the reset pin of the display and ground, and a
* resistor from reset to 3.3V. The values are not critical, 0.1µF and 10kΩ
* work fine.
* You do need some way to reset the display, without it, it won't work.
* Alternatively, you could use an IO pin from the Teensy to reset the
* display, but this just "wastes" a pin.
*
* Behavior
* --------
*
* - The time (bars, beats, fraction), play and record status are shown at the
* top of the display.
* - For each of the 8 first tracks, a VU level meter with peak indicator and
* a V-Pot ring showing the pan are displayed, as well as the the mute, solo
* and record arm status.
* - Two tracks are displayed at once. By pressing the push buttons connected
* to pins 5 and 6, you can cycle through four banks to display all 8 tracks.
*
* Mapping
* -------
*
* Map "Control Surface" as a Mackie Control Universal unit in your DAW.
*
* @note There seem to be some differences in the way some applications
* handle VU meters: some expect the hardware to decay automatically,
* some don't.
* If you notice that the meters behave strangely, try both
* MCU::VUDecay::Hold and MCU::VUDecay::Default, or try a different
* decay time.
*
* Written by PieterP, 2019-11-12
* https://github.com/tttapa/Control-Surface
*/
#include <Encoder.h> // Include the Encoder library.
// This must be done before the Control Surface library.
#include <Control_Surface.h> // Include the Control Surface library
// Include the display interface you'd like to use
#include <Display/DisplayInterfaces/DisplayInterfaceSSD1306.hpp>
// ----------------------------- MIDI Interface ----------------------------- //
// ========================================================================== //
/*
Instantiate a MIDI interface to use for the Control Surface.
*/
USBMIDI_Interface midi;
// USBDebugMIDI_Interface midi(115200);
// ----------------------------- 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 = 17; // 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; // Chip Select pin of the display
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;
// ------------------------------- Bank setup ------------------------------- //
// ========================================================================== //
/*
Create a bank and a bank selector to change its setting.
*/
Bank<4> bank(2); // Create a new bank with two tracks per bank
// Create a new bank selector to control the bank using two push buttons
IncrementDecrementSelector<4> bankselector = {bank, {5, 6}, Wrap::Wrap};
// -------------------------- 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<4> mute[] = {
{bank, MCU::MUTE_1},
{bank, MCU::MUTE_2},
};
// Solo
Bankable::NoteValue<4> solo[] = {
{bank, MCU::SOLO_1},
{bank, MCU::SOLO_2},
};
NoteValue rudeSolo = {MCU::RUDE_SOLO};
// Record arm / ready
Bankable::NoteValue<4> recrdy[] = {
{bank, MCU::REC_RDY_1},
{bank, MCU::REC_RDY_2},
};
// VU meters
MCU::Bankable::VU<4> vu[] = {
{bank, 1, MCU::VUDecay::Hold},
{bank, 2, MCU::VUDecay::Hold},
};
// VPot rings
MCU::Bankable::VPotRing<4> vpot[] = {
{bank, 1},
{bank, 2},
};
// ---------------------------- 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, {14, 50}, WHITE},
{display, mute[1], XBM::mute_10B, {14 + 64, 50}, 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}, 16, 13, WHITE},
{display, vpot[1], {64, 10}, 16, 13, WHITE},
};
// Bank seting
BankDisplay bankDisp[] = {
// first track of the bank (1), position (0, 50), font size (2)
{display, bank, 1, {0, 50}, 2, WHITE},
{display, bank, 2, {64, 50}, 2, WHITE},
};
// --------------------------------- Setup ---------------------------------- //
// ========================================================================== //
void setup() {
// The default SPI MOSI pin (11) is used for I²S, so we need to use the
// alternative MOSI pin (7)
SPI.setMOSI(7);
// Correct relative mode for MCU rotary encoders
RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
Control_Surface.begin(); // Initialize Control Surface
}
// ---------------------------------- Loop ---------------------------------- //
// ========================================================================== //
void loop() {
Control_Surface.loop(); // Refresh all elements
}
These are questions about the Adafruit_SSD1306 library. Please see the examples that come with that library, as well as the pinout diagram of the Teensy board you're using.
I already tried this but as a total noob I don t understand everything don t know where to put data connection by exemple :-( and the reset
Did you get the examples of the Adafruit_SSD1306 library to work? If that doesn't work, you won't get this example to work either.
I m totally confusing between all these things!! 😅 I ll have to find clear documentation on spi protocol and find what correspond to what sck dc cs... all made a big head hake to my brain this evening 😅 I don’t know at all where my screens pins have to go on the teensy and don t understand for the moment how the code work for spi!
It seems that the labeling on my screen is not like the standard spi did you already saw that? I don t have pin labeled mosi or midi or dc,
The images you posted don't work. You have to wait for them to upload before posting.
Sorry!
I've never come across an SSD1306 display with 6 pins. The DC pin suggests that it's an SPI variant, but the lack of a CS pin and the SCL/SDA labels suggest I²C.
Since this is not strictly related to the Control Surface library, I'd suggest using the Arduino forum instead.
I asked on the teensy Facebook group, hope I ll have an answer! It s a display that can be used with i2c and spi, it could be better for me to find a nirmal spi display
Le 28 sept. 2020 à 20:48, Pieter P [email protected] a écrit :
I've never come across an SSD1306 display with 6 pins. The DC pin suggests that it's an SPI variant, but the lack of a CS pin and the SCL/SDA labels suggest I²C.
Since this is not strictly related to the Control Surface library, I'd suggest using the Arduino forum instead.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.
ok so I got it working! with the Adafruit library now! I ll be able to start with your library!
ok so my display work with these pins assignment in the Adafruit exemple
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for SSD1306 display connected using software SPI (default case):
#define OLED_MOSI 11//sda pin on my display
#define OLED_CLK 13//scl pin on my display
#define OLED_DC 18//dc pin on my display
#define OLED_CS 10//not wired
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
but can t make it work with your exemple: mcu OLED display I can t find where you use the clk pin in your code?
The code you posted uses software SPI, which is much slower than hardware SPI. Also try to avoid preprocessor macros, use constants instead.
Try this
constexpr uint8_t SCREEN_WIDTH = 128; // OLED display width, in pixels
constexpr uint8_t SCREEN_HEIGHT = 64; // OLED display height, in pixels
// Declaration for SSD1306 display connected using software SPI (default case):
constexpr uint8_t OLED_DC = 18; // DC pin on my display
constexpr uint8_t OLED_CS = 10; // not wired
constexpr uint8_t OLED_RESET = -1;
Adafruit_SSD1306 ssd1306Display = {
SCREEN_WIDTH, SCREEN_HEIGHT,
&SPI,
OLED_DC, OLED_RESET, OLED_CS,
};
I ll try tomorrow thanks! I think i didn’t show you the finished controler here it is! Thanks again for this I m glad to achieved this with your help!
Looks great! Thanks for sharing.
hi, that doesn't work, is it normal that you don t declare the clk pin that is on pin 13 ?
hi, I found that spa has to be in mode 3 for ssd1306 and teensy 4.0 #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> class Adafruit_SSD1309_SPI : public Adafruit_SSD1306 { public: Adafruit_SSD1309_SPI(uint8_t w, uint8_t h, SPIClass *spi, int8_t dc_pin, int8_t rst_pin, int8_t cs_pin, uint32_t bitrate=8000000UL) : Adafruit_SSD1306(w, h, spi, dc_pin, rst_pin, cs_pin, bitrate) { #ifdef SPI_HAS_TRANSACTION spiSettings = SPISettings(bitrate, MSBFIRST, SPI_MODE3); #endif
I add this lines at the top of the code like in the Adafruit exemple and that works fine now! thanks for the help!
I didn't know that, the SSD1306 SPI displays I have lying around all use the default SPI mode. Are you using an SSD1309 or SSD1306?
Have a look at this page it s where I found the solution! https://github.com/adafruit/Adafruit_SSD1306/issues/167
It s a 1306 here
hi i m relie not enough experienced to use theses screens I got, do you have link where you buy yours to be sure they will work with the library please?
I got mine on eBay long ago, I doubt the same listing will still be available. Just make sure it has 7 pins: Gnd, Vcc, D0, D1, Res, DC, CS
If you made your display work with the Adafruit library, why can't you get it to work with Control Surface? It uses the same library, you just have to wrap your display in the MySSD1306_DisplayInterface
class of the example.
// You should already have this from the Adafruit library, it is identical.
Adafruit_SSD1309_SPI ssd1306Display( /* options */);
// This is a wrapper to pass your display to the Control Surface library
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; // Pass the Adafruit display to the wrapper.
You'll have to post your code and explain exactly what the problem is, otherwise I can't help you.
Wouah thanks, I didn’t want to be insistant with my problem that is not really related to your library! I forgot to save the code when that worked and can t make it working again! I ll try again with that!
I got it but with my code the screen is scrolling, see the vidéo any idea of what can do it? post in the next comment
#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
};
CCPotentiometer fxparameter [] = {
{mux1.pin(0), {85, CHANNEL_16}},//delay time
{mux1.pin(1), {86, CHANNEL_16}},//pingpong
{mux1.pin(2), {87, CHANNEL_16}},//stereo width
{mux1.pin(3), {88, CHANNEL_16}},//feedback
{mux1.pin(4), {89, CHANNEL_16}},//hph
{mux1.pin(5), {90, CHANNEL_16}},//lpf
{mux1.pin(6), {91, CHANNEL_16}},//reverb send
{mux1.pin(7), {92, CHANNEL_16}},//mix volume
{mux1.pin(15), {24, CHANNEL_16}},//pre delay
{mux1.pin(14), {25, CHANNEL_16}},//reverb decay
{mux1.pin(13), {26, CHANNEL_16}},//reverb filter
{mux1.pin(12), {27, CHANNEL_16}},//shelving gain
{mux1.pin(11), {28, CHANNEL_16}},//hpf
{mux1.pin(10), {29, CHANNEL_16}},//lpf
{mux1.pin(9), {31, CHANNEL_16}},//mux volume
{mux1.pin(8), {119, CHANNEL_16}},//pattern volume
};
Bankable::CCPotentiometer ODPAN [] = {
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(0), {81, CHANNEL_1}},//overdrive
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(1), {81, CHANNEL_2}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(2), {81, CHANNEL_3}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(3), {81, CHANNEL_4}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(4), {81, CHANNEL_5}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(5), {81, CHANNEL_6}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(6), {81, CHANNEL_7}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(7), {81, CHANNEL_8}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(15), {10, CHANNEL_1}},//pan
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(14), {10, CHANNEL_2}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(13), {10, CHANNEL_3}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(12), {10, CHANNEL_4}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(11), {10, CHANNEL_5}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(10), {10, CHANNEL_6}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(9), {10, CHANNEL_7}},
{{bank, BankType::CHANGE_CHANNEL},mux2.pin(8), {10, CHANNEL_8}},
};
Bankable::CCPotentiometer fx [] = {
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(0), {83, CHANNEL_1}},//reverb send
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(1), {83, CHANNEL_2}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(2), {83, CHANNEL_3}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(3), {83, CHANNEL_4}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(4), {83, CHANNEL_5}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(5), {83, CHANNEL_6}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(6), {83, CHANNEL_7}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(7), {83, CHANNEL_8}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(15), {82, CHANNEL_1}},//delay send
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(14), {82, CHANNEL_2}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(13), {82, CHANNEL_3}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(12), {82, CHANNEL_4}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(11), {82, CHANNEL_5}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(10), {82, CHANNEL_6}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(9), {82, CHANNEL_7}},
{{bank, BankType::CHANGE_CHANNEL},mux4.pin(8), {82, CHANNEL_8}},
};
Bankable::CCPotentiometer filtre [] = {
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(0), {74, CHANNEL_1}},//filtre freq
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(1), {74, CHANNEL_2}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(2), {74, CHANNEL_3}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(3), {74, CHANNEL_4}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(4), {74, CHANNEL_5}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(5), {74, CHANNEL_6}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(6), {74, CHANNEL_7}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(7), {74, CHANNEL_8}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(15), {75, CHANNEL_1}},//filtre reso
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(14), {75, CHANNEL_2}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(13), {75, CHANNEL_3}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(12), {75, CHANNEL_4}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(11), {75, CHANNEL_5}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(10), {75, CHANNEL_6}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(9), {75, CHANNEL_7}},
{{bank, BankType::CHANGE_CHANNEL},mux3.pin(8), {75, CHANNEL_8}},
};
Bankable::CCPotentiometer fader [] = { //ici on déclare les faders avec comme vu plus haut le numéro de CC et le canal
{{bank, BankType::CHANGE_CHANNEL},mux5.pin(15), {7, CHANNEL_1}},//volume
{{bank, BankType::CHANGE_CHANNEL},mux5.pin(14), {7, CHANNEL_2}},
{{bank, BankType::CHANGE_CHANNEL},mux5.pin(13), {7, CHANNEL_3}},
{{bank, BankType::CHANGE_CHANNEL},mux5.pin(12), {7, CHANNEL_4}},
{{bank, BankType::CHANGE_CHANNEL},mux5.pin(11), {7, CHANNEL_5}},
{{bank, BankType::CHANGE_CHANNEL},mux5.pin(10), {7, CHANNEL_6}},
{{bank, BankType::CHANGE_CHANNEL},mux5.pin(9), {7, CHANNEL_7}},
{{bank, BankType::CHANGE_CHANNEL},mux5.pin(8), {7, CHANNEL_8}},
};
Bankable::CCButtonLatched<2> buttonmute[] = {
{{bank,BankType::CHANGE_CHANNEL}, mux5.pin(0), {94, CHANNEL_1}},//numéro de bank correspondant/indique que le changement de bank change le canal midi (+8 car on a 8 adresses par bank)/pin sur laquelle le controleur est branché/numéro de cc/numéro de canal midi
{{bank,BankType::CHANGE_CHANNEL},mux5.pin(1), {94, CHANNEL_2}},
{{bank,BankType::CHANGE_CHANNEL},mux5.pin(2), {94, CHANNEL_3}},
{{bank,BankType::CHANGE_CHANNEL},mux5.pin(3), {94, CHANNEL_4}},
{{bank,BankType::CHANGE_CHANNEL},mux5.pin(4), {94, CHANNEL_5}},
{{bank,BankType::CHANGE_CHANNEL},mux5.pin(5), {94, CHANNEL_6}},
{{bank,BankType::CHANGE_CHANNEL},mux5.pin(6), {94, CHANNEL_7}},
{{bank,BankType::CHANGE_CHANNEL},mux5.pin(7), {94, CHANNEL_8}},
};
CCButtonLatched button1 = {19, {120, CHANNEL_16}};
CCButtonLatched button2 = {20, {121, CHANNEL_16}};
/*CCButton button2 = {
// Push button on pin 20:
20,
// General Purpose Controller #1 on MIDI channel 1:
{121, CHANNEL_16},
};*/
// -------------------------- 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},
};
// 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},
};
// VPot rings
MCU::Bankable::VPotRing<2> vpot[] = {
{bank, 1},
{bank, 2},
};
// ---------------------------- 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, {14, 50}, WHITE},
{display, mute[1], XBM::mute_10B, {14 + 64, 50}, 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}, 16, 13, WHITE},
{display, vpot[1], {64, 10}, 16, 13, WHITE},
};
// Bank seting
BankDisplay bankDisp[] = {
// first track of the bank (1), position (0, 50), font size (2)
{display, bank, 1, {0, 50}, 2, WHITE},
{display, bank, 2, {64, 50}, 2, 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();
}```
Your code is way too complicated, start with a shorter example when debugging. Remove 90% of it, leaving a single MIDI interface, a single MIDI input element, and a single display element, without all the mux stuff or MIDI routing. Don't start integrating until your separate components work correctly.
constexpr int8_t OLED_CS = 10; //wired on 13
What do you mean "wired on 13"? Pin 13 is the SCK pin, you shouldn't be using it for other purposes. I can't see whether pin 13 is connected from your image. Pin 13 (SCK) should be connected to the clock pin of the display. Please see the Teensy pinout:
Why are you calling Control_Surface.begin()
multiple times? Please see https://tttapa.github.io/Control-Surface-doc/Doxygen/d5/da5/Dual-MIDI-Interface_8ino-example.html, you have to connect the pipes before initializing Control_Surface
.
Do you really want to loop back all MIDI data to the same interface? I just tried it, and it simply crashed my DAW, because the DAW also loops back some messages, creating an infinite loop.
If you are using Control_Surface
to handle the MIDI interfaces, you don't have to call usbmidi.begin()
or update()
yourself.
SPI.setMOSI(11);
is redundant, pin 11 is the default SPI MOSI pin.
I cannot see any videos, so I'm not sure what you mean by flickering. If the problem persists, try shorter cables or a lower SPI clock speed.
Also, what's the value of the capacitor on your reset line? It looks way too small. I'm using 0.1 µF. If it's too small, the display won't reset properly. Also try disconnecting the Teensy entirely to reset the display.
So my code is working fine without the display settings, I loop the midi to be able to use my contrôler over usb for a part of it and midi din for the other part and this work nicely! For the control surface begin it s a mistake I just done by copy/paste from your exemple sorry! I removed the spi pin didn’t t know it was not useful! By screen scrolling I mean my vpots and vu meter... are turning from left to right infinitely, and my capacitor is a 104z that is normaly 0,1 µF i m right?
I tried removing the pots and all I got on mux and this work fine! I think the problem is because my mux are not connected while I try the display screen! Could you just write me a line of code for this line
{{bank,BankType::CHANGE_CHANNEL}, mux5.pin(0), {94, CHANNEL_1}},
display the mute icon on the display to this location I had with the mcu
{display, mute[0], XBM::mute_10B, {10, 13}, WHITE},
Could you just write me a line of code for this line
What do you mean?