The Smart Shoe Counter: a wearable that counts your steps and celebrates when you hit your goal
Clip a tiny motion sensor to your shoe, and it counts every step you take, shows your progress on a mini screen, and bursts into a light show the moment you reach your daily goal. A one-day robotics build using an ESP32, a motion sensor, and an OLED screen.
What you're building
A wearable fitness gadget that teaches motion sensing, displays, and celebration effects.
The Smart Shoe Counter clips onto a shoelace or ankle strap. Inside is a tiny board that feels every bounce of your foot as you walk or run, and turns that motion into a step count. A small screen keeps you updated with a live number and a progress bar, and once you've hit your daily goal, a strip of lights bursts into a celebration animation to let you know you did it.
Motion Sensing
The MPU6050 feels the up-and-down bounce of every step and tells the ESP32 to count it.
Live Progress
The OLED screen shows your step count and a progress bar toward your goal, updated in real time.
Goal Celebration
Reach your target step count and the LED strip bursts into a rainbow celebration animation.
Materials list
Most parts can be reused from a beginner ESP32 kit.
Electronics
- 1x ESP32 dev board
- 1x MPU6050 accelerometer/gyroscope module
- 1x 0.96" OLED display (SSD1306, I2C)
- 1x WS2812 (NeoPixel) LED strip, 5–8 LEDs
- 1x push button
- 1x 3.7V LiPo battery + charging module (or USB power bank)
- Jumper wires + small perfboard or breadboard
Wearable & build supplies
- Small plastic project box or 3D-printed enclosure
- Velcro strap or shoe lace clip
- Foam padding (to cushion the sensor)
- Hot glue gun
- Small screwdriver
- Electrical tape
Wiring reference table
| Component | Component Pin | ESP32 Pin |
|---|---|---|
| MPU6050 | SDA | GPIO21 |
| MPU6050 | SCL | GPIO22 |
| OLED SSD1306 | SDA | GPIO21 (shared) |
| OLED SSD1306 | SCL | GPIO22 (shared) |
| LED Strip (WS2812) | Data In | GPIO5 |
| Push Button | Signal | GPIO4 (internal pull-up) |
| All components | GND | Common GND rail |
Step-by-step build instructions
Work through these in order — test the electronics on a breadboard before mounting anything on a shoe.
-
Wire the sensor and screen on a breadboard
Connect the MPU6050 and OLED to the ESP32's SDA and SCL pins as shown in the wiring table, and confirm both power on before doing anything else.
-
Add the LED strip and button
Connect the LED strip's data line to GPIO5 and the push button to GPIO4. Keep the LED strip powered from the same 5V/battery rail as the rest of the circuit.
-
Upload the code and test on the bench
Upload the sketch below, then gently shake the MPU6050 by hand to make sure the step count on the OLED goes up.
-
Calibrate the step threshold
Walk a known number of steps (say, 20) while watching the count. If it over- or under-counts, adjust the STEP_THRESHOLD value in the code until it matches closely.
-
Build the enclosure
Fit the ESP32, MPU6050, and battery inside a small project box, padded with foam so the sensor sits still against the shoe rather than rattling loose.
-
Mount the OLED and LED strip
Position the OLED screen so it's easy to glance at, and route the LED strip along a visible edge of the enclosure or shoe for the best celebration effect.
-
Attach to your shoe
Strap the finished enclosure to your shoelaces or ankle with the Velcro strap, keeping wires tucked away from moving parts.
-
Set your goal and go
Power it on, press the button once to reset the count to zero, and start walking. Watch the LEDs celebrate once you hit your goal!
Arduino code
Copy this into a new sketch in the Arduino IDE, with an ESP32 board selected. Install the Adafruit_MPU6050, Adafruit_SSD1306, Adafruit_GFX, and Adafruit_NeoPixel libraries first from the Library Manager.
#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_NeoPixel.h>
// ---- Pin setup ----
#define SDA_PIN 21
#define SCL_PIN 22
#define LED_PIN 5
#define NUM_LEDS 8
#define BUTTON_PIN 4
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
int stepCount = 0;
int goalSteps = 100; // change this to your daily goal
float STEP_THRESHOLD = 1.6; // g-force threshold, tune during calibration
unsigned long lastStepTime = 0;
const unsigned long stepCooldown = 300; // ms between counted steps
bool celebrated = false;
void setup() {
Wire.begin(SDA_PIN, SCL_PIN);
mpu.begin();
mpu.setAccelerometerRange(MPU6050_RANGE_4_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
strip.begin();
strip.show();
pinMode(BUTTON_PIN, INPUT_PULLUP);
showProgress();
}
void loop() {
checkButton();
checkStep();
showProgress();
if (stepCount >= goalSteps && !celebrated) {
celebrate();
celebrated = true;
}
}
void checkButton() {
if (digitalRead(BUTTON_PIN) == LOW) {
delay(40); // debounce
if (digitalRead(BUTTON_PIN) == LOW) {
stepCount = 0;
celebrated = false;
strip.clear();
strip.show();
delay(300); // avoid double-reset
}
}
}
void checkStep() {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
float magnitude = sqrt(a.acceleration.x * a.acceleration.x +
a.acceleration.y * a.acceleration.y +
a.acceleration.z * a.acceleration.z) / 9.8;
unsigned long now = millis();
if (magnitude > STEP_THRESHOLD && (now - lastStepTime) > stepCooldown) {
stepCount++;
lastStepTime = now;
}
}
void showProgress() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 5);
display.print(stepCount);
display.setTextSize(1);
display.setCursor(10, 25);
display.print("of ");
display.print(goalSteps);
display.print(" steps");
int barWidth = map(min(stepCount, goalSteps), 0, goalSteps, 0, 110);
display.drawRect(9, 45, 112, 12, SSD1306_WHITE);
display.fillRect(10, 46, barWidth, 10, SSD1306_WHITE);
display.display();
}
void celebrate() {
for (int cycle = 0; cycle < 4; cycle++) {
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, strip.Color(random(80,255), random(80,255), random(80,255)));
}
strip.show();
delay(150);
}
strip.clear();
strip.show();
}
Beginner tip
Every walking style bounces a little differently. Spend five minutes calibrating STEP_THRESHOLD until 20 real steps show up as close to 20 on the screen.
Safety notes for young makers
Ask an adult to help with soldering and battery wiring. Only use a LiPo battery with a proper charging module, never charge it unattended, and keep the enclosure closed while walking so wires can't snag. Take a short break if the enclosure feels warm.
Why this project works so well for learning
The Smart Shoe Counter introduces three robotics ideas kids can actually feel working. Reading a motion sensor teaches how real fitness trackers work under the hood. Driving an OLED screen introduces displaying live data instead of just blinking an LED. And celebrating a goal with lights ties the whole thing together with an instant, rewarding payoff — which makes debugging and calibrating the step threshold feel worth the effort.
Frequently asked questions
What age group is this robotics project best suited for?
Ages 9 and up can build this with an adult helping on soldering and battery steps. Ages 12+ with basic Arduino experience can usually wire and code most of it independently.
Do I need to know how to code to build this?
No. The code above uploads and runs as-is. The one hands-on coding step is calibrating the step threshold, which is a great, low-pressure first edit for a beginner.
Can I build this without the LED strip?
Yes. Replace it with a single LED and resistor on GPIO5, and simplify the celebrate() function to blink it a few times instead of a rainbow animation.
Why does it sometimes miscount steps?
Motion sensors can pick up bumps, taps, or fast movements as "steps." Adjusting STEP_THRESHOLD and stepCooldown in the code, and mounting the sensor snugly against the shoe, both help a lot.
Can I power it with a USB battery pack instead of a LiPo?
Yes — a small USB power bank plugged into the ESP32's USB port works fine for testing, though a LiPo battery with a charging module is more compact for everyday wear.

Comments
Post a Comment