I am trying to daisy-chain thirty MAX7219 based 8x8 LED displays of the sort one can find on eBay for a few dollars a pop. When the chain gets too long, the displays begin to misbehave. Typically a daisy chain of eight would work, but adding a ninth would cause the entire chain to fail.
I am using a 5V 4A supply.
I concluded that I was creating too much fan-out on the clock line, so I decided to insert a few 7414 (Hex Schmitt-trigger inverter) based buffers into the chain. Each buffer circuit wires the 1-2 and 13-12 inverters in series and leaves the other four inverters disconnected.
This worked for the devices arranged loosely on my workbench, so I built three buffer circuits thinking that that would be enough. Arduino plus three buffers each driving eight displays gives me a total of thirty two displays, or thirty displays and a little wiggle room.
Everything worked until I began mounting the displays to a sheet of plexiglass using screws and nylon standoffs. Sometimes the chain works, and sometimes parts of the chain work, with some segments showing either blank, or all lit, or just randomness. Sometimes, hitting the reset button brings some of the displays online. Sometimes with enough reset triggers the thing will work fine. But I just can't get the reliability I am looking for.
My questions are as follows. Could the disconnected inverters be causing some of the issues that I am seeing? Would connecting the unused inverters into their own pairs and then adding them in parallel have any effect?
Look at 7414 high level output drive:
Current - Output High, Low 800µA, 16mA
Little bit of capacitance in the wiring will kill your high-going signal.
Try adding 4.7K pullup on its outputs, get those highs pulled up nice & solid.
I used the 7414s because those are what happened to be available.
As far as the pullup idea is concerned. The values you quote are that an output can source 800µA or sink 16mA? Is there a reason for the imbalance?
And to be sure I understand, given that the thing is running on 5v, would it be fair to say that a 4.7k resistor pullup means that the pin-plus-pullup could then source 1.8mA or sink 15mA?
Each pair of displays is connected by a 20cm length of ribbon cable. Is that likely to provide the kind of capacitance that is causing this problem?
7414s - original TTL series, or for that matter 74LS14 - are essentially obsolete, and this is one of the reasons.
74HC14 is dirt common and dirt cheap, would be a much better choice; they have symmetrical drive which is correct for driving CMOS such as the MAX7219 which was never intended to be driven by antique 7400 series. A common discussion here is how much current you can drive a LED with from a 74HC series chip - quite a decent amount (at least 10 mA) as it turns out.
Chuck the 7414s into your "history of electronics in the twentieth century" display cabinet.
If all the buffers are connected in serial to the CLK line, at the last chip, the CLK signal might be with clock skew and the last chips won't work correctly.
So use a mix of serial with parallel connections, like:
The values you quote are that an output can source 800µA or sink 16mA? Is there a reason for the imbalance?
Original TTL parts would pullup their input pins themselves, so not much high output current was needed.
And to be sure I understand, given that the thing is running on 5v, would it be fair to say that a 4.7k resistor pullup means that the pin-plus-pullup could then source 1.8mA or sink 15mA?
Yes. Maybe a smaller value pullup even for more source current (and somewhat smaller sink current). Put it at the end of the line.
[quotepEach pair of displays is connected by a 20cm length of ribbon cable. Is that likely to provide the kind of capacitance that is causing this problem?[/quote]More than likely! If you had an oscilloscope, you would see horrendous low to high signals.
First off, thanks so much for all your help. We made some progress, so here is hoping.
I wound up using 2.2k pullups and they appear to be helping. (It could also be my insomnia-fueled imagination). We got about six modules running on a buffer.
We slowed down the clock rate from 4MHz to 125kHz to account for the slowness of the 7414s. Which also helped. If we are clever about the updates we should be able to do a whole refresh in just over 32.5ms
We also found that not all MAX7219 clones are created equal. Some are positively flakey. By flakey I mean that swapping certain modules into or out of the chain appears to cause problems. Luckily we bought many extra modules, so it is just a matter of figuring out which modules are flaky.
The current state of the project is that we have the arduino driving three modules and the first buffer. The first buffer can drive six modules and a second buffer. But the second buffer can only drive two or three modules before we need a third buffer.
This diminishing return is going to be a problem. For one thing, I haven't got enough 7414s to get to thirty displays. And even if I did, I suspect we reach a point where no additional buffers are going to help, and that point will come before we reach thirty.
So now I'm wondering what else I could be missing.
I'm concerned that, focusing on the clock signal means that I'm missing something else, like maybe the LOAD signal. Is there any value in buffering those as well? Or perhaps there is something else I should consider?
Finally, if I had it all to do over again, what would be your ideal buffer chip in this application?
Ensure every logic chip has its own decoupling right close to the chip.
Run all signals alongside their ground wires in close proximity (ribbon
cable or twisted pair or coax). For ribbon cable alternate signal-gnd-signal-gnd...
Use CMOS chips, 74HC14, not 7414 or 74LS14. Connect all unused
inputs to gnd - very important for CMOS logic.
For long cable runs add at the receiving end of each signal 270 ohm resistors to
both +5V and gnd, providing an approximation of termination. Probably only needed
for clock signals.
If you have used 7414 then omit the 270 ohm to ground, just use a 1k pullup.
74AC541. Lots of drive capability. +/- 24mA per output. Vs +/-8 with HC logic family.
Drive all 8 inputs on 2 devices with SCK, SS, let each output drive 4 of the displays.
How is your serial data routed? Can also use multiple SS outputs, write to the MAX7219s in 'banks' of 4 perhaps to limit how much daisychaining of data has to occur.
Bump up to an Atmega1284P so you have 12 more IO pins to support that.
The arduino wires into the leftmost module, and the rest just daisy-chain with the provided dupont lines.
My current buffer circuits just sit on individual bits of perfboard. One chip in a socket, two 5 pin headers, and now a resistor. They are wired into the chain using the same sort of dupont lines.
As a programmer, I really like the elegance of this solution. Each item in the chain has the same interface (a 5-pin header coming in and a 5 pin header going out). It means that the devices can be easily swapped, which is useful because this is very experimental.
I see the value of the 74AC541, but the idea of multiple SS lines sounds like a daunting increase in complexity, both in hardware and in code.
Would it be reasonable to drive A0-A3 from SCK and A4-A7 from SS, and then have Y0-Y3 ganged together to drive the outgoing SCLK and have Y4-Y7 ganged together to drive the outgoing SS for a string of say sixteen modules, or even eight?
I made a 8x32 fdisplay using 4 MAX7219s, I found it easier to code with a separate SS for each vs figuring out the no-op coding to pass data thru 3 to access the 4th part.
The 7414s are what I have, in my hand, right now. To throw them out for another part that will take two weeks to ship, and cost tens of times more to ship than the purchase price is not realistic.
After studying the datasheet for the MAX7219, the digital input lines draw only 1uA! If the arduino can source/sink 40mA on a pin, why can't I just wire 40000 of them in parallel (with the data lines in serial)? Of course, part of the reason is that I am using cheap knockoffs, but surely they don't draw hundreds of times more current than the original?
The capacitance of the wiring degrades the signal. If you had nice clean traces on a PCB with termination resistor(s) on the far end to prevent any signal reflection, you could get away with many more loads.
I think we finally discovered the root cause of most of our problems. The tiny dupont wires that thread these modules together aren't of a thick enough gauge to properly provide power to the modules near the end of the chain.
We added some 18-gauge lamp wire from the power supply as kind of a bus which we tapped into using terminal blocks spaced every ten inches. Then we provided power to the modules in groups of four by running the dupont lines from the first module in each group to the nearest terminal block. The thing has worked flawlessly ever since.
Feed power into one end, and then use the screw terminals as taps to bring power to every fourth module or so.
That cleaned up all our problems.
I don't know if the buffers helped or not. We decided not to remove them from the final project because we had severely slipped our installation date, and didn't want to risk it.
You may also want to slow down the clock speed. We started (in true Tim "the tool man" Taylor fashion) at maximum speed on the SPI bus (8 MHz). Slowing it down got us a lot more reliability.
The power is doing just fine on mine, have it all powered up through a 14AWG main power branch that runs next to all of the MAX7219s.
My display is broken down into 10 sections of 6 MAX7219s each, and like you said, I could only get the first 8 of the MAX7219's to work properly. Last night I hooked up a SN74LVC245AN non-inverting buffer between the first two sections of 6, and got all 12 MAX7219's working perfectly in the first two sections.
I went ahead and ordered 9 more SN74LVC245AN's to place inbetween each section of 6. I am worried though that it still might not work if all of the buffers are in series. I understand each buffer introduces delay, but I'm feeding all 3 of the SPI lines (CLK, CS/SS, and MISO) through each buffer in an attempt to make sure they are all delayed by the same amount and stay in synchronization.
The SN74LVC245AN is actually an octal buffer, so I tried to use the one I had last night to serve as a buffer between the first and second sections as well as the second and third sections. I could not get the third section to work, hoping that the reason was because I was trying to use one buffer instead of two. I'll find out as soon as I get my other buffers, but in the meantime, anybody have an insight as to why this wouldn't work?
FYI, I finally found the problem. I had added the SN74LVC245AN buffers, but it still wasn't working. I found out that it was because I had been passing MOSI, SS, and CLK through the buffers. By only putting CLK through the buffers instead, I was able to get 18 MAX7219s (3 sections of 6, each section with its own buffer) working perfectly @ 32MHz. Tonight, I'm going to try and hook up a few more sections and increase the CLK frequency to see if I can get the whole group of 60 MAX7219s working at 4MHz. If it works, I'm going to write up and post a nice guide with how to hook up long chains of MAX7219s since it seems like there are a lot of people with this problem.
In the meantime, anybody have any idea why it wouldn't work when MOSI and SS were going through the buffers along with CLK?