I've been fiddling around with this project for a couple of years, never having actually gotten it to work. I am so close now, I can almost taste it.

The idea is to be able to dim any number of LEDs in a 60-lamp matrix. Maybe I'll just dim up and down A7 or maybe I'll want to bring up B4, B5, B6, C3, D8 and F0. It depends upon the arrangement of where the LEDs sit on a prop and the colors of the individual lamps.

I finally decided that I don't have the software chops to do this on a PIC or a vanilla AVR and moved it over to Arduino Duem/328 a few weeks ago. It is just the Arduino, resistors on the rows and a UNL2803 on the columns. I've attached a wiring diagram.

I chose B. Hagman's SoftPWM library (http://code.google.com/p/rogue-code/wiki/SoftPWMLibraryDocumentation) to handle the PWM; I'm not wedded to this library, but it looks pretty good, and I've been able to dim up and down on specific colors (because of the way the LEDs are laid out).

But I don't have a clue how to bring up and down specific lamps perceived to be all at the same time. I want to do patterns, which may mean I'll need to build tables that have the patterns pre-built.

For example, in the code below, I can't make the blue lamp at position A7 (or the first column, eighth lamp) ramp up and down with the other blue lamps.

Here is the code I've cobbled together; I found that if I tried to do the digitalWrites in loops, everything flickered, but by just writing the lines one by one, I got smooth dims:

Thanks for the thought ... as I said, I've been doing this for a couple of years and have a drawer full of chips that I haven't been able to make work, including the 5940 and a variety of 595s.

Additionally, a chip like the 5940 throws away eight pins when configured to drive this type of matrix and while I don't plan on building a million (or even 100), it's an expensive solution to what should be a simple problem: PWM on eight pins and high and low on eight pins.

This hardware works; I'm looking for some software insights to make it do exactly what I want.

You might want to look at my DLT project. It does exactly what you're looking to do - except the DLT is only 5x5 (easy to expand to 8x8).

In the case of the DLT, I separated the LED control to one Wiring S board, and I'm using a second Wiring S board for controlling the rMP3 and input.

Please mind the mess on the wiki - I don't get much time to work on it, so I add to it when I can. I'll put the current source code for the LED controller so that you can see what's going on.

The trick with the SoftPWM Library with an LED matrix is to use an "undocumented" feature of the SoftPWMSet function which makes SoftPWM begin it's pulses when the SoftPWMSet function is called (I call it "hard set"). It's a "hidden" third parameter to SoftPWMSet, which takes TRUE or FALSE (it defaults to FALSE).

Have a look at the code - it's a bit to wade through, but you should be able to find what you're looking for.

This hardware works; I'm looking for some software insights to make it do exactly what I want.

Only certain pins can produce PWM, you seem to have scattered them between columns and rows with no thought to how you will use them.If you want to be able to dim individual LEDs in a scanning matrix with PWM you will have to synchronise the matrix scanning with the PWM signal. This you can't do. You will also have to have a PWM output for each row, that's 8 PWM outputs, this you don't have unless you have a mega.

If you want to dim the LEDs by just software you have to have N scans per column scan, where N is the number of brightness levels you want. You do not have time to do this and get the whole refresh rate at 30 per second to prevent flicker.

This project is based on a schematic from another hobbyist. While he has been generous about sharing the electronic design, he has kept the firmware private, only distributing hex code. I have had a series of messages with him over the years and he has no problem with me trying to reverse-engineer the code.

The original project is based on the PIC18f2620, which while having 40 pins, is remarkably similar to the Atmel 328 in terms of horsepower. In fact, the Atmel chip supports more hardware PWM pins than the PIC, so it's clear that the original design used software PWM.

In its current iteration, the code easily fades in and out the three groups of colored LEDs, so there is some method to what you perceive as madness. The wiring of the Arduino pins is taken from this playground entry: http://www.arduino.cc/playground/Main/DirectDriveLEDMatrix ... perhaps I shouldn't have followed an official entry, but it seemed like a good way to at least start.

I feel I am maybe 80 or 90 percent of the way to my goal at this point -- and am just looking for the right trick to finish it off -- but perhaps you are right: maybe this project is doomed to never work.

On the DLT, the end result is 60Hz refresh (over 5 columns), with just over 48 shades of brightness. One could, of course, tweak the values and get a wider range of shades, but I stuck with 48 shades. e.g.: @ 30 Hz, you could get 96 shades, and so on.

So, while I am certainly nervous about arguing with Grumpy Mike , I have to say that it is possible to achieve what you want to do with software.

Let me know if you have any questions about the DLT sketches/code, or about the SoftPWM library (that goes for you too, GM)

This is some code to show you the basic idea of dimming LEDs in a matrix using PWM generated by the refresh routine.In order to get to 30 complete refreshes per second you have to run the refresh every 0.2mS, this sample code just refreshes it at 1mS intervals.It is untested, you might have to change the pin assignments to match the pins you have used I I had not access to your circuit when I wrote this.

/* * Dimming matrix - Mike Cook * * multiplexes a matrix and allows each LED to have its brightness controlled * with 16 levels of brightness for each * all rows on at any one time with the multiplexing happening on the columns ****** warning this is not tested code may contain nuts ******** */

byte rowPins[] = {2, 3, 4, 5, 6, 7, 8, 9 }; // set up the 8 pins to use as row output - source for LEDs through a resistorbyte colPins[] = {10, 11, 12, 13, 14, 15, 16, 17 }; // set up the 8 pins to use as column output driving a darlington pulling to groundlong int pattern[] = {0x01234567, 0x89ABCDEF, 0x76543210, 0xFEDCBA98, 0x01234567, 0x89ABCDEF, 0x76543210, 0xFEDCBA98}; // array to hold the pattern data// each LED's brightness is stored in 4 bits in a long int giving data for all 8 LEDs in a column in one long intlong int refreshTime;

byte tick = 0, col = 0; // global variables to keep track of what to do next

Where? the linerefreshTime = millis()+1;is an integer so adding 0.1 or .2 makes no sense at all, in fact it is adding zero so it just refreshes as fast as it can which is not what you want because the refresh code takes a variable time to execute and you need a fixed rate of refresh to have the brightness stable.

Quote

It appears in the sample code you provided, you just created random HEX values

No these are brightness scale, take the first value0x01234567this breaks down intoRow 0 LED brightness level 0 (that's off)Row 1 LED brightness level 1Row 2 LED brightness level 2Row 3 LED brightness level 3Row 4 LED brightness level 4Row 5 LED brightness level 5Row 6 LED brightness level 6Row 7 LED brightness level 7for column 0the next long int is for column 10x89ABCDEF - this is increasing in brightness then for column 20x76543210 - decreases brightness for each LED.So not random at all.

Quote

If I'm right there, how would one go about calculating the HEX values?

Split your patten into columns and write down the hex value of the required brightness.

Quote

So the idea is to envision a specific pattern, calculate the brightness of all the LEDs in a column for a specific iteration of the pattern and then load each iteration as a HEX value into a table?

Where? the linerefreshTime = millis()+1;is an integer so adding 0.1 or .2 makes no sense at all, in fact it is adding zero so it just refreshes as fast as it can which is not what you want because the refresh code takes a variable time to execute and you need a fixed rate of refresh to have the brightness stable.

refreshTime = millis()+.1; // actually needs to be done every 0.2mS but here doing it every 1mS

And it went from all jumpy to the appearance of being constantly on ... some columns are brighter than others, everything except Column 8 is "on" ... all the LEDs in Column 8 appear to "off" (quotes, because I know we're talking appearances not reality).

I will examine your explanation of the HEX code more carefully before responding.

Check that rowPins[] and colPins[] match the pins you are using and their contents are in the right order for your matrix.

It is probably the extra time it takes trying to add 0.1 that is smoothing things. However why this is diffrent from trying to add 0.2 I don't know. You could try a delay microseconds in place of the mills() test. The LEDs in each column should be of varying brightness as well, but as I said it is a first go at the code and I have not tried it.