tttapa / Control-Surface

Arduino library for creating MIDI controllers and other MIDI devices.
GNU General Public License v3.0
1.22k stars 137 forks source link

Arduino MEGA/Moco-Lufa : SD1306 don't work in MIDI mode #189

Open sucrz opened 4 years ago

sucrz commented 4 years ago

Hi,

I've almost finished my midi controller and thanks again for all the help I received here.

I work on Arduino MEGA (I need lots of pins for encoders) I use Moco-Lufa to allow my board to act like a Generic MIDI controller.

It work very well except for my oled screen (SD1306) connect by I2C.

When I'm in"debug" mode everything work fine, but when I switch back to "MIDI" mode the screen doesn't work, it stay black.

I don't know if the issue come to MOCO-LUFA/I2C or something else.

I post my issue here because the MOCO-LUFA Git seem abandonned, I don't know if someone already had the same issue and can help me.


#include <Encoder.h>
#include <Control_Surface.h> // Include the Control Surface library
#include <AH/STL/vector>    // std::vector
#include <AH/STL/algorithm> // std::copy

#include <Banks/Bank.hpp>
//#include <Display/DisplayElement.hpp>
#include <Selectors/Selector.hpp>

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

USBDebugMIDI_Interface midi;
//USBMIDI_Interface midi;
//
constexpr uint8_t SCREEN_WIDTH = 128;
constexpr uint8_t SCREEN_HEIGHT = 32;
constexpr int8_t OLED_RESET = -1;

Adafruit_SSD1306 display  = {SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET};

// sysex example message : F0 77 48 65 6C 6C 6F F7
// sysex "Cutoff : 127 : F0 77 43 76 74 6F 66 66 3A 31 32 37 F7
//                               H  e  l  l  o
/*bool sysExMessageCallback(SysExMessage se) {
  if (se.length < 3) // Ensure that the message is long enough
    return false;
  if (se.data[1] != 0x77) // Check for desired manufacturer code
    return false;
  // Get the length of the text message and limit it to 32 characters
  auto length = se.length - 3;
  length = constrain(length, 0, 32);
  // Allocate memory for the text + null terminator
  std::vector<char> text(length + 1);
  // Copy the text from the message
  const uint8_t *text_start = se.data + 2;
  std::copy(text_start, text_start + length, std::begin(text));
  text.back() = '\0'; // properly terminate the string
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 18);
  display.println(text.data());
  display.display();
  //Serial.println(text.data()); // print it
  return true; // Return true to indicate that handling is done,
  // and Control_Surface shouldn't handle it anymore.
  // If you want Control_Surface to handle it as well,
  // return false;
}*/

class MySelectorCallback {
  public:
    // Constructor
    MySelectorCallback() {}

    void begin() {
      show(0);
    }

    void update() {
      }

    void update(setting_t oldSetting, setting_t newSetting) {
      (void) oldSetting; // unused in this example
      show(newSetting);
    }

  private:
    void show(setting_t setting) {
      uint8_t color = getColor(setting);
      display.clearDisplay();
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(0, 0);
      display.println("Bank:");
      display.setCursor(72, 0);
      display.println(color);
      display.display();
    }

    // Convert the given setting to a 3-bit RGB color value.
    static uint8_t getColor(setting_t setting) {
      switch (setting) {
        case 0: return 1;
        case 1: return 2;
        case 2: return 3;
        case 3: return 4;
        case 4: return 5;
        case 5: return 6;
        case 6: return 7;
        case 7: return 8;
        default: return 0;
      }
    }

  private:

};

CD74HC4067 mux = {
  43,       // Analog input pin
  {35 , 37, 39, 41} // Address pins S0, S1, S2
};

Bank<8> bank(8);
GenericManyButtonsSelector<8, MySelectorCallback> selector = {
  bank, {},
  {
    mux.pin(0),
    mux.pin(1),
    mux.pin(2),
    mux.pin(3),
    mux.pin(4),
    mux.pin(5),
    mux.pin(6),
    mux.pin(7)
  }
};

Bankable::CCRotaryEncoder rowAenc[] = {
  {{bank, BankType::CHANGE_ADDRESS}, {21, 20}, {MIDI_CC::Bank_Select , CHANNEL_1}, 4, 4,},
  {{bank, BankType::CHANGE_ADDRESS}, {50, 51}, {MIDI_CC::Modulation_Wheel , CHANNEL_1}, 4, 4,},
  {{bank, BankType::CHANGE_ADDRESS}, {48, 49}, {MIDI_CC::Breath_Controller, CHANNEL_1}, 4, 4,},
  {{bank, BankType::CHANGE_ADDRESS}, {46, 47}, {MIDI_CC::Controller_3, CHANNEL_1}, 4, 4,},
  {{bank, BankType::CHANGE_ADDRESS}, {22, 23}, {MIDI_CC::Foot_Controller , CHANNEL_1}, 4, 4,},
  {{bank, BankType::CHANGE_ADDRESS}, {24, 25}, {MIDI_CC::Portamento_Time, CHANNEL_1}, 4, 4,},
  {{bank, BankType::CHANGE_ADDRESS}, {26, 27}, {MIDI_CC::Data_Entry_MSB, CHANNEL_1}, 4, 4,},
  {{bank, BankType::CHANGE_ADDRESS}, {28, 29}, {MIDI_CC::Channel_Volume, CHANNEL_1}, 4, 4,},
};

void setup() {

  //   - TWOS_COMPLEMENT (default)
  //   - BINARY_OFFSET
  //   - SIGN_MAGNITUDE
  //   - MACKIE_CONTROL_RELATIVE
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
    FATAL_ERROR(F("SSD1306 allocation failed."), 0x1306);

  /*Control_Surface.setMIDIInputCallbacks(nullptr,              //
                                        sysExMessageCallback, //
                                        nullptr);             //*/
  RelativeCCSender::setMode(relativeCCmode::TWOS_COMPLEMENT);
  Control_Surface.begin();
}

void loop() {
  Control_Surface.loop(); // Update the Control Surface
}
tttapa commented 4 years ago

I've never tried Moco-Lufa.

Does the baud rate match? On boards that don't support MIDI over USB natively, like the MEGA, USBMIDI_Interface uses the standard MIDI baud rate of 31250 baud. This should match the baud rate used by the MIDI firmware.

You could try some alternatives to Moco-Lufa, like Hiduino or USBMidiKlik, or even Hairless (Hairless uses 115200 baud, you can use the HairlessMIDI_Interface).

sucrz commented 4 years ago

Thank for the reply.

looks like default Moco-lufa baud rate is 31250...

I've never heard about USBMidiKlik but it look like a way better solution than Moco-Lufa, I'll give it a try.