# 4x16 matrix

I need help programming a homemade 4x16 led matrix. 4 pins are the rows and 16 are the columns.

Thank you, Joey2point0

We need to know what pins are rows, the best way is to post a schematic so we can see if anything else is wrong as well as to know what to write.

this is what it looks like

@joey: We need to know how you are connecting it to the Arduino, perhaps you are confused about that as well?

@all: With all these matrix questions, I'm thinking we need a HOW-TO or to put something in the wiki!!

Andrew

So what limits the LED current?

I do not show in the schematic but i have the appropriate size resistors connected to each of the bottom 16 pins.

-terribly sorry about all of the confusing with the design and such. this is how it is hooked up to the arduino.

So the best way of driving this is to put the data on the columns (high for on) while you put one row low with the other rows high. So a complete definition of the matrix will take will take four integers.

The problem you will face is that you are using pins 0 & 1. These are reserved for serial communications and so when you connect LEDs to them you might find you can't upload code. It is best to arrange these so that you can have a switch to disconnect them when uploading.

The problem is I have no idea where to start with programming it.

The problem is that you can't run that circuit without damaging you arduino.

You say:-

i have the appropriate size resistors connected to each of the bottom 16 pins.

If this were true then there will not be enough light from the LED to see.

First of all look at the sinking four outputs. These have to take the current from 16 LEDs. The absolute limit on a pin is 40mA, so lets go with that at the moment. You have 40mA to light up 16 LEDs that works out at 2.5mA per LED and given a 2V drop on the LED gives a resistor value of 1K2. Clearly this is not enough, so these outputs have to be driven with a darlington driver. If you do this then you are face with the problem of sourcing the currents from the other outputs. There is an absolute limit of 200mA for the whole chip so lets say there is 160mA free. Spread over 16 LEDs that gives a current of 10mA per LED, much better but still not brilliant. That gives a resistor value of 300R, which is not too bad. What value do you have?

I do not have it in front of me for I am out of town but if I remember corectly it was in the low 100 ohms. Also I do not understand why you say it can not work, because I have built a 4x4x4 led cube with the same resistor values, hooked right up to the arduino and it has turned out just fine.

Also I do not understand why you say it can not work

Please re read the post. I did not say it will not work. I said that it will damage your arduino. This will eventually cause your arduino to fail. Of course it is your decision if you want to stress your arduino in this way, but I feel it would be irresponsible of me to be complicit in this abuse of electronic components.

I have built a 4x4x4 led cube with the same resistor values,

And exactly how many LEDs were on an any one instant? You can tell from the code. In your proposed matrix you will have up to 16 LEDs on at any one time. With a 100R resistor this is too much:- The calculations:- assume 2V drop across the LED 3V across 100R = 30mA For 16 LEDs this is 16 * 30 = 480mA Absolute current sourcing limit on the arduino 200mA Stress rating 2.4 times over the limit where damage will occur.

Anywhere from 1 to all 64 were on at the same time.

Pardon me but it seems we have gone off one a tangent. I can give you the code from the led cube but the problem I have using that code for this new matrix is that the led cube code would program the leds from the side of the cube inward and I would like to program the leds from the top, down

``````#include <avr/pgmspace.h> // allows use of PROGMEM to store patterns in flash

#define CUBESIZE 4
#define PLANESIZE CUBESIZE*CUBESIZE
#define PLANETIME 3333 // time each plane is displayed in us -> 100 Hz refresh
#define TIMECONST 20 // multiplies DisplayTime to get ms - why not =100?

// LED Pattern Table in PROGMEM - last column is display time in 100ms units
// TODO this could be a lot more compact but not with binary pattern representation
prog_uchar PROGMEM PatternTable[] = {

/*
..1..,..2..,..3..,..4..,..5..,..6..,..7..,..8..,..9..,.10..,.11..,.12..,.13..,.14..,.15..,.16..,.T, */
B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,5,
B0001,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,5,
B0011,B0001,B0000,B0000,B0001,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,5,
B0111,B0011,B0001,B0000,B0011,B0001,B0000,B0000,B0001,B0000,B0000,B0000,B0000,B0000,B0000,B0000,5,
B1111,B0111,B0011,B0001,B0111,B0011,B0001,B0000,B0011,B0001,B0000,B0000,B0001,B0000,B0000,B0000,5,
B1111,B1111,B0011,B0011,B1111,B0111,B0011,B0001,B0111,B0011,B0001,B0000,B0011,B0001,B0000,B0000,5,
B1111,B1111,B1111,B0111,B1111,B1111,B0111,B0011,B1111,B0111,B0011,B0001,B0111,B0011,B0001,B0000,5,
B1111,B1111,B1111,B1111,B1111,B1111,B1111,B0111,B1111,B1111,B0111,B0011,B1111,B0111,B0011,B0001,5,
B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B0111,B1111,B1111,B0111,B0011,5,
B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B0111,5,
B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,5,
B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,5,
B1110,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,5,
B1100,B1110,B1111,B1111,B1110,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,5,
B1000,B1100,B1110,B1111,B1100,B1110,B1111,B1111,B1110,B1111,B1111,B1111,B1111,B1111,B1111,B1111,5,
B0000,B1000,B1100,B1110,B1000,B1100,B1110,B1111,B1100,B1110,B1111,B1111,B1110,B1111,B1111,B1111,5,
B0000,B0000,B1000,B1100,B0000,B1000,B1100,B1110,B1000,B1100,B1110,B1111,B1100,B1110,B1111,B1111,5,
B0000,B0000,B0000,B1000,B0000,B0000,B1000,B1100,B0000,B1000,B1100,B1110,B1000,B1100,B1110,B1111,5,
B0000,B0000,B0000,B0000,B0000,B0000,B0000,B1000,B0000,B0000,B1000,B1100,B0000,B1000,B1100,B1110,5,
B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B1000,B0000,B0000,B1000,B1100,5,
B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B1000,5,
B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,5,

// this is a dummy element for end of table (duration=0) aka !!!DO NOT TOUCH!!!
B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, 0
};

/*
** Defining pins in array makes it easier to rearrange how cube is wired
** Adjust numbers here until LEDs flash in order - L to R, T to B
** Pin DigitalOut0 (serial RX) and AnalogIn5 are left open for future apps
*/

int LEDPin[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int PlanePin[] = {16, 17, 18, 19};

// initialization
void setup()
{
int pin; // loop counter
// set up LED pins as output (active HIGH)
for (pin=0; pin<PLANESIZE; pin++) {
pinMode( LEDPin[pin], OUTPUT );
}
// set up plane pins as outputs (active LOW)
for (pin=0; pin<CUBESIZE; pin++) {
pinMode( PlanePin[pin], OUTPUT );
}
}

// display pattern in table until DisplayTime is zero (then repeat)
void loop()
{
// declare variables
byte PatternBuf[PLANESIZE]; // saves current pattern from PatternTable
int PatternIdx;
byte DisplayTime; // time*100ms to display pattern
unsigned long EndTime;
int plane; // loop counter for cube refresh
int patbufidx; // indexes which byte from pattern buffer
int ledrow; // counts LEDs in refresh loop
int ledcol; // counts LEDs in refresh loop
int ledpin; // counts LEDs in refresh loop

// Initialize PatternIdx to beginning of pattern table
PatternIdx = 0;
// loop over entries in pattern table - while DisplayTime>0
do {
// read pattern from PROGMEM and save in array
memcpy_P( PatternBuf, PatternTable+PatternIdx, PLANESIZE );
PatternIdx += PLANESIZE;
// read DisplayTime from PROGMEM and increment index
DisplayTime = pgm_read_byte_near( PatternTable + PatternIdx++ );
// compute EndTime from current time (ms) and DisplayTime
EndTime = millis() + ((unsigned long) DisplayTime) * TIMECONST;

// loop while DisplayTime>0 and current time < EndTime
while ( millis() < EndTime ) {
patbufidx = 0; // reset index counter to beginning of buffer
// loop over planes
for (plane=0; plane<CUBESIZE; plane++) {
// turn previous plane off
if (plane==0) {
digitalWrite( PlanePin[CUBESIZE-1], HIGH );
} else {
digitalWrite( PlanePin[plane-1], HIGH );
}

// load current plane pattern data into ports
ledpin = 0;
for (ledrow=0; ledrow<CUBESIZE; ledrow++) {
for (ledcol=0; ledcol<CUBESIZE; ledcol++) {
digitalWrite( LEDPin[ledpin++], PatternBuf[patbufidx] & (1 << ledcol) );
}
patbufidx++;
}

// turn current plane on
digitalWrite( PlanePin[plane], LOW );
// delay PLANETIME us
delayMicroseconds( PLANETIME );
} // for plane
} // while <EndTime
} while (DisplayTime > 0); // read patterns until time=0 which signals end
}
``````

I apologize if you are confused by this, I am willing to draw a diagram to make what i am saying more understandable.

Thank you

Anywhere from 1 to all 64 were on at the same time.

No you can't have all 64 on at one time. They might look it because they are multiplexed but all the LEDs are not on at the same time.

Pardon me but it seems we have gone off one a tangent.

No really unless you get the hardware right you can't even begin to write the software. I am not prepared to help you write software that will damage your arduino. Maybe some on else is willing but I feel it is irresponsible.