portfolio/PetWatch System

PetWatch

Teaching cats that keyboards aren't toys-with computer vision, AI, and a well-timed spray of water.

Yocto ProjectOpenCVBeagleBoneRaspberry PiYOLOv5PythonC

Demo Media

Overview

Ever stepped away from your desk for two minutes, only to return to find your cat has typed random characters in your workspace? Yeah, me too. My cat thinks my table is the perfect place to nap, my mouse is a toy, and other objects are obstacle to be eliminated.

Motion sensors? They trigger on everything. Manual supervision? Not exactly practical when you're not around. What I needed was something smarter-a system that could tell the difference between me grabbing a pen and a cat jumping onto my desk.

So I built PetWatch: an embedded system that uses computer vision to detect motion, AI to identify if it's actually a pet, and automated deterrents (water spray + alarm) to teach them to stay away. The system runs on three devices working together: BeagleBone Black for vision, Raspberry Pi Pico 2W for networking and control, and a detection server running YOLOv5 for accurate AI identification.

Project Goal: Build a system reliable enough to run constantly, smart enough to distinguish pets from humans and capable of threatening the cats.

What It Does

  • Watches Constantly - Motion detection using OpenCV runs constantly, only capturing frames when something actually moves
  • Thinks Before Acting - YOLOv5 AI analyzes each frame to confirm it's actually a pet, not me or some object
  • Responds Instantly - Water pump and buzzer activate within seconds of detection to deter the pet (the only thing I know they're afraid of is a spray of water)
  • Keeps You Informed - Email notifications with annotated photos show exactly what was detected and when
  • Never Gives Up - Automatic WiFi reconnection means temporary network issues don't stop the system
  • Custom Image - Custom Yocto Linux distribution optimized for this specific purpose

How It Works

The system uses a distributed architecture where each device has a specific job. This separation means if WiFi dies, the camera keeps detecting. If the server goes down, the Pico can still receive frames.

BeagleBone Black: The Eyes

  • Monitors video feed continuously via a USB camera
  • Detects motion using background subtraction method
  • Captures frames only when needed
  • Sends images via UART at 460800 baud
  • Runs custom Yocto Linux for ease of usage

Raspberry Pi Pico 2W: The Bridge

  • Receives frames from BeagleBone via UART
  • Forwards images to server over WiFi
  • Controls water pump and buzzer
  • Handles automatic WiFi recovery
  • Manages alarm sequences and timing

Detection Server: The Brain

  • Runs YOLOv5 AI model for pet detection
  • Identifies cats, dogs, and other animals (whichever class you include)
  • Sends "ALARM" or "NO_PETS" response
  • Creates annotated detection images
  • Emails notifications with photos

The Flow

  • 1. Motion detected → BeagleBone captures frame
  • 2. Frame sent via UART to Pico 2W
  • 3. Pico forwards to server via WiFi
  • 4. YOLOv5 analyzes: pet or not?
  • 5. If pet: trigger water + buzzer + email
  • 6. If not: continue monitoring

Designing Highlights

Custom Yocto Linux Distribution

Instead of using a bloated off-the-shelf Linux distro, I built a minimal custom distribution using Yocto Project. This allows to simply write image to an SD card, insert it into BBB's SD slot and boot it. After booting up service needed for the project will start automatically.

Bulletproof UART Protocol

Transferring JPEG images over UART isn't trivial-one corrupted byte and the entire image is garbage. I used a frame-based protocol with CRC-16 validation for both headers and data. The Pico uses an interrupt-driven ring buffer to handle incoming data, then a state machine parser validates everything before acceptance. This allows me using UART at high baudrates.

Real-Time AI That Actually Works

Running YOLOv5 on a server instead of edge device means I can use the large model variant for better accuracy. I tried all of the YOLOv5 models but only large was giving acceptable result. The system responds fast enough for real-time deterrence while maintaining high detection accuracy. When a pet is detected, the server annotates the image with bounding boxes and confidence scores, then sends both the alarm signal and email notification.

Smart Water Pump Control

The latching relay module toggles state with brief pulses, like pressing a button. I implemented pulse generation logic that keeps the GPIO pin in Hi-Z mode normally to avoid interference, then sends precisely-timed LOW pulses to toggle the pump on and off. Multiple activation cycles during the alarm sequence ensure maximum deterrent effectiveness and the sound of pump also works well.

What I Built With

Computing Hardware

  • BeagleBone Black - TI Sitara AM335x ARM Cortex-A8 running custom Yocto Linux
  • Raspberry Pi Pico 2W - RP2350 with WiFi for wireless networking and control
  • Detection Server - Any PC/laptop with Python 3+ (I used my PC)

Sensors & Actuators

  • USB Webcam - Any UVC-compatible camera (I used an old HP HD-3300)
  • 12V Water Pump - Submersible pump for deterrent spray
  • Latching Relay - 12V relay module for pump control
  • PWM Buzzer - Buzzer alarm module for additional deterrence

Software Stack

  • Yocto Linux - Custom kirkstone build with meta-petwatch layer
  • OpenCV + Python - Motion detection and image capture
  • Pico SDK + LWIP - Basic firmware and TCP/IP stack for Pico 2W
  • PyTorch + YOLOv5 - AI detection server

Communication

  • UART Protocol - Custom frame format with CRC-16 validation
  • WiFi - CYW43 driver on Pico 2W with auto-reconnection
  • HTTP - POST requests to detection server
  • SMTP - Email notifications

Problems I Encountered And Solved

  • Problem: Reliably transferring 100+ kB images over UART without corruption
    Solution: Designed a frame protocol with magic , size headers, and CRC-16 validation. Added interrupt-driven ring buffer and state machine parser for better communication.
  • Problem: WiFi disconnections causing complete system failures
    Solution: Implemented automatic reconnection with exponential backoff (1s → 2s → 4s → 10s max). System preserves state during network issues.
  • Problem: Controlling a latching relay that requires specific pulse patterns
    Solution: Created pulse generation logic with Hi-Z state management. GPIO stays high impedance normally, then sends brief 100ms LOW pulses to toggle relay state without interference.
  • Problem: Building a minimal Linux image that has the PetWatch service working out-of-the-box
    Solution: Created custom Yocto meta-layer from scratch. Wrote BitBake recipes for the application, kernel patches for UART enablement in devicetree, and systemd service integration.
  • Problem: Balancing detection accuracy with response speed
    Solution: YOLOv5 large model runs on powerful hardware while BeagleBone handles real-time capture.