Capturing MIDI messages stops after a couple of seconds

Status
Not open for further replies.

bcnx

Active member
Hi guys and girls!

I'm building a project where I plan to capture incoming MIDI messages and show them on a TFT screen. I used the code on https://www.pjrc.com/teensy/td_libs_MIDI.html and commented out some stuff to really get to the bare essentials (always good for troubleshooting).
I am using a Teensy LC with a classic 6N138 setup. I have added a LED to show activity. I get some MIDI values in the serial console (much less than there are in the MIDI song I use, but showing the right MIDI channel, so it is picking up something) but after a couple of seconds the capturing stops and the serial console does not get any additional info. The activity LED continues to work, so the signal is good. In my code you see the inactivity part commented out, but when it was not, it never got to that part. It is as if the Teensy freezes.
Any idea what could be causing this?

Code:
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
#include <MIDI.h>

#define sclk 13  // SCLK can also use pin 14
#define mosi 11  // MOSI can also use pin 7
#define cs   10  // CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define dc   15   //  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define rst  9   // RST can use any pin
//#define sdcs 4  

#define HWSERIAL Serial1

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, mosi, sclk, rst);

MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);

void setup() {
  //Serial.begin(9600);
  //Serial.print("Hello! ST7735 TFT Test");

  MIDI.begin(MIDI_CHANNEL_OMNI);
  //Serial.begin(57600);
  Serial.begin(9600);
  Serial.println("MIDI Input Test");

  ///tft.initR(INITR_GREENTAB); // initialize a ST7735R chip, green tab
  
  //Serial.println(time, DEC);
  //delay(500);
 
  ///tft.invertDisplay(true);
  ///tft.setRotation(1);

  ///drawtext("Hello World!", ST7735_WHITE);
  //tft.println("test");
  //delay(1000);


}

unsigned long t=0;

void loop() {
 
 //Serial.println("Keep Alive");
  int type, note, velocity, channel, d1, d2;
  if (MIDI.read()) {                    // Is there a MIDI message incoming ?
    byte type = MIDI.getType();
    switch (type) {
      case midi::NoteOn:
        note = MIDI.getData1();
        velocity = MIDI.getData2();
        channel = MIDI.getChannel();
        if (velocity > 0) {
          Serial.println(String("Note On:  ch=") + channel + ", note=" + note + ", velocity=" + velocity);
        } else {
          Serial.println(String("Note Off: ch=") + channel + ", note=" + note);
        }
        break;
      case midi::NoteOff:
        note = MIDI.getData1();
        velocity = MIDI.getData2();
        channel = MIDI.getChannel();
        Serial.println(String("Note Off: ch=") + channel + ", note=" + note + ", velocity=" + velocity);
        break;
      ///default:
      ///  d1 = MIDI.getData1();
      ///  d2 = MIDI.getData2();
      ///  Serial.println(String("Message, type=") + type + ", data = " + d1 + " " + d2);
    }
    ///t = millis();
  }
  ///if (millis() - t > 10000) {
  ///  t += 10000;
  ///  Serial.println("(inactivity)");
  ///}
}

///void drawtext(const char *text, uint16_t color) {
///  tft.fillScreen(ST7735_BLACK);
///  tft.setCursor(0, 0);
///  tft.setTextColor(color);
///  tft.setTextWrap(true);
///  tft.setTextSize(2);
///  tft.print(text);
///}

MIDIINTHRU-1.jpg
 
OK, so I stripped the code to a simple for loop and removed all other hardware (TFT screen and MIDI electronics). I also used a different Teensy LC and I still get the same behaviour. I'm starting to think my power supply is the culprit. Going to replace that one now.

BC
 
If the power supply doesn't turn out to be the problem, any chance you could set up that other Teensy to send a well defined batch of MIDI messages to reproduce the problem? Then I could wire it up here and try to investigate...
 
Could the issue be with Arduino IDE Serial Monitor in Windows?

I've always found it a bit unreliable in Windows.

I assume changing the serial rate didn't help.

BTW - your schematic look like it is sending 5 volt to the TLC's Rx pin.
 
Oddson is right- the LC uses 3.3V logic- and is not 5 Volt tolerant, so you are overloading the Rx input. The 470 ohm resistor is limiting the LC input current to some extent, but the Rx input circuit is probably not functioning properly in this configuration. The 6N138 was designed for 5V TTL operation- I don't see in the Vishay datasheet whether it would work on 3.3V. But, if you supplied just the 470 ohm resistor with a 3.3V source (add a 3.3V regulator or 3.3V Zener) , that would provide the necessary 3.3V logic signal required by the Teensy LC.
 
Hi,

thanks all - yo umust have read my minds: I looked this mourning at the supplied card and only then noticed the "Caution" warning. So it is a basic case of RTFM. I still have the problem after disconnecting all inputs, but maybe I just blew up two Teensy LCs. Luckily I have a third one to test.
I will report back soon!

BC
 
and of course my last teensy LC does not function (not programmable). let's see if there is some life left in the two first ones.
 
Hi Bmiller,

I dug up a zener of 3.3 volts and I added it to the 470 ohm resistor. I don't think the 74LS14 I am using to drive the LED and add several MIDI Thru connectors, will be triggered by 3.3V, so I will need to split those things up. I saw a zener can have about 250 mA, should be OK for my circuit.
 
OK, found the problem - that is to say: running the Arduino IDE on my Mac outputs serial info just fine. So for some reason the serial communication on my Linux Mint does not work. Bummer.
 
If you are still looking to provide a 3.3V logic signal to the Teensy LC, you need a bit more than just a diode:

Midi.PNG
 
dang, I just finished adding the zener diode and finding the correct resistors. back to the drawing board! regardless, was a good lesson in using zeners!

thanks for the suggestions by the way!
 
I do see there is a 100mA limit on the Teensy 3.3V. I'm driving a ST7735 TFT and of course the 6N138. Will I end up in burn-out land?
 
Mmm, there is a second 3.3V I just noticed. It does not seem to have a mentioning of maximum current...
 
Are you running the display directly from 3.3V?

This really depends on the particular display you have, but many of them actually have a 5 to 3.3V regulator on the PCB. Those types are actually meant to be powered with more than 3.3V. If so, your display might be just barely running.

Likewise, the 6N138 is meant to be powered from 5 volts. Only the pullup resistor should connect to 3.3V. Here's the recommended schematic.

td_libs_MIDI_sch_t3.png
 
Hi Paul,

The TFT screen is the ST7735 from Adafruit. It is designed for 3.3V to 5V. I feed the backlight from 5V, but the rest from 3.3V, as I figure that the SPI connections to the LC are then also 3.3 (not breaking the 3.3 V input rule). I am now actually following your schematic, so the 6N138 is getting 5 volts on pin8, but 3.3V via the 470 resistor on its pin 6.

thanks!

BC
 
Almost all the power those TFT displays use goes to the backlight. The actual display electronics uses relatively little power. The specifics vary depending on the display (and even vary depending on which batch), especially the power consumed by the LEDs in the backlight.
 
The original MIDI specification only gave a circuit for 5V logic, and didn't really document that this was a 5mA current loop signalling system. It is perfectly possible to make a 3V3 circuit (it is a current loop, so the resistor values need to be altered to give the same current with the lower voltage).

The MIDI Manufacturers Association also released an updated electrical specification in 2014, which accounts for 3V3 logic and also has EMI protection (the latter can probably be skipped in hobbyist projects which don't have to meet the relevant standards).

The updated circuit provided by Paul and the updated MMA circuit are thus pretty similar. Paul uses 47Ω pullup and 47Ω from the UART; MMA uses 33Ω 5% 0.5W pullup and 10Ω 5% 0.25W from the UART, plus some ferrite beads. The input likewise has a couple of ferrites and a couple of 100n caps. They still seem kind of vague about the optocoupler output pullup value for non-5V systems. You can find the MMA circuit details at

https://www.midi.org/specifications/item/the-midi-1-0-specification

follow the link "Electrical Specification Update [2014]". They make you create an account and log in, but the spec itself is free.
 
dont know if teensy tolerates String class because of all the memory it has, but you should loose the String class and use character arrays instead
 
Status
Not open for further replies.
Back
Top