Skip to content
Lasse Reinhold edited this page Apr 3, 2024 · 137 revisions

The $13 open source/hardware DIY bicycle power meter

Update 30. aug. 2018: Now with 56 samples/s. You need to update both the Android app and upload the new Arduino program

Android app

Specifications

  • Strain gauge based left-only pedal arm power meter
  • Only Android phones are supported. Needs Android 4.1 or later, and even very small screen sizes are supported
  • Around 0.08% wattage drift per degree celcius change (tested on Shimano 105), but with fast and simple zero calibration.
  • Precision: No idea. Please contribute.
  • Sampling rate: 56 / second (up to 100 with some tweaking)
  • File logging of speed (GPS based), watt, torque, RPM and pedal position at full sampling rate
  • 52 mA at 3.6 V (50 hours on a 2600 mAh 18650 lithium-ion battery, or 15 hours on three 800 mAh AAA NiMH batteries in serial, for example inside a hollow crank)

FAQ

Is Powerino compatible with Ant+ or GATT bike computers or watches? No, That would need a different transceiver than the Bluetooth HC-05 used in this project, and also need major rewrites of the source code to match the Ant+ or GATT protocols.

Buying all the stuff

You will need all the items below. I suggest to verify that their pinouts and descriptions match the schematics in this wiki to avoid confusion.

HX711 ADC. I used this red-colored device that comes with a metal shielding that can be attached to reduce interference. Other versions have their OUT+ pin named E+, rightmost GND named E-, D0/RX named DT and CK/TC named SCK and their positions differ from the schematics. These might also be possible to use.

HC-05 Bluetooth. There are HC-06 versions too and I'm not sure if these are directly compatible.

MPU-6050 gyro/accel. There are numerous gyros that are based on other ICs than MPU-6050 and these are not compatible with the provided Arduino program in this repository.

Arduino Mini Pro 3.3V with Atmega328P. Note that older versions exist that do not have the same pin layout. Make sure it's a 3.3V version and not 5V to get more battery options and better battery life.

Five 350 Ohm strain gauges. You will only need two, but I suggest to buy five because these cheap gauges are extremely brittle and may break. I recommend buying gauges that have thin wires pre-attached, because the torque that a thicker soldered-on wire can exert will snap off the soldering pad. Update: 120 ohm gauges should also work with no adjustments or modifications, though it has not been tested by me in practise.

FT232 to upload the Arduino program. Many versions have a mini USB port instead of micro USB, just be aware if you don't have a mini USB cable around.

Four 10K 1% resistors. Any other identical set of precision resistors will also work, but they should be in the range 5K - 20K. A smaller resistance will increase the effects of variances in wire lengths and diameters. A larger resistance will make it more sensitive to moisture and current creep.

You will also need a 3.6V LiIon or LiPo battery, or 3 NiMH batteries in series. The power meter uses 52 mA @ 3.6 V which is the minimum required voltage.

Uploading Arduino program

Do this step before soldering everything together. First install the driver for the FT232 and also install the Arduino IDE.

Now download the Powerino "firmware" and open the Arduino\powermeter\powermeter.ino file from the Arduino IDE. Select Arduino Pro or Pro Mini as Board and select Atmega328P (3.3V, 8 MHz) as Processor and then plug the FT232 into an USB port and select the corresponding Port by trial-and-error.

Now plug the 6 pin headers of the FT232 directly into the row of pin holes on the end of the Arduino, turned such that Vcc goes into Vcc, and exert a little torque to make good contact of all pins, and click Upload.

If everything succeeded, the program will make the Arduino flash its green LED light rapidly eight times in a row each time you power it on (supply 3.3 - 5V to its RAW and GND pins). If it only flashes a single time or not at all, something failed.

Assembly

Wire up everything like this: Schematics

Other versions of the HX711 ADC have their OUT+ pin named E+, rightmost GND named E-, D0/RX named DT and CK/TC named SCK and their positions differ from the schematics.

The connections between the gauges and HX711 must be soldered and go through continuous wires without any connectors or switches - the wires carry delicate millivolts that do not travel well across the surfaces of a switch or a connector. So if you want the power meter to be removable, glue to HX711 to the pedal arm and place a 4 wire connector after that. The Android app supports that you can switch between two bikes.

It's important to connect the Vcc pin of the Bluetooth module to the RAW pin of the Arduino and not to the Vcc pin because the Vcc pin only provides 3.3 V which is too little for the required 3.6 V of the Bluetooth module.

Assembled

On the above photo, the two resistors that are connected to the Arduino are missing. These two are actually optional - they are only for measuring and displaying the battery voltage on the Android display. If you leave them out, the low-battery icon will just be permanently on.

Strain gauges

With the left pedal arm pointing horizontally on the bike, one gauge must be mounted on the top surface of the pedal arm and one directly beneath it on the bottom side. Find a spot which is as flat as possible and orient them such that they follow the direction of the arm. The wires can point either both forwards or backwards, chose whatever direction gives the best cable wiring.

Any mounting position is fine, both at the middle or around either end. The gauges will sense how much they are being elongated, and the elongation is due to the stretching of the pedal arm surface as it bends under load. The resolution (due to noise-to-signal ratio) is better than 10 grams if averaging over 56 samples like shown in the "kg" field on the Android screen.

By using these two opposing strain gauges in a half Wheatstone bridge, you get good temperature compensation and a decent absense of parasitic forces.

Use super glue and tape to mount them like in this video. Because the cheap non-branded gauges are so brittle, don't attempt to peel off the tape at the end. Just trim off some of the excess instead.

It doesn't matter which gauge you glue to the top or which you glue to the bottom - chose whatever combination gives the best cable wiring.

Battery

I used three NiMH cells in serial which are stored inside the hollow crank and connects through a water tight audio jack connector. I also sealed the powermeter itself with the shrink wrap that covers various plastic bottles.

Android

From your Android phone, download this apk file. If it doesn't install automatically after downloading, then try and navigate to the downloaded file and open it.

Older stable version, if above latest version has bugs

Turn on the Powermeter and pair with it in the Bluetooth settings of your phone. Its name is most likely HC-05 and if it asks for a pairing password, it's usually 1234 or 0000.

NOTE: If the app fails to connect, it might help to recompile and upload the Arduino program again, but with "bool command_mode = false;" in the beginning of the powermeter.ino file.

Calibration

After pairing, start the app, swipe to the right to go to settings and do a setup calibration. You will need a weight of some kilograms to hang on the pedal for this step. I'm using big a hammer. Note that you can turn the bike upside down during the calibration steps - just reverse "forwards" and "backwards" in the calibration instructions. The "Forwards with weight" step is shown below.

All calibration data is stored in the Arduino EEPROM so that you can switch phone or reinstall the app without having to calibrate again.

App and data logging

The "kcal" field in the app tells how many physical watts you have exerted on the pedals. The "metabolic kcal" basically tells how many kcalories you need to eat, taking the efficiency of your body in count. I think this is what all the cardio machines in gyms are showing.

All data during a ride will be saved in the Documents folder in two files: Powermeter <date>_<time>.txt which contains all samples received from the Bluetooth module, and Powermeter <date>_<time>_simple.txt which contains only the data fields that are visible on the user screen.

The simple file doesn't need much explanation, it contains one line for each second, plus a summary at the bottom with total kcalories, etc. The other file contains around 56 lines per second and looks like this:

# time, watt, cadence, torque, pedal position, speed

0	201	75.5	70.3	765	9.70
18	202	75.7	70.4	800	9.70
217	199	75.4	70.0	804	9.70
...
20314	100	60.3	9.32	-242	3.60
20338	98.5	61.0	9.30	-247	3.60
20363	100	60.3	9.31	-279	3.60

Time is in milliseconds, cadence is in RPM, torque is in Nm, speed is in m/s. Pedal position is the component of gravity that is directed along the pedal arm (and is very noisy and not used in any calculations yet).

Using Sigview you can easily plot a file as graph:

Terminal

Download Serial Bluetooth Terminal from the Android store and connect to the powermeter.

First send the letter c (lower case c) to make it show live data. NOTE: If you later want to connect it to the Powerino app, turn the powermeter off and on to restore its defaults, else it might not be able to connect or work properly.

Now send the string p 0 1000 to make it output only once every second so that you can experiment:

s: Show battery voltage and temperature.

p y g: Read the strain gauges each g milliseconds and read the gyro (which senses pedal arm RPM) each y milliseconds. Example: p 0 10 (which is default). Higher frequencies increase power consumption.

y n: When reading the gyro, read n values and use the average to calculate RPM. Higher value increases precision but decreases sample rate. Example: y 4 (which is default).

er a n: Print n bytes of EPROM, starting at address a. Example: er 0 10

ew a n b1 b2 b3...: Store n user-given bytes of EPROM, starting at address a. Example: er 0 3 111 222 123. Don't use this feature unless you know what you're doing :)

All settings are restored to defaults when power is turned off, except data written to EPROM.

Advanced

You can program the HC-05 Bluetooth module from its default baudrate of 9600 to 38400 which will both increase the sample rate to 100 / second and also decrease total power consumption from 52 to 35 mA. After programming it you need to recompile the Arduino project with the //const int btrate = 38400; line enabled in the powermeter.ino file.

If you want to measure measure both pedal arms you will need a second HX-711 module; even though it is dual-channel, it takes some 100 ms to switch channel (you may poll it earlier but get random values until it has stabilized) which would decrease the sample rate too much.

Contributions

If you want to contribute, here's a list of things that could be useful:

Phone application

  • Making the file log output in a format compatible with all the existing pedaling/power analysis software out there
  • The Java application is mostly on the "functional prototype" state. It uses lots of polling rather than events because I'm not very familiar with proper Android development. A rewrite might be needed.
  • Auto calibration at temperature changes (store table of zero points at different temperatures in EEPROM). The Arduino already sends ambient temperature to the app every 30 seconds (from the MPU-6050 temperature sensor).
  • iOS version (Android version should probably be re-structured first, to have a nice reference)

Arduino program

  • The delay_idle() method isn't really saving much power because it wakes up every 128 clocks? Make it sleep longer when possible? Expertise needed...
  • I think the MPU 6050 might have a mode where it averages all the values over a period and returns that. That would give more smooth results. It currently reads 4 values and takes the average (reading more values would decrease sample rate too much).
  • Find a compressed format for the data samples, so that 9600 baudrate is sufficient. Because programming HC-05 can be cumbersome.