All right-I have had some success! I got that software midi input working. I am now able to receive those MIDI feedback notes from Ableton into Arduino! Now I just have to figure out how to tell Arduino what to do with that information!
OK-I'm having some fun now. I imported the library for the matrix and got that working for me as well! Yea!
Now I just have to figure out the glue that brings these two worlds together!
Good, you see, never give up !
Simplify the matrix code to just manual light on some led, it will be very clear later.
For the moment don't look after the blinking leds, just on and off and will look at that later
Thanks for your informations about midi note control in ableton live! I didn't yet looked after that, but the possibilities are great!
Thank you for your help in getting me on the right track! I can almost taste success.
Simplify the matrix code to just manual light on some led, it will be very clear later.
I'm not sure I understand...which code? Do you mean the library? The only matrix code I have is from the demo that is supplied with the library:Arduino Playground - LedControlDemos
You just have to make a working LED matrix and add the code instead of my digitalWrites.
I don't know which part of the code I need to put in there? :-/
At this point, I have midi->serial converter, and his demo code:
// *****************************************************************************************************************
// * *
// * SpikenzieLabs.com *
// * *
// * Very Simple Serial to MIDI DEMO *
// * *
// *****************************************************************************************************************
//
// BY: MARK DEMERS
// May 2009
// VERSION: 0.1
//
// DESCRIPTION:
// Demo sketch to play notes from middle C in the 4th octave up to B in the 5th octave and then back down.
//
//
// HOOK-UP:
// 1. Plug USB cable from Arduino into your computer.
//
//
// USAGE:
// 1. Install and Set-up Serial MIDI Converter from SpikenzieLabs
// 2. Open, compile, and upload this sketch into your Arduino.
// 3. Run Serial MIDI Converter in the background.
// 4. Launch your music software such as Garage Band or Ableton Live, choose a software instrument and listen to the music.
//
//
// LEGAL:
// This code is provided as is. No guaranties or warranties are given in any form. It is up to you to determine
// this codes suitability for your application.
//
int note = 0;
void setup()
{
Serial.begin(57600); // Default speed of the Serial to MIDI Converter serial port
}
void loop()
{
for(int note=60; note<=83; note++) // Going Up
{
MIDI_TX(144,note,127); // NOTE ON
delay(100);
MIDI_TX(128,note,127); // NOTE OFF
delay(100);
}
for(int note=82; note>=61; note--) // Coming Down
{
MIDI_TX(144,note,127); // NOTE ON
delay(250);
MIDI_TX(128,note,127); // NOTE OFF
delay(250);
}
}
void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY)
{
Serial.print(MESSAGE);
Serial.print(PITCH);
Serial.print(VELOCITY);
}
And then I have the example code for the matrix:
//We always have to include the library
#include "LedControl.h"
/*
Now we need a LedControl to work with.
***** These pin numbers will probably not work with your hardware *****
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
We have only a single MAX72XX.
*/
LedControl lc=LedControl(12,11,10,1);
/* we always wait a bit between updates of the display */
unsigned long delaytime=100;
void setup() {
/*
The MAX72XX is in power-saving mode on startup,
we have to do a wakeup call
*/
lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);
}
/*
This method will display the characters for the
word "Arduino" one after the other on the matrix.
(you need at least 5x7 leds to see the whole chars)
*/
void writeArduinoOnMatrix() {
/* here is the data for the characters */
byte a[5]={B01111110,B10001000,B10001000,B10001000,B01111110};
byte r[5]={B00111110,B00010000,B00100000,B00100000,B00010000};
byte d[5]={B00011100,B00100010,B00100010,B00010010,B11111110};
byte u[5]={B00111100,B00000010,B00000010,B00000100,B00111110};
byte i[5]={B00000000,B00100010,B10111110,B00000010,B00000000};
byte n[5]={B00111110,B00010000,B00100000,B00100000,B00011110};
byte o[5]={B00011100,B00100010,B00100010,B00100010,B00011100};
/* now display them one by one with a small delay */
lc.setRow(0,0,a[0]);
lc.setRow(0,1,a[1]);
lc.setRow(0,2,a[2]);
lc.setRow(0,3,a[3]);
lc.setRow(0,4,a[4]);
delay(delaytime);
lc.setRow(0,0,r[0]);
lc.setRow(0,1,r[1]);
lc.setRow(0,2,r[2]);
lc.setRow(0,3,r[3]);
lc.setRow(0,4,r[4]);
delay(delaytime);
lc.setRow(0,0,d[0]);
lc.setRow(0,1,d[1]);
lc.setRow(0,2,d[2]);
lc.setRow(0,3,d[3]);
lc.setRow(0,4,d[4]);
delay(delaytime);
lc.setRow(0,0,u[0]);
lc.setRow(0,1,u[1]);
lc.setRow(0,2,u[2]);
lc.setRow(0,3,u[3]);
lc.setRow(0,4,u[4]);
delay(delaytime);
lc.setRow(0,0,i[0]);
lc.setRow(0,1,i[1]);
lc.setRow(0,2,i[2]);
lc.setRow(0,3,i[3]);
lc.setRow(0,4,i[4]);
delay(delaytime);
lc.setRow(0,0,n[0]);
lc.setRow(0,1,n[1]);
lc.setRow(0,2,n[2]);
lc.setRow(0,3,n[3]);
lc.setRow(0,4,n[4]);
delay(delaytime);
lc.setRow(0,0,o[0]);
lc.setRow(0,1,o[1]);
lc.setRow(0,2,o[2]);
lc.setRow(0,3,o[3]);
lc.setRow(0,4,o[4]);
delay(delaytime);
lc.setRow(0,0,0);
lc.setRow(0,1,0);
lc.setRow(0,2,0);
lc.setRow(0,3,0);
lc.setRow(0,4,0);
delay(delaytime);
}
/*
This function lights up a some Leds in a row.
The pattern will be repeated on every row.
The pattern will blink along with the row-number.
row number 4 (index==3) will blink 4 times etc.
*/
void rows() {
for(int row=0;row<8;row++) {
delay(delaytime);
lc.setRow(0,row,B10100000);
delay(delaytime);
lc.setRow(0,row,(byte)0);
for(int i=0;i<row;i++) {
delay(delaytime);
lc.setRow(0,row,B10100000);
delay(delaytime);
lc.setRow(0,row,(byte)0);
}
}
}
/*
This function lights up a some Leds in a column.
The pattern will be repeated on every column.
The pattern will blink along with the column-number.
column number 4 (index==3) will blink 4 times etc.
*/
void columns() {
for(int col=0;col<8;col++) {
delay(delaytime);
lc.setColumn(0,col,B10100000);
delay(delaytime);
lc.setColumn(0,col,(byte)0);
for(int i=0;i<col;i++) {
delay(delaytime);
lc.setColumn(0,col,B10100000);
delay(delaytime);
lc.setColumn(0,col,(byte)0);
}
}
}
/*
This function will light up every Led on the matrix.
The led will blink along with the row-number.
row number 4 (index==3) will blink 4 times etc.
*/
void single() {
for(int row=0;row<8;row++) {
for(int col=0;col<8;col++) {
delay(delaytime);
lc.setLed(0,row,col,true);
delay(delaytime);
for(int i=0;i<col;i++) {
lc.setLed(0,row,col,false);
delay(delaytime);
lc.setLed(0,row,col,true);
delay(delaytime);
}
}
}
}
void loop() {
writeArduinoOnMatrix();
rows();
columns();
single();
}
But I'm still not sure how to get the info I'm recieving from the converter to send a signal to the LEDs, :-[
The first code you give is for TX, and you want RX (receive).
Please use the code I gave you, just change the baud rate to 57600.
And look at this simplified code of the matrix code: this should blink the (4,4) led.
//We always have to include the library
#include "LedControl.h"
/*
Now we need a LedControl to work with.
***** These pin numbers will probably not work with your hardware *****
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
We have only a single MAX72XX.
*/
LedControl lc=LedControl(12,11,10,1);
/* we always wait a bit between updates of the display */
unsigned long delaytime=100;
void setup() {
/*
The MAX72XX is in power-saving mode on startup,
we have to do a wakeup call
*/
lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);
}
void loop() {
lc.setLed(0,3,3,true);
delay(1000);
lc.setLed(0,3,3,false);
delay(1000);
}
Well, I used your above code, and I do have the LED at 4,4 blinking...and I do have the little onboard RX led giving me an indication that I'm getting something to the board, but the blinking LED doesn't seem to be interacting with the input...it blinks with any or no input. :-?
Wait...I'm sure I'm doing something wrong...are you saying to use your code, and then instead of "digital write" put in this last code? I'm sorry I am so new to this, I just don't know!
Do I just replace the words "digital write" with the whole code? :-? Do I do that for both "digital writes"?
Yeah-I'm sorry, but I'm trying to merge these two pieces of code, and just getting errors because I don't know what I'm doing. 4:30am here, so I'm going to have to sleep and try again tomorrow. Thank you so much for your help in getting me this far! I'm glad to know that I want to do is possible.
//variables setup
byte incomingByte;
int statusLed = 13; // select the pin for the LED
//setup: declaring iputs and outputs and begin serial
void setup() {
pinMode(statusLed,OUTPUT); // declare the LED's pin as output
Serial.begin(57600); //start serial with midi baudrate 57600 or 38400 for debugging
}
void loop () {
if (Serial.available() > 0) {
incomingByte = Serial.read();
if (incomingByte==144){ // 144 is note on ch1
incomingByte = Serial.read();
if (incomingByte==60){ // 60 is middle C
incomingByte = Serial.read();
if(incomingByte>0){ //velocity >0
digitalWrite(statusLed, HIGH);
}else{ //velocity=0
digitalWrite(statusLed, LOW);
}
}
}
}
}
And then...
//We always have to include the library
#include "LedControl.h"
/*
Now we need a LedControl to work with.
***** These pin numbers will probably not work with your hardware *****
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
We have only a single MAX72XX.
*/
LedControl lc=LedControl(12,11,10,1);
/* we always wait a bit between updates of the display */
unsigned long delaytime=100;
void setup() {
/*
The MAX72XX is in power-saving mode on startup,
we have to do a wakeup call
*/
lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);
}
void loop() {
lc.setLed(0,3,3,true);
delay(1000);
lc.setLed(0,3,3,false);
delay(1000);
}
No!
Analyse this code:
This has to be before the setup() :
//We always have to include the library
#include "LedControl.h"
/*
Now we need a LedControl to work with.
***** These pin numbers will probably not work with your hardware *****
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
We have only a single MAX72XX.
*/
LedControl lc=LedControl(12,11,10,1);
/* we always wait a bit between updates of the display */
unsigned long delaytime=100;
This is the setup
void setup() {
/*
The MAX72XX is in power-saving mode on startup,
we have to do a wakeup call
*/
lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);
}
This is the main loop
void loop() {
lc.setLed(0,3,3,true);
delay(1000);
lc.setLed(0,3,3,false);
delay(1000);
}
lc.setLed(0,3,3,true); is led on col 3 row 3 on.
lc.setLed(0,3,3,false); is the same off
So, now if you understand this:
This is before the setup:
//variables setup
byte incomingByte;
int statusLed = 13; // select the pin for the LED
This is the setup:
//setup: declaring iputs and outputs and begin serial
void setup() {
pinMode(statusLed,OUTPUT); // declare the LED's pin as output
Serial.begin(57600); //start serial with midi baudrate 31250 or 38400 for debugging
}
This is the main loop, commented.
void loop () {
if (Serial.available() > 0) { //if serial incoming
incomingByte = Serial.read(); //read it
if (incomingByte==144){ // analyse the first byte (status) : 144 is note on ch1
incomingByte = Serial.read(); //read the next byte
if (incomingByte==60){ // analyse the second byte (note) : 60 is middle C
incomingByte = Serial.read(); //read the next byte
if(incomingByte>0){ //analyse the third byte : velocity >0
digitalWrite(statusLed, HIGH);
}else{ //analyse the third byte : velocity=0
digitalWrite(statusLed, LOW);
}
}
if (incomingByte==61){ // analyse the second byte (note) : 61 is middle C#
incomingByte = Serial.read(); //read the next byte
if(incomingByte>0){ //analyse the third byte : velocity >0
digitalWrite(statusLed, HIGH);
}else{ //analyse the third byte : velocity=0
digitalWrite(statusLed, LOW);
}
}
}
}
}
Merge the two codes :
- before the setup
- the setup
- inside the main loop, digitalWrite(statusLed, HIGH); and digitalWrite(statusLed, LOW); will be basically replaced by lc.setLed(0,col,row,true); or lc.setLed(0,col,row,false);
(Donations welcome! :P)
lol. I'll happily donate to your cause. Got paypal?
Thanks for the clear explanation in the code. I understand much more now. There still seems to be a problem in the lighting of the LED. I'm getting the signal out of ableton and into arduino (the RX led is lighting). Midiox is telling me I'm sending the right information, though it is written in hex on midiox-could that be the problem?
I think most likely, I have just done something stupid and dropped a bit of code somewhere or something. Thank you for your help and patience in working with me! Here is the complete code I'm using now:
//We always have to include the library
#include "LedControl.h"
/*
Now we need a LedControl to work with.
***** These pin numbers will probably not work with your hardware *****
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
We have only a single MAX72XX.
*/
LedControl lc=LedControl(12,11,10,1);
/* we always wait a bit between updates of the display */
unsigned long delaytime=100;
//variables setup
byte incomingByte;
int statusLed = 13; // select the pin for the LED
void setup() {
/*
The MAX72XX is in power-saving mode on startup,
we have to do a wakeup call
*/
lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);
//setup: declaring iputs and outputs and begin serial
pinMode(statusLed,OUTPUT); // declare the LED's pin as output
Serial.begin(57600); //start serial with midi baudrate 31250 or 38400 for debugging
}
void loop () {
if (Serial.available() > 0) { //if serial incoming
incomingByte = Serial.read(); //read it
if (incomingByte==144){ // analyse the first byte (status) : 144 is note on ch1
incomingByte = Serial.read(); //read the next byte
if (incomingByte==60){ // analyse the second byte (note) : 60 is middle C
incomingByte = Serial.read(); //read the next byte
if(incomingByte>0){ //analyse the third byte : velocity >0
lc.setLed(0,3,3,true);
}else{ //analyse the third byte : velocity=0
lc.setLed(0,3,3,true);
}
}
if (incomingByte==61){ // analyse the second byte (note) : 61 is middle C#
incomingByte = Serial.read(); //read the next byte
if(incomingByte>0){ //analyse the third byte : velocity >0
lc.setLed(0,3,3,true);
}else{ //analyse the third byte : velocity=0
lc.setLed(0,3,3,false);
}
}
}
}
}
Cheers!
Joel Laviolette
After reading as much as my eyes will allow today and trying lots of different ideas...I'm pretty sure that the problem is somewhere with the assigning of the pins?
A couple areas of the code, I'm unclear on is this:
int statusLed = 13; // select the pin for the LED
and this:
pinMode(statusLed,OUTPUT); // declare the LED's pin as output
What are these supposed to be doing?
Cheers,
Joel
You can remove those, that was for the onboard 13 pin LED.
Did you test the matrix as is with the example code? (for the connection)
I had a bit of other help and changed
Serial.available() > 0
to
Serial.available() > 3
Now I get the LED to light up.
Now I'm moving on to how to get the LED to respond to the specific velocity signals...
This part here:
a) clip has been triggered but is not yet playing:
message type: NOTE ON
velocity: 126 (LED is BLINKING)
b) clip is playing:
message type: NOTE ON
velocity: 127 (LED is ON)
c) clip is looping:
message type: NOTE ON
velocity: 1 (LED is ON)
d) clip has been stopped:
message type: NOTE OFF
velocity: 0 (LED is OFF)
IMO, for the blinking one you should look into modifying the code in to parts inside the loop:
- The first one listen like now for MIDI IN and puts into variables (one for each led) the status : 0 for off, 1 for on and 2 for blink.
- The second part you check those variables and do it.
For the blink the trick is that you must do a checkpoint (see millis() in reference and forum) and check each time it arrives at this condition (the main loop is very fastly done!) if millis()>checkpoint+500 and change then the led.
Note also that you need to have a variable for global status of the blinking leds (blinking=1 means for exemple all the blinking ones are on).
I hope this is clear, experiment a little the millis() function to understand how it works!
Are you saying to use a switch statement? That's what I'm reading about now...
Ugh,
Going nuts trying to figure out how to make that last LED blink. I have read the above reference, but I don't understand hot to implement it with the matrix. Please help! I have the other three states working correctly (still for this first LED).
I do not understand how to set the blink without Delay using milli since the LED is connected to the max, and not a direct digital pin...
:-[ :o :-/
Here's what I have so far
//We always have to include the library
#include "LedControl.h"
/*
Now we need a LedControl to work with.
***** These pin numbers will probably not work with your hardware *****
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
We have only a single MAX72XX.
*/
LedControl lc=LedControl(12,11,10,1);
//variables setup
byte incomingByte;
unsigned long delaytime = 100;
void setup() {
/*
The MAX72XX is in power-saving mode on startup,
we have to do a wakeup call
*/
lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);
//setup: declaring iputs and outputs and begin serial
Serial.begin(57600); //start serial with midi baudrate 57600
}
void loop () {
if (Serial.available() > 3) { //if serial incoming
incomingByte = Serial.read(); //read it
if (incomingByte==144){} // analyze the first byte (status) : 144 is note on ch1
else {lc.setLed(0,3,3,false);} //if the first byte is not a note on message, LED is off
incomingByte = Serial.read(); //read the next byte
if (incomingByte==60){ // If the byte is note60
incomingByte = Serial.read(); //read the next byte
if(incomingByte==127){ //if velocity is 127 then clip is playing and LED is on
lc.setLed(0,3,3,true);
}else if(incomingByte==1){ //if velocity is 1 then clip is looping and LED is still on
lc.setLed(0,3,3,true);
}else if(incomingByte==126){
lc.setLed(0,3,3,true); //if velocity is 126 then clip is launched but not yet playing LED is blinking...but how???
delay(100);
lc.setLed(0,3,3,false);
delay(100); //this is probably wrong?
}else{ //The LED will shut off if the above paremeters are not met
lc.setLed(0,3,3,false);
} //close else
}
} //close first if
} //close loop
I would do it that way. You have to adapt it for more leds !
//We always have to include the library
#include "LedControl.h"
/*
Now we need a LedControl to work with.
***** These pin numbers will probably not work with your hardware *****
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
We have only a single MAX72XX.
*/
LedControl lc=LedControl(12,11,10,1);
/////////NEW variables
int blinkingledsare=0;
int ledstatus[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ledwas[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lednumber=1;
unsigned long checkpoint;
//variables setup
byte incomingByte;
void setup() {
/*
The MAX72XX is in power-saving mode on startup,
we have to do a wakeup call
*/
lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);
//setup: declaring iputs and outputs and begin serial
Serial.begin(57600); //start serial with midi baudrate 57600
}
void loop () {
//listening loop
if (Serial.available() > 3) { //if serial incoming
incomingByte = Serial.read(); //read it
if (incomingByte==144){} // analyze the first byte (status) : 144 is note on ch1
else {lc.setLed(0,3,3,false);} //if the first byte is not a note on message, LED is off
incomingByte = Serial.read(); //read the next byte
if (incomingByte==60){ // If the byte is note60
incomingByte = Serial.read(); //read the next byte
if(incomingByte==127){ //if velocity is 127 then clip is playing and LED is on
ledstatus[0]=1; //on
}else if(incomingByte==1){ //if velocity is 1 then clip is looping and LED is still on
ledstatus[0]=1; //on
}else if(incomingByte==126){
ledstatus[0]=2; //blink
}else{ //The LED will shut off if the above paremeters are not met
ledstatus[0]=0; //off
} //close else
}
} //close first if incoming
//Let's do it
if(ledstatus[0]!=ledwas[0]){
if(ledstatus[0]==1){lc.setLed(0,3,3,true);} //do on
if(ledstatus[0]==0){lc.setLed(0,3,3,false);}// do off
if(ledstatus[0]==2 && millis()>(checkpoint+500) ){ //change blink status if half second passed since last time
if(blinkingledsare==0){ //if blinking leds were off
lc.setLed(0,3,3,true); //on
blinkingledsare=1; //change status
checkpoint=millis(); //checkpoint
}
if(blinkingledsare==1 && millis()>(checkpoint+500) ){
lc.setLed(0,3,3,false);
blinkingledsare=0;
checkpoint=millis();
}
}
}
//}
} //close loop
(Btw my e-mail is below, but I was just kidding about the title! Here we prefer to help the people learn step by step than doing it for them ;))