Gal OfelNirit Altony
Published © GPL3+

TailTrack - DIY WiFi Activity Monitor for Senior Dogs

A $15 WiFi activity tracker for my 13-year-old lab. Classifies Resting, Walking, Active and pushes state to my phone. No subscription.

BeginnerFull instructions provided3 hours9
TailTrack - DIY WiFi Activity Monitor for Senior Dogs

Things used in this project

Hardware components

Wemos D1 Mini
Espressif Wemos D1 Mini
×1
6 DOF Sensor - MPU6050
DFRobot 6 DOF Sensor - MPU6050
×1
TP4056 Lithium Battery Charger Module
×1
LiPo battery
×1

Story

Read more

Code

TailTrack firmware (.ino)

C/C++
/*
 * TailTrack WiFi Activity Monitor
 * 
 * Description:
 * Monitors senior dog mobility using an MPU-6050 accelerometer/gyroscope
 * and a WeMos D1 Mini Pro (ESP8266). Data is processed to detect activity
 * levels and transmitted via WiFi to a local monitoring endpoint.
 * 
 * PIN CONNECTIONS (WeMos D1 Mini Pro):
 * ------------------------------------
 * MPU-6050 VCC  -> 3.3V
 * MPU-6050 GND  -> GND
 * MPU-6050 SCL  -> D1 (GPIO 5)
 * MPU-6050 SDA  -> D2 (GPIO 4)
 * 
 * LIBRARIES REQUIRED:
 * - Adafruit MPU6050
 * - Adafruit Unified Sensor
 * - ESP8266WiFi
 */

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <ESP8266WiFi.h>

// --- Configuration ---
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
const char* host = "192.168.1.100"; // IP of your monitoring server/dashboard
const uint16_t port = 8080;

// --- Constants & Thresholds ---
const float ACTIVITY_THRESHOLD = 1.5; // G-force threshold for movement
const unsigned long REPORT_INTERVAL = 5000; // Send data every 5 seconds

// --- Global Objects ---
Adafruit_MPU6050 mpu;
WiFiClient client;
unsigned long lastReportTime = 0;

void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10);

  Serial.println("\nTailTrack Initializing...");

  // Initialize I2C on WeMos D1 Mini default pins (D1=SCL, D2=SDA)
  Wire.begin(4, 5); 

  // Initialize MPU-6050
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip! Check wiring.");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  // Configure Sensor Ranges
  mpu.setAccelerometerRange(MPU6050_RANGE_2_G);
  mpu.setGyroRange(MPU6050_RANGE_250_DEG);
  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);

  // Connect to WiFi
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi");
  
  int retryCount = 0;
  while (WiFi.status() != WL_CONNECTED && retryCount < 20) {
    delay(500);
    Serial.print(".");
    retryCount++;
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\nWiFi Connected!");
    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println("\nWiFi Connection Failed. Operating in offline mode.");
  }

  Serial.println("Setup Complete.");
}

void loop() {
  sensors_event_t a, g, temp;
  
  // Read sensor data with timeout protection (handled by library)
  if (!mpu.getEvent(&a, &g, &temp)) {
    Serial.println("Error reading MPU6050 data!");
    delay(1000);
    return;
  }

  // Calculate Magnitude of Acceleration (Vector Sum)
  float magnitude = sqrt(sq(a.acceleration.x) + sq(a.acceleration.y) + sq(a.acceleration.z));
  
  // Normalize (Subtract gravity approx 9.8 m/s^2)
  float activityLevel = abs(magnitude - 9.81);

  // Determine State
  String state = "Resting";
  if (activityLevel > ACTIVITY_THRESHOLD) {
    state = "Moving";
  }

  // Debug Output to Serial Monitor
  Serial.print("Accel X: "); Serial.print(a.acceleration.x);
  Serial.print(" | Y: "); Serial.print(a.acceleration.y);
  Serial.print(" | Z: "); Serial.print(a.acceleration.z);
  Serial.print(" | Activity: "); Serial.print(activityLevel);
  Serial.print(" | State: "); Serial.println(state);

  // Transmit Data periodically
  if (millis() - lastReportTime > REPORT_INTERVAL) {
    if (WiFi.status() == WL_CONNECTED) {
      if (client.connect(host, port)) {
        // Simple HTTP GET request to log data
        String url = "/log?activity=";
        url += String(activityLevel);
        url += "&state=";
        url += state;

        client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                     "Host: " + host + "\r\n" +
                     "Connection: close\r\n\r\n");
        
        Serial.println("Data transmitted to server.");
        client.stop();
      } else {
        Serial.println("Server connection failed.");
      }
    }
    lastReportTime = millis();
  }

  delay(100); // Sampling rate
}

Credits

Gal Ofel
2 projects • 1 follower
DIYer building smart home devices that solve real problems. No engineering degree, just curiosity and an Arduino. Founder of make-it.ai
Nirit Altony
2 projects • 1 follower

Comments