Ever wondered why a speedometer on your bicycle is called a computer?
A coffee machine or a dish washer is certainly also not called a computer, while the embedded computing power of these machines is much larger than the computing power of your cyclocomputer.
But things are changing! here you will find a description of a real Linux powered cyclocomputer for my Flevobike velomobile.
The system is based on an edimax/sweex router with new firmware and linux root system on an usb stick. A serial GPS receiver is attached for logging the position. In the future a display and sensors for logging temerature and battery voltage will be added.
Index
Hardware:
An edimax BR-6104KP router is used. New firmware is flashed and linux runs from an usb stick. Detailed information can be found on the sunspit and midge sites (see links below). An RS232 port is available on the board, but the signal levels are 3.3 and 0 volt. An max3232 level converter is used to get rs232 levels needed for the GPS unit. Here is an image of the board.

The yellow lines are the rs232 connections on J2 for /dev/ttyS0.
J2 connections:
- 1- RX
- 2- +3.3v,
- 7- TX
- 8- GND
Here the MAX3232 is connected, as follows:
- 9- RX
- 10- TX
- 15- GND
- 16- +3.3v
The red wire is the +5v from the power supply of the USB circuit, which is needed to power the GPS unit.

Here the circuit is attached to the router. A case covering the whole thing still needs to be made.
Software:
All kinds of applications can be runned on this device, including web-server, ftp-server, windows file server, it can be programmed in C, basic, PHP, shell scripts, etc. Information can be found in the links below. For the cyclocomputer a shell script was made which logs the NMEA sentences from the GPS device. First it waits for a valid sentence, then it extracts the date and time from it and set this as the system time. Then all $GPRMC sentences are loged in /var/log.
/usr/local/bin/gpsstart.sh#!/bin/sh # settings SERIALPORT=/dev/ttyS0 DUMMYREADS=200 DATECC=20 LOGDIR=/var/log/ # some dummy reads to clear buffer echo "led blink 100" > /dev/gpio0 counter=0 while [ $counter != $DUMMYREADS ] do counter=$((coun=er++)) # echo $counter read line < $SERIALPORT done # check for valid NMEA data echo "led blink 300" > /dev/gpio0 notvalid=true while $notvalid do read line < $SERIALPORT navwarn=$(echo $line |sed -n 's/\$GPRMC,\([0-9]\{6\}\).[0-9]*,\([AV]\{1\}\).*/\2/p') if [ "$navwarn" = "A" ] then notvalid=false fi done # get time echo "led blink 500" > /dev/gpio0 thetime=$(echo $line |sed -n 's/\$GPRMC,\([0-9]\{6\}\).*/\1/p') thedate=$(echo $line |sed -n 's/\$GPRMC,[0-9.a-zA-Z]*,[0-9.a-zA-Z]*, \ [0-9.a-zA-Z]*,[0-9.a-zA-Z]*,[0-9.a-zA-Z]*,[0-9.a-zA-Z]*, \ [0-9.a-zA-Z]*,[0-9.a-zA-Z]*,\([0-9]\{6\}\).*/\1/p') if [ -n "$thetime" ]; then datedd=$(echo $thedate |sed -n 's/\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\1/p') datemm=$(echo $thedate |sed -n 's/\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\2/p') dateyy=$(echo $thedate |sed -n 's/\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\3/p') datehhmm=$(echo $thetime |sed -n 's/\([0-9]\{4\}\)\([0-9]\{2\}\)/\1/p') datess=$(echo $thetime |sed -n 's/\([0-9]\{4\}\)\([0-9]\{2\}\)/\2/p') setdate=$datemm$datedd$datehhmm$DATECC$dateyy.$datess date -s $setdate logfile=$LOGDIR"/gps_"$datedd$datemm$dateyy"_"$datehhmm.log echo $logfile fi # log GMRMC sentences echo "led on" > /dev/gpio0 notvalid=true while true do read line < $SERIALPORT navwarn=$(echo $line |sed -n 's/\$GPRMC,\([0-9]\{6\}\).[0-9]*,\([AV]\{1\}\).*/\2/p') if [ "$navwarn" = "A" ] then echo $line >> $logfile fi done
In order to shutdown the router properly using the reset button on the back, a shutdown script was written. This is needed, since the GPS data is continiously written to the USB stick. When this process is not stopped before switching the file system on the stick can be damaged.
/usr/local/bin/buttonhalt.sh#!/bin/sh # halt when reset button pressed # settings SLEEPTIME=1 POWERDOWNLED=/dev/gpio1 USB1LED=/dev/gpio3 SWITCH=/dev/switch # initialisation echo "led switch 1" > $POWERDOWNLED echo "led switch 1" > $USB1LED echo "led switch 0" > $SWITCH echo "led off" > $USB1LED echo "led on" > $POWERDOWNLED # test switch in loop while true do read pressed < $SWITCH if [ "$pressed" = "0" ] then echo "led off" > $POWERDOWNLED /etc/init.d/K95init_it stop halt fi sleep $SLEEPTIME done
These scripts are started from /etc/init.d.
/etc/init.d/init_it/etc/init.d/S95init_it and /etc/init.d/K95init_it are softlinks to /etc/init.d/init_it
#!/bin/sh RUN_D=/var/run/it GPS_PID_F=$RUN_D/gps.pid HALTBUT_PID_F=$RUN_D/haltbut.pid case $1 in start) mkdir -p $RUN_D # halt when reset button pressed /usr/local/bin/buttonhalt.sh & echo $! > $HALTBUT_PID_F # gps set time and log /usr/local/bin/gpsstart.sh & echo $! > $GPS_PID_F ;; stop) [ -f $GPS_PID_F ] && kill $(cat $GPS_PID_F) # [ -f $HALTBUT_PID_F ] && kill $(cat $HALTBUT_PID_F) ;; *) echo "usage: $0 (start|stop)" exit 1 esac exit $?
Future plans:
- display
- power off circuit
- batery voltage monitor
- temperature sensors
History:
- September 2007: initial release, only GPS logging
Links:
- http://en.wikipedia.org/wiki/Velomobile
- http://en.wikipedia.org/wiki/Cyclocomputer
- http://www.sunspot.co.uk/Projects/sweexproject.htm