Goals
- Track how far, how fast, and how long Ruby runs
- Visualize and export data
- Learn more about a Phodopus campbelli hamster behavior through real data
How It Works
The first prototype was made with an Arduino UNO:

We measure speed using the basic formula:
Speed = Distance / Time
We know the wheel's radius (6 cm), so we can compute its circumference using:
C = 2 * π * r
Each time the magnet passes the reed sensor, we count a full rotation. By measuring how many rotations happen every 2 seconds, we can estimate Ruby’s speed.
To count the wheel’s rotations, we use a reed switch sensor, which detects magnetic fields. By carefully placing the sensor and attaching a small magnet to the wheel, we can count each time the magnet passes in front of the sensor.
The magnet’s position must be chosen so that it passes close to the sensor once per full rotation.
Pay some attention because the magnet can pass near the sensor slowly, which may result in multiple readings. To avoid this, we used a comparison with the previous value in the code to detect only the falling edge of the magnet's passage.

Over time, we calculate:
- Maximum speed
- Total distance run
- Time spent running
- Average speed (only while active)
The Code
The code changed a lot during times, the first version was not connected to internet and run on an Arduino UNO:
After the first prototype with Arduino I've created a version for Wemos microcontroller with a small SSD1306 display (128x64 pixel).
The simplified sketch (available in the file section and also in my repository on Github) handles all core functions of the smart hamster wheel: reading the sensor, calculating speed and distance, tracking activity time, and displaying the data on an OLED screen.
This is the final configuration schema:

Display and Sensor Initialization
-
The SSD1306 OLED display is connected via I2C on pins
D2
andD1
. -
The reed switch sensor is connected to pin
D7
to detect each full wheel rotation. -
Wheel radius is set to
6 cm
, and the circumference is computed in meters.
Main Loop Behavior
The loop handles several tasks:
1. Speed Calculation (every 2 seconds)
-
Counts how many times the magnet passed the sensor in the last 2 seconds.
-
Multiplies that by the wheel’s circumference to get the distance.
-
Calculates instantaneous speed in km/h.
-
Stores the highest speed recorded as
vmax
.
2. Activity Time
-
If speed is non-zero, it increments the running time (
totS
) every 0.5 seconds. -
This gives a measure of how long the hamster has actually been running.
3. Reed Sensor Debounce
Detects transitions from HIGH to LOW on the sensor.
Ignores noise or repeated triggers if less than 200ms have passed since the last trigger.
Increments two counters:
c
: total number of wheel spins (for distance)q
: spins in current 2-second window (for speed)
4. Average Speed Calculation
-
Calculated only if total running time is greater than 0.
-
Only considers active periods (not idle time).
Display Functions notes
I've used several functions to handle the display of the data in the screen, this is necessary to have a nice dashboard on the tiny screen. There is also a timer that every 5 seconds changes the data printed on the display to show maximum speed, instant speed, avarage speed, total distance... So I have different functions:
-
printLabels()
: Draws static text labels depending on screen mode. -
printSpin()
: Shows the total spin count on the screen. -
printInstantSpeed()
: Displays current speed in large or small font depending on context (running or resting).
Design notes
-
Sampling time (
deltat
) is fixed to 2 seconds. -
All key data —speed, distance, time— are updated in near real time.
-
The system is designed to run continuously and display data clearly on a small screen.
After a few period of test, I've improved the system adding wifi connectivity.
IoT Connectivity
The ESP8266 is connected...
Read more »