Processing > Arduino Serial connection 8x8 matrix

Hi everyone,
I'm trying to make an interface for an 64Led Matrix which reacts to sound in realtime and is controlled by an Arduino duemilanove and 4 TLC5940 drivers.
I want to define and store the different frames with processing and with every beat detection(minim library) send them to the arduino to display them right after receiving.

I tried to store the frames in an Array like this: frames[25][64]
But i think this is way to much data to send within such a short time.
So i tried to store the frames as binary data for each row like {01110111,10001111,10001111,11111111,10001111,10001111,10001111,10001111} but this causes only more problems. How can i access each of the 8 digits separately?

I hope someone understands me :wink:

Thanks
Alec

Sorry for replying but i wasn't allowed to send a link within my first post.

Here is an example of realtime serial communication with an 64led matrix but sadly i dont understand the code files
http://www.bryanchung.net/?p=177

Thanks very much
Alec

You can't drive this matrix in the way you want. A TLC5940 will control 16 individual LEDs but not arranges in a matrix. If you want to use one you will have to multiplex it and you will only need half of one chip. Like in this project:-http://www.thebox.myzen.co.uk/Hardware/Mini_Monome.html

The link shows the LED being controlled by a chip that does the multiplexing for you. It involves talking to the chip, that is probably why you don't understand it.

Thanks for your help.

I've tried to make a new circuit layout based ready for multiplexing.

I did it with eagle pcb but the transistor I want to use was not available. The one i've chosen is this 2N7002 GEG SMD NXP http://www.conrad.de/ce/de/product/151006/TRANSISTOR-2-N-7002-GEG-SMD-NXP (sorry for the german site)

Would this work? Specially the ports connected to the transistors?

Thanks for your help!

Alec

P.s.: now I try to figure out the programming^^

The problem is that the transistor you have chosen is an N channel fet. For this to work you need a P channel FET. The BS250 is a P channel FET and it will just about do although the current limit is small and the on resistance is a bit high, but as long as the LEDs are driven at 20mA or less it should be ok.

Thank you very much! The LEDs are driven at 20mA so this should work. Thanks!

Alec

Just a point on the way you have drawn this.

It does look like the cathode of LED1 feeds into the anode of LED9. Where as the cathodes of LEDs 1, 9, 17, 25, 33, 49 & 57 should all be directly connected to pin 28 of the shift register. I know it is a pain to draw but as long as you know that is how you actually wire it up.

I know it is a pain to draw

Yeah, it's the first thing i've ever drawn.

But thanks for bringing this back to my mind.

Alec

So, I've tried to figure out how this multiplexing thing is working but i think i don't get it.

Normaly the Tlc works like this tlc.set(number_of_led, 4095); but the multiplexing thing seems to need much more parameters: Tlcm.set(ledbuffer, x, y, 4095); I don't get what this ledbuffer is for and how this multiplexing thing should make my serial submission faster.

In my project I don't need to pwm my LEDs. Every LED turned on is 4095 and every LED off is 0. So the only thing i have to submit is the state of each LED(1 or 0). This should be 64bit to submit.

How did I have to design my frames?
This is what they look like at the moment

int[][]frame = { {01110111,10001111,10001111,11111111,10001111,10001111,10001111,10001111},
                    {01010101,10101010,01010101,10101010,01010101,10101010,01010101,10101010}};

But I don't think this is a good way, because I don't know how to access each digit of an integer. Maybe bitshifting?

I hope this was not to confusing and someone could help me.

Thanks.

Alec

Just noticed you are using pins 0 and 1, they are used for serial communications and that will screw you up.

To drive it you make one of your FET connected pins low and all the others high. Then you shift out the bit pattern for that row into the shift register and latch it.
Then when it is time for the refresh, make the low FET pin hing and put the next one low and shift out the pattern for that.
And so on until all the pattern has been output, then you start all over again.

Sorry but I think I don't get it, or maybe this is just a misunderstanding.

I've tested a 4*4 Matrix with a single tlc5940 and the Tlc.set(led_number, 4095); command. This worked fine. After that I wrote a sketch to analyze the LineIn Signal from my computer for beats. With every beat I send a signal to the arduino to display a new frame stored in an array on the arduino. This worked fine as well.
The next challange was to do an frame-editor in processing and send the whole frame instead of just the signal to change. But this caused trouble owed to the serial submission speed.
So my question is, is there any way to send like 64bit in realtime to an arduino. Or is there a way to shrink the 64bit to something smaller? Is the multiplexing thing helping me with this? If yes, how?

Any help would be appreciated!

Alec

Sorry but I think I don't get it,

See how I did it:-
http://www.thebox.myzen.co.uk/Hardware/Econo_Monome.html

is there any way to send like 64bit in realtime to an arduino

Yes you send it one byte at a time down the serial port.

s the multiplexing thing helping me with this?

No multiplexing is of no help to you doing this.

I did some coding and tryed to convert my integer patterns into bytes, submit them and turn each digit into a boolean.
I guess this works fine, but it seems there is still a submission problem.

I wired up a test matrix(4x4) with one tlc5940 and tryed to only affect the LEDs 1-16. But the result is a bit strange: LED 14 and LED 12 are off the whole time and LED 2 is flickering and then of for a litte bit longer(~half a second) the other 13LEDs are always on.

This is my code for the processing interface:

//***********************table_grid.pde***********************************//
//************************************************************************//
//**********************by Mathias Kuse***********************************//
//************************************************************************//
//provides controll interface for DER_TISCH v.7***************************//
//************************************************************************//
//special thanks to: extrapixel (bits2byte) and grumpy_mike(arduino forum)//

import cc.arduino.*;
import processing.serial.*;
import ddf.minim.*;
import ddf.minim.analysis.*;

Serial arduino;
Minim minim;
AudioPlayer song;
BeatDetect beat;
int i=0;


//defines pattern
int b = 0;
int z = 0;
int counter = 0;

color currentcolor;

RectButton field[][], lock, play;

int cols = 8;
int rows = 8;

boolean locked = true;
boolean play_song = false; 
                 
byte[][] byte_pattern = new byte[8][8];
//define patterns
int[][][]  pattern = new int[][][] {{{0,1,1,1,0,1,1,1},{1,0,0,0,1,1,1,1},{1,0,0,0,1,1,1,1},{1,1,1,1,1,1,1,1},{1,0,0,0,1,1,1,1},{1,0,0,0,1,1,1,1},{1,0,0,0,1,1,1,1},{1,0,0,0,1,1,1,1}},
                                    {{0,1,0,1,0,1,0,1},{1,0,1,0,1,0,1,0},{0,1,0,1,0,1,0,1},{1,0,1,0,1,0,1,0},{0,1,0,1,0,1,0,1},{1,0,1,0,1,0,1,0},{0,1,0,1,0,1,0,1},{1,0,1,0,1,0,1,0}},
                                    {{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1}},
                                    {{1,1,1,1,1,1,1,0},{1,1,1,1,1,1,0,1},{1,1,1,1,1,0,1,1},{1,1,1,1,0,1,1,1},{1,1,1,0,1,1,1,1},{1,1,0,1,1,1,1,1},{1,0,1,1,1,1,1,1},{0,1,1,1,1,1,1,1}},
                                    {{0,1,1,1,1,1,1,0},{1,0,1,1,1,1,0,1},{1,1,0,1,1,0,1,1},{1,1,1,0,0,1,1,1},{1,1,1,0,0,1,1,1},{1,1,0,1,1,0,1,1},{1,0,1,1,1,1,0,1},{0,1,1,1,1,1,1,0}},
                                    {{0,1,1,1,1,1,1,0},{1,0,1,1,1,1,0,1},{1,1,0,0,0,0,1,1},{1,1,0,1,1,0,1,1},{1,1,0,1,1,0,1,1},{1,1,0,0,0,0,1,1},{1,0,1,1,1,1,0,1},{0,1,1,1,1,1,1,0}},
                                    {{0,1,1,1,1,1,1,0},{1,0,0,0,0,0,0,1},{1,0,1,1,1,1,0,1},{1,0,1,1,1,1,0,1},{1,0,1,1,1,1,0,1},{1,0,1,1,1,1,0,1},{1,0,0,0,0,0,0,1},{0,1,1,1,1,1,1,0}},
                                    {{0,0,0,0,0,0,0,0},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,0},{0,0,0,0,0,0,0,0}}
                                   };
                    
void setup(){
  //convert all patterns to bytes
  for(int i = 0; i < pattern.length; i++) {
    for(int j = 0; j < 8; j++) {
      byte_pattern[i][j] = bits2byte(pattern[i][j]); 
      } 
  }
  
  //size of the window
  size(640, 800);
  smooth();

  // define and create rectangle buttons
  color buttoncolor = color(80,80,80);
  color highlight = color(255,0,0); 

  field = new RectButton[cols][rows];

  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      // Initialize each object
      field[i][j] = new RectButton(i*80,j*80,80,buttoncolor, highlight);
    }
  }

  //define and create navigate buttons
  lock = new RectButton(0, 680, 50, color(0,100,0), color (0,200,0));
  play = new RectButton(60, 680, 50, color(0,0,100), color (0,000,200));

  //define and initialize Arduino
  //print(Serial.list());
  arduino = new Serial(this, Serial.list()[1], 115200);

  //initialize Minim library
  minim = new Minim(this);

  //load track
  song = minim.loadFile("track.mp3", 2048);

  //initialize beat detection
  beat = new BeatDetect();
  beat.setSensitivity(400);

}

void draw()
{
  background(0);
  stroke(255);
  update(mouseX, mouseY);
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      // display each object
      field[i][j].display();
    }
  }
  lock.display();
  play.display();

  //execute beat detection 
  if(play_song == true) {
    beat.detect(song.mix);
    if (beat.isOnset()) {
      //do this for every 2nd beat
      if (counter < 2) {
        //sending pattern to arduino
        sendPattern(byte_pattern[z]);
        if(z < 7) z++; else z = 0;
        print(byte_pattern[z]);
        counter++;
      }else {
        counter = 0;
      }
    }
  }
}

void sendPattern(byte[] pattern) {
  for(int i = 0; i < 8; i++) {
    arduino.write(pattern[i]);
  }   
}

// turns an int-array into a byte
byte bits2byte(int[]bits) {
 byte returnByte = 0x00; // = 00000000
 byte bitMask = 0x01; // = 00000001

   if (bits.length==8) {
   // loop through the 8 bits
   for (int bitNr=7; bitNr>=0; bitNr--) {

     if (bits[bitNr]==1) {
        returnByte = (byte) (returnByte | bitMask);
     } 
     bitMask = (byte) (bitMask << 1) ;

   } 
 }
 return returnByte;
}

//checks weather a bit "n" from a byte is 1 or 0
boolean is_on(int ledNumber) {
  if ((b & 1 << ledNumber) != 0) return true; else return false;
}

void update(int x, int y)
{
  if(locked == false) {
    for (int i = 0; i < cols; i++) {
      for (int j = 0; j < rows; j++) {
        // update each object
        field[i][j].update();
      }
    }
    lock.update();
    play.update();   
  } 

  if(mousePressed) {
    for (int i = 0; i < cols; i++) {
      for (int j = 0; j < rows; j++) {
        // display each object
        if(field[i][j].pressed()) {
          field[i][j].basecolor= color(255,0,0);
        }
      }
    }

    if(lock.pressed()) {
      if(locked == false) {
        locked = true;
        print (locked);
      }
      else {
        locked = false;
        print(locked);
      }
    }

    if(play.pressed()) {
      play.basecolor=color(0,0,255);
      song.play();
      play_song = true;
    }
  }

}

//Button class
class Button
{
  int x, y;
  int size;
  color basecolor, highlightcolor;
  color currentcolor;
  boolean over = false;
  boolean pressed = false;   

  void update() 
  {
    if(over()) {
      currentcolor = highlightcolor;
    } 
    else {
      currentcolor = basecolor;
    }
  }

  boolean pressed() 
  {
    if(over) {
      locked = true;
      return true;
    } 
    else {
      locked = false;
      return false;
    }    
  }

  boolean over() 
  { 
    return true; 
  }

  boolean overRect(int x, int y, int width, int height) 
  {
    if (mouseX >= x && mouseX <= x+width && 
      mouseY >= y && mouseY <= y+height) {
      return true;
    } 
    else {
      return false;
    }
  }
}

//RectButton class
class RectButton extends Button
{
  RectButton(int ix, int iy, int isize, color icolor, color ihighlight) 
  {
    x = ix;
    y = iy;
    size = isize;
    basecolor = icolor;
    highlightcolor = ihighlight;
    currentcolor = basecolor;
  }

  boolean over() 
  {
    if( overRect(x, y, size, size) ) {
      over = true;
      return true;
    } 
    else {
      over = false;
      return false;
    }
  }

  void display() 
  {
    stroke(255);
    fill(currentcolor);
    rect(x, y, size, size);
  }
}

and this is the arduino code:

#include "tlc_config.h"
#include "Tlc5940.h"

byte input[8];

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

void loop() {
 if(Serial.available() > 0) {
   for(int row = 0; row <8; row++) {
     input[row] = Serial.read();
   }
   draw_matrix(input);
 } 
}

//checks weather a bit "n" from a byte is 1 or 0
boolean is_on(byte b, int ledNumber) {
  if ((b & 1 << ledNumber) != 0) return true; else return false;
}

void draw_matrix(byte row[]) {
  //each row of the matrix 
  for(int i = 0; i < 8; i++) {
     for(int a = 0; a < 8; a++) {
      int led_num = (i+1)*a;
      if (is_on(row[i], a) && (led_num < 16)) Tlc.set(led_num, 4095); else Tlc.set(led_num, 0);
     }
   }
   Tlc.update();
}

I hope this is not to much code.

Thanks
Alec

Just looking at the arduino code, the only time you do the multiplexing is when you receive data. You need to constantly refresh the display and then when you have new data change the memory that you are using to refresh your display. But you keep on going with the refresh.