LIA — an Open-Source, Off-Grid LoRa Pet Tracker (No Subscription, No Cloud)
by Jon G Aguado in Circuits > Wearables
1065 Views, 8 Favorites, 0 Comments
LIA — an Open-Source, Off-Grid LoRa Pet Tracker (No Subscription, No Cloud)
Most commercial pet trackers depend on a cellular subscription or a phone-tethered Bluetooth range of a few dozen meters. Lose signal, stop paying the bill, or wander somewhere off the grid, and the tracker goes dark.
LIA takes a different approach. It's an open-source pet and asset tracker built on top of Meshtastic and LoRa mesh networking: a compact, collar-mountable device that broadcasts GPS position over a decentralized radio mesh instead of a cell network. As long as there's a chain of Meshtastic nodes between the tracker and a gateway, you get a position — no monthly fee, no carrier lock-in, no cloud backend to go down.
This Instructable walks through the whole build: the PCB, the two hardware/battery revisions, the three enclosure variants, 3D printing and assembly, flashing the firmware, and configuring it as a Meshtastic tracker node. Everything — schematics, PCB layout, BOM, enclosure CAD, and firmware — is fully open, released under CC BY-NC-SA 4.0.
📺 Watch the demo video 📖 Full documentation 💻 Source repository
Features
- Long-range LoRa communication over the open Meshtastic protocol — no proprietary radio stack
- GPS/GNSS tracking, sent only as a direct message to a predefined node — not broadcast to the wider public mesh
- A physical 3-position switch: continuous Beacon mode (LED on, position every 30s), a low-power Tracker sleep cycle (a fix roughly once a minute), or fully OFF
- A text-command interface over the mesh — query position/battery on demand, toggle notifications, override the LED
- Deep-sleep, low-power firmware with real hardware wake sources (timer, switch flip, charger plug-in)
- Fully open hardware: schematics, PCB layout, BOM, and enclosure CAD, in three enclosure variants
Supplies
Electronics (per tracker)
- 1x LIA main PCB, assembled — order fabrication + assembly from the KiCad project and production files (Gerbers, BOM, pick-and-place), e.g. via Seeed Fusion — see the full interactive BOM for every part number
- Core ICs already on that BOM: ESP32-S3-MINI-1-N8 (MCU), Wio-SX1262 LoRa module, u-blox SAM-M10Q GNSS module, MAX17048 fuel gauge, TP4056 charge controller
- 1x battery — either an unprotected 18650 Li-ion cell, 3500 mAh (V1.0) or a 50×37×4 mm pouch cell, 1000 mAh (V1.1); no built-in protection circuit needed, the board handles it
- 1x YFNF868F3AM FPC LoRa antenna (on-board default) or an omnidirectional 868/915 MHz LoRa antenna, e.g. Seeed's LoRa Antenna Kit
- 1x ceramic GNSS patch antenna
- USB-C-to-magnetic-4-pin-pogo charging cable, e.g. Seeed's T1000 cable
Enclosure
- 3D printer (resin or FDM) or CNC access — print files for all three variants live under enclosure/ (STEP + STL)
- Small screws for the shell halves (see the manufacturing drawings)
- A collar strap to mount it on
Tools
- Computer with PlatformIO for building/flashing firmware
- USB-C cable (for the initial flash)
- Phone with the Meshtastic app (Android/iOS)
- A second Meshtastic node to act as your mesh gateway/receiver
- Soldering iron — only needed if you're doing the I2C rework described in the bonus step, or hand-assembling a board yourself
How LIA Works
Before building anything, here's the loop the firmware runs, over and over, for the life of the battery:
- Wake from deep sleep, on a timer or a motion trigger.
- Fix — the GNSS module acquires a GPS position.
- Broadcast the location over LoRa, using the Meshtastic protocol.
- Relay — nearby mesh nodes pass the packet toward a gateway, node by node, until it reaches the internet.
- Sleep — radio and GPS power down, and the device goes back to deep sleep.
A physical 3-position switch on the board controls how aggressively this loop runs:
- HIGH — Beacon mode. LED solid red, never sleeps, broadcasts every 30 seconds. Good for actively searching — a walk, or "where did the dog just go."
- LOW — Tracker mode. Wakes roughly once a minute, gets a fix, sends it, sleeps again. The low-power default for everyday wear (roughly 3.3 days on the 18650 pack in this mode, versus ~4 hours in Beacon mode — the status LED alone eats about 87% of the awake current).
- OFF — a real hardware cutoff. Cuts power to the MCU entirely while still letting the battery charge.
There's also a text-command interface — send GPS, BATTERY, or HELP as a direct message to the device over the mesh and it replies the same way (more on this in the configuration step).
The PCB
LIA's board is designed in KiCad and built for turnkey PCBA — you don't need to hand-solder any of the fine-pitch parts.
- MCU + Wi-Fi/BLE: ESP32-S3-MINI-1-N8
- LoRa transceiver: Wio-SX1262
- GNSS: u-blox SAM-M10Q
- Battery gauge: MAX17048G+T10
- Charge controller: TP4056
- Power: 18650 (V1.0) or 5023450 pouch cell (V1.1) + USB-C charging
To build one yourself: open hardware/kicad/LIA.kicad_pro in KiCad 8+, or send the ready-made fabrication outputs (Gerbers, BOM, pick-and-place) straight to a PCBA house. The full interactive, click-to-highlight BOM is in the docs.
Choose Your Battery & Enclosure Version
V1.0 and V1.1 are electrically identical — same PCB design, same lia_v1 firmware. The only difference is the battery:
- V1.0- 18650 Li-ion, 3500 mAh. Mounts directly on the collar, no latch. Best for: longest runtime, simpler build.
- V1.1- 50×37×4 mm pouch cell, 1000 mAh. Mounts directly on the collar. Best for: smallest, lightest — for smaller animals, trading runtime for size.
All clip onto a standard collar strap and have a separate window over the status LED.
Pick the variant that matches the battery you're using, then grab its STEP/STL files from enclosure/ — no CAD license required, just to view or print them.
3D Print (or Machine) the Enclosure
Each variant's step/ and stl/ folders have everything needed to print or CNC the shells — top shell, bottom shell, the LED window, and (for the Detachable version) the separate collar clip and latch pieces. There's no injection-molding tooling defined yet; this is resin/FDM-print or CNC territory for now.
Print the shells, the clear-ish window piece over the LED cutout, and — if you're building V1.0-Detachable — the separate collar top/bottom and latch. Manufacturing drawings with dimensions are here if you'd rather machine them.
Assemble
- Seat the battery in its clip (Keystone 54 for the 18650), observing polarity, and clip the LoRa antenna onto the SX1262 module.
- Flash and smoke-test the board before closing it up — see Step 6. Debugging a sealed enclosure is no fun.
- Route the LoRa antenna along the inside of the top shell (the FPC antenna or an omnidirectional one both use the same connector).
- Lower the PCB into the bottom shell, onto its standoffs.
- Fit the top shell and the LED window, then screw the shells together.
- Confirm the status LED is visible through the window, and that the board still gets a GPS/mesh fix once sealed — enclosed RF performance isn't automatic, check it before you call it done.
Charging goes through that 4-pin magnetic pogo connector, so once it's sealed, it stays sealed — a standard USB-C-to-magnetic-pogo cable does the rest.
Flash the Firmware
LIA runs stock Meshtastic firmware for the ESP32-S3 target, plus a LIA-specific lia_v1 board variant layered on top for the mode switch, status LED, charger status, battery gauge, IMU, and text-command interface. Both V1.0 and V1.1 boards use the exact same lia_v1 build.
Note: the Meshtastic Web Flasher won't work here — it only has stock, generic ESP32-S3 firmware with no idea LIA's peripherals exist. You need to build the overlay yourself.
From firmware/tools/ in the repo (run this from a native PowerShell session, not Git Bash — the ESP-IDF toolchain needs it):
That script clones Meshtastic's firmware, checks out the pinned tag, copies LIA's overlay in, and builds + flashes in one step. Full manual steps (if you want to see exactly what it's doing) are in Building the Firmware.
Before flashing: make sure the mode switch is in HIGH or LOW, not OFF — the OFF position cuts power to the MCU entirely, and USB/pogo power alone won't turn it on from there (it only charges the battery).
Before you build, edit firmware/services/MeshTargets.h's kLiaTargetNode to the NodeNum of whichever node you want this tracker reporting to — that's baked in at build time, not app-configurable (yet).
Configure It As a Meshtastic Tracker
- Open the Meshtastic app, add the device over Bluetooth, and select it from the scan list.
- Set its role to Tracker: Radio Configuration → Device → Role → Tracker (or meshtastic --set device.role TRACKER over CLI). This matters beyond labeling — stock Meshtastic only skips its own competing sleep timers for tracker-role nodes, on the assumption sleep is handled elsewhere, which is exactly what LIA's firmware does itself.
- Confirm it reports a GPS fix.
- Send HELP as a direct message to the device. A reply listing commands confirms the radio, antenna, and firmware are all working end-to-end.
Everything LIA-specific — position, charge notifications, command replies — goes out as a direct message to that one predefined node, never a public broadcast, so your pet's location isn't visible to the wider mesh.
Useful commands (send as a DM, case-insensitive):
- GPS — current position, or "No GPS fix yet"
- BATTERY — current gauge charge percentage
- IMU ON / IMU OFF — arms/disarms motion-detection alerts
- CHG ON / CHG OFF — toggles the "Charging" notification
- LED ON / LED OFF — manually overrides the status LED
- HELP — lists all commands
Mount It and Test in the Field
Clip the finished tracker onto the collar strap (or the detachable collar piece, for V1.0-Detachable) and take it outside. GPS needs a clear-ish view of the sky — expect a cold fix in under a minute in the open, degraded performance under tree canopy, and no fix at all indoors (the firmware correctly reports "no fix" rather than making one up).
Flip to Beacon mode (switch HIGH) for active searching or low-light visibility, or leave it in Tracker mode (switch LOW) for everyday low-power wear.
(Bonus) a Real Hardware Debugging Story — the I2C Rework
Open-source hardware means showing the mistakes too, not just the finished renders. The first assembled batch had its IMU's SDA/SCL lines crossed as manufactured — bad enough that I2C had to be disabled entirely on that board until it got reworked. If you're staring at a similarly cross-wired board, here's the fix, step by step:
- Remove the soldermask to expose the two SDA/SCL routes.
- Cut the routes.
- Cross the routes with two jumper wires.
- Cover the fix with hot glue or resin to protect it.
With that rework applied, both hardware revisions run identical firmware and both have a working IMU and battery gauge over I2C — the earlier lia_v2 variant that existed just to work around this got retired once the fix was in. The full, warts-and-all build log — including a null-pointer crash, an inverted LED, and a "dead battery" that turned out to just be a dead battery — is in Development History, if you want the complete story.