- An interrupt to provide the time interval between radial raster lines
- One to increment a counter for timing the wheel rotation interval
- One to reset all counters and update the raster interval value every time the hall effect sensor is triggered
- And finally, an interrupt that shuts down all LEDs when the battery voltage gets too low.
Timing values for the radial raster line interval are retrieved from a lookup table that exists in the microcontroller’s program space. Data for the lookup table is generated with a Qbasic program, although you only need to run this program if you want to experiment with different timing values from the ones I’ve come up with.
- Support for In Circuit Serial Programming (ICSP)
- 32 LEDs on each side of each circuit board (64 LEDs per board, 192 LEDs total)
- Displays a 1 kilobyte image (32 LEDs x 256 radial "raster lines")
- All LEDs can be driven with 20mA at 100% duty indefinitely. This produces a very bright image.
- The firmware shuts the circuit down automatically when the voltage gets too low to prevent damage to rechargeable battery packs.
- This project can be constructed entirely from "through-hole" soldered components
- Fits most bike wheels that are 26" and larger
TIMER1 is used to measure the time elapsed during one complete wheel revolution. The only problem was that even when the TIMER1 prescaler was set to its maximum value, it still wasn’t long enough to measure one revolution at low speed (walking speed). Of course a persistent image would never be visible at such a speed, but I wanted to strive for a fairly wide operating range. In order to overcome the TIMER1 limitation, I decided to increment a counter so that TIMER1 could do two complete cycles, which takes about one second. (One wheel revolution per second is a reasonably slow riding pace.) After two complete cycles of TIMER1, this "postscaler" counter stops incrementing.
The halleffecttrigger routine is where we determine the timebase for the radial "raster lines".
The least significant bit of the TIMER1 "postscaler" is combined with the seven most significant
bits from the high byte of TIMER1. The resulting number is used to reference a timebase value in a lookup
table. After that, TIMER1, the TIMER1 postscaler and the raster line counter are reset and then we return
to the main routine.
Since we can only know the duration of one wheel revolution after it has happened, the timing of the LED raster output is always lagging behind slightly. If the rider is moving at a constant speed, this is not a problem, however if the rider changes speed, the image will become slightly distorted. In practice, this distortion isn’t really a big deal.
The TIMER0 rollover routine is responsible for displaying radial raster lines at a rate dictated by the timebase value acquired from the hall effect trigger routine. Whenever TIMER0 overflows, this routine calls the outputimage routine to display one radial raster line of the image. A counter is used to keep track of which raster line is to be displayed next. Once the last raster line has been displayed, the counter stops incrementing. Finally, before returning to the main program, this routine resets TIMER0 to the timebase value.
This routine fetches image data from a lookup table. To avoid the problems associated with trying to access a lookup table that crosses memory page boundaries, I’ve chosen an image size that occupies exactly four consecutive memory pages and then interleaved the image data across them, with each raster line composed of one byte from each page. That way, one simply has to load PCLATH with the appropriate page number prior to fetching each byte. After fetching each byte of image data, this routine calls the writebyte routine which sends the data serially out to the shift registers.
The writebyte routine sends serial image data to the shift registers. It does this by copying the least significant bit of an image byte, rotating the bits in the image byte one place to the right, then repeating the process for all remaining bits. After a bit is copied, the shift register clock line must be pulsed so that the data in the shift register is "shifted" over by one place, making room for the next bit.
The LowBattery routine checks to see if the supply voltage is lower than a predetermined reference voltage. If so, it switches off all LEDs by way of the TurnOffLeds routine and then enters sleep mode. This prevents the POV board from "locking up" when the battery voltage gets too low for the microcontroller and it also prevents the battery pack from being over-discharged which could result in damage.
By default, the reference voltage is set to 3.4375 volts, which should be used with 8.4 volt battery packs. If you plan to use a 7.2 volt pack, then line 149 of the firmware must be modified. For more information, refer to step 4 of the Loading an image section. For information on selecting the right battery voltage, refer to the Batteries section.
The TurnOffLeds routine is called once after the device is switched on, and then again by the LowBattery routine when the battery voltage drops below a predefined threshold. It simply sends a sequence of 0x00 bytes to the shift registers so that no image is displayed.
Because of the limitations of Qbasic and the fact that I didn’t want to bother figuring out how to read TIFF files, I’ve made it read headerless RAW files. The images must be 700x700 pixels, 8 bits per pixel, with the pixels being either pure black (0x00) or pure white (0xff). Such a file can be created with Photoshop. When you’ve finished creating the image, the final file size should be exactly 490000 bytes.
To keep this device from lighting up when the bike is stationary, the last raster line is always set to zero (off). Because the firmware stops incrementing the raster line counter when it reaches the last line in the image, having all LEDs off in that line will cause them to remain that way until the next hall effect trigger.
Here are some improvements that I’m considering:
- Use an LED driver that supports PWM brightness control for displaying images with varying shades of colour.
- Use RGB LEDs in conjunction with PWM brightness control for a full colour Spoke POV!
- Have the microcontroller access image data from a serial flash RAM chip for greater data storage and the ability to upload new images without having to re-program the microcontroller.
- Use an accelerometer instead of a hall effect sensor. This would eliminate the need for an external magnet, which would in turn eliminate the need to re-write the image data if the magnet is relocated to a different part of the bicycle frame.
- A simple and reliable way to supply power to the POV boards from outside of the bicycle wheel, thereby allowing the use of larger and cheaper batteries. The two methods I’ve considered are a slip ring and and an inductive coupling.
- The ability to upload image data on the fly via some sort of wireless technology such as Bluetooth.