# Case Study: MADPAW — Pet Tracker, GPS + Activity ML, 30-Day Battery Life
Problem: A 30+ day battery life target for pet tracker hardware (a collar device). The device performs GPS location tracking plus activity classification (sleep/walk/run) from a 3-axis accelerometer, and syncs with the owner's iPhone.
Result: 32-day battery test passed (lab environment), 95% activity accuracy, 12K devices sold, App Store rating 4.8/5.
1. Power Budget
The pet tracker uses an 800mAh LiPo battery. The processing that must not drain it within 30 days:
Component | Daily budget | |
|---|---|---|
GPS fix (every 60 min) | 24 fixes × 2s lock | ~3% battery |
Accelerometer (continuous) | 1.5%/day | |
BLE advertise (every 5s) | 2%/day | |
ML inference (every 5min) | 0.4%/day | |
Wi-Fi sync (owner's home, daily) | 1%/day | |
Total | ~8% / day | |
30-day projection | 240% — fail! |
Optimization was required.
2. Smart Scheduling
The device stays in native sleep and only wakes when motion is detected:
- Accelerometer interrupt (motion threshold) wake-up
- Motion detected → ML inference + GPS fix
- No motion → sleep mode, GPS off
With this pattern, the daily budget dropped to 3%/day. 30 days = 90%. 32-day lab test passed.
3. On-Device ML Pipeline
3-axis accelerometer at 25Hz → 60-sample window → Core ML model.
Model: Create ML Activity Classifier, 4 classes (sleep/walk/run/play). Training:
- 200 hours of data (15 dogs, various breeds and sizes)
- Train 80% / val 10% / test 10%
- Validation accuracy: 94.2%
- Model size: 18KB (.mlmodelc)
The ESP32-class hardware has no Apple Neural Engine — the Core ML model was converted to TFLite Micro. Inference: 8ms / window.
4. iOS App: Owner Side
The iOS app is a low-power BLE listener:
1@MainActor2final class TrackerManager: ObservableObject {3 private var central: CBCentralManager?4 @Published var lastSyncedAt: Date?5 @Published var lastActivity: ActivityClass?6 7 func startListening() {8 central = CBCentralManager(delegate: self, queue: .main, options: [9 CBCentralManagerOptionRestoreIdentifierKey: "MADPAW.tracker"10 ])11 }12}Background BLE scan runs only when the phone is home (geofence) — for battery savings.
Map UI: GPS history for the last 24 hours, activity heatmap.
5. Cloud Sync
The iOS app acts as a proxy:
- BLE \<-\> Firebase Realtime DB
- Activity events: tracker → BLE → iOS → Firebase
- Owner can share with multiple family members (Firestore family-id collection)
Daily volume per device: ~3MB. Firebase free tier is sufficient (12K devices → ~36GB/month).
6. Hardware Pin-out & Firmware
- ESP32 (S3, ARM Cortex M4)
- u-blox NEO-M9N GPS module
- ADXL355 accelerometer
- Power management IC (TI BQ24295)
- BLE-only (no Wi-Fi during travel — power)
Firmware in C (Arduino IDE → migrating to ESP-IDF in v2):
- FreeRTOS task layout
- 4KB ML model embedded
- OTA via BLE (iOS app uploads firmware)
7. Manufacturing & Production
- 12K devices sold
- China supplier (Shenzhen)
- 4 hardware revisions over 18 months
- App Store-side approval was fairly smooth (no NFC, no health regulatory)
- Returns: 1.8% (industry 3-5%)
8. Lessons Learned
1. The battery target must be committed to upfront. "I'll optimize it later" doesn't work — the power profile needs to be a day-0 target.
2. Always-on listener vs. scheduled yielded a 95% battery saving. Motion-triggered wake-up is best practice for DIY hardware.
3. ML model size matters. The 18KB Core ML model works via TFLite Micro. At 100KB+ it wouldn't have fit on the hardware.
4. BLE-only design. Wi-Fi consumed too much power during travel. Wi-Fi is used only for the home dock and syncing.
5. iOS background BLE requires CBCentralManagerOptionRestoreIdentifierKey — without restoration, sync would drop while the owner was away from home.
6. Activity training data: 200 hours — the first model used 50 hours, with 78% validation accuracy. 4x the data → a jump to 94%.
7. App Store reviews are driven by the battery accuracy claim. A "one charge per 30 days" claim needs proof. Lab data plus a 100-customer beta test supported the App Store description. Trust increases conversion by 35%.
Result: IoT hardware + iOS app is a combined problem. Battery optimization, on-device ML, and the BLE state machine each carried 2 months of technical debt. Combined, that's 6-8 months of R&D. When the output is the best-in-class pet tracker, it's worth it.
Tags
iOS Development News
Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.
We respect your privacy. You can unsubscribe at any time.

