HELP! Burning up boards. Software PWM driving 48 LEDs with Arduino MEGA

I’m a novice to electronics, but not to programming. I've been trying to build a lamp containing 16 segments of RGB led strip. That makes 48 separate led clusters (3 colors x 16), each ready to go at 12 volts with built-in resistors, and each drawing about 100mA. I twice failed to get things to work using 3 TLC5940s, and then ran across this article: http://www.picano.nl/microcontrollers/arduino/control-many-leds-with-pwm about software PWM. Instead of using shift registers, I decided to try using the Arduino Mega (with ATmega1280). I would use 48 of its 54 digital I/O pins, with interrupt-driven PWM using direct bitSet and bitClear instructions. Since I haven’t seen this “obvious” approach discussed elsewhere, I will provide some details here.
I first tested this with only one led connected, but with a program using a timed interrupt to control 48 pins. The board seemed to handle the load well enough, using 30 levels of brightness on a 60Hz basis (hence doing 1800 interrupts per second). That appeared to use about 1/3 of the board’s capacity, since it would saturate and begin to run very slowly if I went to 100 levels of brightness.
The interrupt routine is very simple:
void iserve(){
static byte counter;
for (int i = 0; i <48 ; i++) {
if (ledvalue > counter) { bitSet(ports_,portnum); } //see explanation below*
else bitClear(*ports,portnum*);
}
counter++;_

if(counter>__maxBrightness) counter=0;
_}
Here is the rest of the minimum code necessary to the approach I’ve taken:
#include "TimerOne.h"
// A pin on the Arduino board is directly addressed by a command like “bitSet(PORTE,3)”—for pin 5.
//I’ll include a complete table of pin and port address associations near the end of this forum message.
volatile uint8_t * ports[48] = {&PORTE, &PORTH, &PORTH, &PORTH, &PORTH, &PORTB, &PORTB, &PORTB, &PORTJ, &PORTJ, &PORTE, &PORTB, &PORTD, &PORTD, &PORTE, &PORTB, &PORTG, &PORTA, &PORTA, &PORTA, &PORTA, &PORTA, &PORTA, &PORTA, &PORTA, &PORTC, &PORTC, &PORTC, &PORTC, &PORTC, &PORTC, &PORTC, &PORTC, &PORTD, &PORTG, &PORTG, &PORTG, &PORTL, &PORTL, &PORTL, &PORTL, &PORTL, &PORTL, &PORTL, &PORTL, &PORTB, &PORTB, &PORTB};
byte portnum[48] ={3, 3, 4, 5, 6, 4, 5, 6, 1, 0, 4, 7, 3, 2, 5, 0, 5, 0, 4, 1, 2, 3, 5, 6, 7, 7, 5, 4, 6, 3, 2, 1, 0, 7, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 3, 2, 1};
byte ledvalue[48]; //holds the brightness level for the leds. Modified by main program, read by interrupt service routine.
int __maxBrightness = 30;
long __ledFreq = 60;
void setup(){_

Timer1.initialize(round(1000000/(__ledFreq(__maxBrightness+1)))-1); // initialize timer1

* //This sets the interrupt at about every 556 microseconds. Formula from picano article.*
Timer1.attachInterrupt(iserve); // attaches iserve () as timer overflow interrupt.
}
void loop(){
//commands to set led values and make lamp do exciting things.
}
It’s that simple.
Now to my difficulties.
I set my board up with 7 ULN2003 Darlington arrays, each of which can handle 7 leds. The Arduino pins are connected directly to the ULN2003 inputs, and the led cathodes (with current-limiting resistors) are connected to the ULN2003 outputs. The ULN2003s have only one other connection: ground to Arduino ground, which is also attached to ground for my 12 volt (actually 12.6 volt) power supply. The 12.6 volt (6 amp) positive attaches to all led anodes and to VCC on the Arduino. Again, it’s that simple (if you count 4*48+ solder connections as simple).
Twice everything seemed to be working fine—almost. Leds were lighting and dimming as they should. I was tracking down isolated problems with a few leds not lighting when first the board seemed to stop corking, and then suddenly I heard a fizzle—or, last night, I think I saw a little flash and puff of smoke from the Arduino—and the board now seems dead. (Actually, it’s power light still comes on, but I can’t upload programs and it doesn’t function) Last night I determined that the ATmega1280 chip itself had gotten extremely hot, although I had not noticed it getting even warm before then. I had noticed some warmth on a chip very close to the on-board power plug, which I thought might be the voltage regulator. A worry, but it seemed to be just warm, not hot.
So any ideas? It is surely possible that my novice wiring and soldering skills led to a problem. That’s what I assumed the first time this happened, because it coincided with me reinserting the 12 volt wire into VCC (maybe I accidently put it into 5V?). But I now worry that maybe I am overloading the board or something like that. There are two possibilities:
I just read something about how I should have resistors between the Arduino pins and the ULN2003 inputs. Could that be the problem? On the other hand, overloading sounds unlikely because I had the system operating for some hours running with most leds lit—except for the few problem ones—and saw neither smoke nor fire. At the time the board failed last night, I was running software that would light only a single led at a time (i.e., only one pin in bitSet mode, although the interrupt routine would have been running, and giving repeated bitClear commands for the other 47 pins). So that hardly seems like an overload condition unless pins in bitClear mode are still placing demands on the board.
Last night, I was working to fix a problem with the led on pin 2 not lighting, and noticed that most of pins showed about 2.4 volts when in bitSet state (but 0 or maybe 0.01 volts with bitClear). Pin 2 was only showing 0.61 volts. I had previously solved a problem with some pins by adding into setup a loop that gave a pinMode(pin, OUTPUT) instruction for those pins. Pin 2 began working right after I put in a loop that gave the pinMode OUTPUT instruction for every pin from 2 through 53. But the board blew not long after the fix to pin2. Is that a hint?
I’m really at a loss about how to proceed. The software PWM seems like such a nice straightforward approach (especially if you don’t need the ULN2003s and just directly connect regular 20mA leds with limiting resistors to the Arduino Mega pins). And I really don’t want to replace the Arduino board only to have another one do a little fireworks display on me. I could revert to trying TLC5940s, but I’d prefer for now to pursue the software PWM approach unless it is just a bad idea.
I’ll be grateful for any help.
*As I promised I am including a table of the pin – port address assignments in the Arduino Mega (this is for the ATmega1280, I don’t know if it is the same for the new board). Taken from the schematic at http://arduino.cc/en/uploads/Main/arduino-mega-schematic.pdf*_
Pin Port,Bit
0 PORTE, 0
1 PORTE, 1
2 PORTE, 4
3 PORTE, 5
4 PORTG, 5
5 PORTE, 3
6 PORTH, 3
7 PORTH, 4
8 PORTH, 5
9 PORTH, 6
10 PORTB, 4
11 PORTB, 5
12 PORTB, 6
13 PORTB, 7
14 PORTJ, 1
15 PORTJ, 0
16 PORTH, 1
17 PORTH, 0
18 PORTD, 3
19 PORTD, 2
20 PORTD, 1
21 PORTD, 0
22 PORTA, 0
23 PORTA, 1
24 PORTA, 2
25 PORTA, 3
26 PORTA, 4
27 PORTA, 5
28 PORTA, 6
29 PORTA, 7
30 PORTC, 7
31 PORTC, 6
32 PORTC, 5
33 PORTC, 4
34 PORTC, 3
35 PORTC, 2
36 PORTC, 1
37 PORTC, 0
38 PORTD, 7
39 PORTG, 2
40 PORTG, 1
41 PORTG, 0
42 PORTL, 7
43 PORTL, 6
44 PORTL, 5
45 PORTL, 4
46 PORTL, 3
47 PORTL, 2
48 PORTL, 1
49 PORTL, 0
50 PORTB, 3
51 PORTB, 2
52 PORTB, 1
53 PORTB, 0_

Could you post a simple drawing of how you wired your components before things got bad? If it's the same for all leds, a drawing for just one will be enough.

You've written a lot and I'm getting confused.

ULN2003 input pins present almost no current load to the Arduino output pins. I would caulk up your experience to somehow wiring or touching +12.6vdc to the Arduino board, which would be instantly fatal for the important parts of the board. However the leds and thermofuse most likely were unharmed. :wink:

A soldering iron in the hands of a software programmer can be interesting thing to watch. :smiley:

Just kidding, no one was born knowing how to solder wires and components. It just takes patience and practice.

Two beginning soldering lessons to learn, 1. Know which end of the soldering iron to hold. 2. Don't solder while wearing shorts.

Lefty

Could you post a simple drawing of how you wired your components before things got bad? If it's the same for all leds, a drawing for just one will be enough.

You've written a lot and I'm getting confused.

I hope I'm posting this correctly. Here's a drawing: (OK, I don't know how to put a drawing into this window, so I've attached a simple jpg drawing.
Sorry to be such a klutz about the forum. This is my first.

Don't solder while wearing shorts.

Oh, you will do this one day... and then never forget.

Don't solder while wearing shorts.

real men solder in their underwear

OK, now you can post pictures. What I meant was schematic, a drawing of the electrical connections :sweat_smile:

The software PWM seems like such a nice straightforward approach (especially if you don’t need the ULN2003s and just directly connect regular 20mA leds with limiting resistors to the Arduino Mega pins).

There is a limit on the total amount of current a board can supply, it is 200mA so only 10 LEDs maximum could be driven direct from the board, and I would keep it down to 8 as you need current for other things like the CPU.

100mA LEDs through an TLC5940 will fry it every time. Look at the data sheet in the section on power dissipation.

Oops.Sorry, wrong picture. I knew you meant a schematic. Here is the correct one, showing one of 48 led connections.
Thanks for your help.

mega-uln2003 drawing.jpg

What about the "+" pin (#9 I think) on the ULN2003 ?

I did not attach the #9 pin, since I understood that it was needed/relevant only when using the ULN2003 with motors. Should I have attached it--directly to the 12V supply? Could that failure cause problems for the Arduino board?

[I thought I already posted this, but it didn't show up. Sorry if this becomes a duplicate.]
Thanks, grumpy_mike. I understand the point about how the board can't directly power more than maybe 8 regular LEDs, so my "straightforward" idea won't fly. I guess I see what you mean about power dissipation on the TLC5940. As I read the graph, it says a maximum of about 2400 mW total at room temperature, which is 150 for each of the 16 outputs, meaning 16 20mA LEDs will work only with voltage below 7.5. And it can barely handle two 100mA 12VDC outputs. If that is all correct, then the TLC5940 doesn't really help much for projects like mine (where the lamp will total about 20 watts), unless I use it in conjunction with something else to handle the power.
Thanks for the education. I'm sure I would have burned up some more TLC5940's before I figured that out.
But about the ULN2003's: do you see any reason why they should not work? I tried to figure out from the data sheet what the ULN2003 might demand from the Arduino board. I don't understand everything there, but I need to learn some of this stuff, so please bear with me while I walk you through it rather than just ask you for the answer. I have ULN2003AINs, and from the electrical characteristics table I take it that those draw a maximum of 1.45mA (that's per input not per chip, I assume from the test figure schmatic). So for the 48 channels I am using (from 7 ULN2003s), that's about 70mA. That's over 1/3 of what the board can supply, but it should be fine if I'm don't have other things using up the remaining 130mA of board capacity. The only thing else I had attached was a little peizo buzzer (on a digital pin, but it was inactive) and 3 potentiometers (on analog pins). So if that is basically correct, my set-up with 7 ULN2003's should not overtax the Arduino mega. Right?
I'm really grateful for your help.

So if that is basically correct, my set-up with 7 ULN2003's should not overtax the Arduino mega. Right?

Right :slight_smile:

That would be fine.

The 2003 is OK for switching about 640mA of current at any one time before getting too hot, see:- Power Examples
Switching that much current is always tricky and I would add some decoupling to each 2003 chip to stop things oscillating, 0.1uF should do for a start, see:- De-coupling

Thanks. Stuff gets complicated. So I am pushing the 640mA with about 100mA on each of 7 pins--I'll re-check the 100mA figure and may use another ULN2003 so I use just 6 pins on each.

Switching that much current is always tricky and I would add some decoupling to each 2003 chip to stop things oscillating, 0.1uF should do for a start, see:- De-coupling

OK, so the de-coupling you suggest would look like the attached modified schematic? It's a bit non-obvious to me since the ULN2003 has no direct connection to the supply voltage--it is "supplied," I guess, by the LED cathodes. Is there anything more I should know about the capacitor size (e.g. wattage) or type to use here? Will any 0.1uF capacitor be fine?
Thanks again. I'm learning far more from this than I anticipated.

mega-uln2003plus decoupling drawing.jpg