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.

Image

The yellow lines are the rs232 connections on J2 for /dev/ttyS0.

J2 connections:

  • 1- RX
  • 2- +3.3v,
  • 7- TX
  • 8- GND

Image

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.

Image

Here the circuit is attached to the router. A case covering the whole thing still needs to be made.

Index


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 $?

Index


Future plans:

  • display
  • power off circuit
  • batery voltage monitor
  • temperature sensors

Index


History:

  • September 2007: initial release, only GPS logging

Index


Links:

Index