Boat Pager

2026

I have a small power boat that I spend time on in the summers in the Puget sound. Every time I anchor it, I worry that it is going to float away. I set my anchor and pay out reasonable scope, but I can't shake the thought that I will return and find my boat not there. I typically am going to places without cell service, and I am also venturing far enough from the boat that WiFi wouldn't have the range to reach me. My solution was to build a board to monitor the position of the boat with GPS and transmit a message to a UHF pager when the boat drifts away.

Boat Pager

The end result works reasonably well. The pager operates at 449.925 MHz within the Amateur radio 70CM band which gives it enough range to reach me just about everywhere I am likely to go. The end result is certainly not going to win any DFM (design for manufacture) awards, but it gets the job done.

Design

I originally bought these pagers several years ago to coordinate at a yearly float trip that I organized with friends in Missouri. While they worked technically well for that purpose in reaching to everywhere in the expansive camp ground, they failed for the practical reasons that they could not be heard over loud music, and drunk float trip goers are not particularly attentive. For that project, I designed a basic interface board between an ESP32 and a NiceRF radio module with a Semtech LoRa chip and wrote some terrible pre-AI code for it that I documented here. Another big learning from that project was that without a TCXO, typical LoRa radio modules do not have enough frequency stability / precision to reliably send FSK with +/- 4.5kHz deviation (which is what POCSAG uses). For the camping pager project, I ended up programming in a static offset to stay within the receive bandwidth of my pagers.

A 20 ppm oscillator at 450 MHz can have an offset of as much as 9 kHz which is fine for LoRa (the whole idea behind LoRa is that you can get high sensitivity reception of low rate data with a cheap oscillator), but for a 12.5 kHz or 25 kHz narrowband signal, more precision is required. I selected a LoRa-CC68-433-TCXO module from G-NiceRF since it has a 0.5 ppm TCXO and a 22 dBm output.

PCB Layout

I based the design of the boat pager transmitter on a radiosonde project that I have yet to write up. That project de-risked the on-board GPS antenna and Chinese knock-off (of a uBlox NEO-M6) GPS receiver and is the reason why there is a programming header rather than a built in USB to serial bridge. To program the board, I jumper in an ESP32_Devkit_V4 with its own ESP32 module depopulated. I added 18650 cell holders to make this rechargeable and brushed up on my Google Lens Mandarin and added an LP28013A charger IC and an FM2113 battery protection IC. I added an on-off toggle switch, swapped the transmitter, modified the mechanical interfaces to fit into a waterproof Amazon box, and kept the humidity and temperature sensor for fun.

Programmer Connected

I designed the radiosonde board in Eagle originally, but it imported without issue into KiCad. The design files and vibe coded Arduino sketch can be found here.

I attempted to size the PCB to the Amazon box, but I was off by a couple mm on some of the curves. I solved this with a Dremel. It should not have been as surprising to me as it was given that PCBs are literally routed on the edges, but the Dremel did a fantastic job adjusting the perimeter of the PCB. The battery holders just barely fit and required a slight bit of Dremeling themselves, but with those changes the board fit into the box with some short nylon standoffs.

PCBAs as they Arrived from JLC PCB

I had JLCPCB assemble most of the parts on the boards. Their 'Economic' assembly option doesn't cover the ESP32 (or the BMP280 pressure sensor, so I marked that DNP). This assembly option did include a vertical through hole USB-C connector and through hole toggle switch, though.

Aside from the ESP32, I had to install the programming header, the battery holders, and the GPS chip antenna. I used a surface mount SMA connector here because the board is protected inside a box. These connectors are quite easy to snap off of boards because they don't have the strength of through hole pins, so I do not recommend them for general purpose applications. I didn't make an effort to match the impedance of the pad for the RF pin into the connector, but this is a two layer board, the pad is not much larger than the nominally 50 Ω trace, and this is only 450 MHz.

Back of the Board with 18650 Cells Installed

Pager Configuration

I got a good deal on a lot of 6 unlocked Apollo Pilot 450-458 MHz pagers off of eBay a few years ago. By holding down the center button while installing the battery, I am able to enter a programming menu where I can set the operating frequency and the pager CAP codes. Fortunately, the pager accepts operating frequencies just barely inside the Amateur Radio 70 CM band. I configured the main CAPCODE as what I would page to in an alarm scenario, and I set up a different CAPCODE as a non-ringing 'mailbox' so that I could receive periodic position updates without constantly beeping.

Mailbox Pager CAPCODE

I modified the code to transmit my Amateur radio call sign at the start of each message to make things legal. The upper end of the 70cm band is allocated for pager inputs which this is obviously not compliant with, but checked and the closest repeaters that use 449.925 MHz as an input frequency are more than 100 miles away and are blocked by terrain.

Bringup

I must have gotten distracted while implementing the battery charge IC because I left three resistors as copy paste 1k defaults rather than specifying appropriate parts. I had to swap a 10k NTC thermistor onto the NTC pin, a 3k resistor onto the ISET pin for a charge current of 500mA, and a 10k resistor onto the IBF pin to terminate charge when the current reaches 150mA.

After fixing those issues, I could not get the board to transmit. I could program the ESP32, the GPS worked, and all of the power stuff worked fine, but the LoRa module kept returning error codes. I figured it had something to do with it using a TCXO, but I couldn't figure out what was wrong and Cursor AI also failed to get it to work. I tried various ways of enabling the TCXO in the RadioLib library before finally finding this post showing that the opposite issue to be done with "radio.XTAL = true;" prior to initializing. I switched it to false and it finally worked.

First Successful Page

At this point I dictated some basic behavior to AI, and set up a soft AP with a landing page to arm and disarm the system.

Web Interface

I then decided to take advantage of some header inputs that I designed in to add a tilt switch to arm and disarm the system outside of the web app. This did not go well. Ten years ago I discovered that eBay was allowing mercury tilt switches to be sold and imported directly from China. I obviously bought a bunch since I felt that I was at the end of an era and that it would soon be difficult to buy mercury toggle switches for cheap. Sure enough, the only mercury tilt switches you can find on eBay today are Mercury brand outboard motor trim switches. I soldered in a tilt switch, enabled an internal pullup, and then spent several hours trying to diagnose why the board was crashing every time I brought the toggle switch into a closed state.

Mercury Tilt Switch

I am not sure exactly what was physically going on, but all of the odd crashing behavior went away when I soldered a ceramic capacitor in parallel with the switch. I also realized that I would not be able to take this already sketchy device on a plane if it contained mercury, so I desoldered the toggle switch and decided to stick with the app.

Open Box With Tilt Switch Removed

To secure the board to the Amazon project box, I used some short nylon standoffs since their bending would forgive any offsets. I added an SMA panel mount passthrough for the UHF output which connected nicely with a short right angle SMA to straight SMA cable. I was initially worried that the plastic box would detune the GPS antenna, but that didn't end up having any noticeable effect.

Result

It is a bit annoying to have to unscrew the lid of the box to turn the unit on and off, but the battery lasts long enough that I can leave it on for a couple days.

Completed Box

I first tested it out by leaving it in my car, and after I was satisfied that it could be trusted, I left it on my boat while I was on a mooring ball. Its range was exactly what I had hoped for, and I can now sleep soundly in a tent on shore with my boat at anchor in a bay.

Anchor Alarm Functioning (The Cheap Boat to the Right)