Microdot - Wrist Watch LED Pattern Timepiece

by rgbphil in Circuits > Clocks

81844 Views, 183 Favorites, 0 Comments

Microdot - Wrist Watch LED Pattern Timepiece

100_0735.jpg
Another RGB Sunset Productions production!

This project is a circuit board for making a wrist watch size version of my minidot clock:
https://www.instructables.com/id/EEGLXQCSKIEP2876EE/
with a few more functions more applicable to a portable device. A lot of help and suggestions came from ians 01/\/atch binary watch:
https://www.instructables.com/id/EYNTHEN1WUEP287APH/
Eaglecad schematic and PCB are available below from the original design, and an updated version with a few corrections is also included. The project is aimed to more experienced electronics hobbyiests as it involves small SMD components, and special programming methods. I'll be going through some of the problems and solutions that arose from making this device. This will hopefully help anyone else attempting to make a small microcontroller device. It might get a bit wordy, if you want action in a hurry....just download the project files and build.
Battery and case construction will be handled in another instructable. This one is just for the board itself.
Downloadable files:
- microdotfw.zip ...the sourcecode for the Soureboost compiler, includes a .HEX file
- microdotv1.zip ...the original PCB, with a couple of mistakes as mentioned in the text regarding missing resistors
- microdot2.zip ...a slightly modified PCB design, with all the proper components. Note I haven't tested this PCB, but it isn't too different from the original. The software should work on both.
Update 3 August 2007!:
From my other two instructables:
The holoclock - https://www.instructables.com/id/E11GKKELKAEZ7BFZAK/
Charliplexing tutorial - https://www.instructables.com/id/ERHG974F1ZM4KIR/
I've updated the microdot code to incoorporate cross fading between patterns and some better battery management. See attached file "microdot with crossfade and autotimeout.zip" below.

The Idea

microdot.gif
As in the mini dotclock the idea came from a pattern clock found at Thinkgeek. Basically the time is shown by a random distribution of different coloured LEDs. The number of LEDs in each colour corresponds to the time. The opening picture of the microdot show the time 3:45pm (1 red, 5 yellow, 4 green, 5 blue -> 15:45 or 3:45pm)
Having done the mini-dotclock I wanted to do a much smaller design. This was mocked up in Eaglecad and visualised in Povray using the Eagle3d user language program for Eaglecad. See ians \/atch project for more details.
This pic sort of set the basic scene, and by printing out the board layout and pasting onto little pieces of paper I could start to visualise the final design. One thing obviously missing from this early design was a way to set the time.....so I thought,and thought.
Then I added SMD switches for input which can be seen in the intro picture.

Programming and Micro Selection

microdotbits.jpg
microdoticsp.jpg
I am pretty familiar with programming and PIC 16F88 and had a few lying around from other projects. It seemed an obvious choice to save learning a new instruction set or new lot of onchip peripherals. This device has two ports A,B a selection of things like a serial i/f, A/D converter, a nice comfortable 8kb Flash rom and scads of memory...a whole 368 bytes of ram. One thing that was also handy was that it had pins for an onboard oscillator which could be connected to a common 32.768khz watch crystal for timekeeping and low power modes. The timekeeping oscillator can run even when the device was in low power mode. Lastly it could wake up when it detected a change on some of the pins (pins 4-7/portb have wake on change of state capability).

Because this was to be as small as possible I used a 20pin SOIP 16F88. This was a 300MIL wide version, Microchip have a 150mil SSOIP (skinny, small outline package), but considering the device was to be hand prototyped, I wanted to use a bigger easier to handle chip.

Obviously a SOIP package wont fit in a programmer so I had to use ICSP....which resulted in a whole lot of grief! ICSP is a way of programming the microcontroller, while it is still in a circuit. ICSP stands for In Circuit Serial Programming and is commonly used to program 'blank' boards, or update software without unsoldering/socketing the microcontroller.

Firstly I didn't read enough about ICSP to add the right circuitry to handle ICSP in my first prototype. Then I didn't read the microchip datasheet regarding a couple of extra pins on the 20pin 16F88SOIP. These pins are the AVss and AVdd pins. They normally provide the reference voltages for the A/D converter.

I took a while to figure out that these pins must be connected (I connected to GND/Vdd) for ICSP to work.

Also important is to have a proper reset circuit for the MCLR pin. This is very important so the ICSP program can reset the microcontroller, prior to doing its programming.

See the main picture in this section. It shows the MCLR pin connected to Vss via a pullup resistor and a diode. The pullup is necessary, because for ICSP to work you should really have the MCLR configured as a reset pin, rather than a input pin (more on this later). The diode prevents the Vpp voltage from the ICSP programmer which can be around 13V from damaging the rest of the circuit.
The picture also shows the connections for Vdd and AVdd connected together as for GND/AVss.

Refer to the Eagle schematic files for full schematic( or in the next section) but in the main picture note the little 'X' shaped symbols. These are SMD pads, there are no connectors in this device so SMD pads are used to solder power connections and the ICSP connection. The ICSP pins are arranged on the board in a convienient location. Short lengths of wire connect to a 10pin IDC header (pretty standard for ICSP programmers). The sub picture shows this arrangement.

They are also used to solder in the watch crystal. In the 16F88 the PGD and PGC pins are also the T1OSO and T1OSI pins which are used to connect an external crystal to the PIC T1 oscillator to make a real time clock. Fortunately you can also use these when programming via ICSP as well.....if you are careful.
If the oscillator is going when the ICSP programmer tries to use the pins, the ICSP programmer is going to have trouble. You need to add a delay at the start of your program. The code fragment below shows this in action. Note I'm also disabling the external oscillator as soon as possible after startup just for good measure :
void main()
{
unsigned char i;
unsigned short nDelay;
t1con = 0; //disable timer1 as soon as we reset
osccon = 0x76; //set for internal 8MHz clock
while( (osccon & 0x04)==0); //and wait for clock to settle and be ready

//setup peripherals
porta = 0;
portb = 0;
cmcon = 0x07; //disable comparator output, do now to set trisa properly
trisa = 0xff; //All set to input at startup
trisb = 0xff; //all pins in portb set to input
ansel = 0x00; //no analog in this cct....important step often forgotten, I did!!

delay_s(2); //allow programmer time to do stuff... VERY IMPORTANT

Lastly in the main picture note the symbol SMJ100 which is bridged in the upper top left hand corner called SJ100. This was to be used in an emergency if I accidentally programmed in a configuration that disabled the MCLR pin and couldn't stop the watch oscillator stuffing up the ICSP PGD/PGC pins. This is another handly Eaglecad library part, a simple SMD link. By bridging it on my board it is a convienient place to unbridge if necessary. This would be necessary in the above situation. Normally you only connect the MCLR pin (to reset the chip), the GND pin (for reference) and the PGD/PGC pins to use ICSP. In practice the programmer will reset the chip, send magic control signals to the processor via PGD/PGC and get it to be receptive for some new data lovin'.
However if the processor is busy doing other things and is not going to respond to a reset, you need to yank it's power rail to get it's attention. In this case the Vdd pin of the ICSP programmer needs to be connected to the circuit. I would cut the bridge, connect a wire to the Vdd SMD pad (the little 'X' symbol nearby) and give the processor new instructions. In the end when I downloaded dodgy code, I just powered up the cct from the programmer without using this system. If you had a more complex or power hungry circuit you should have some way of disconnecting the processor from the circuit power rail and connect it to the Vdd pin on your programmer.

So in summary to do successful ICSP remember:
- setup a proper reset circuit with protection diode and pullup resistor
- connect AVdd/AVss to the power rails if you are not using them (and the chip has them, only for 20pin 16F88...not for other versions).
- in your layout, put the ICSP connections somewhere sensible and easy to get at.
- have a way of isolating the processor power from the cct power and connecting ICSP Vdd for emergencies
- avoid emergencies by ensuring that the PGD/PGC pins are ready for use as soon as possible after a reset.

Some Circuit Problems

microdotsch.jpg
The main image below shows the circuit used in the intro picture. It has a few omissions that I think should be noted for anyone attempting to make a simliar cct.
Apart from the ICSP and processor which we've seen, we now see the charliegrid which will discussed next section. This is the LEDs and limiting resistors in the top right hand corner.
At the bottom left hand corner we see the three microswitches.
Note that the switches just connect three pins on port B to ground.

This was a problem.

I had originally intended to use the weak pullup function on Port B of the 16F88 to save some components, notably pullup resistors on the switch inputs. However when laying out the board I assigned one of the charliegrid control lines to another pin on PortB. This was a simple layout decision, it was easier to layout the board in such a small space by moving the traces to more easily accessible pins on the PCB. If you have enough space you'd connected all of the charliegrid controls lines to the same port.

However when the charliegrid program was written, it worked OK, except for some sort of leakage on LEDs connected to the PortB pin. When one LED was lit up, a couple of other ones lit up weakly. In the end I added pullups to the switches and disabled the weak pullups. You can see the extra added pull up resistors and some prototyping mistake wire in the ICSP picture of the previous section.

Another problem was a silly one, made by me cutting and pasting code from another project to the microdot project without thinking.

I had inadvertantly copied code that enabled the A/D converter for one of the pins. This is a big problem if you then use that pin as an output. It draws too much current and eventually will kill or seriously damage the pin. This is exactly what happened, everything ran OK at first, and after testing overnight I found some LEDs were not lighting at all, and some were lighting several LEDs at once. This took several nights to track down to a faulty RA0 pin....the one I had accidentally configured as an analog input. The charliegrid multiplexing system necessarily configures it's control pins as either input or output.

I replaced the chip, very carefully making sure not to lift the fine tracks in the process and now make sure I disable all analog inputs, which can be seen in the previous sections code fragment.

Last problem was with the power supply. I've used a simple dropping diode to drop the 6V to 5.4V from two button cells, this saved frying the micro everytime you changed batteries. Not the best way to regulate the voltage, but it is very space saving.
The problem came about because I only had a 16F88 device handy, not a 16LF88 device. The 'LF' allows operation down to about 3V, so the battery could drop to nearly half power before the device would stop operating. With the 'F' device, the battery pair can only drop about 1V before the device will start resetting itself because the power is too low.
I'd also planned to get the watch to put itself into low power mode, and wake up when a button is pressed to conserve power. The software at the moment doesn't have this functionality, it will be added when the housing and mounting instructable is written.

So for this section:
- you can't use weak pullups on an charliegrid control signals
- be careful not to configure a charliegrid control signal as an analog input as well
- use a 16LF88 device instead of a 16F88 device so you can get better life from the battery.

The Charliegrid...layout and Programming

topandbottom.jpg
The previous section introduced the 'charliegrid'.

For those not familiar with this, it is a way of controlling lots of LEDs with only a few pins by taking advantage of the tri-state nature of a microcontrollers pins and the forward voltage of the LEDs. There are numerous explanations of the charliegrid and their applications on the net so I won't give more than a quick explanation.

Note the configuration of LEDs on the charliegrid.

You can put a +ve voltage on one control line, and you can put a 0V on another line. You leave the other control lines unconnected to anything. Imagine having the charligrid on a breadboard and you connect two control lines to a battery. In the case of the microcontroller, you program these two pins to be outputs, and set one pin to a logic '1' and the other to a logic '0'.

You leave the other control lines unconnected, or in the case of a micrcontroller you set these pins as inputs.

The LED with the most direct connection to this connection will light up. Even though there are multiple paths through these pins through other LEDs, only one will light because when it does, the forward voltage of that LED will always be lower than any combination of other LEDs.

When the position of the logic '1' and '0' are reversed, and the same control lines are selected, the LED in the reverse position lights up. You can see these in the circuit diagram as pairs of LEDs between every combination of control inputs. As such 6 control lines can operate 30 LEDs individually....not at the same time of course!

To light up an LED it is simply a matter to program the microcontroller to send a logic '1' or a logic '0' to which ever two control lines corresponded to that LED and set the others to inputs.

By briefly illuminating each desired LED in turn, you can build a display like a monitor due to persistance of vision effect. Because only one LED can be lit at a time, this is always necessary in a charliegrid.

In the code the porta/portb output registers and tris registers are loaded with values pre-calculated to light up an LED. Took a while to calculate them all. Here is a fragment:
// LED1 LED2 LED3 LED4
unsigned char LEDS_TRISA [31] = { 0xfd, 0xee, 0xf7, 0xfd,
unsigned char LEDS_PORTA [31] = { 0x02, 0x01, 0x08, 0x00, 0
unsigned char LEDS_TRISB [31] = { 0xfb, 0xff, 0xfb, 0xfb, 0
unsigned char LEDS_PORTB [31] = { 0x00, 0x00, 0x00, 0x04, 0x
If anyone knows of a generalised charliegrid algorithm, I'll be very interested.

But first the grid had to be layed out. For the microdot this was a big challenge because of the lack of space. The main picture shows how this became managable.

Initially I put the LEDs in pairs in the grid and the bottom components in as well where I wanted them. This was very confusing when trying to sort out the best most efficient connectivity of the complex charliegrid. By moving the LEDs away from the bottom components, the ratsnest became easier to read. After that it was simple to move the grid back onto the bottom side components and do the bottom layout with a minimum of layer to layer vias and crossover tracks. You can see the impact of moving and rotating the LEDs to get the best arrangement in the crazy naming sequence of the charliegrid schematic after renumbering LEDs on the board.

Construction Hints and Tips

via detail.jpg
bottom detail.jpg
This project is for experienced people only, the trackwork is very fine and the spacing of the components is very tight.

Because the tracks are very fine, you need to use a temp controlled soldering iron with a fine tip. If you make a mistake, use solder braid and suck up excess solder first, then move the problem component. Be very careful not to lift any tracks, this is a real possibility with tracks this small.

First etch and drill the board using whatever method you are comfortable with. I used the press'n'peel technique successfully. I suggest making multiple copies of the board artwork on your PCB and picking the one that prints the best image before etching.

Use a 0.5mm drill for drilling, the vias are very small and do the vias first. There are no through hole components but there are a few vias. Be careful not to short any tracks.

Note that some vias are inbetween LEDs and one is under a switch. Not a problem if you are using through plated boards, however doing it by hand you may need to trim the result with a scalpel to make the connection between the sides of the boards flat enough. Have a look at the pictures in this section, note the vias in-between the LEDs.

After doing the vias, check with a multimeter that the via is connecting. Use the multimeter on a connecting track, not the via itself.

Now install the LEDs and driver resistors on the top of the board, be careful to note the orientation of the LEDs from the cad files, they are not in any particular order. Check that the LEDs are not butting up too close to a via, and trim the via with a scalpel if you need to get a closer fit.....be very careful to wipe away anything removed with the scalple as it may cause a short later on.

With a voltage around 3.5 volts from a bench supply or a battery test each combination of charlieplex control lines and make sure that each LED lights individually and that there are no missing or multiple LEDs lit up. If you have, then there is a track being shorted or broken.

Now install the SMD switches.

Once you've checked the LED array is correctly you can start on the bottom side. There is much more space on the bottom side and if you can solder in the PIC, nothing else should present any problems except for the crystal. See the sub picture in this section. The crystal overhangs another track by a little bit, when installing the crystal, ensure that it doesn't touch this and is raised a bit. The modified PCB artwork in microdot2.zip should have less of an overhang.

Also note the omitted resistors and wire links in this picture. These are properly layed out in the second revision of the artwork.

Double check no shorts between pins on the PIC or other components.

Connect wires to the power supply pads and check that the PIC gets power. The cct has a diode dropping 6V to 5.4V (approx)....for an initial test, don't crank it up to full power.

Now connect the ICSP wires to whatever ICSP programming adapter you are using.

Programming

The hex file is located in the firmware download archive, simply connect your ICSP programmer and fire it away.

When the device is reset or first powered up, each LED should be lit up in turn. When this sequence is finished the RTC is activated and the crystal starts oscillating.

If you modify the code, add new functions etc you may note that initially the next program may have troubles communicating. This might happen if your programmer doesn't wait long enough after resetting the device before trying to communicate to the chip to program it and the oscillator is still oscillating on PGD/PGC.

Just fire a second attempt at programming the device before the powerup sequence finishes.

If you've done major mods to the code and you still can't get a new program in to the chip, you may have inadvertantly disabled MCLR....in this case you'll need to connect the Vdd pin from your programmer to the device, disconnect seperate power supply in this case).

Operation

100_0735.jpg
Note these instructions may change as the software undergoes revisions and more/cooler functions are added. Refer to the video for an example of first setting the time, then going through the functions.

To set the time, press SW2/SW3 together. The display will blink, then the first group (red) of LEDs will blink to indicate that it is ready to change the tens hours. Pressing SW3 will increment the number of LEDs lit up for the 10s hours.

Pressing SW2 will advance to the hours, again to the 10mins and again to the minutes, then again back to the 10 hours.

Pressing SW1 will exit time setting mode and the watch will start at the set time.

Pressing SW1 again will enter the function mode. There are four functions, each indicated by a blinking cursor at the four colour groups. Pressing SW3 will exit any function.
They are:
(red) Display wipe - The display will wipe from right to left
(yellow) Random - random LEDs will be turned on/off to simulate a computer calculating
(green) Detector - a bar graph will be displayed with a bit of simulated noise jitter. The average length of the bar will increase to a maximum in about 20 seconds, and the display will blink continuously. You can use this to 'detect' anything you like.
(blue) Count down timer - When entering this mode, a 3 minute timer is setup by default. Similiar to setting the time, use the SW2/SW3 switches to change the display which is in mins:secs. Pressing SW3 will start the timer. When the timer reaches zero, the display will start to blink. The LEDs are not randomly patterened in countdown mode so as to make reading the time remaining easier.

Sorry the video is a bit blurry, my camera doesn't do macro in video recorder mode. The video shows first the delay at startup to allow ICSP programming, the LED test then setting the time. Next it shows going through all four functions, wipe/random/detector and finishing with a 9 second countdown.

That's all for now. Stay tuned for another instructable when it gets put into a moulded casing and another firmware upgrade.