PathShield is an RF awareness tool for M5StickC Plus 1.1 and Plus 2. It uses BLE/WiFi scanning to detect nearby devices, alerting on those following you.
Caution
ETHICAL USE ONLY Users are solely responsible for: Compliance with all applicable laws. Respecting reasonable expectations of privacy
- Features
- Installation
- Controls
- Display Guide
- Detection Algorithm
- Customization
- Troubleshooting
- Known Limitations
- Credits
- License
- Dual-Band Scanning: Alternates WiFi and BLE detection, displays MAC, vendor, SSID, channel, hit count & RSSI
- Persistence Scoring: Multi-factor algorithm reduces false positives. Allowlist for known devices
- Real-Time Alerts: Visual notifications for detected trackers and user-specified MAC targets
- Tracker Detection: AirTag, Tile, SmartTag, Chipolo, Google FMDN identified by protocol
- Known Device Ring Buffer: Stable-RSSI devices promoted to compact storage, freeing active slots
- 24,500+ MAC Database: Offline manufacturer identification
- Hardware Adaptive: Auto-detects CPlus2 PSRAM for 2x device tracking capacity
- Dynamic Memory Scaling: Device limits scale to available heap at boot
Tip
Modify allowlistMacs to ignore known devices.
Change the specialMacs to your own target devices (default detects Flock and Axon Taser cameras).
- Open link in Chrome, Edge, or Opera (not Safari/Firefox)
- Select your hardware (Plus 1.1 or Plus 2)
- Connect device via USB-C
- Click "Deploy Firmware"
- Select serial port, wait ~2 minutes
M5StickC Plus 1.1:
- Board: M5StickCPlus
- PSRAM: Disabled
- Partition: Huge APP (3MB No OTA/1MB SPIFFS)
M5StickC Plus 2:
- Board: M5StickCPlus2
- PSRAM: Enabled
- Partition: 8M with spiffs (3MB APP/1.5MB SPIFFS)
Both require M5Unified and NimBLE-Arduino libraries.
Button A: Pause scanning
Button B: Toggle name filter
A+B (hold): Settings menu
Button A: Scroll up
Button B: Scroll down (tap)
Button B hold: Resume (hold 1 second)
Button A: Navigate options (up/down)
Button B: Select option
A+B hold: Exit menu
Available Settings:
- Brightness: Low/High (saves battery on low brightness)
- Clear Devices: Clears all tracked devices from memory
- Display Timeout: How long before screen turns off when idle (10-300 seconds)
- Shutdown Device: Power off the device
- Scan Mode:
SCAN(green = actively scanning),PAUSE(red = paused) - WiFi/BLE Indicator: Current scan mode (WiFi or Bluetooth)
- Battery Bar: Device battery percentage (0-100%)
- Memory Bar: Available RAM in KB (green = good, yellow = warning, red = critical)
Each device shows:
Device Name (BLE) or SSID (WiFi)
Manufacturer (identified from MAC)
Detection Count + Signal Strength (RSSI)
CYAN = WiFi networks / Normal Bluetooth devices
ORANGE = User-defined tracker (special MAC)
RED = Suspected tracker detected (high persistence score)
YELLOW = Manufacturer name
GREEN = Scan active, status messages
- Press Button B to toggle between "Show All" (all devices) and "Named Only" (only named devices)
- Useful for cutting through noise when there are many unnamed devices
- Page counter: Shows which page you're viewing (e.g., "1-3/23")
- Scroll hint: When paused, shows navigation instructions
PathShield uses a multi-layer packet inspection approach to reliably identify trackers from BLE advertisement data. Since modern trackers use standardized Bluetooth identifiers, this method catches them regardless of MAC randomization.
Layer 1: Manufacturer Data (Company IDs)
BLE packets include manufacturer-specific data identified by a 16-bit company ID (stored little-endian). Known trackers advertise predictable company IDs:
-
AirTag & Find My Devices: Company ID
0x004C(Apple Inc.)- Must have ≥27 bytes of payload
- Payload type byte at offset 2 must be
0x12or0x07(Find My authentication) - Also catches: Chipolo ONE Spot, Eufy cameras in Find My mode
-
Samsung SmartTag: Company ID
0x0075(Samsung Electronics) -
Chipolo (native mode): Company ID
0x0133(Chipolo d.o.o.) -
Google FMDN: Company ID
0x00E0(Google Find My Device Network)
Layer 2: Service UUIDs
Some trackers advertise standard BLE service UUIDs instead of (or in addition to) manufacturer data:
- Tile: Service UUIDs
0xFD51or0xFD52 - Samsung SmartTag (alt): Service UUID
0xFD6F(SmartThings/Find)
Layer 3: Device Name (Fallback)
If manufacturer data and service UUIDs don't match, PathShield falls back to case-insensitive name matching:
- Device name contains "tile" → Tile tracker
- Device name contains "smarttag" → Samsung SmartTag
- Device name contains "chipolo" → Chipolo
This layered approach works because trackers must advertise these identifiers to function — they can't hide their identity without breaking their intended purpose. The combination of multiple detection methods eliminates false negatives.
Factor 1: Detection Frequency (0.25 max)
- Requires minimum 8 detections
- More frequent = higher score
Factor 2: Time Window Distribution (0.30 max)
- Tracks across 4 windows: 5/10/15/20 minutes
- Must appear in 3+ windows
- Consistent presence = tracking behavior
Factor 3: ε-Connectedness (0.25 max)
- No gaps >3 minutes between detections
- Continuous tracking pattern
- Distinguishes stalking from coincidence
Factor 4: RSSI Pattern (0.20 max)
- Signal strength variations
- Movement correlation
Alert Threshold: ≥ 0.65
Edit specialMacs[] in PathShield.ino:
const char *specialMacs[] = {
// Apple OUIs (AirTags use rotating addresses from Apple's OUI space)
"AC:DE:48", // Apple Inc.
"F0:98:9D", // Apple Inc.
"BC:92:6B", // Apple Inc.
// Tile
"C4:AC:05", // Tile Inc.
"E0:00:00", // Tile Inc. (some models)
// Samsung SmartTag
"E4:5F:01", // Samsung Electronics
"74:5C:4B", // Samsung Electronics
"E8:50:8B", // Samsung Electronics (additional)
// Chipolo
"EC:81:93", // Chipolo d.o.o.
};Add your own trusted devices to allowlistMacs[] to prevent false alerts:
const char *allowlistMacs[] = {
"AA:BB:CC", // Your trusted device 1
"DD:EE:FF", // Your trusted device 2
// Add MAC prefixes of devices you own
};Allowlisted devices are completely ignored during scanning and will never trigger tracker alerts.
More Sensitive (more alerts):
#define PERSISTENCE_THRESHOLD 0.50 // Lower threshold
#define MIN_DETECTIONS 5 // Fewer detections needed
#define MIN_WINDOWS 2 // Fewer time windowsLess Sensitive (fewer false positives):
#define PERSISTENCE_THRESHOLD 0.75 // Higher threshold
#define MIN_DETECTIONS 12 // More detections needed
#define MIN_WINDOWS 4 // More time windowsScan Timing:
#define SCAN_SWITCH_INTERVAL 3000 // 3 seconds each (WiFi/BLE)
// Change to 2000 for faster scanning
// Change to 5000 for slower, battery-savingMax devices shown:
const int maxDisplay = 3; // Change to 2 or 4Color scheme (in displayTrackedDevices):
M5.Display.setTextColor(CYAN); // Change to GREEN, BLUE, etc.
M5.Display.drawFastHLine(0, 0, SCREEN_WIDTH, MAGENTA); // Border colorSolution:
- Lower threshold temporarily:
#define PERSISTENCE_THRESHOLD 0.40- Check Serial Monitor (115200 baud) for detection counts
- Verify tracker is powered on and advertising
Quick fix: Use name filter
- Press Button B to show only named devices
- Hides random MAC addresses and noise
Persistent false positives: Add to allowlist
- Note the MAC address from the display
- Add to
allowlistMacs[]in PathShield.ino - Re-upload and restart
Fine-tune sensitivity (advanced)
#define PERSISTENCE_THRESHOLD 0.75 // Raise to be more strict
#define MIN_DETECTIONS 12 // Require more detectionsHold Button B for 1 full second (not just tap).
Watch the memory bar on screen — red means critically low. Device limits scale dynamically at boot based on available heap.
Normal on first flash. The device formats SPIFFS automatically (~30 seconds), then boots normally.
- Screen may be dimmed (press any button to wake)
- Wait 200ms between presses (debounce)
- For menu: hold both buttons 300ms+
| M5StickC Plus 1.1 | M5StickC Plus 2 | |
|---|---|---|
| SoC | ESP32-PICO-D4 | ESP32-PICO-V3-02 |
| Flash | 4MB | 8MB |
| PSRAM | None | 2MB |
| Device Limits | ~50 BLE, ~50 WiFi | ~70 BLE, ~50 WiFi |
Separate firmware builds required per board (different PSRAM/partition configs).
- MAC Randomization: Modern phones randomize MACs — use name filter
- Range Limited: BLE/WiFi ranges vary by environment
- No GPS: Detects proximity only, not location
- Battery: Continuous dual-band scanning drains battery in 4-6 hours
Detection algorithms based on:
- Chasing-Your-Tail-NG - Persistence tracking
- BLE-Doubt - Topological classification
- CreepDetector - Original concept
MIT License - Use at your own risk. Developers provide no warranty and accept no liability for unlawful or unethical use. Review local regulations before deployment.
Issues and pull requests welcome. Test thoroughly before submitting.
- GitHub Issues: Bug reports and feature requests
- Serial Monitor: Enable debugging (115200 baud)
- Web Flasher
