Hello Guys, newbie here.
I am trying to use PieterP's Control Surface library to make a custom Mackie compatible MIDI controller.
My end goal is to have 4 screens and 8 encoders, each screen displaying 2 DAW tracks info + meters but as of now while I am learning I am only concerned with getting 1 screen to correctly display 8 DAW channel meters.
I got it working, however, the meter decay is rather slow especially in Ableton Live, specifically the first couple of segments. With Logic Pro the decay right after the first peak is faster and more acceptable. Here is a video example with Logic on the right and Ableton on the left:
(ignore the white line across the screen)
Now I am wondering if
- this is Ableton's fault due to the way it's Mackie Remote Script template is written.
- if I butchered the code and made too many mistakes.
- if it's because I am using I2C displays instead of SPI.
I realize Mackie uses 150ms to decay each segment but on videos I see online of Mackie controllers they seem a lot snappier than the results I am getting with Ableton.
I tried using both Hold and Default for the VUDecay and it doesn't make any difference, also tried setting a custom value in milliseconds (in line 41 of the code) but that also makes no difference in Logic but in Ableton it makes the segments blink repeatedly before disappearing if the ms value is lower than 85ms.
Is there a way to make the decay faster? Any help would be deeply appreciated.
I am using a teensy 3.2 and an I2C SSD1306 OLED.
#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>
#include <Wire.h> // Include the I²C library for the display
// ----------------------------- MIDI Interface ----------------------------- //
USBMIDI_Interface midi;
// USBDebugMIDI_Interface midi(115200);
// ----------------------------- Display setup ------------------------------ //
constexpr uint8_t SCREEN_WIDTH = 128;
constexpr uint8_t SCREEN_HEIGHT = 64;
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 ssd1306Display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void initializeDisplay() {
// Initialize with the display with I²C address 0x3C
ssd1306Display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
Wire.setClock(3400000); // Set the I²C clock to 1.8 MHz for faster refresh / 1800000 was the default, changed to 3400000 not sure if this even works this fast.
ssd1306Display.setRotation(0); // Normal screen orientation.
}
// --------------------------- Display interface ---------------------------- //
class MySSD1306_DisplayInterface : public SSD1306_DisplayInterface {
public:
MySSD1306_DisplayInterface(Adafruit_SSD1306 &display)
: SSD1306_DisplayInterface(display) {}
void drawBackground() override { disp.drawLine(1, 8, 126, 8, WHITE); } //remove this later
} display = ssd1306Display;
// -------------------------- MIDI Input Elements --------------------------- //
//constexpr unsigned int decay = MCU::VUDecay::Hold;
// Try this option if your DAW doesn't decay the VU meters automatically
constexpr unsigned int decay = 85; // milliseconds to decay one block
// VU meters
MCU::VU VUMeters[8] = {
{1, decay}, // The VU meter for the first track, decay time as specified above
{2, decay}, {3, decay}, {4, decay}, {5, decay},
{6, decay}, {7, decay}, {8, decay},
};
// ---------------------------- Display Elements ---------------------------- //
MCU::VUDisplay vuDisp[8] = {
// Draw the first VU meter to the display, at position (2, 50),
// (12) pixels wide, blocks of (3) pixels high, a spacing between
// blocks of (1) pixel, and draw in white.
{display, VUMeters[0], {2 + 16 * 0, 50}, 12, 3, 1, WHITE},
{display, VUMeters[1], {2 + 16 * 1, 50}, 12, 3, 1, WHITE},
{display, VUMeters[2], {2 + 16 * 2, 50}, 12, 3, 1, WHITE},
{display, VUMeters[3], {2 + 16 * 3, 50}, 12, 3, 1, WHITE},
{display, VUMeters[4], {2 + 16 * 4, 50}, 12, 3, 1, WHITE},
{display, VUMeters[5], {2 + 16 * 5, 50}, 12, 3, 1, WHITE},
{display, VUMeters[6], {2 + 16 * 6, 50}, 12, 3, 1, WHITE},
{display, VUMeters[7], {2 + 16 * 7, 50}, 12, 3, 1, WHITE},
};
// --------------------------------- Setup ---------------------------------- //
void setup() {
initializeDisplay(); // Start the OLED display
Control_Surface.begin(); // Initialize Control Surface
}
// ---------------------------------- Loop ---------------------------------- //
void loop() {
Control_Surface.loop(); // Refresh all elements
}