Pages: [1]   Go Down
Author Topic: Problem with midi callbacks and large 3D matrix  (Read 5295 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I bought the square led pixels from adafruit, this led's are all adressable and they are very simple to control.
We use this leds in a big 3*3*3mts cube, so to make the functions easier we make a virtual matrix.
What we try to do is to control the functions that we create with Ableton MIDI signals.
I'm using the hairless midi-serial program to do the midi-serial job. This works well.
The problem is that when I include the matrix thing in the midi reactive code the hole thing stops working.
But that's not all, the worst thing is that when I shrink the matrix the problem get's solved, but that's not an option because we need the whole matrix to be working.
This is the code:
Quote
#include "SPI.h"
#include "Adafruit_WS2801.h"
#include <stdio.h>
#include "MIDI.h"

int dataPin  = 2;    // Yellow wire on Adafruit Pixels
int clockPin = 3;    // Green wire on Adafruit Pixels
//int cubo[5][5][5]= {0};
int cubo[4][4][4] = {};


Adafruit_WS2801 strip = Adafruit_WS2801(325, dataPin, clockPin);
//const int ledPin =  13;

void setup() {
 
 /*
    int i, j, k;

    for (i=0; i<3; i++)
            for (j=0; j<3; j++)
                    for (k=0; k<3; k++)
                      cubo[j][k] =0;
                           //printf("%i %i %i: %i\n", i, j, k, cubo[j][k]);
                   
  */
 
  llenarCubo();
  MIDI.begin(MIDI_CHANNEL_OMNI);
  Serial.begin(9600);
  MIDI.setHandleNoteOn(HandleNoteOn);  // Put only the name of the function
  MIDI.setHandleNoteOff(HandleNoteOff);
  strip.begin();
  // Update LED contents, to start they are all 'off'
  strip.show();
  //pinMode(ledPin, OUTPUT);
   

}


void loop() {
  midi.poll();
  //MIDI.read();

  //void HandleNoteOn(byte channel, byte pitch, byte velocity);
  //void HandleNoteOff(byte channel, byte pitch, byte velocity);

   }
   
   void HandleNoteOff(byte channel, byte pitch, byte velocity) { 
     if (velocity == 64){
       for (int i=0; i < strip.numPixels(); i++) {
       strip.setPixelColor(i, 0,0,0);
       }
     strip.show();
     }
   
   }

  void HandleNoteOn(byte channel, byte pitch, byte velocity) {
    if (pitch == 64) {
      //fAbajoArriba();
             for (int i=0; i < strip.numPixels(); i++) {
       strip.setPixelColor(i, 255,0,0);
       }
     strip.show();

     }
   
   
    if (pitch == 60) {
      //fArribaAbajo();
                  for (int i=0; i < strip.numPixels(); i++) {
       strip.setPixelColor(i, 0,255,0);
       }
     strip.show();

     }
   
    if (pitch == 62) {
      //fArribaAbajo2();
                  for (int i=0; i < strip.numPixels(); i++) {
       strip.setPixelColor(i, 255,0,0);
       }
     strip.show();

     }
   
   
  // Try to keep your callbacks short (no delays ect) as the contrary would slow down the loop()
  // and have a bad impact on real-time performance.
   



//fArribaAbajo2();
}
/**************************************** OTRAS *****************************************/
//
//void fAbajoArriba(){
//  int a = random(0,13);
//  int f = random(0,5);
//  int ff = random(0,5);
//  int g = random(0,256);
//  for(int altura=0; altura<=a; altura++){
//    strip.setPixelColor(cubos[altura][f][ff], Color(255,g,0));     
//    strip.show();
//    strip.setPixelColor(cubos[altura][f][ff], negro());
//  }   
//}
//
//void fArribaAbajo(){
// 
//  int a = random(0,13);
//  int f = random(0,5);
//  int ff = random(0,5);
//  int g = random(0,256);
// 
//  for(int altura=a; altura>=0; altura--){
//    strip.setPixelColor(cubos[altura][f][ff], Color(255,g,0));     
//    strip.show();
//    strip.setPixelColor(cubos[altura][f][ff], negro());
//   
//  }   
//}
//
//void fArribaAbajo2(){
// 
//  int a = random(0,13);
//  int f = random(0,5);
//  int ff = random(0,5);
//  int g = random(0,256);
// 
//  for(int altura=12; altura>=a; altura--){
//    strip.setPixelColor(cubos[altura][f][ff], Color(g,g,0));     
//    strip.show();
//    strip.setPixelColor(cubos[altura][f][ff], negro());
//   
//  }   
//}
//
//
//void fIzquierdaDerecha(){
// 
//  int a = random(0,13);
//  int f = random(0,5);
//  int ff = random(0,5);
//  int g = random(0,256);
// 
//  for(int filas=f; filas>=0; filas--){
//    strip.setPixelColor(cubos[a][filas][ff], Color(255,g,0));     
//    strip.show();
//    strip.setPixelColor(cubos[a][filas][ff], negro());
//   
//  }   
//}
//
//void fDerechaIzquierda(){
// 
//  int a = random(0,13);
//  int f = random(0,5);
//  int ff = random(0,5);
//  int g = random(0,256);
// 
//  for(int filas=0; filas<=f; filas++){
//    strip.setPixelColor(cubos[a][filas][ff], Color(255,g,0));     
//    strip.show();
//    strip.setPixelColor(cubos[a][filas][ff], negro());
//   
//  }   
//}

/************************ AUXILIARES ****************************/
//
//void tintinear(int a,int b,int c){
//  for(int j=0; j<3; j=j++){
//    fadeIn(a,b,c);
//    fadeOut(a,b,c);
//    strip.setPixelColor(cubos[a][c], negro());
//  }
//}
//
//void fadeIn(int a,int b,int c){
//  for(int i=0; i<200; i=i+30){
//    strip.setPixelColor(cubos[a][c], blanco(i));
//    strip.show();
//  } 
//}
//
//void fadeOut(int a,int b,int c){
//  for(int i=200; i>=0; i=i-30){
//    strip.setPixelColor(cubos[a][c], blanco(i));
//    strip.show();
//  } 
//}
//
//void apagarcubos(){
//  cubosBlanco(0);
//}
//
//void cubosBlanco(int a){
//  for (int i=0; i < strip.numPixels(); i++) {
//     strip.setPixelColor(i, blanco(a));
//  }
//  strip.show();
//}
//
boolean esPar(int numero){
  return numero%2==0;
}
//
//uint32_t blanco(int intensidad){
//  return Color(intensidad,intensidad,intensidad);
//}
//
//uint32_t negro(){
//  return Color(0,0,0);
//}
//

/*
 * Crea un cubos de 13x5x5 (leds)
 * y relaciona a cada posicion, el led
 * de la tira que le corresponde.
 *
 */
void llenarCubo(){
  int c = 0;             // c es el numero de led
 
  for(int k=0; k<4; k++){    //k es profundidad
      for(int j=0; j<4; j++){
          for(int i=0; i<4; i++){
            cubo[k][j] = 0;
            c++;
           }
         }
}
}

//

Here is the problem:
this way work's well ---------int cubo[4][4][4] = {};
this way doesn't work ----------------int cubo[5][5][5]= {};

It appears to be that the program can't support a more than 4*4*4 matrix. But we work with a 13*5*5 matrix when creating the functions and
it was working fine. Please help we try with all as you can see in the code.
Thanks

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not to be too quick to diagnose it, but it seems likely your symptoms are consistent with running out of RAM.  Arduinos are sometimes very quiet when this happens.  It looks like you have 325 LEDs in your cube, so at least 975 bytes of RAM for the Adafruit library.  Add in your 5*5*5 matrix, serial buffering, Arduino overhead, and some variables and somehow you are over 2048 bytes (the limit on variants using a '328 like the Uno).  Should be testable, at least when it runs on the smaller cube sizes.

Check the RAM remaining:  http://playground.arduino.cc/Code/AvailableMemory  I use the last method because it's small and clean.

Digression:  There is a point on all RGB matrix projects where you either have to get clever or move to a board with more RAM (Teensy++ or Maple board I've used).  You could also buy a MEGA--it's usually overkill and a little expensive, but it is readily available.  Some recent arduino variants have 2.5K instead of 2K, which might just get you there.  Perhaps someone has something you can try?

If you cannot spend another dime and the RAM limit is close, you can tweak it by trying some of these (somewhat generic) ideas:

- Use symmetry so the same RAM is used to keep track of two or more lights' values.  

- Use constants throughout the program (like on the datapin/clockpin inits --they are not going to change) to save a few bytes.  

- You don't need the crazy-huge MIDI library.  It's serial at 31250 baud.  It's 30 years old!  The MIDI library eats some RAM (so will the plain serial, to buffer, but less I do imagine).  Set up serial, then instead of MIDI.read(); go check the buffer.  Lean code to process the limited MIDI you are sending is out there (everything pre-MIDI library, also check out http://www.instructables.com/id/Send-and-Receive-MIDI-with-Arduino/).  

I am sure there is an adjacent forum with comprehensive RAM saving suggestions.  

I am sorry to not be specific to the code, but I have run into this problem time after time and hope it is a quick and painless fix for you.
« Last Edit: December 21, 2012, 11:36:57 pm by dehack » Logged

Pages: [1]   Go Up
Jump to: