Control-Surface icon indicating copy to clipboard operation
Control-Surface copied to clipboard

ssd1306 and teensy 4.0

Open benwadub opened this issue 3 years ago • 63 comments

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
}

benwadub avatar Sep 27 '20 20:09 benwadub

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.

tttapa avatar Sep 27 '20 20:09 tttapa

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

benwadub avatar Sep 27 '20 21:09 benwadub

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.

tttapa avatar Sep 27 '20 21:09 tttapa

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!

benwadub avatar Sep 27 '20 21:09 benwadub

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, Uploading 228E0333-93BF-4CE5-973D-48DA97416005.jpeg…

benwadub avatar Sep 28 '20 17:09 benwadub

Uploading 6EE67709-783D-4EF3-BD6A-7CB639878EE2.jpeg…

benwadub avatar Sep 28 '20 17:09 benwadub

The images you posted don't work. You have to wait for them to upload before posting.

tttapa avatar Sep 28 '20 18:09 tttapa

Sorry! 297C5D65-34EB-48B8-B974-FE4EDAAAC07A Uploading EB0DC1AA-C7F1-43D4-8961-5DF7DB7E97AA.jpeg…

benwadub avatar Sep 28 '20 18:09 benwadub

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.

tttapa avatar Sep 28 '20 18:09 tttapa

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.

benwadub avatar Sep 28 '20 19:09 benwadub

ok so I got it working! with the Adafruit library now! I ll be able to start with your library!

benwadub avatar Sep 28 '20 20:09 benwadub

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?

benwadub avatar Sep 28 '20 20:09 benwadub

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,
};

tttapa avatar Sep 28 '20 21:09 tttapa

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! 10CC0C35-1E54-4918-A54B-8649E165EBA1

benwadub avatar Sep 28 '20 21:09 benwadub

Looks great! Thanks for sharing.

tttapa avatar Sep 28 '20 21:09 tttapa

hi, that doesn't work, is it normal that you don t declare the clk pin that is on pin 13 ?

benwadub avatar Sep 29 '20 14:09 benwadub

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!

benwadub avatar Sep 29 '20 14:09 benwadub

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?

tttapa avatar Sep 30 '20 11:09 tttapa

Have a look at this page it s where I found the solution! https://github.com/adafruit/Adafruit_SSD1306/issues/167

benwadub avatar Sep 30 '20 11:09 benwadub

It s a 1306 here

benwadub avatar Sep 30 '20 11:09 benwadub

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?

benwadub avatar Oct 01 '20 20:10 benwadub

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.

tttapa avatar Oct 03 '20 10:10 tttapa

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!

benwadub avatar Oct 03 '20 13:10 benwadub

I got it but with my code the screen is scrolling, see the vidéo any idea of what can do it? image post in the next comment

benwadub avatar Oct 03 '20 15:10 benwadub

#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();
}```

benwadub avatar Oct 03 '20 15:10 benwadub

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: Teensy 4.0 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.

tttapa avatar Oct 03 '20 15:10 tttapa

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.

tttapa avatar Oct 03 '20 15:10 tttapa

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?

benwadub avatar Oct 03 '20 16:10 benwadub

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},

benwadub avatar Oct 03 '20 17:10 benwadub

Could you just write me a line of code for this line

What do you mean?

tttapa avatar Oct 04 '20 11:10 tttapa