Arduino Mega - LED limitations?

Hello all,

So I'm well underway on a project that consists of three arduino megas communicating over I2C reading a multitude of buttons and knobs, sending that data to Max/MSP, and then illuminating a large number of LEDs (86).

I've gotten all of the communications up and running perfectly - but before I set off to test my LEDs I wanted to know a little bit more about the power output limitations of my Arduino mega boards so I don't wind up frying my precious arduinos.

The LEDs I'm using are SparkFun RGB LEDs, with forward voltages of 2.0 (R), 2.2 (G), and 3.2 (B) and forward currents of 20 mA on each LED channel. I know that the pin limit is 50 mA of current, so with a 250 Ohm resistor in series I'm pulling about 7-12 mA per LED channel.

I've read that each arduino has a maximum output of 200 mA. Seems like I should be good to drive my 86 LEDs across the three boards if I keep the current down as much as possible on each LED, but I'm wondering if there is a limit for groups of pins or if I can increase the maximum output capacity of my boards in any way.

Any help would be much appreciated.

Thanks

I know that the pin limit is 50 mA of current,

Then you know wrong. The absolute maximum is 40mA and even at that rate you are overloading it. Stick to 20 - 30mA.

There are limits for groups of pins from the data sheets:-

Although each I/O port can source more than the test conditions (20mA at VCC = 5V, 10mA at VCC = 3V) under steady
state conditions (non-transient), the following must be observed:
ATmega1281/2561:
1)The sum of all IOH, for ports A0-A7, G2, C4-C7 should not exceed 100 mA.
2)The sum of all IOH, for ports C0-C3, G0-G1, D0-D7 should not exceed 100 mA.
3)The sum of all IOH, for ports G3-G5, B0-B7, E0-E7 should not exceed 100 mA.
4)The sum of all IOH, for ports F0-F7 should not exceed 100 mA.
ATmega640/1280/2560:
1)The sum of all IOH, for ports J0-J7, G2, A0-A7 should not exceed 200 mA.
2)The sum of all IOH, for ports C0-C7, G0-G1, D0-D7, L0-L7 should not exceed 200 mA.

ATmega640/1280/1281/2560/2561
3)The sum of all IOH, for ports G3-G4, B0-B7, H0-H7 should not exceed 200 mA.
4)The sum of all IOH, for ports E0-E7, G5 should not exceed 100 mA.
5)The sum of all IOH, for ports F0-F7, K0-K7 should not exceed 100 mA.
If IOH exceeds the test condition, VOH may exceed the related specification. Pins are not guaranteed to source current
greater than the listed test condition.

Finally for why you need a resistor see:-
http://www.thebox.myzen.co.uk/Tutorial/LEDs.html

The standard way to drive large numbers of LEDs is to multiplex them and scan through them to have the LEDs look like they are all on.

This is the code that I use for driving an 8x8 led matrix I built a few weeks ago. Note that there are 64LEDs. Without multiplexing, this would be way over the current specs for Atmega CPUs.

This is easily extended by using a 74154 4-16 bit decoder and driving the columns or rows using 4-bits instead of the 8-bits that I use. Also, the LEDs do not have to be a matrix, any organization will do as long as your program is set up to turn on/off the correct LED when you want.


// Matrix image values
unsigned char POWER[8]={1,2,4,8,16,32,64,128}; // The first 8 powers of 2.

unsigned char V[8]={0xF1,0x73,0x37,0x1F,0xF8,0xEC,0xCE,0x8F}; // An image of a pinwheel.
unsigned char U[8]={0x8F,0xCE,0xEC,0xF8,0x1F,0x37,0x73,0xF1}; // A rotated version of the pinwheel.

unsigned char D[8]; // Data to be transfered to the matrix.

int counter;
int load=0;

unsigned char i;
unsigned char j;

void setup()
{
Serial.begin(9600);

// set PORTA and PORTC as output.
DDRB = 0xff;
DDRC = 0xff;
for(j=0;j<8;j++)
{
D[j]=V[j];
}

//Initialize the matrix element loop counters.
i = 0;
j = 0;
}

void loop()
{
unsigned char MX; // 8-bit column data.
unsigned char MY; // 8-bit row data.
unsigned char c; // Utility counter.

// Set up the data.
MX=POWER*; // Set the scan column.*
_ MY=D*; // Set the row data._
_
// Transfer the data to the appropriate column and row registers._
_
PORTC = MX; // Set a single column bit to high._
_
PORTB = ~(MY); // Note! Invert the column data so current will flow from PortC to PortB._
_
// LEDS are diodes, so we do not need to worry about current flow in the*_
* // opposite direction. I.E. A high bit on PORTB coupled with a low bit on*
* // PORTC will do nothing.*

* delay(0); // A delay of 0 is required for matrix stability, otherwise random transient*
* // events can be displayed.*
// Select the next column.
* i=i++;*
* if ( i == 8) // If the column selection has gone past the end, start over.*
* {*
* i=0; *

* counter++; // Count the number of natrix refreshes.*

* if( counter==32) // If enough refreshes have occurred, change the display data.*
* {*
* counter=0;*
* load=1-load; // load alternates between 0 and 1.*
* if( load==0) // If load is 0, set the data to V.*
* {*
* for(c=0;c<8;c++)*
* {*
* D*
c*_ <em>*=V[c];                }              }              else              {                for(c=0;c<8;c++) // If the load is 1, set the data to U.                {                      D[c]=U[c];                }              }          }       } }*</em> _*