Measure distance while riding bicycle. Direct display in meter unit.
Battery operated with Nitron 68HC908QY4, 16-pin MCU.
The MCU uses internal oscillator, internal reset, so we need only to supply the +VDD and VSS. I put the decoupling cap 0.1uF to VDD and VSS. Interface signals for LCD are D4-D7, RS and E. It was 4-bit interfacing, no BUSY checking. The LCD connector is 16-pin SIP socket. D0-D3 is not used, so we must tie to GND. Also R/W# was tied to GND. Since we can not check BUSY bit, so the delay routine must be used to wait LCD ready for command and data writing. The sensor inputs are PTA2 for reed switch contact and PTA0 for 0/+5V analog input. I used small phone jack for both sensors. The analog input is optional. I haven't got the idea what sensor should be used. The power supply is battery with simple +5.1V zener diode. You can use +9V battery or 1.5Vx3 AA battery. The circuit can run properly when the supply down to +3V. Care should be taken if you will use ADC, since the VREF is the same as VDD!Figure 2: Complete hardware schematic of distance meter v1.0. |
We have seen the schematic is quite simple, so we can build the board with universal pcb. Figure 3 shows the sample of placement of Nitron chip and LCD connector. I used small phone jack on the left hand to connect sensor. After the jack was soldered, I could not put the plug, it was too close to pcb, so I cut it, but unfortunatly the pcb was broken. It looked not nice, but the program running was fine.
Figure 3: 16-pin Nitron chip 68HC908QY4. |
Reed Switch Sensor
Figure 4 shows a sample sensor and cable making. Later we need shrinkage tube to protect the sensor. The position when sensor when fix to the bicycle wheel also important. We need the magnetic flux perpendicular to the contact.
Figure 4: Reed switch sensor and cable. |
Software
The firmware for distance meter was written in c with ICC08 compiler. Let's look at the the main code and you may need to modify for your bicycle.
If bicycle has 50cm diameter front wheel. Above constant, one_revolution then was computed for one revolution. This value will use for calculating distance in meter#include <io908QY4.H>#define one_revolution 157 // 2PIr, radius is 25cm
#define p 1 // scale of ADC reading
The computed value is cm unit with one revolution equal 157cm. print_dec( ) function prints the distance is meter unit by dividing length with 100. I have added the analog display reading from ADC0 with function read_adc_scale( ) also. You may add your own sensor. I just tested with photocell using simple voltage divider with 4.7k tied to +V.void print_distant()
{
if(++timer1>10)
{
timer1 = 0;
PTA ^= 2; // toggle PA1
// count++; // test auto increment
length = count*one_revolution; // one revolution = 157cm
print_dec(0x80,length/100); // 100cm = 1m
LCDWD(' ');
LCDWD('m');
print_dec(0xc0,read_adc_scale());
}
}
Main code is simple forever loop with tick generation by timer0. The internal oscillator and timer0 control byte were set to provide approx. 1/120Hz tick. Main codes are pulse detection and print the accumulated distance. Each loop running the COPCTL must be cleared, otherwise it will reset MCU!void main()
{
// OCSTRIM = 0x81; // trim internal oscillator
delay(1000); // powerup delay for LCD
n = k=0;
count = 0;
average = 0;
TMODH = 0x01;
TMODL = 0xf4;
TSC = 0x06; // run timer
DDRA = ~0x1; // PA0 is ADC input
DDRB = 0xff; // port B is output port
PTB = 0; // clear port B
PTAPUE = ~0x81; // osc2 pin is PTA4 I/O
ADCLK = 0x40; // ADC clock= fbus/4
i_LCD();
print_lcds(title);
delay(60000);
now = old = PTA&4;
LCDWI(1); // clear lcd
//asm(" cli"); //enable irq interrupt
for(;;)
{
while(!(TSC&0x80))
;
TSC &= ~0x80; // clear TOF
// PTA ^= 2; // task running ~60Hz so the loop running is 120Hz or 1/120Hz
task_led();
print_distant();
detect_pulse_input();
COPCTL = 0; // clear COP
}
}
schematic: schematic.pdf firmware source code: LCD.C s-record: lcd.s19