The problem
Energy-per-km and range figures swing widely on hilly routes because climbing stores potential energy and descending returns part of it. A consumption figure that ignores road grade misleads both the range estimator and the rider. Production vehicles use GPS altitude, maps or inertial sensors; a low-cost barometer plus an IMU can give a usable grade signal if drift, noise and vehicle acceleration are handled properly.
Objectives
- Estimate altitude from BMP280 pressure and road pitch from the MPU6050, and fuse them into a road-grade estimate
- Model longitudinal vehicle energy (rolling, aerodynamic, grade and inertial terms) and separate the grade component
- Report raw and grade-corrected Wh/km on the LCD and over UART
- Compare the fused estimator against barometer-only and IMU-only baselines on logged runs with a known elevation change
What you need
From the EV Embedded Development Kit
- STM32F103C8T6 microcontroller unit (main controller)
- BMP280 pressure and temperature sensor
- 3-axis accelerometer and gyroscope (MPU6050, I2C)
- Analog potentiometer input
- SPI flash memory
- 16×2 LCD
- Serial UART interface
Software
- STM32CubeIDE with HAL drivers
- Embedded C (fixed-point maths)
- Python with pandas, NumPy, SciPy and matplotlib
- MATLAB/Simulink (optional, for the vehicle energy model)
Extra parts
- Portable low-voltage supply suited to the kit's power port, and a padded enclosure — Field runs on a ramp, staircase or as a secured passenger load need the board powered away from the laptop and protected from knocks.
Key concepts
- Barometric altitude
- Altitude follows from pressure through the hypsometric (barometric) formula. Absolute altitude drifts with weather, but altitude differences over a few minutes are usable for grade.
- Road grade
- Grade is rise over run, dh/ds. With speed v, it can be computed as (dh/dt)/v, which becomes unstable at low speed and must be gated.
- Accelerometer pitch contamination
- A static accelerometer measures gravity, so pitch follows from atan2 of its axes; when the vehicle accelerates, the longitudinal acceleration adds to the reading and must be subtracted using the speed derivative.
- Complementary and Kalman fusion
- The barometer is noisy but drift-free over short spans; the gyro is smooth but drifts. A complementary filter or a small Kalman filter combines them into one grade estimate.
- Grade energy term
- Climbing power is m·g·v·sin(θ). Subtracting it from total traction energy gives a consumption figure that reflects driving and vehicle efficiency rather than terrain.
Step-by-step guide
- 1
Define the vehicle model and test routes
Choose a reference vehicle class (for example an electric two-wheeler) and write down mass, rolling-resistance coefficient, frontal area and drag coefficient from published textbook ranges, citing your source. Plan at least three test routes with a known elevation change: a building staircase or lift, a ramp and a short road loop. Measure the height difference with a tape or from building drawings so you have ground truth. Decide how speed will be emulated, because the kit has no wheel-speed sensor: the potentiometer as a speed set-point, or a PC-side speed profile sent over UART.
Checkpoint: A one-page model sheet lists every parameter with its source and every route has a measured elevation change.
- 2
Board setup and clock configuration
In STM32CubeMX set SYSCLK to 72 MHz from HSE through the PLL. Enable the DIP switches for the BMP280, MPU6050, potentiometer, LCD, SPI flash and UART blocks only. Configure I2C1 at 400 kHz for the MPU6050, SPI for the BMP280 and the flash with separate chip-select GPIOs, ADC1 on the potentiometer channel, a UART at 115200 baud and a basic timer for a 50 Hz sampling tick. Run an I2C bus scan and print every responding address over UART.
Checkpoint: The UART console shows the MPU6050 address and the BMP280 chip-ID register returns its expected value over SPI.
- 3
BMP280 driver with oversampling
Read the factory calibration words once at start-up, configure pressure oversampling high and enable the internal IIR filter, then implement the datasheet's integer compensation routines rather than the floating-point ones, since the Cortex-M3 has no FPU. Convert compensated pressure to altitude relative to a reference pressure captured at power-up. Log 10 minutes of stationary data and compute the standard deviation of altitude to know your noise floor before any filtering.
Checkpoint: Stationary altitude noise is measured and documented, and lifting the board by about one metre shows a clear step in the log.
- 4
MPU6050 driver and pitch estimate
Configure the MPU6050 with a sensible digital low-pass setting and ±2 g accelerometer range. Calibrate gyro bias by averaging 2 seconds of stationary samples. Compute accelerometer pitch with atan2 and integrate the gyro pitch rate. Implement atan2 with a lookup table or a polynomial approximation in Q15 to keep the 50 Hz loop light. Mount the board so its axes align with the direction of travel and record the mounting convention.
Checkpoint: Tilting the board to a measured angle on a protractor jig gives pitch within your stated tolerance, and gyro drift over one minute is logged.
- 5
Speed emulation and acceleration compensation
Map the potentiometer to a speed range (for example 0–40 km/h) or accept a speed profile streamed from Python. Differentiate the filtered speed to get longitudinal acceleration and subtract it from the accelerometer's forward axis before computing pitch, so that acceleration is not mistaken for climbing. State clearly in the report that speed is emulated and that real deployment needs a wheel-speed signal.
Checkpoint: With the board level, sweeping the emulated speed quickly does not produce a false pitch above your tolerance once compensation is on.
- 6
Grade fusion filter
Implement two baselines first: barometer-only grade from (dh/dt)/v with a speed gate below which grade is held, and IMU-only grade from compensated pitch. Then implement a complementary filter on pitch using barometric grade as the low-frequency reference, and optionally a two-state Kalman filter (grade, gyro bias). Keep all three running in parallel so a single log compares them. Use Q-format arithmetic and document the scaling of every variable.
Checkpoint: On the staircase or ramp, all three estimates are logged together and the fused estimate is visibly smoother than barometer-only and less drift-prone than IMU-only.
- 7
Energy model and grade correction
Compute traction power from the model: rolling, aerodynamic, inertial and grade terms, using emulated speed and estimated grade. Integrate total energy and grade energy separately over distance. Report raw Wh/km and corrected Wh/km, where the corrected figure removes the grade energy. Choose whether to credit downhill energy fully or with a regeneration efficiency factor and justify it. Run the model on the PC in Python with the same equations to cross-check the firmware.
Checkpoint: Firmware and Python give the same energy totals within rounding for a replayed log.
- 8
Logging, display and data export
Write each 50 Hz sample (time, pressure, altitude, pitch, three grade estimates, speed, power) as a packed binary record to the SPI flash, with a header page holding the run number and parameters. Show grade and corrected Wh/km on the 16×2 LCD at 2–4 Hz. Add a UART command to dump a run as CSV. Write a Python script that parses the dump, plots each estimator against ground-truth elevation and computes error metrics.
Checkpoint: A complete run is dumped, parsed and plotted without lost records, verified by a record counter.
- 9
Field runs and quantified comparison
Repeat each route at least five times. For each run compute the elevation-change error, RMS grade error where ground truth exists, and the difference between raw and corrected Wh/km on climbing and descending segments. Also record a stationary run of 30 minutes to quantify barometric drift from weather and ventilation. Tabulate mean and spread for each estimator. Keep the mounting, warm-up time and starting procedure identical across runs so that differences come from the estimators, not the setup.
Checkpoint: A results table gives mean and standard deviation of error for barometer-only, IMU-only and fused estimates on every route.
- 10
Report and sensitivity analysis
Write up the model, the estimators, the fixed-point design and the results. Include a sensitivity study: how corrected Wh/km changes with ±10 per cent error in mass, rolling coefficient and grade. Discuss the limits honestly: emulated speed, short routes, the barometer's sensitivity to air movement, and the board not being a real vehicle. Close with recommendations for using such a grade signal in a range estimator.
Checkpoint: The report contains the comparison table, sensitivity plots and a limitations section reviewed by the guide.
Testing & validation
- Elevation change measured by each estimator against tape-measured or drawing-based ground truth on repeated runs
- Stationary 30-minute drift test of barometric altitude
- False-grade test: level board with rapid emulated acceleration, with and without compensation
- Firmware energy totals cross-checked against an independent Python implementation on replayed logs
- Loop timing measured with a GPIO toggle to show the 50 Hz deadline is met
Expected results
A working grade estimator on the main controller that displays live grade and grade-corrected Wh/km, a flash-logged dataset of repeated runs, and a quantified comparison of barometer-only, IMU-only and fused estimates with a sensitivity analysis of the energy correction.
Research angle for your M.Tech thesis
Research questions: how accurately can a low-cost barometer and IMU estimate grade at two-wheeler speeds, and how much of the run-to-run variance in Wh/km does grade correction remove? Metrics: RMS grade error, elevation-change error, variance of Wh/km across repeated runs before and after correction, and CPU load of each filter in fixed point. Baselines: barometer-only, IMU-only and no correction. A credible contribution would be a careful fixed-point fusion design with an error budget, validated on repeated runs with ground truth, together with an honest account of the emulated-speed limitation.
Take it further
- Feed the corrected Wh/km into a range estimator and compare range error on a hilly versus flat profile
- Add a wheel encoder on a bicycle wheel as an add-on to replace emulated speed
- Replace the complementary filter with an adaptive Kalman filter that tunes noise covariances online
- Broadcast grade and corrected consumption as CAN frames for a vehicle control unit
Viva and review questions
Why not compute grade from the accelerometer alone?
When the vehicle accelerates or brakes, the longitudinal acceleration appears on the same axis as the gravity component, so accelerometer-only pitch confuses acceleration with slope. It must be compensated with the speed derivative or fused with another source.
Why does barometric grade become unreliable at low speed?
Grade is (dh/dt)/v, so as v approaches zero any altitude noise is divided by a tiny number. The estimator holds the last grade below a speed threshold.
Why did you use integer compensation for the BMP280?
The STM32F103 has no FPU, so floating-point maths is emulated in software and is slow. The datasheet's integer routines and Q-format arithmetic keep the 50 Hz loop within its deadline.
How do you treat downhill energy in the corrected figure?
Downhill segments return potential energy; we credited it with a stated regeneration efficiency factor, and the report shows results for the chosen factor and for full credit.