Display libraries conflicts with Midi messages

Hello everyone

I am finding an issue related to displays conflicting with midi messages. I am not the best developer out here and this is my first project ever so my appologies for the long topic and please accept my stupidity.

To start with I have built an ecludean sequencer with an Arduino Nano and the idea was to change to Daisy so that i could do more with it. Converting from Arduino to Daisy was easy, just changed some pins initiliasation and everything worked flawlessly. Then it was time to start working on the new functionalities and my first priority is to sync other devices with my sequencer, in my case I want to send a midi clock and keep my sequencer as master.

In my first test I was using the Adafruit library with I2C communication on a 128x64px oled display and millis() to handle the timing for the sequencer. Internally the timing is ok, not perfect but I can understand that using millis will not be the best solution. I am also using the Midi library to handle anything related to midi.

When i first tested the sync on Ableton it showed a flxed clock of around 103bpm when on my Daisy display the clock was 120 so the clocks were not in sync. Thats when i started debugging and noticed that for some reason the 103bpm had nothing to do with the timing i coded to send the clock messages. I even removed code and kept only MIDI.sendRealTime(midi::Clock); without timing and noticed that ableton was still getting a clock of 103bpm.

After a lot of debugging i removed everything that was related to the display from the code and all of a sudden Ableton was perfectly in sync with the Daisy. Thats when i noticed that the display somehow is conflicting with the midi messages.

2nd test was using the U8g2lib for display instead of Adafruit but this time the clock was even worst, around 30bpm and litteraly frozen its like the midi start messages arent being sent.

To try and keep this as short as possible I tested other methods of timing for example using the hardware timers, micros() and timing libraries, none of them worked and as soon as I remove everything related to display then everything works good.

Then I came to a conclusion that the I2C commucation might be causing the conflict so I tested with SPI communication and this time I didnt get the static 103bpm but more or less pretty close to the internal sequencer, thats when I thought I finally managed to solve the problem but i was wrong again. Until I decided to update the tempo in realtime using the encoder thats when I noticed that the tempo on Ableton was jumping weirdly, it jumps from 115 to 125 when i turn the encoder its like it cant stay between that amount. Again when i remove the displays everything works perfectly.

Now i came to understand that currently only Serial1 can be used on the Daisy in my case im using USART1 TX to send midi messages and data.

I also tried using the Arduino nano to handle the display but to send data from daisy theres only one TX avalable.

I litteraly gave up now and I hope someone in this forum can help. It’s like I cant find a way to handle a display and send midi messages at the same time.

I’m attaching a piece of code stripped down from my sequencer which replicates the issue.

Thanks

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MIDI.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define BUTTON_PIN 4  

MIDI_CREATE_DEFAULT_INSTANCE();
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

bool isPlaying = false;  
bool lastButtonState = LOW;  

void setup() {
  MIDI.begin(MIDI_CHANNEL_OMNI);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    while (true)
      ;
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  pinMode(BUTTON_PIN, INPUT_PULLUP);  
}

void loop() {
  unsigned long currentMicros = micros();
  static unsigned long lastMicros = 0;
  unsigned long interval = 20833;  // Corresponds to 120 BPM

  // Read the button state
  bool currentButtonState = digitalRead(BUTTON_PIN);

  // Check for button press
  if (currentButtonState == LOW && lastButtonState == HIGH) {
    isPlaying = !isPlaying;  // Toggle play state

    if (isPlaying) {
      MIDI.sendRealTime(midi::Start);  // Send Start message
    } else {
      MIDI.sendRealTime(midi::Stop);  // Send Stop message
    }
  }
  lastButtonState = currentButtonState;  // Update the last button state

  // Send MIDI clock messages if the button has been pressed
  if (isPlaying && (currentMicros - lastMicros >= interval)) {
    MIDI.sendRealTime(midi::Clock);  // Send MIDI Clock message
    lastMicros = currentMicros;
  }

  display.clearDisplay();
  display.setCursor(0, 0);
  display.print("MIDI Clock Test");
  display.display();
}
1 Like

Dont mind this I managed to find the problem finally, display.display(); cannot be handled in the loop cause its making the midi messages acting wierd. It was something very stupid at the end but will cause me to do a lot of change in my code to make it work now. At least I can say I can finally start syncing the sequencer to perform with other gear.

1 Like

Glad you found a fix! Don’t hesitate to reach out in the future with any other questions.