tttapa / Control-Surface

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

SSD1306 OLED Display - Display simple MIDI Method #99

Closed LukaszChrzanowski closed 4 years ago

LukaszChrzanowski commented 4 years ago

Hello, it's me again :)

I'm trying to set to OLED simple text message received by MIDI (I didn't use Mackie interface, becouse it's very heavy in the end). I've writed my own codec for DAW, and I'm receiving text for my OLED in this format:

System Exclusive message: f0 11 22 33 10 54 65 73 74 20 20 20 20 20 20 20 20 20 20 20 20 f7 on cable 0

where this is configurable prefix: f0 11 22 33 10 this is text: 54 65 73 74 20 20 20 20 20 20 20 20 20 20 20 20 this is end of text: f7

In project there is attached Adafriut library. So basically I know (by many tutorials) how to display data - but where I can get MIDI input event with all data? or maybe even better - look fof SysEx message with starting "f0 11 22 33 10"?

also I cannot use Your's classes for display becouse I've bought SSD1306 with IIC protocol only (SCL,SDA,VCC,GND pins olny)

tttapa commented 4 years ago

also I cannot use Your's classes for display becouse I've bought SSD1306 with IIC protocol only (SCL,SDA,VCC,GND pins olny)

The classes support most Adafruit_GFX displays. You can use the I²C versions as well. The only difference is the initialization of the displays. This is independent from the Control Surface library, you can find examples in the Adafruit_SSD1306 library.

where I can get MIDI input event with all data? or maybe even better - look fof SysEx message with starting "f0 11 22 33 10"?

You can use the Mackie LCD class as a template: https://github.com/tttapa/Control-Surface/blob/master/src/MIDI_Inputs/MCU/LCD.hpp

The function of interest is updateImpl, it's called when a new MIDI SysEx message comes in. It checks the preamble, and returns false if it doesn't match. If it does match, it saves the text of the SysEx message, and returns true. Returning true indicates to the Control Surface library that the message was handled, and it doesn't have to check the other MIDI Input SysEx elements.

LukaszChrzanowski commented 4 years ago

ok, I will try that.

I've tried for now something like this... and I'm a little bit confused, becouse that code below should work. o.O I've inserted in sysExMessageCallback from MIDI Debug example to send static text to screen... and nothing happens - therefore even it hangs my sending midi debug program...


#include <Control_Surface.h> // Include the Control Surface library
//OLED
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//OLED END

// Instantiate a MIDI over USB interface.
USBMIDI_Interface midi;

//OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//OLED END

//----------------------FOR DEBUG START----------------------
bool channelMessageCallback(ChannelMessage cm) {
  Serial << F("Channel message: ") << hex << cm.header << ' ' << cm.data1 << ' '
         << cm.data2 << dec << F(" on cable ") << cm.CN << endl;
  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.
}

bool sysExMessageCallback(SysExMessage se) {
  Serial << F("System Exclusive message: ") << hex;
  for (size_t i = 0; i < se.length; ++i)
    Serial << se.data[i] << ' ';

delay(2000);
display.clearDisplay();

display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);

display.println("TEST LCD");
display.display();

  Serial << dec << F("on cable ") << se.CN << endl;
  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.
}

bool realTimeMessageCallback(RealTimeMessage rt) {
  Serial << F("Real-Time message: ") << hex << rt.message << dec
         << F(" on cable ") << rt.CN << endl;
  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.
}

//----------------------FOR DEBUG END----------------------

void setup() {
  Serial.begin(115200);  //-----------FOR DEBUG-----------
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {                //-----------FOR OLED-----------
    //Serial.println(F("OLED FAILED INITIALIZATION"));              //-----------FOR OLED-----------
    for(;;);                                                      //-----------FOR OLED-----------
  }     

  Control_Surface.begin();
  Control_Surface.setMIDIInputCallbacks(channelMessageCallback,   //-----------FOR DEBUG-----------
                                        sysExMessageCallback,     //-----------FOR DEBUG-----------
                                        realTimeMessageCallback); //-----------FOR DEBUG-----------
                                             //-----------FOR OLED-----------

}

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

What board are you using? Do you have enough RAM? Try uncommenting the Serial.println(F("OLED FAILED INITIALIZATION")); in your setup. The for(;;) is consistent with your program hanging.

tttapa commented 4 years ago

Also note that I edited my first reply with some extra information.

LukaszChrzanowski commented 4 years ago

I'm using Pro Micro board (clone).

I've uncommented but nothing changed. :/ nothing on screen and unresponsable midi

I know, that I'm asking for much here, but besides I will change mask (offset) in updateImpl - how my code in setup/loop should looks like? I just want some raw text, nothing fancy :)

tttapa commented 4 years ago

Does it print anything to the serial monitor? How much memory does your sketch use? (It displays this when you 'verify' the sketch.)

LukaszChrzanowski commented 4 years ago

On serial monitor there is nothing.

Sketch uses 25128 bytes (87%) of program storage space. Maximum is 28672 bytes. Global variables use 1569 bytes (61%) of dynamic memory, leaving 991 bytes for local variables. Maximum is 2560 bytes.

tttapa commented 4 years ago

Global variables use 1569 bytes (61%) of dynamic memory, leaving 991 bytes for local variables. Maximum is 2560 bytes.

There's your problem. You need at least 128×64 bits = 1024 bytes of RAM for the display buffer of the display. You only have 991 available.

LukaszChrzanowski commented 4 years ago

So my only choice is to move to Arduino Mega (8k of SRAM)? I don't see how can I optimize my code...

is board like this compatible with Your's library? Arduino MEGA 2560 PRO mini CH340 ATmega2560 AVR

tttapa commented 4 years ago

I wouldn't recommend an Arduino Mega at all, it has no MIDI USB support, it's more expensive, and it's still a slow 8-bit AVR microcontroller.
I would recommend using a Teensy instead, it's much more powerful than an Arduino Mega.
There's an overview of MIDI USB-compatibility for different boards here: MIDI over USB

The Control Surface library uses quite some memory because it primarily aims to be easy to use. You could reduce the memory consumption by writing your own MIDI code etc. from scratch, but I wouldn't recommend that. If you're using a frame buffer for the display, you'll always use 1KiB of RAM (and you only have 2.5KiB total).

You could also try a text-only SSD1306 library, but if you can afford it, buying a more powerful board is going to be the easiest solution.

LukaszChrzanowski commented 4 years ago

Thank You. I will buy it then if there is no other way.

Thread for closing

tttapa commented 4 years ago

If you're going to buy a Teensy, I'd recommend a 3.2, 3.5, 3.6 or 4.0.

Teensy 2 is probably not powerful enough if you want displays, and I cannot test the library on Teensy 2s because I don't have any, so I cannot offer support if you encounter problems with the library.

LukaszChrzanowski commented 4 years ago

is this will be the right choice?

I can choose between: Teensy 4.0 ARM Cortex-M7 NXP iMXRT1062 600MHz Teensy 3.2 ARM Cortex-M4 MK20DX256 72MHz

will Your's library work for two of them?

tttapa commented 4 years ago

Yes. I have both of these boards myself and they work fine with the library.

LukaszChrzanowski commented 4 years ago

ok I choosed Teensy 4.0 ARM Cortex-M7 NXP iMXRT1062 600MHz :) it's not cheap but we shall se how it work out :)

LukaszChrzanowski commented 4 years ago

Works with Teensy 4.0 - you Can close this topic (display also works fine)