So Justin picked an image of the interwebs and set about making a design. He found a picture of some UFOs and decided to have a number of LEDs light up in a sequence, to give the image of "tractor beams" rising up from the ground:
The basic idea is that at any one time, all the same numbered LEDs are on together. So firstly all the ones come on, then a few hundred milliseconds later, all the twos, then all the threes and so on. This gives each beam it's own animation, while allowing multiple beams to be controlled from a single PIC output pin.
It's going to be a battery operated card, and - unlike an earlier, similar project - we've convinced Justin to invest some time in making a PCB rather than just poking LEDs into the card and soldering them all up with wire on the back! We're trying to avoid through hole components here, because of the little spiky legs on the back - so its SMT all the way; for LEDs, resistors and microcontroller. Initially we thought of using the 16F1825 with it's low pin count, but in the end opted for a 16F628a because it runs from an internal oscillator (no need for an external, chunky crystal) at the lower rate of 4Mhz, not 32Mhz as per the '1825. Nothing on the card is time critical (it has no serial comms, for example) and, generally, the lower clock speed means lower power consumption when running (so hopefully those LEDs can stay flashing for a little bit longer).
Normally we wouldn't bother making up a schematic for something like this - it's just bunches of LEDs being driven directly from the output pin of a PIC. But the offset/staggered nature could cause a few headaches when laying out the board, so out came ExpressPCB...
(we've drawn every bunch of LEDs as four, although sometimes on the card, only two or three LEDs light up at a time - it was just easier to draw them all in - copy and paste went mad - and then just not include them on the PCB later)
While it's a really simple circuit, the key thing is that when this is linked to the PCB layout software in ExpressPCB, it, rather handily, lights up all connected pads when you click on them. This makes laying out our PCB so much easier than just trying to do it all in one go off the top your head! The numbering is a bit weird - we used 1,2,3,4 for the first "row" of LEDs, then 11,12,13,14 for the next row and so on. So when we come to run the code, we'll switch on 1,2,3,4 together, then 11,12,13,14 together, then 21,22,23,24 - basically the "tens column" of the number represents the current row to be lit.
Because the LEDs need to line up with a printed image, it was important to position each LED exactly in the right place. We used our old friend Inksc(r)ape to do this. First, we imported the bitmap to be used and resized it to the size of our eurocard copper board (100mm x 160mm). Then we simply draw 1206 sized rectangles and positioned them over the image:
The painstakingly slow bit was selecting each LEDs, noting it's position (in mm) and transferring these positions to the 1206 LEDs drawn in ExpressPCB.
It was slow going, but we got there in the end!
Because the schematic and the PCB layout were linked, whenever a single pad on one LED was clicked, all the others that it needed to be connected to lit up. This made routing the traces a little bit easier, and also ensured that no LED was inadvertently left out
To make assembly easier later on down the line, we positioned every LED with the ground pin on the same side; it would have made routing easier not to do this, but there would be nothing worse than ending up with a failed board because one or more LEDs were soldered the wrong way around!
So after about an hour or so of routing and re-routing traces, we ended up with a single-sided PCB with no jumpers (since the board will be hand assembled, vias were a big no-no as they'd introduce more nasty spiky bits where bits of wires had to be soldered)
The PCB as drawn in ExpressPCB
Because we're using press-n-peel (which reverses an image during transfer) AND entirely surface mount components, the whole PCB needs to be flipped before printing (so after transfer, it's back the right way around)
That's all the hard work done! Now it's just a matter of etching the board and sticking the LEDs onto it! Here's the board fresh from the ferric chloride:
(there's a bit of pitting in places on the board - our new Brother 3012 isn't a patch on the old Xerox Phaser for printing toner-transfer images)
Justin made a great job of soldering all the components in place. Using a bit of wire connected to a 3v coincell battery he made sure all the LEDs were connected the right way around and working before the last stage of the project - programming the PIC.
The firmware is incredibly simple. Simply flash PORTB.0 high, wait a few milliseconds, send PORTB.0 low and PORTB.1 high - repeat for each pin 0-6 and cycle forever. Rather than use an if statement to determine which pin to light up, we used bit-shifting and wrote a single byte value to the entire port:
Define CONF_WORD = 0x3f18
Define CLOCK_FREQUENCY = 4
AllDigital
Config PORTB = Output
PORTB = 0x00
Dim counter As Byte
Dim tmp As Byte
WaitMs 1000
init:
counter = 0
loop:
tmp = 1
tmp = ShiftLeft(tmp, counter)
PORTB = tmp
counter = counter + 1
If counter > 6 Then counter = 0
WaitMs 200
Goto loop
End
Define CLOCK_FREQUENCY = 4
AllDigital
Config PORTB = Output
PORTB = 0x00
Dim counter As Byte
Dim tmp As Byte
WaitMs 1000
init:
counter = 0
loop:
tmp = 1
tmp = ShiftLeft(tmp, counter)
PORTB = tmp
counter = counter + 1
If counter > 6 Then counter = 0
WaitMs 200
Goto loop
End
The PIC was programmed using a SOIC-clip and a homemade programming cable (the PIC was already mounted onto the PCB before it was programmed).
And there you have it. A cycling, flashing LED battery-operated UFO-themed greetings card. And all for a few hours work.
As it was getting late by the time the board was assembled and working, Steve took it away to produce the sticker front and hid all the scary looking electronics away. Hopefully a follow up post will show the final, working card in all it's glory.....
No comments:
Post a Comment