The base on the pole makes every decision. The phone, the remote, the voice box and the heading puck only tell it things - over three kinds of link: wires, its own radio (ESP-NOW) and Wi-Fi.
Everything from the remote, phone or voice box is a one-shot request: "start SCAN", "move 10° left", "speed 60". The base applies it and then carries on by itself on its own compass, GPS and clock. If a message arrives late, twice, or never, the pole still does the right thing - and losing the phone or remote never stops it.
Inside the base: the compass and GPS on the I²C bus (STEMMA QT cables), the motor driver on two pins. Fast and never drops.
Remote and puck talk straight to the base, no router, about 11 bytes a message. Works on home Wi-Fi and on the water.
The phone and the voice box reach the base's little web server - through the home router, or the base's own ScottsPole hotspot on the water.
| FROM | TO | WHAT | HOW |
|---|---|---|---|
| Phone | Base | Commands (mode, nudge, drag, settings) | WI-FI |
| Base | Phone | Live status ~25×/s, flight log, settings | WI-FI |
| Voice box | Base | Commands, then a status check, then a log note | WI-FI |
| Remote | Base | Button presses, wheel turns, its battery | ESP-NOW |
| Base | Remote | Heading 20×/s, pole state, GPS, battery | ESP-NOW |
| Puck | Base | Boat heading 10×/s, battery, version | ESP-NOW |
| Phone | Internet | Live log, weather, shared spots | CELLULAR |
ESP-NOW is a feature of the ESP32 chip: short messages straight from one board to another on a Wi-Fi channel, with no router and no connection to set up. It is how the remote and the heading puck talk to the base - at home and on the water.
| NAME | TYPE | DIRECTION | CARRIES | HOW OFTEN |
|---|---|---|---|---|
| HEADING | 3 | base → remote | Pole heading ×10 + accuracy 0-3 | 20×/s |
| POLE | 11 | base → remote | Mode + flags, pole angle and target (from the bow) | steady |
| POLESET | 12 | base → remote | Speed, arc, pause, held direction | steady |
| SPOT | 20 | base → remote | SPOT distance, range, GPS ok | steady |
| GPS / GPSPOS | 18 / 19 | base → remote | Satellites, fix, latitude / longitude | ~1×/s |
| HOLD / LOG | 14 / 15 | base → remote | Motor power, flight-log state | steady |
| BUTTON / ACK | 1 / 2 | both | A press and its receipt | on press |
| WHEEL | 7 | remote → base | Wheel position, spin, buttons held | on turn |
| POLECMD | 13 | remote → base | A pole command (mode, nudge, speed...) | on press |
| NAV | 16 | remote → base | Which screen the remote is on | on change |
| BOATHDG | 21 | puck → base | Boat heading ×10 + accuracy (65535 = no compass) | 10×/s |
| BATT / RATE / TEMP | 4 / 5 / 6 | all | Battery % + volts, charge rate, chip temperature | every few s |
| VER | 8 | all | Firmware version (puck adds its up-time) | every 10 s |
| PING | 0 | all | "Still here" (base → puck 1×/s) | 1×/s |
| PAIR | 9 | all | Pairing steps (see Pairing) | while pairing |
| CMD | 10 | all | Save calibration, switch link, turn the puck off | on request |
The pole works exactly the same both ways - only the road the phone takes to the base changes. The remote and puck use their own radio either way.
Once the base has been on home Wi-Fi it remembers its address (192.168.1.46) and uses the same one on DIRECT, so one home-screen icon works everywhere. Hold D2 on the base for 3 s to see it.
The hotspot tells the phone "there's no internet here", so the iPhone keeps using cellular for the internet while it talks to the base over Wi-Fi.
SETUP › LINK: pick WI-FI or DIRECT. Both base and remote restart into the new mode; the app tells you what to join and finds the base again.
The pill in the app's header: bars = DIRECT, fan = WI-FI.
/a?c=scanon once. There's no stream of "keep going" messages - the base keeps scanning on its own./stream) carries a small JSON status about 25 times a second: mode, angle, target, GPS, batteries, warnings.| ADDRESS | WHAT IT DOES | USED BY |
|---|---|---|
/ | The phone app itself (gzipped page) | Phone |
/stream | Live status pushed ~25×/s | Phone |
/st | Status once, as JSON | Phone, voice box |
/i | Settings and info (versions, battery, voice settings, weather kept on the base) | Phone, voice box |
/a?c=&v= | Do something: a pole command or a setting | Phone, voice box |
/lg · /lgack | Copy the flight log · "got it, free that space" | Phone |
/cfg | Setup the app needs (log key, names) | Phone |
/wx | Weather handed to the base (logged, and for voice "wind") | Phone |
/vn | A voice-box note for the flight log | Voice box |
/parts · /perf | Flash layout + last update error · timing | Debugging |
The voice box is just another client of the base's web server, like the phone. It sends the same one-shot commands, then checks the status to make sure the pole really did it before it answers. Everything it heard and said goes into the flight log as NOTE rows (LOGS › MORE › VOICE COMMANDS on the phone).
Directions like hard left are measured from the bow, using the heading puck's boat heading. More on the Voice box page.
20-byte rows in the base's own 896 KB of flash: 10 rows a second while the pole is busy, 1 a second when idle - about 1.2 h busy or 12 h idle. Events (mode changes, notes, GPS positions, weather, boat heading) go in between.
While the app is open it copies new rows (/lg), then says "got it" (/lgack) so the base can free the space. A full base just stops recording until a phone copies it.
The phone pushes new pieces to log.scottspole.com every 30 s (cellular on the water). Kept for 7 days, so a problem on the boat can be looked at almost live.
Each power-up of the base is a trip, summarised on the phone (TRIPS tab: playback, charts, fish, weather). PUSH TO CLOUD on a trip, or PUSH EVERYTHING NOW on LOGS, sends it to the live log right away. Spots you SHARE go to trips.scottspole.com.
Reads the pole heading, works out what the motor should do for the current mode, and sets the motor. It runs in its own task, so nothing the network does can hold it up.
Everything else: web pages, the status stream, radio messages, the screen, the flight log, Wi-Fi. A slow phone or weak Wi-Fi only slows this side.
The two share the pole's settings through one lock. The loop lets go of it for every network call and for drawing the screen, so the pole task never waits on a phone.
Motor: no fresh drive command in time = motor off. Loop stuck for 30 s = the base restarts (the motor is always off at start-up) and logs where it was stuck as a HANG note.