Communicating USB MIDI Board with teensy 3.6

Status
Not open for further replies.

Nader

Member
Hello everyone,

I am new to teensy board, I had a working setup to control my LEDs to turn on when i press a key on my digital piano. But my arduino uno R3 was too slow so i want to move my setup to work with a teensy 3.6.

Now I want to send serial data from a USB MIDI Board (It translates MIDI data to serial) to my teensy 3.6

Now I tried to do that but apparently the teensy is not responding to my commands.

Can you please help me in that regards? I will post the code that I am using below (coded on arduino IDE)

#include <MIDI.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#include "noteList.h"
#include "pitches.h"

MIDI_CREATE_DEFAULT_INSTANCE();

static const unsigned sMaxNumNotes = 16;
MidiNoteList<sMaxNumNotes> midiNotes;
byte curWheelPos = 0;

#define KEYBOARD_LOWEST_NOTE 21
#define KEYBOARD_HIGHEST_NOTE 108
#define STRIP_REVERSED true

#define STRIP_PIN 12
#define STRIP_NUM_PIXELS 73

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(STRIP_NUM_PIXELS, STRIP_PIN, NEO_GRB + NEO_KHZ800);

// -----------------------------------------------------------------------------

inline void handleGateChanged(bool inGateActive)
{
digitalWrite(LED_BUILTIN, inGateActive ? LOW : HIGH);
}

inline void pulseGate()
{
handleGateChanged(false);
delay(10);
handleGateChanged(true);
}

// -----------------------------------------------------------------------------

byte noteToStripIndex(byte pitch)
{
byte index;
if(pitch < KEYBOARD_LOWEST_NOTE)
index = 0;
else if(pitch > KEYBOARD_HIGHEST_NOTE)
index = STRIP_NUM_PIXELS -1;
else
index = (STRIP_NUM_PIXELS -1) * (pitch - KEYBOARD_LOWEST_NOTE) / (KEYBOARD_HIGHEST_NOTE - KEYBOARD_LOWEST_NOTE);
if(STRIP_REVERSED)
index = (STRIP_NUM_PIXELS -1) - index;

return index;
}

void handleNotesChanged(bool isFirstNote = false)
{
if (midiNotes.empty())
{
strip.clear();
strip.show();
handleGateChanged(false);
}
else
{
byte pitch = 0;
strip.clear();
for (byte i = 0; i < midiNotes.size(); ++i)
{
if(midiNotes.get(i, pitch))
{
strip.setPixelColor(noteToStripIndex(pitch), 0,255,119);
curWheelPos++;
}
}
strip.show();

if (midiNotes.getLast(pitch))
{
if (isFirstNote)
{
handleGateChanged(true);
}
else
{
pulseGate(); // Retrigger envelopes. Remove for legato effect.
}
}
}
}

// -----------------------------------------------------------------------------

void handleNoteOn(byte inChannel, byte inNote, byte inVelocity)
{
const bool firstNote = midiNotes.empty();
midiNotes.add(MidiNote(inNote, inVelocity));
//digitalWrite(LED_BUILTIN, LOW);
handleNotesChanged(firstNote);
}

void handleNoteOff(byte inChannel, byte inNote, byte inVelocity)
{
midiNotes.remove(inNote);
//digitalWrite(LED_BUILTIN, HIGH);
handleNotesChanged();
}

// -----------------------------------------------------------------------------

void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
MIDI.setHandleNoteOn(handleNoteOn);
MIDI.setHandleNoteOff(handleNoteOff);
MIDI.begin(MIDI_CHANNEL_OMNI);
//Serial.begin(115200);//For debug only
digitalWrite(LED_BUILTIN, HIGH);

strip.begin();
//strip.show(); // Initialize all pixels to 'off'
//rainbow(10);
strip.clear();
strip.show();
}

void loop()
{
MIDI.read();
}
 
Adafruit_NeoPixel is incompatible with MIDI and pretty much all other libraries needing interrupts.

WS2812Serial is an alternative to Adafruit_NeoPixel. It uses more memory (usually not a problem on Teensy 3.6), but never blocks interrupts like Adafruit_NeoPixel, so you can have reliable communication from MIDI while the LEDs are updating. WS2812Serial is also limited to using only certain pins. See the comments in its examples (File > Examples > WS2812Serial) for details.

You might also consider connecting your MIDI device directly to Teensy 3.6's USB host port, rather than going through a converter. You'll need this cable:

https://www.pjrc.com/store/cable_usb_host_t36.html

The cable pinout is the same as the USB2 internal cables used with PC motherboards, so if you have one of those cables, it will probably work.
 
Hello! Thank you for your reply!
I have been searching around and i have noticed that i have to specify a Serial1 so i can read the data from my MIDI USB HOST? is that true?
Also is the Ws2812Serial a library that i can download on Arduino IDE?
And i will try to buy the cable you mentioned if i know that my setup wont work, maybe i can use FASTLED Library instead of NeoPixel??
 
I have been searching around and i have noticed that i have to specify a Serial1 so i can read the data from my MIDI USB HOST? is that true?

Assuming you're talking about "MIDI USB HOST" by using the USBHost_t36 library, then no, it's completely independent of Serial1.

However, at least one of the USBHost_t36 library's examples shows how to also use it together with the MIDI library (so you can formward MIDI messages between serial MIDI and USB MIDI devices on the host port). In that case, Serial1 is used by MIDI, but not USBHost_t36.


Also is the Ws2812Serial a library that i can download on Arduino IDE?

Its one of the many libraries that Teensyduino installs, so unless you decided to not install the libs, you probably already have it.

But if you want to download it from github and manually install, you certainly can.

https://github.com/PaulStoffregen/WS2812Serial


maybe i can use FASTLED Library instead of NeoPixel??

Yes, but if you use FastLED the normal way, it will also interfere with interrupts.

There is a way to use FastLED with WS2812Serial. In fact, one of WS2812Serial's examples shows how to do this. If you go that route, you get the non-blocking goodness of WS2812Serial plus all the powerful color & rendering functions of FastLED.
 
Hello friend!
I have looked at the library you suggested “ws2812serial.h” and the basic example worked, however the other example that had both FastLED and your library did nothing to my setup, the LEDs were completely turned off.
So i tried using the “setPixel” command in my code that controls the LEDs when a key is pressed on my piano, but the only thing that happened is the LEDs to the far right of the piano (the first 4 were on with random colors, although i specified the color).
Please let me know if am doing something wrong! If you need pictures or anything of my setup then i’ll be more than happy to provide all the info to make this work.
Thank you so much for your time Paul!
 
Status
Not open for further replies.
Back
Top