It's an ATtiny13 connected to an 74HC595 shift register. The outputs of the shift register are connected to the anodes of the pillar. The cathodes of the pillar are connected to pins PB0-2 of the ATtiny and have a few series resistors. By configuring the pins as output pins we can sink some current when we write them low, turning the LEDs on. When we write a high to the pins we source current and the LEDs go off. So with the shift register we can control which LED should be on, and with the input pins we can select the color.
Normally you'd use some transistors instead of connecting the LEDs to the pins/register directly because the ATtiny nor the shift register will be able to handle the current of all LEDs going on simultaneously (3 x 8 x 20mA = 480 mA), but we'll program the ATtiny to only turn on one LED at a time so we can get away with this setup.
Both the storage and shift clock of the shift register are connected to PB4, this causes data that is shifted into the register to appear almost directly on the output pin, which is fine for this setup. The output enable is connected to ground so we'll have continuous output. The reset pins of both ICs are connected to +5V through a 10K pull-up resistor. The DS pin of the 595 is connected to PB3, the Q7S pin is left floating since we're not using it, which seems to be common practice. There's a 100nF ceramic cap added as a bypass for the ICs, and a power connector of course.
And for kicks, here's a dirty PCB:
For my test jig I'm not going to put those LEDs on the board, instead I'll have a three terminal connector near the resistors to connect the cathode wires of the pillar to. And an eight terminal connector for the anodes.
As you can see, I used Fritzing for this quick prototype. It just works a bit faster and the breadboard view is handy for this situation. If you want to download the Fritzing project, click here.
As for the programming: that's easy:
- Setup
- DDRB should be set as input for PB5 (reset) and output for PB0-4
- PORTB should be set high for PB0, PB1 and PB2 so they don't sink any current.
- define an eight bit anode counter variable, initialize it with 1.
- define a cathode counter variable, initialize it with 1.
- Main loop
- Start setting PORTB to 7, so we set PB0-2 high
- Shift the anode counter variable out on PB3 while toggling PB4.
- Set PB3 low and toggle PB4 twice to shift out a zero, because the 595's output is lagging behind one cycle.
- Shift the anode counter variable left by one.
- Toggle one of the output pins by writing the cathode counter variable to PINB.
- Shift the anode counter variable left one position.
- If the result is zero, set it to one. Shift the cathode counter variable left one position as well.
- If the result is eight, set it to one.
- Add a delay for 1/8th of a second.
One thing I can't remember correctly is whether or not the system clock prescaler is active by default. If so then it's set to 8, reducing the system clock to 1.2MHz. We can tackle this by changing the timer prescaler to 8, so we'll still have our 150,000Hz timer clock. Easy!
I'm not too happy with the custom cable I made. It's a bit too much work to stick those connectors in and I risk bending the anode legs. I think I'll create a wooden jig with some contacts, to place the pillar in.
No comments:
Post a Comment