MAX7219, Arduino y Pure data

Hola, soy nuevo por aquí, espero haber colocado el mensaje en el sitio correcto.

Estoy intentando controlar una matriz de leds de 8x8, concetada a un MAX7219+Arduino a través de Pure data. Con Pduino y firmata no puedo hacerlo, al menos no se como o si se podría hacer.

Yo no tengo mucha idea de Arduino, así que he buscado ejemplos que usan exactamente la misma matriz+integrado, hay muchos y funcionan, pero en ninguno he podido ver como enviar datos desde Pure data a esta.

De momento, mezclando códigos de otros, solo he conseguido esto, que si funciona:

#include "LedControl.h" //  need the library
LedControl lc=LedControl(12,11,10,1); // 

// pin 12 is connected to the MAX7219 pin 1
// pin 11 is connected to the CLK pin 13
// pin 10 is connected to LOAD pin 12
// 1 as we are only using 1 MAX7219

void setup()
{
  // the zero refers to the MAX7219 number, it is zero for 1 chip
  lc.shutdown(0,false);// turn off power saving, enables display
  lc.setIntensity(0,1);// sets brightness (0~15 possible values)
  lc.clearDisplay(0);// clear screen
  Serial.begin(9600);
}

void loop()
{
  while(Serial.available()){
    byte LedState = Serial.read() - '0';
      if(LedState==1) lc.setLed(0,0,0,true);
      if(LedState==2) lc.setLed(0,0,0,false);
  }
}

Si envío el mensaje “[print 1(” desde Pure data, enciendo el led de la fila 0, columna 0.
Si envío el mensaje “[print 2(” desde Pure data, apago el mismo led.

Aclaro que, esta forma “[mensaje(”, la pongo para representar la forma física que tienen las cajas de mensajes en Pure data.

El problema de este método (y ahora me refiero al código) es que aparte de no ser muy elegante, me hace repetir esas dos filas 63 veces más para cubrir todos los leds. A las malas lo usaré, pero estoy buscando otra cosa mejor.

Entonces, un amigo al que pedí ayuda y que ha tenido que sufrir ms preguntas, me pasó el siguiente código, que en teoría, si funcionase, simplificaría mucho las cosas, solo que no funciona y no sabemos porqué.

#include "LedControl.h" //  need the library
LedControl lc=LedControl(12,11,10,1); // 

// pin 12 is connected to the MAX7219 pin 1
// pin 11 is connected to the CLK pin 13
// pin 10 is connected to LOAD pin 12
// 1 as we are only using 1 MAX7219

void setup()
{
  // the zero refers to the MAX7219 number, it is zero for 1 chip
  lc.shutdown(0,false);// turn off power saving, enables display
  lc.setIntensity(0,1);// sets brightness (0~15 possible values)
  lc.clearDisplay(0);// clear screen
  Serial.begin(9600);
}

void loop()
{
  static int temp, col, row, state;
  while(Serial.available()){
    byte inByte = Serial.read();
    if((inByte >= '0') && (inByte <= '9'))
      temp = 10 * temp + inByte -'0';
    else{
      if(inByte == 'c') col = temp;
      else if(inByte == 'r') row = temp;
      else if(inByte == 's') state = temp;
    }
    if(state == 1) lc.setLed(0, col, row, true); // if state is 1 turn LED on
    else lc.setLed(0, col, row, false); // if state is 0 turn LED off
  }
}

En este caso, mando los mensajes de la siguiente forma; “[print 1c1r1s(” y puedo ver que llega al arduino, porque se enciende el led RX, pero nada, no funciona.

¿Tenéis alguna idea de porque puede estar fallando?

Bueno, muchas gracias y espero haberme expresado con claridad.

Saludos!

El unico error que veo es que en cada loop de la lectura de los datos serie temp nunca se inicializa. De hecho no veo si lo inicializas en algun momento. Para colmo lo defines como static no se para que? Veamos ahora

#include "LedControl.h" //  need the library
LedControl lc=LedControl(12,11,10,1); // 

// pin 12 is connected to the MAX7219 pin 1
// pin 11 is connected to the CLK pin 13
// pin 10 is connected to LOAD pin 12
// 1 as we are only using 1 MAX7219
unsigned int temp = 0;
unsigned int col, row, state;

void setup()
{
  // the zero refers to the MAX7219 number, it is zero for 1 chip
  lc.shutdown(0,false);// turn off power saving, enables display
  lc.setIntensity(0,1);// sets brightness (0~15 possible values)
  lc.clearDisplay(0);// clear screen
  Serial.begin(9600);
}

void loop() {

  while(Serial.available()) {
    byte inByte = Serial.read();

    switch (inByte) {
      case '0'...'9':
          temp = 10 * temp + inByte -'0';
          break;
      case 'c':
          col = temp;
          temp = 0;
          break;
      case 'r':
          row = temp;
          temp = 0;
          break;
      case 's': 
          state = temp;
          temp = 0;
          break;
        default: 
                temp = 0;
                break;
    }

    if(state == 1) 
      lc.setLed(0, col, row, true); // if state is 1 turn LED on
    else 
      lc.setLed(0, col, row, false); // if state is 0 turn LED off
  }
}

Muchas gracias por ayudarme surbyte, te lo agradezco. :)

Tu código si me funciona, pero solo si enciendo y apago el led antes de encender otro. Si lo dejo encendido y envío otro mensaje desde Pure Data para encender otro led distinto, enciende dos leds de una tacada. Para ser más específico, si por ejemplo enciendo el led de la columna-2/fila-5 y luego enciendo el led de la columna-1/fila-1, además de encenderse dicho led lo hace también el de la columna-1/fila-5. Es decir, que siempre recuerda la última fila y la repite además de la nueva que introduzca. Esto contando que las filas-columnas van de 0 a 7, no de 1 a 8, es decir que si envío el mensaje desde pd [print 0c0r1s( enciendo el led de la primera columna/fila.

¿Alguna idea? Muchas gracias.

Creo que, si no me equivoco, ya lo tengo. El código de surbyte está bien. Al enviar los mensajes desde Pure data de la siguiente forma: [print 0c0r1s( , Arduino recibe primero el valor de la columna, después la fila y por último el estado de encendido/apagado del led. Por ello al enviar de nuevo otro mensaje, lee de nuevo en primer lugar el número (de entre 0 y 7) asignado a la columna. Al tener los otros dos valores (fila y estado) del mensaje anterior, enciende de la nueva columna el led de la fila anterior y el de la nueva. La solución es simple, desde Pure data envío un mesaje más largo, que asigna valores inservibles a col y row después de recibir los útiles. Es decir, si antes un mensaje era así: [print 0c0r1s( , ahora sería de esta otra forma: [print 0c0r1s8c8r(

Al menos a mi me funciona. Supongo que subiré el .ino + patch.pd al foro de Pure data, dejando crédito a los que me han ayudado, que prácticamente lo han hecho todo.

Bueno, nada más, muchas gracias por la ayuda!

Yo corregí lo que tu enviaste, para que pudiera encender el los leds. En realidad el único que te genera problemas es temp pensando en esta instrucción

temp = 10 * temp + inByte -'0';

En la situación de recibir entre '0' y '9' no borro temp, pero yo no lo hice porque tu no lo hacias en tu código. Pensando que pudiera ser que actuaras sobre la fila 12 columan 34, yo no se que cosas tienes cableadas. Si no vas a actuar mas que en 0 a 9, entonces al terminar pones temp = 0; Asi

case '0'...'9':
          temp = 10 * temp + inByte -'0';
                temp = 0;
          break;

o mas simple, antes de leer inByte borras temp y ya esta.

Tengo dos matrices, aunque solo había probado con una. Pensaba cambiar algunas cosas del código, aunque ya te digo que soy más que novato, solo llevo unos días probando con Arduino y tampoco soy muy hábil. Por eso, a veces no tengo del todo o más bien nada claro si estoy haciendo las cosas bien. :) Por ejemplo, pensaba adaptar ese código con el que me ayudaste, para usarlo con las dos matrices más adelante y pensaba que sería más sencillo. Por ejemplo, cambiando esta linea del inicio:

LedControl lc=LedControl(12,11,10,1);

por esta otra:

LedControl lc=LedControl(12,11,10,2);

Y después pensaba (lo he malentendido buscando info por ahí), que cambiando esta otra linea era suficiente para asignar a que matriz van los datos:

lc.setLed(0, col, row, true);

Es decir "0" para la primera matriz, "1" para la segunda, etc... y cambiarlo después por algo tipo esto:

lc.setLed(mat, col, row, true);

Por cierto, algo que no se si se puede cambiar, porque no lo he encontrado. He leido que ese primer valor que he cambiado por "mat" es "address" y he probado varios números, sin resultado.

Pero ahora lo he probado uniendo dos matrizes y no funciona, al menos a mi no.

Siento liarla y no ser muy claro, pero es que de momento no me entero mucho.

Por cierto, ahora no he puesto los códigos entre codes como dicen las normas del foro, porque me salían unos espacios enormes, no se porqué.

De nuevo, muchas gracias surbyte por echarme un cable.

Estoy intentando controlar una matriz de leds de 8x8, concetada a un MAX7219+Arduino a través de Pure data

Bueno, como siempre ocurre se viene por un problema puntual pero no se expresa la idea global que veo recién comienzas a esbozar. Esto no es un reclamo pero hubiera ayudado que lo cuentes en el arranque para que al tomar parte de nuestros tiempos en tu código lo hagamos con mentalidad de lo que se viene. De todas formas el criterio siempre es solucionar uno y luego ampliarlo a mas.

Comienza diciendo cuantos matrices led vas a usar, como para ver que intentas hacer porque tu forma de enviar datos me parece compleja para alimentar muchos leds y en la medida que éstos crezcan en cantidad será mas dificil decir que debe encenderse y que no.

Disculpa mi falta de claridad, entiendo lo que dices.

Mi confusión ha llegado por mezclar intereses. Cuando comencé solo tenía la idea de usar una matriz de leds, que para mis necesidades es suficiente. Por ello el primer código era así. Después es cuando he liado el proyecto, pensando como variar el código, para que modificando pocas cosas, pueda ser elegido el número de matrices según las necesidades de cada uno. En este sentido, estaba pensando más en dejarlo listo para que no solo lo pueda usar yo, sino otros con intenciones de usar mas de 64 leds.

En realidad mi primera pretensión ya está cubierta y con eso ya te estoy agradecido.

Lo que de todas formas he probado y no me funciona es esto:

case '0'...'9':
          temp = 10 * temp + inByte -'0';
                temp = 0;
          break;

Tampoco borrar temp antes de leer inByte, que supongo que será poniendolo a cero,¿O me equivoco?

Ahora estoy probando como hacer funcionar dos matrices a la vez, es decir 128 leds.

Mi último mensaje no ha sido muy claro y parece que vuelvo a preguntar, pero mi intención en realidad es agradecerte la ayuda y explicar un poco (aunque no he sido muy hábil :) ) el porqué de mis líos, asumiendo que con la información que me has dado y lo que aprenda de Arduino mirando otros ejemplos ya me buscaré la vida.

Lo dicho, muchas gracias surbyte.

Si te dije eso pues no puedes usarlo. Si asignas algo a temp y luego lo borras no tiene sentido. Me equivoqué porque creo haberte sugerido eso.

retira temp = 0;

Eso es lo que te sugerí, borrar temp antes de leer inByte. Ya no lo recordaba

Por nada, hoy hay un buen grupo de gente que damos buenos consejos creo yo. De todos soy el mas gruñón por mis años con las normas y los tags y todo eso pero me da gusto que la gente progrese. Ya hay algunos que ahora pueden aconsejar.. y eso es progreso.