Go Down

Topic: LED matrix (Read 5798 times) previous topic - next topic

Tatjana

Hi!
I would like to control individually 36 LEDs in 6x6 matrix by an OpenGL programme well known as PPM reader. Do you have any suggestion on how to connect C code withe LEDs most efficiently in Arduino environment? I guess serial with multplexer would be a solution, but that's where my knowlegde ends so far...
Thank you in advance.
Best regards,
Tatjana

admin

Hello

There are multiple ways.... (as usual)


There are these chips from Maxim called MAX7219 that can drive up to 8x8 leds matrices. They are very simple to wire up, you just need a resistor and a capacitor. in the arduino distribution there should be some code called MAX7219 (written by Nick Zambetti) that shows how to send data to these guys.

you can find a schematic here in the datasheet http://pdfserv.maxim-ic.com/en/ds/MAX7219-MAX7221.pdf

this can drive even fairly bright LEDs.

I'll attach the code here.
Code: [Select]



// define arduino pins

byte pin_max7219_dataIn =  2;
byte pin_max7219_clock  =  3;
byte pin_max7219_load   =  4;


// specify wiring pin i/o directions
void setPinModes()
{
 pinMode(pin_max7219_dataIn, OUTPUT);
 pinMode(pin_max7219_clock,  OUTPUT);
 pinMode(pin_max7219_load,   OUTPUT);
}

// define max7219 registers
byte max7219_reg_noop        = 0x00;
byte max7219_reg_digit0      = 0x01;
byte max7219_reg_digit1      = 0x02;
byte max7219_reg_digit2      = 0x03;
byte max7219_reg_digit3      = 0x04;
byte max7219_reg_digit4      = 0x05;
byte max7219_reg_digit5      = 0x06;
byte max7219_reg_digit6      = 0x07;
byte max7219_reg_digit7      = 0x08;
byte max7219_reg_decodeMode  = 0x09;
byte max7219_reg_intensity   = 0x0a;
byte max7219_reg_scanLimit   = 0x0b;
byte max7219_reg_shutdown    = 0x0c;
byte max7219_reg_displayTest = 0x0f;

// define max7219 as rows and cols (for nexus 8x8 displays)
byte max7219_row0 = 0x01;
byte max7219_row1 = 0x02;
byte max7219_row2 = 0x03;
byte max7219_row3 = 0x04;
byte max7219_row4 = 0x05;
byte max7219_row5 = 0x06;
byte max7219_row6 = 0x07;
byte max7219_row7 = 0x08;
byte max7219_col0 = 0x01;
byte max7219_col1 = 0x02;
byte max7219_col2 = 0x04;
byte max7219_col3 = 0x08;
byte max7219_col4 = 0x10;
byte max7219_col5 = 0x20;
byte max7219_col6 = 0x40;
byte max7219_col7 = 0x80;

// function to control max7219 data line
void max7219_setData(boolean value)
{
 digitalWrite(pin_max7219_dataIn, value);
}

// function to control max7219 clock line
void max7219_setClock(boolean value)
{
 digitalWrite(pin_max7219_clock, value);
}

// function to control max7219 load line
void max7219_setLoad(boolean value)
{
 digitalWrite(pin_max7219_load, value);
}

// function that puts a byte of data to the max7219
void max7219_putByte(byte data)
{
 byte i = 8;
 byte mask;
 while(i > 0) {
   mask = 0x01 << (i - 1);  // get bitmask
   max7219_setClock(LOW);   // tick
   if (data & mask){        // choose bit
     max7219_setData(HIGH); // send 1
   }
   else{
     max7219_setData(LOW);  // send 0
   }
   max7219_setClock(HIGH);  // tock
   --i;                     // move to lesser bit
 }
}

// function that puts a byte of data into a max7219 register
void max7219_put(byte reg, byte data)
{
 max7219_setLoad(LOW); // begin
 max7219_putByte(reg);  // specify register
 max7219_putByte(data); // put data
 max7219_setLoad(LOW);  // latch in data
 max7219_setLoad(HIGH); // end
 max7219_setClock(LOW);   // tick
}

// function that sets brightness of the max7219
void max7219_setIntensity(byte intensity)
{
 // range: 0x00 to 0x0f
 max7219_put(max7219_reg_intensity, intensity & 0x0f);
}

// function that sets the same value for all registers of the max7219
void max7219_all(byte value){
 max7219_put(0x01, value);
 max7219_put(0x02, value);
 max7219_put(0x03, value);
 max7219_put(0x04, value);
 max7219_put(0x05, value);
 max7219_put(0x06, value);
 max7219_put(0x07, value);
 max7219_put(0x08, value);
}

// function that initializes the max7219 to use a matrix of leds
void max7219_init()
{
 max7219_put(max7219_reg_scanLimit, 0x04);   // use 5 columns
 max7219_put(max7219_reg_decodeMode, 0x00);  // using an led matrix (not digits)
 max7219_put(max7219_reg_shutdown, 0x01);    // not in shutdown mode
 max7219_put(max7219_reg_displayTest, 0x00); // no display test
 max7219_all(0x00);                          // empty registers
 max7219_setIntensity(0x08);                 // set initial brightness to dim
}

// program initialization routine
void setup()
{
 beginSerial(9600);
 setPinModes();
 max7219_init();

}

// program loop
void loop()
{
 //printString("blank\n");
 max7219_all(0x00);
 delay(500);
 // draw diagonal line
 //printString("diagonal");
 max7219_put(max7219_row0, 0x0f);
 max7219_put(max7219_row1, 0x0e);
 max7219_put(max7219_row2, 0x08);
 max7219_put(max7219_row3, 0x03);
 max7219_put(max7219_row4, 0x1e);
 max7219_put(max7219_row5, 0x0e);
 max7219_put(max7219_row6, 0x0e);
 max7219_put(max7219_row7, 0x0e);
 delay(500);
}




If you have more questions just ask

massimo

Tatjana

Hi Massimo,
Thank you very much!
I need some time now to figure things out...
All best,
Tatjana

Tatjana

Hello!
I am quite new in the physical computing world and I need your help.
I want to upgrade my 6x6 LED matrix to 6x6x6 cube that works as 2D display with "extruded" z direction (basically it's like a chess board, where each field (e.g. A2 or B5) is in parallel with 5 more diods that turn on and off as the first one controlled by an OpenGL-Arduino code.
The matrix is controlled by an OpenGL program, which proceeds images taken from the camera and notices changes for 6x6 fields. Since the extreme case could require turning on all the LEDs, I have to count on much stronger current...
So, I'm thinking of having established serial communication in between OpenGL code and microchip on the Arduino board. OpenGL code should send array of data  to 12 pins (6 for rows A to F, 6 for coloumns 1-6). An OpenGl code proceeds image taken from the camera  and for example if something happens on the field A5, the pins set to A and to 5 should be high...only in case if the two pins controling the exact row and exact column are set to high should turn the LED high (e.g. digital.Write(pinA, HIGH); digital.Write(pin5, HIGH); )
I'm thinking to use power transistor Darlingtons for this purpose. However, I set the codes in C and Arduino for test communication ( and printing for debugging), but there is probably something that I'm missing... I don't know how to send the data from computer to Arduino chip to clearly know what to do...this far I came on my own...
I would appreciate if you take a look at this codes and give some advice how to solve this...
Thank you very much,
Tatjana
...
//C code sends data from the computer
/* Standard input/output definitions */
#include <stdio.h>  
/* String function definitions */
#include <string.h>  
/* UNIX standard function definitions */
#include <unistd.h>  
/* File control definitions */
#include <fcntl.h>  
/* Error number definitions */
#include <errno.h>  
/* POSIX terminal control definitions */
#include <termios.h>


#define BAUDRATE B9600
#define MODEMDEVICE "/dev/ttyUSB0"
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define FALSE 0
#define TRUE 1

int fd;
int n;

//FILE *input;
int output;
char readBuf[255];  //buffer for where data is put

int main(void)
{

     //init serial stuff

     struct termios oldtio, newtio;
       
     /* open the device to be non-blocking (read will return immediatly) */
     fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY);
     
     if (fd <0) {
        perror(MODEMDEVICE);
        return(-1);
          }  
 
     tcgetattr(fd,&oldtio); /* save current port settings */
     /* set new port settings for canonical input processing */
     newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
     newtio.c_iflag = IGNPAR | ICRNL;
     newtio.c_oflag = 0;
     newtio.c_lflag = ICANON;
     newtio.c_cc[VMIN]=1;
     newtio.c_cc[VTIME]=0;
     tcflush(fd, TCIFLUSH);
     tcsetattr(fd,TCSANOW,&newtio);
       


     //fd_set input;
       fd_set output;
     struct timeval timeout;
     int res;
     int paramValue;

     FD_ZERO(&output);
     FD_SET(fd, &output);
     timeout.tv_sec = 0;
     timeout.tv_usec = 0;
       
     while(write(fd+1, &output,&timeout)) {
       res = write(fd, readBuf, 1);
       }
               
     FD_ZERO(&output);
               
     FD_SET(fd, &output);
     timeout.tv_sec = 0;
     timeout.tv_usec = 0;
}

....

// On Arduino

int ledPin = 13; //select the pin for LED

int val;

int serialGet = 0; //variable to store the value coming from the serial port

int delaytime = 1; //delaytime for the main loop





void setup() {

 pinMode(ledPin, OUTPUT); //declared LED as output

 beginSerial(9600);

 }

 

void loop() {

// if (Serial.available() > 0)

 serialGet = serialRead(); //read the serial port

 if (serialGet != -1) { //if the input is -1, then there is no data

   val = serialGet;     //otherwise store it

   }

 if (val == 'H') {

   digitalWrite(ledPin, HIGH);

   Serial.print("I received: ");

   Serial.println(val);

   } else if(val == 'L') {

     digitalWrite(ledPin, LOW);

     Serial.print("I received: ");

     Serial.println(val);

     }

     delay(delaytime);

}

David Cuartielles

Hej,

I might be wrong, because I don't code C from the computer to perform this type of task but ... your C program is not handling the event of receiving data from the port, and therefore it is impossible for you to capture the data that Arduino sends.

The Arduino program looks ok, it is a "relay server" that sends back whatever it gets at the input. It is the program for the computer that is not finished.

/David

Tatjana

Hej David,

Thanx! You're right...I fixed it...now I have the chip and the C code communicating very well...when I finish the project, I'll post sample codes for beginners like me...:)
All best,
Tatjana


trialex

#6
Sep 12, 2006, 12:25 am Last Edit: Sep 12, 2006, 12:50 am by trialex Reason: 1
Thanks for your info and especially code for using the 7219 LED driver.

Found a bit more info to help those like me having trouble connecting the 7219 to an LED matrix

MAX7219 --> LED Connections:
'
' MAX7219.2 (0) --> Col 1 (left)
' MAX7219.11 (1) --> Col 2
' MAX7219.6 (2) --> Col 3
' MAX7219.7 (3) --> Col 4
' MAX7219.3 (4) --> Col 5
' MAX7219.10 (5) --> Col 6
' MAX7219.5 (6) --> Col 7
' MAX7219.8 (7) --> Col 8

' MAX7219.17 (g) --> Row 1 (top)
' MAX7219.15 (f) --> Row 2
' MAX7219.21 (e) --> Row 3
' MAX7219.23 (d) --> Row 4
' MAX7219.20 (c) --> Row 5
' MAX7219.16 (b) --> Row 6
' MAX7219.14 (a) --> Row 7
' MAX7219.22 (DP) --> Row 8

' MAX7219.18 (I_set) --> 10K resistor --> +5V

' MAX7219.4 (GND) --> GND
' MAX7219.9 (GND) --> GND
' MAX7219.19 (V+) --> +5V

' MAX7219.13 (CLK) --> Arduino (pin 3 in example code)
' MAX7219.12 (LOAD) --> Arduino (pin 4 in example code) and in parallel 10K resistor to GND
' MAX7219.1 (DIN) --> Arduino (pin 2 in example code)

Please let me know if I've got something wrong! I'm not sure if pin 22 should go to the first or last row... guess I'll find out when i power it up.


thanks,

alex


kuuk

hi,

i wonder if it's possible to use TWO max7219 to control a matrix of 64 BI-color leds.

the bicolor leds share the same anode and have different cathodes.
my first thought was to control red with one max7219 and green with the other.

a different approach would be to to have each max7219 control a matrix of 4x8 bicolor leds.

has anyone tried something like this? or do you know of a bicolor version that is easily available in europe and that you can recommend?

thanks for the code so far. i speant 2 full days writing my own. but now i can save another 2 days for cleaning it up :-)

// kuk




tomek

hej,

i guess the 4x8 biocolour version could work, the problem is just that the code for the max7219 (posted by  massimo) is just working for one max7219, if you want to use more then one max7219 you have to change the code,  
for example: you have to change the  max7219_init(); because this version is just talking to the first guy, you should have a look in the data sheet, i*m not so good in explaining this stuff, but right now i*m trying a vesion with two max7219, if will post it if it is working, tomorrow,...

ha de bra
tomek

wolos

hi,
I have an 8x8 matrix that is "cathode row & anode column".  

http://www.lc-led.com/View/itemNumber/339

It doesn't seem to work when I use zambetti's code and wiring following trialex's post.  Some lights blink but it's not a diagonal line.  Do I need a "common cathode" matrix? Is it possible to use the matrix I bought?

thanks,
greg

kuuk

hi greg,

i think i was the same for me. but i had a bug in my wiring too: i thought that "DP-out" on the max7219 was equivalent to "segment H" but it's actually before "Segment A".

the basics of the code is right. you might have to adapt it. i can post mine if you want, but i'd need to clean it up.
there is no problem with your matrix module. two-color modules are either "common cathode" or "common anode". they have 8+8+8=24 pins for 64 bicolor LEDs. if your module has 16 pins, it's only one color and perfect for the max7219, which can't do two colours anyway.

///kuk

@tomek
hej (potsdam?),
i don't think it will work. because (funny to say that) of the MATRIX.
i started on the wiring when i noticed that i would have to connect each segment-anode of the module to two different max7219. since they are not synchronized with their digit scanning, the output would be uncontrolled i guess.

you can just use one 4x8 portion of the display though. which isn't so cool.


wolos

kuk,
thanks for the help.  it turns out i had the led matrix pins connected incorrectly to the MAX7219.  I found a site that helped me decipher the matrix data sheet.  It may help others...

https://itp.nyu.edu/~lg691/physComp/w8.html

ritzdank

wow! it worked out of the box. wired up my 6x6 led matrix and max7219. started arduino board and got a diagonal line :) . but i´ve encountered another problem! it seems my leds are not being switched off correctly. they lightly dim even when i call max7219_all(0x00).

up to now, i´m using the LED-grid with 1k resistors for each coloumn.

datasheet says sthg like this:
Quote
DIG 0-DIG 7: Eight-Digit Drive Lines that sink current from the display common cathode. The MAX7219 pulls the digit outputs to V+ when turned off. The MAX7221's digit drivers are high-impedance when turned off.


what´s the reason for this kind of "leaking current" ??

bod

Hi everyone, i've been working on a project for a while now using the max7219 chips, and it works great with PD and MAX, but does any one have any example code on sending data from processing to the arduino to run these chips?

i've never really learned processing/java, and i realise that i might be better off asking over at the processing forum, but theres seems to be more activity over here concerning the Max7219.


cheers,

bod.  :)

Ternus

I am trying to get my led matrix to run off the 7219, but wierd crap is happening.  I copied the code for the diagonal, uploaded it, and then all the leds come on.  They are all way to bright, and are not in a diagonal.  I can get them to flash messing with the hex numbers in the loop, but they only go from really bright to a slightly less really bright.  WTF IS GOING ON!!!  i cant get them to turn off at all unless i remove the clock wire on the arduino, removing the 5v going to the 7219 pin 19 makes them dimmer but doesnt turn them off.  Any help would be great, if no one can help I will post a picture of my breadboard later.

Go Up