Go Down

Topic: MIDI react LED using Arduino. (but im really stuck) (Read 1 time) previous topic - next topic

Grumpy_Mike

My soloution when using an I2C slave was to make an ATtiny85 system that sent the Neopixel data and I talked to it using a two wire SPI like protocol to send the data to the tiny which could be interrupted.

ozguney

My soloution when using an I2C slave was to make an ATtiny85 system that sent the Neopixel data and I talked to it using a two wire SPI like protocol to send the data to the tiny which could be interrupted.
My english can not suffice your explanation. Did you say make your own processor and send data to there?

PieterP

#32
Jul 14, 2018, 11:06 pm Last Edit: Jul 14, 2018, 11:07 pm by PieterP
Does Teensy work with MIDI.h and FastLED.h libraries?
Even better: it supports MIDI over USB, so no Hairless clutter, just plug it in, and it works. It also supports non-blocking WS2812. https://www.pjrc.com/non-blocking-ws2812-led-library/

Grumpy_Mike

#33
Jul 15, 2018, 09:38 am Last Edit: Jul 15, 2018, 09:39 am by Grumpy_Mike
My english can not suffice your explanation. Did you say make your own processor and send data to there?
This is the circuit I used to send data to a Neopixel strip without disabling the Arduino's interrupts. If you stick with MIDI on an Arduino Uno this is a solution for you.


However:-
Quote
Even better: it supports MIDI over USB,
By removing the serial input data and going over to USB it removes the interrupt problem anyway. Yes the USB interface uses interrupts to transfer data but the protocol makes it try again if there is no response.

ozguney


this code is works perfectly. but i need 88 output :d

Code: [Select]
#include <MIDI.h>

#define led7 7
#define led6 6
#define led5 5
#define led4 4
#define led3 3

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  pinMode(led7, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led3, OUTPUT);
  MIDI.begin(1);
  Serial.begin(115200);
  MIDI.setHandleNoteOn(MyHandleNoteOn);
  MIDI.setHandleNoteOff(MyHandleNoteOff);
}

void loop() {
  MIDI.read();
}

void MyHandleNoteOn(byte channel, byte pitch, byte velocity) {
  switch (pitch) {
    case 60:
      digitalWrite(led7, HIGH);
        break;
    case 62:
      digitalWrite(led6, HIGH);
        break;
    case 64:
      digitalWrite(led5, HIGH);
        break;
    case 65:
      digitalWrite(led4, HIGH);
        break;
    case 67:
      digitalWrite(led3, HIGH);
        break;
  }
}

void MyHandleNoteOff(byte channel, byte pitch, byte velocity) {
  switch (pitch) {
    case 60:
      digitalWrite(led7, LOW);
        break;
    case 62:
      digitalWrite(led6, LOW);
        break;
    case 64:
      digitalWrite(led5, LOW);
        break;
    case 65:
      digitalWrite(led4, LOW);
        break;
    case 67:
      digitalWrite(led3, LOW);
        break;
  }
}

PieterP


ozguney

I think you should re-read this thread.
because your shift register project is solving my pin problem am i rite?

ozguney

Does  <Control_Surface.h> compatible with <FastLED.h> or <Adafruit_Neopixel.h> ?

Grumpy_Mike

Quote
because your shift register project is solving my pin problem am i rite?
No because the thread describes your problem and also describes the many solutions open to you.

PieterP

Does  <Control_Surface.h> compatible with <FastLED.h> or <Adafruit_Neopixel.h> ?
You cannot use FastLED on an UNO if you need MIDI communication.
Not using WS2812 is one solution. Not using an UNO is another.

I'd recommend using a different microcontroller, like the Teensy, because it supports MIDI over USB and it can drive WS2812 strips without losing MIDI data.

Another solution would be to use normal LEDs instead of the WS2812, or addressable LEDs that don't have a tight timing. Shift registers are one of the possibilities to drive many LEDs with very few microcontroller pins.
You can easily drive 88 LEDs using 11 8-bit shift registers and only 3 pins.

ozguney

You cannot use FastLED on an UNO if you need MIDI communication.
Not using WS2812 is one solution. Not using an UNO is another.

I'd recommend using a different microcontroller, like the Teensy, because it supports MIDI over USB and it can drive WS2812 strips without losing MIDI data.

Another solution would be to use normal LEDs instead of the WS2812, or addressable LEDs that don't have a tight timing. Shift registers are one of the possibilities to drive many LEDs with very few microcontroller pins.
You can easily drive 88 LEDs using 11 8-bit shift registers and only 3 pins.
Yes I was very hasty for finish my project. Now I'm starting again. I think Teensy is a good choice. It has really fast microcontroller. Already I have already 3meters of LED strip and I dont wanna waste them. This time I'm gonna slowly, carefully, calmy and for learning purpose. Also I started learning about Teensy.

In my country Teensy a little expensive. I can buy Teensy 3.2, If you highly recommend upper versions(3.5 or 3.6) I can buy them. Which Teensy do you recommend to me?

PieterP

#41
Jul 15, 2018, 04:19 pm Last Edit: Jul 15, 2018, 04:20 pm by PieterP
I only have a Teensy 3.2, and it works fine. I can't say anything about the newer versions, but they seem to be very powerful, and knowing PJRC's usual products and libraries, they will be well-supported.

Grumpy_Mike

I have a Couple of Teensy 3.6s, I think they are overkill for your project a Teensy 3.2 would be fine.

ozguney

I have a Couple of Teensy 3.6s, I think they are overkill for your project a Teensy 3.2 would be fine.
I only have a Teensy 3.2, and it works fine. I can't say anything about the newer versions, but they seem to be very powerful, and knowing PJRC's usual products and libraries, they will be well-supported.
Hi, Teensy 3.2 works perfectly. I tried lots of examples and works. Inputs, outputs are okay also WS2812-NeoPixel Libraries are okay. But I have trouble about using usbMIDI examples. When I try to usbMIDI examples. I got this "'usbMIDI' was not declared in this scope"

This is InputRead example(internal example.):

Code: [Select]
/* Receive Incoming USB MIDI by reading data.  This approach
   gives you access to incoming MIDI message data, but requires
   more work to use that data.  For the simpler function-based
   approach, see InputFunctionsBasic and InputFunctionsComplete.

   Use the Arduino Serial Monitor to view the messages
   as Teensy receives them by USB MIDI

   You must select MIDI from the "Tools > USB Type" menu

   This example code is in the public domain.
*/

void setup() {
  Serial.begin(115200);
}

void loop() {
  // usbMIDI.read() needs to be called rapidly from loop().  When
  // each MIDI messages arrives, it return true.  The message must
  // be fully processed before usbMIDI.read() is called again.
  if (usbMIDI.read()) {
    processMIDI();
  }
}

void processMIDI(void) {
  byte type, channel, data1, data2, cable;

  // fetch the MIDI message, defined by these 5 numbers (except SysEX)
  //
  type = usbMIDI.getType();       // which MIDI message, 128-255
  channel = usbMIDI.getChannel(); // which MIDI channel, 1-16
  data1 = usbMIDI.getData1();     // first data byte of message, 0-127
  data2 = usbMIDI.getData2();     // second data byte of message, 0-127
  cable = usbMIDI.getCable();     // which virtual cable with MIDIx8, 0-7

  // uncomment if using multiple virtual cables
  //Serial.print("cable ");
  //Serial.print(cable, DEC);
  //Serial.print(": ");

  // print info about the message
  //
  switch (type) {
    case usbMIDI.NoteOff: // 0x80
      Serial.print("Note Off, ch=");
      Serial.print(channel, DEC);
      Serial.print(", note=");
      Serial.print(data1, DEC);
      Serial.print(", velocity=");
      Serial.println(data2, DEC);
      break;

    case usbMIDI.NoteOn: // 0x90
      Serial.print("Note On, ch=");
      Serial.print(channel, DEC);
      Serial.print(", note=");
      Serial.print(data1, DEC);
      Serial.print(", velocity=");
      Serial.println(data2, DEC);
      break;

    case usbMIDI.AfterTouchPoly: // 0xA0
      Serial.print("AfterTouch Change, ch=");
      Serial.print(channel, DEC);
      Serial.print(", note=");
      Serial.print(data1, DEC);
      Serial.print(", velocity=");
      Serial.println(data2, DEC);
      break;

    case usbMIDI.ControlChange: // 0xB0
      Serial.print("Control Change, ch=");
      Serial.print(channel, DEC);
      Serial.print(", control=");
      Serial.print(data1, DEC);
      Serial.print(", value=");
      Serial.println(data2, DEC);
      break;

    case usbMIDI.ProgramChange: // 0xC0
      Serial.print("Program Change, ch=");
      Serial.print(channel, DEC);
      Serial.print(", program=");
      Serial.println(data1, DEC);
      break;

    case usbMIDI.AfterTouchChannel: // 0xD0
      Serial.print("After Touch, ch=");
      Serial.print(channel, DEC);
      Serial.print(", pressure=");
      Serial.println(data1, DEC);
      break;

    case usbMIDI.PitchBend: // 0xE0
      Serial.print("Pitch Change, ch=");
      Serial.print(channel, DEC);
      Serial.print(", pitch=");
      Serial.println(data1 + data2 * 128, DEC);
      break;

    case usbMIDI.SystemExclusive: // 0xF0
      // Messages larger than usbMIDI's internal buffer are truncated.
      // To receive large messages, you *must* use the 3-input function
      // handler.  See InputFunctionsComplete for details.
      Serial.print("SysEx Message: ");
      printBytes(usbMIDI.getSysExArray(), data1 + data2 * 256);
      Serial.println();
      break;

    case usbMIDI.TimeCodeQuarterFrame: // 0xF1
      Serial.print("TimeCode, index=");
      Serial.print(data1 >> 4, DEC);
      Serial.print(", digit=");
      Serial.println(data1 & 15, DEC);
      break;

    case usbMIDI.SongPosition: // 0xF2
      Serial.print("Song Position, beat=");
      Serial.println(data1 + data2 * 128);
      break;

    case usbMIDI.SongSelect: // 0xF3
      Serial.print("Sond Select, song=");
      Serial.println(data1, DEC);
      break;

    case usbMIDI.TuneRequest: // 0xF6
      Serial.println("Tune Request");
      break;

    case usbMIDI.Clock: // 0xF8
      Serial.println("Clock");
      break;

    case usbMIDI.Start: // 0xFA
      Serial.println("Start");
      break;

    case usbMIDI.Continue: // 0xFB
      Serial.println("Continue");
      break;

    case usbMIDI.Stop: // 0xFC
      Serial.println("Stop");
      break;

    case usbMIDI.ActiveSensing: // 0xFE
      Serial.println("Actvice Sensing");
      break;

    case usbMIDI.SystemReset: // 0xFF
      Serial.println("System Reset");
      break;

    default:
      Serial.println("Opps, an unknown MIDI message type!");
  }
}


void printBytes(const byte *data, unsigned int size) {
  while (size > 0) {
    byte b = *data++;
    if (b < 16) Serial.print('0');
    Serial.print(b, HEX);
    if (size > 1) Serial.print(' ');
    size = size - 1;
  }
}


This is my code and I also get same trouble mesagge here.

Code: [Select]
#include <Adafruit_NeoPixel.h> // Add Led Library

//define NeoPixel Pin and Number of LEDs
#define PIN 6
#define NUM_LEDS 88

//    strip.setPixelColor(4, 120, 255, 40);
//    strip.setPixelColor(Number of LED, RedDensity, GreenDensity, BlueDensity);
#define RedDensity    150
#define GreenDensity  199
#define BlueDensity   88

//create a NeoPixel strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
 
  strip.begin(); // start the strip and blank it out
  strip.show();
 
  Serial.begin(115200);  // Hairless MIDI speed

  usbMIDI.setHandleNoteOn(myNoteOn);
  usbMIDI.setHandleNoteOff(myNoteOff);
}


void loop() {
  // The handler functions are called when usbMIDI reads data.  They
  // will not be called automatically.  You must call usbMIDI.read()
  // regularly from loop() for usbMIDI to actually read incoming
  // data and run the handler functions as messages arrive.
  usbMIDI.read();
}

void myNoteOn(byte channel, byte note, byte velocity) {
  // When using MIDIx4 or MIDIx16, usbMIDI.getCable() can be used
  // to read which of the virtual MIDI cables received this message.
    strip.setPixelColor(pitch-20, RedDensity, GreenDensity, BlueDensity);
    strip.show();
}

void myNoteOff(byte channel, byte note, byte velocity) {
      strip.setPixelColor(pitch-20, 0, 0, 0);
      strip.show();
}


If I want to use usbMIDI do I write the #include usbMIDI or something like that?

PieterP

You have to select the correct USB mode from the Tools menu.

Also, your program will crash/behave unpredictably if pitch is less than 20 or greater than 107.

Go Up