All projects
January 2025 – February 2025 Shipped

PiTrainer

A connected gym tracker: Raspberry Pi sensors, a cloud backend and a mobile app

  • 3 workout states synchronised between app, cloud and Pi
  • 96 statistical features per rep for the quality model
  • iOS + Android from one React Native codebase

PiTrainer turns a gym machine into a tracked exercise. A Raspberry Pi with an accelerometer and a magnetometer counts reps and measures how each one moved, a backend on AWS stores the workout and scores every rep, and a mobile app starts and ends sets and shows the results. It supports seated cable rows and lat pulldowns. I built it with Hector Oga and Zakariyyaa Chachia, who wrote the software on the Pi: the sensor drivers, a Kalman filter to estimate motion from the accelerometer, rep counting and the per-set feedback on range, pace and smoothness.

Backend

I wrote the Flask backend that connects the phone and the Pi, running on an AWS EC2 instance. The system is a state machine with three states (idle, doing reps and resting) controlled from the app: the app sends workout and set starts and ends to the server, and the Pi polls the server to find out which exercise to track and whether a set is in progress. State is kept per user and per device, so several people can train at the same time with their own phones and Pis. The app polls the server every 500 ms for the live rep count.

Accounts use salted bcrypt password hashes and JWT authentication, and each user record is linked to a Pi so that sensor data reaches the right account. Workouts and sets are stored in DynamoDB across three tables (users, workouts and per-set results), and the Pi’s endpoints are guarded against malformed requests.

Mobile app

I built the mobile app in React Native with Expo, so one codebase runs on iOS and Android. It has login and registration, a workout screen that starts and ends sets and shows the live rep count, a home screen with a breakdown of the last workout, a history screen with charts of rep quality over time and the average quality of each workout, and an analysis screen with the Pi’s feedback on each set of the latest workout.

Scoring rep quality

The Pi sends a summary of each rep’s motion, and the backend scores it from 0 to 100 with a model I trained. Each rep is described by 12 signals (acceleration, velocity, position and magnetic field on three axes), each reduced to 8 statistics such as mean, spread, skew and kurtosis, giving 96 features. I started with a decision tree tuned by grid search and moved to XGBoost, trained on 50 labelled reps of seated cable rows. When a workout ends, the backend loads the model for that exercise, scores every rep and stores the results with the workout.

The backend also computes the figures the app displays: total reps and workouts, estimated calories, average rep quality over time, the best workout, and a breakdown of the latest workout into perfect, good, fair and poor reps.