Assume Python version 3 environment. Version 2 is not supported.
$ git clone https://github.com/hishizuka/pizero_bikecomputer.git
$ pip3 install PyQt5 numpy pyqtgraph cython oyaml pillow polyline aiohttp aiofiles qasync garminconnect stravacookies tb-mqtt-client
$ pip3 install git+https://github.com/hishizuka/crdp.git
# mac
$ brew install sqlite3
# linux
$ sudo apt install sqlite3 libsqlite3-dev
$ cd pizero_bikecomputer
Note: Pyqt version 5.15.0 in macOS has a qpushbutton issue, so installing newest version(5.15.1~) is recommended.
Raspberry Pi OS (32-bit) with desktop is recommended.
The program works with Raspberry Pi OS (32-bit) Lite, but missing libraries will need to be installed. Especially installing python3-pyqt5 with apt
command will also installs massive libraries of desktop software, so building PyQt5 package is recommended.
Here is my setup guide in Japanese.
Install in the home directory of default user "pi". Also, your Raspberry Pi is connected to internet and updated with apt update & apt upgrade
.
$ cd
$ git clone https://github.com/hishizuka/pizero_bikecomputer.git
$ sudo apt install python3-pip cython3 cmake python3-numpy python3-pyqt5 python3-pyqtgraph sqlite3 libsqlite3-dev libatlas-base-dev python3-aiohttp python3-aiofiles python3-smbus python3-rpi.gpio python3-psutil python3-pil bluez-obexd dbus-x11
$ sudo pip3 install oyaml sip polyline garminconnect stravacookies qasync dbus-next bluez-peripheral tb-mqtt-client timezonefinder
$ sudo pip3 install git+https://github.com/hishizuka/crdp.git
$ cd pizero_bikecomputer
Assume Serial interface is on and login shell is off in raspi-config and GPS device is connected as /dev/ttyS0. If GPS device is /dev/ttyAMA0, modify gpsd config file(/etc/default/gpsd).
$ sudo apt install gpsd gpsd-clients
$ sudo pip3 install gps3 timezonefinder
$ sudo cp install/etc/default/gpsd /etc/default/gpsd
$ sudo systemctl enable gpsd
Check with cgps
or gpsmon
command.
Assume I2C interface is on in raspi-config.
$ sudo pip3 install timezonefinder pa1010d
Check with pa1010d example program
$ sudo apt install libusb-1.0-0 python3-usb
$ sudo pip3 install git+https://github.com/hishizuka/openant.git
Assume SPI interface is on in raspi-config.
You can use python3-pyqt5 package. Don't need building Qt.
$ sudo apt install python3-pigpio
$ sudo systemctl enable pigpiod
$ sudo systemctl start pigpiod
$ sudo pip3 install st7789
see hardware_installation_pitft.md
You can use python3-pyqt5 package too.
Follow official setup guide
Follow official setup guide and install manually.
Assume I2C interface is on in raspi-config.
Install pip packages of the sensors you own.
Here is an example.
$ sudo pip3 install adafruit-circuitpython-bmp280
Manufacturer | Sensor | additional pip package |
---|---|---|
Pimoroni | Enviro pHAT | None |
Adafruit | BMP280 | None |
Adafruit | BMP390 | None |
Sparkfun | BMP581 | None |
Adafruit | LPS33HW | adafruit-circuitpython-lps35hw |
Strawberry Linux | LPS33HW | None |
DFRobot | BMX160+BMP388 | BMX160(*1) |
Adafruit | LSM6DS33 + LIS3MDL | adafruit-circuitpython-lsm6ds adafruit-circuitpython-lis3mdl |
Sparkfun | ISM330DHCX + MMC5983MA | adafruit-circuitpython-lsm6ds |
Adafruit | LSM9DS1 | adafruit-circuitpython-lsm9ds1 |
Adafruit | BNO055 | adafruit-circuitpython-bno055(*2) |
Adafruit | VCNL4040 | adafruit-circuitpython-vcnl4040 |
ozzmaker | Berry GPS IMU v4 | adafruit-circuitpython-lsm6ds adafruit-circuitpython-lis3mdl |
GPS PIE | GPS PIE | adafruit-circuitpython-bno055(*2) |
waveshare | Environment Sensor HAT | adafruit-circuitpython-bme280 adafruit-circuitpython-icm20x adafruit-circuitpython-tsl2591 adafruit-circuitpython-ltr390 adafruit-circuitpython-sgp40 |
*1 Install manually https://github.com/spacecraft-design-lab-2019/CircuitPython_BMX160
*2 You must enable i2c slowdown. Follow the adafruit guide.
If you want to get a more accurate direction with the geomagnetic sensor, install a package that corrects the geomagnetic declination.
$ sudo pip3 install magnetic-field-calculator
$ sudo apt install python3-buttonshim
$ sudo apt install adafruit-circuitpython-mcp230xx
Follow official setup guide of PiSupply/PiJuice
If cython is available, it will take a few minutes to run for the first time to compile the program.
If you use Raspberry Pi OS with desktop, starting on X Window (or using VNC) at first would be better.
$ python3 pizero_bikecomputer.py
If you use MIP Reflective color LCD module, SHARP Memory Display or E-Ink displays, run with QT_QPA_PLATFORM=offscreen
see hardware_installation_pitft.md
Before run the program, add the following environment variable.
$ QT_QPA_PLATFORM=offscreen python3 pizero_bikecomputer.py
see hardware_installation_pitft.md
If you use displays in console environment not X Window, install auto-run service and shutdown service.
If you use MIP Reflective color LCD module, SHARP Memory Display or E-Ink displays, modify install/etc/systemd/system/pizero_bikecomputer.service.
ExecStart=/home/pi/pizero_bikecomputer/exec-mip.sh
Install service scripts.
$ sudo cp install/etc/systemd/system/pizero_bikecomputer.service /etc/systemd/system/
$ sudo cp install/usr/local/bin/pizero_bikecomputer_shutdown /usr/local/bin/
$ sudo cp install/etc/systemd/system/pizero_bikecomputer_shutdown.service /etc/systemd/system/
$ sudo systemctl daemon-reload
$ sudo systemctl enable pizero_bikecomputer.service
$ sudo systemctl enable pizero_bikecomputer_shutdown.service
The output of the log file will be in "/home/pi/pizero_bikecomputer/log/debug.txt".
$ sudo systemctl start pizero_bikecomputer.service
The buttons at the bottom of the screen are assigned the following functions from left to right.
Button | Short press | Long press |
---|---|---|
Left (<) | Screen switching(Back) | None |
LAP | Lap | Reset |
MENU | Menu | None |
Start/Stop | Start/Stop | Quit the program |
Right (>) | Screen switching(Forward) | None |
The hardware buttons are designed to roughly match the software screen. You can change both short and long presses in "modules/config.py".
see hardware_installation_pitft.md
From left to right, the button assignments are as follows.
Button | Short press | Long press |
---|---|---|
A | Left (<) | None |
B | Lap | Reset |
C | Screenshot | None |
D | Start/Stop | None |
E | Right (>) | Menu |
Button | Short press | Long press |
---|---|---|
A | Left (<) | None |
B | Zoom out | Reset |
C | Change button mode(*1) | None |
D | Zoom in | None |
E | Right (>) | Menu |
Another button mode
Button | Short press | Long press |
---|---|---|
A | Move left | None |
B | Move down | Zoom out |
C | Restore button mode | Change move amount |
D | Move up | Zoom in |
E | Move right | Search route(*) |
(*)Search route by Google Directions API. Set your API key in setting.conf.
Button | Short press | Long press |
---|---|---|
A | Left (<) | None |
B | Zoom out | None |
C | Restore button mode | None |
D | Zoom in | None |
E | Right (>) | None |
Another button mode
Button | Short press | Long press |
---|---|---|
A | Move left | None |
B | Zoom out | None |
C | Restore button mode | None |
D | Zoom in | None |
E | Move right | None |
In the menu, the button assignments are changed.
Button | Short press | Long press |
---|---|---|
A | Back | None |
B | Brightness control(*) | None |
C | Enter | None |
D | Select items (Back) | None |
E | Select items (Forward) | None |
(*) If you use the MIP Reflective color LCD with backlight model.
The button assignments are as follows.
Button | Short press | Long press |
---|---|---|
PAGE | Left (<) | Right (>) |
CUSTOM | Change button mode | Menu |
LAP | Lap | None |
Another button mode
Button | Short press | Long press |
---|---|---|
PAGE | ANT+ Light ON/OFF | Brightness control |
CUSTOM | Restore button mode | None |
LAP | Start/Stop | None |
Button | Short press | Long press |
---|---|---|
PAGE | Left (<-) | Right (->) |
CUSTOM | Change button mode | Zoom out |
LAP | Zoom in | None |
Another button mode
Button | Short press | Long press |
---|---|---|
PAGE | None | None |
CUSTOM | Restore button mode | Zoom out |
LAP | Zoom in | None |
Button | Short press | Long press |
---|---|---|
PAGE | Left (<-) | Right (->) |
CUSTOM | Change button mode | Zoom out |
LAP | Zoom in | None |
Another button mode
Button | Short press | Long press |
---|---|---|
PAGE | None | None |
CUSTOM | Restore button mode | Move left |
LAP | Move right | None |
In the menu, the button assignments are changed.
Button | Short press | Long press |
---|---|---|
PAGE | Select items (Forward) | None |
CUSTOM | Select items (Back) | None |
LAP | Enter | None |
Left side
- "-": zoom in
- "L": lock / unlock
- The map can be moved when unlocked.
- "+": zoom out
- "G": route search by Google Directions API
- set token in GOOGLE_DIRECTION_API section of setting.conf
Right side
- "left"
- "up"
- "down"
- "right"
Left side
- "-": zoom in
- "L": lock / unlock
- The course profile can be moved to left or right when unlocked.
- "+": zoom out
Right side
- "left"
- "right"
- ANT+ Sensors
- Pairing with ANT+ sensors.
- You need to install the ANT+ library and to set ANT section of setting.conf with
status = True
. - The pairing setting is saved in setting.conf when a sensor is connected, so it will be automatically connected next time you start the program.
- ANT+ MultiScan
- Wheel Size
- Enter the wheel circumference in mm when the ANT+ speed sensor is available.
- It is used to calculate the distance.
- The default value is 2,105mm, which is the circumference of 700x25c tire.
- The value is saved in setting.conf
- Adjust Altitude
- Enter the current altitude to correct the sea level and increase the accuracy when an I2C pressure sensor is connected.
- Local Storage
- Select course .tcx file in
courses
folder.
- Select course .tcx file in
- Ride with GPS
- If you set token in setting.conf, select course from Ride with GPS. Internet access is required. Sample image are shown as belows.
- Android Google Maps
- Receive routes from Google Maps on Android via Bluetooth. The result is parsed using https://mapstogpx.com.
- To use this feature, pair the device with an Android smartphone with obexd activated.
bluez-obexd
anddbus-x11
packages are required to be installed in advance.eval 'dbus-launch --auto-syntax' /usr/libexec/bluetooth/obexd -d -n -r /home/pi -l -a
- If properly paired, Android Google Maps Directions route search results can be sent with 'Share Directions' > 'Bluetooth' > (your Raspberry Pi).
- Auto BT Tethering
- Upload to ThingsBoard via bluetooth tethering via a paired smartphone which are already paired using
bluetoothctl
. - The following
Select BT device
must also be specified. - Since it operates intermittently once every two minutes, the power consumption of the Raspberry Pi and smartphone is much lower than a constant connection via Wifi tethering.
- Upload to ThingsBoard via bluetooth tethering via a paired smartphone which are already paired using
- Select BT device
- Specify the device to use for bluetooth tethering.
- Live Track
- Enable real-time data upload to the ThingsBoard dashboard.
tb-mqtt-client
package, which can be installed with thepip3
command, is required.- Also, thingsboard device access token is required in THINGSBOARD_API of setting.conf.
- You will also need to upload and set up a dashboard. For more details of Thingboard setup, see thingsboard_setup.md.
Uploads the most recent activity record file(.fit) created by the reset operation after the power is turned on.
- Strava
- You need to set the Strava Token in Strava API section of setting.conf.
- Garmin
- You need to set the Garmin setting in GARMINCONNECT_API section of setting.conf.
- Ride with GPS
- You need to set the Ride with GPS Token in RIDEWITHGPS_API section of setting.conf.
- Select Map
- Select a standard map.
- Map Overlay
- Toggle map overlay(heatmap, rain map and wind map) and select an overlay map.
- Heatmaps are cached, but rain map and wind map require internet connection to fetch the latest images.
Strava heatmap (bluered)
RainViewer
気象庁降水ナウキャスト(Japan)
openportguide
If ANT+ powermeter is available, set both parameters are used in W'balance (%). They are determined by histrical activity data with bicycle power with GoldenCheetah or intervals.icu.
- Network
- See below.
- Debug (experimental)
- Debug log: view "log/debug.log".
- Disable Wifi/BT, Enable Wifi/BT: modify /boot/config.txt to turn Wifi and BT On/Off at the hardware level. Reboot required for settings to take effect.
- Update: execite
git pull origin master
.
- Power Off
- Power off the raspberry pi zero when the program is started with the service.
- Wifi, Bluetooth
- Turn Wifi and BT On/Off at the software level using
rfkill
.
- Turn Wifi and BT On/Off at the software level using
- BT Tethering
- If dbus and bluez is available, start bluetooth tethering with a smartphone which are already paired using
bluetoothctl
.
- If dbus and bluez is available, start bluetooth tethering with a smartphone which are already paired using
- IP Address
- Show IP address. This can be used for ssh access while tethering a smartphone.
- GadgetBridge
- Recieve notifications and GPS location from a smartphone. Install GadgetBridge Android app and toggle on.
dbus-next
andbluez-peripheral
packages, which can be installed with thepip3
command, is required.- GadgetBridge app settings
- Enable all permissions.
Settings
>Discovery and Pairing options
>Ignore bonded devices
: Off,CompanionDevice Pairing
: On,Discover unsupported devices
: On,Scanning intensity
: 2 or 3- From
Connect new device
in the menu or+
button, you can enter 'Device discovery
. Select the device(shown as host name), long press, and do pairing asBangle.js
.
- Get Location
- Enable GPS location acquisition by Gadgetbridge.
- GadgetBridge app settings
- Click the Settings button in the list of devices on the top screen.
Use phone gps data
: On,GPS data update interval in ms
: 5000-10000.
- Click the Settings button in the list of devices on the top screen.
There are five different configuration files. You need to edit at the first "setting.conf" and don't need to care about the other files.
The settings are dependent on the user environment.
Set the value before starting the program. If the value is set during running, it will not be read.
display
- Set the type of display.
- There are definitions in
modules/config.py
for the resolution and availability of the touchscreen. None
: default (no hardware control)MIP_JDI_color_400x240
: JDI 2.7 inch MIP reflective color LCD module. (LPM027M128C/LPM027M128B)MIP_JDI_color_640x480
: JDI 4.4 inch MIP reflective color LCD module. (LPM044M141A)MIP_Sharp_mono_400x240
: SHARP 2.7 inch MIP monochrome LCD module. (Sharp LS027B7DH01)MIP_Sharp_mono_320x240
: SHARP 4.4 inch MIP monochrome LCD module. (Sharp LS044Q7DH01)Papirus
: PaPiRus ePaper / eInk Screen HATDFRobot_RPi_Display
: e-ink Display ModulePirate_Audio
,Pirate_Audio_old
: Pirate Audio ("old" assigns the Y button to GPIO 20.)Display_HAT_Mini
: Display HAT MiniPiTFT
: PiTFT2.4 (or a PiTFT2.8 with the same resolution)
autostop_cutoff
- Set the threshold for the speed at which the stopwatch will automatically stop/start after it is activated.
- The default value is
4
[km/h].
wheel_circumference
- Set the wheel circumference required for ANT+ speed sensor use.
- It can also be set on the screen.
- The default value is
2105
(unit is mm) for 700x25c.
gross_ave_speed
- Set the gross average speed, which is used in the brevet and the like.
- It is used for cycling long distances with a set time limit.
- The screen shows the actual gross average and the gained time from this gross average speed.
- The default value is
15
[km/h].
lang
- The language setting of the label of items.
- The default is
EN
.
font_file
- Set the full path of the font which you want to use.
- Place the fonts in
fonts/
folder.
map
- Set the map.
- The
G_MAP_CONFIG
in modules/config.py provides some preset definitions. wikimedia
: An example map of a full-color map. https://maps.wikimedia.org/jpn_kokudo_chiri_in
: A map from Japan GSI. https://cyberjapandata.gsi.go.jp- (obsolete)
toner
: A map for monochrome colors. http://maps.stamen.com/toner/ - You can add a map URL to map.yaml. Specify the URL in tile format (tile coordinates by [x, y] and zoom level by [z]). And The map name is set to this setting
map
. - Also, you can set raster mbtiles mapsets generated from mb-util. It is sqlite3 db packed with raster maptile images. The definition in map.yaml is following with sample mbtile map named
sample_mbtile
placed atmaptile/sample_mbtile.mbtiles
.
map.yaml entry
sample_mbtile:
url:
attribution: some attribution.
use_mbtiles: true
- Enable ANT+ with
status = True
. - Additional setting is not necessary because the settings are written when pairing ANT+ sensors.
- If there are some settings, the program will connect at startup.
If ANT+ power meter is available, set cp
as CP and w_prime
as W prime balance.
In modules/sensor_i2c.py, use the change_axis method to change the axis direction of the IMU (accelerometer/magnetometer/gyroscope) according to its mounting direction. The settings are common, so if you use individual sensors, make sure they are all pointing in the same direction.
X, Y, and Z printed on the board are set to the following orientations by default.
- X: Forward. Positive value for upward rotation with accelerometer.
- Y: Left. Positive value for upward rotation with accelerometer.
- Z: Downward. Positive value at rest with accelerometer.
Axis conversion is performed with the following variables.
axis_swap_xy_status
: Swaps the X and Y axes.- The default is
False
, orTrue
if you want to apply it.
- The default is
axis_conversion_status
: Inverts the signs of X, Y and Z.- Change to
False
by default, orTrue
if you want to apply it. axis_conversion_coef
: Fill in [X, Y, Z] with ±1.
- Change to
mag_axis_swap_xy_status
, mag_axis_conversion_status
and mag_axis_conversion_coef
can be set if magnetometer axes are different from accelerometer and gyroscope. For example, SparkFun 9DoF IMU Breakout - ISM330DHCX, MMC5983MA (Qwiic).
mag_declination
is automatically set by magnetic-field-calculator package.
(experimental)
spi_clock
: specify SPI clock of the following displays.MIP
: MIP color reflective LCD module 2.7 inch.MIP_Sharp
: SHARP Memory Display Breakout
Set up for uploading your .fit file to Strava in the "Strava Upload" of the menu. The upload is limited to the most recently reset and exported .fit file.
To get the Strava token, see "Trying the Authorization Method (OAuth2) of the Strava V3 API (In Japanese)".
Set the client_id
, client_secret
, code
, access_token
and refresh_token
as described in the article. Once set, they will be updated automatically.
If you want to use Strava HeatMap, set email
and password
.
If you want to use heatmap or upload activities to RidewithGPS, set your token
of the Ride with GPS API.
- Sign up for an account with RideWithGPS.
- Create an API key on RWGPS API.
- Set your token.
If you want to upload activities to Garmin Connect, set your email
and password
.
If you want to search for a route on a map, set your token
of the Google Directions API.
If you want to use ThingsBoard dashboard, set your token
of the Thingboard device access token.
It stores temporary variables such as values for quick recovery in the event of a power failure and sensor calibration results.
Most of them are deleted on reset.
Set up the placement of each item on the display of a screen consisting only of numerical values. (Maps and graphs cannot be edited with this setting.)
The following is an example of a top screen.
MAIN:
STATUS: true
LAYOUT:
Power: [0, 0, 1, 2]
HR: [0, 2]
Speed: [1, 0]
Cad.: [1, 1]
Timer: [1, 2]
Dist.: [2, 0]
Work: [2, 1]
Ascent: [2, 2]
MAIN
: The name is optional. It is not used in the program, but the followingSTATUS
andLAYOUT
are displayed on one screen. The number of screens can be increased or decreased.STATUS
: Show this screen or not.- Set the boolean value of
true
orfalse
of yaml format.
- Set the boolean value of
LAYOUT
: Specify the position of each element.- Each element is defined in modules/gui_congig.py under
G_ITEM_DEF
. You can also add your own variables to the modules/gui_congig.py file. - The position is set up in the form of [Y, X], with the top left as the origin [0, 0], the right as the positive direction of the X axis, and the bottom as the positive direction of the Y axis. The implementation is the coordinate system of QGridLayout.
- If you want to merge multiple cells, the third argument should be the bottom Y coordinate + 1, and the fourth argument should be the right X coordinate + 1. For example,
Power: [0, 0, 1, 2]
merges the [0, 0] cell with the right next [0, 1] cell.
- Each element is defined in modules/gui_congig.py under
Register the map name, tile URL and copyright in this file. An example of Strava HeatMap is shown below.
strava_heatmap_hot:
url: https://heatmap-external-b.strava.com/tiles-auth/ride/hot/{z}/{x}/{y}.png?px=256
attribution: strava
- Line 1: Map name
- This is the string to be set to GENERAL -> map in setting.conf.
- Second line: tile URL
- Set the tile URL. Tile coordinates X, Y, and zoom Z should be listed with
{x}
,{y}
, and{z}
.
- Set the tile URL. Tile coordinates X, Y, and zoom Z should be listed with
- Line 3: Copyright.
- Set the copyright required for the map.
There are some settings which the user doesn't need to care about and some variables defined in the above configuration file.
Put course.tcx file in course folder. The file name is fixed for now. If the file exists, it will be loaded when it starts up.
To download the map in advance, run the program manually with the --demo option. It will start in demo mode.
$ python3 pizero_bikecomputer.py --demo
Press the left button to move to the map screen and leave it for a while. The current position will move along the course and download the required area of the map.