Use BoatKit with Meshtastic LoRa
BoatKit can send vessel state and alerts over a Meshtastic LoRa channel without an internet connection. A Meshtastic radio connected to the dedicated BoatKit device transmits the data. A second Meshtastic radio connected to your iPhone, iPad, or Android device receives it, and the BoatKit app retains the latest state for each associated vessel. While BoatKit owns that receiver connection, the Meshtastic entry in BoatKit's Messages panel also stores and sends ordinary channel and direct-node text messages.
BoatKit uses Meshtastic's shared client protocol, so the integration is not a separate driver for each radio board. A device must run compatible Meshtastic firmware and expose its standard USB serial or Bluetooth LE interface. The Heltec WiFi LoRa 32 V4 is the initial vessel-side target; the SenseCAP T1000-E and Heltec Mesh Node T1 are initial mobile-receiver targets. Confirm behavior with the firmware version and regional radio configuration you plan to use before relying on a particular installation.
The connection also provides a narrow, constrained fallback view when the normal LAN or internet path is unavailable. This is a supplemental awareness path, not a distress, fire, security, or certified marine alarm system. LoRa delivery depends on radio power, antenna installation, terrain, interference, regional airtime rules, and the mesh between the radios. BoatKit does not receive a delivery guarantee from the recipient phone.
Before you start
You need:
- A dedicated BoatKit device with an available USB data port.
- A Meshtastic radio for the boat, with a suitable antenna, USB data cable, and reliable power.
- A Bluetooth-capable Meshtastic radio carried with the phone or tablet.
- The official Meshtastic app for the initial radio configuration.
- The BoatKit native app on iOS, iPadOS, or Android. A normal browser cannot maintain the required Bluetooth receiver connection.
Both Meshtastic radios must use the correct regulatory region and the same private channel name and key; their local slot numbers may differ. Set these on the radios with the official Meshtastic app. BoatKit deliberately does not copy or store the channel key.
Configure the radios
- Install current compatible Meshtastic firmware on both radios by following the Meshtastic device instructions.
- In the official Meshtastic app, set the correct regulatory region on each radio.
- Configure the same private channel name and key on each radio. The radios may use different local slot numbers; BoatKit learns the phone receiver's slot from valid packets.
- Confirm that an ordinary text message sent by either radio appears on the other before introducing BoatKit.
- Disconnect or close the official app's active Bluetooth session to the phone-side receiver. The BoatKit app needs that Bluetooth connection while it is listening. Meshtastic's phone client connection is effectively single-client: the official app and BoatKit cannot reliably use the same receiver at the same time.
Do not transmit without the correct antenna attached. Follow Meshtastic's regional configuration guidance and all applicable radio rules.
Connect the boat radio
- Connect the boat radio to the dedicated BoatKit device with a USB data cable. A charge-only cable will power the radio but will not expose it to BoatKit.
- In BoatKit, open Settings > Integrations > Add Integration.
- Choose Radios & LoRa, then Meshtastic LoRa.
- Under Boat Radio, select the USB Meshtastic radio.
- Enable Meshtastic LoRa and confirm Connected appears directly below the enable switch.
- Select the channel already configured on both radios. BoatKit displays its name and slot after reading the radio; Slot 0 is the first channel.
- Choose the Basic vessel info interval. It defaults to one minute; shorter intervals keep the fallback chart fresher but use more shared LoRa airtime.
Prove both radio directions
After both radios and the phone receiver are configured, use BoatKit's explicit application-level round-trip test:
- On the vessel, open Radio Tests and select Send test message. The single progress line moves from Queued to send ... to Sent at [time]! Waiting for response... when BoatKit hands the challenge to the boat radio. This local handoff alone does not prove radio delivery.
- With BoatKit notifications allowed, a fresh challenge raises an ordinary notification on the phone. Tap it to open LoRa receiver directly, or open the vessel list and select LoRa. A yellow warning triangle under LoRa means a fresh test awaits your response. Find the vessel; its received challenge shows The boat-to-phone path works, its receive time, and available RSSI/SNR. Select Test ACK. The warning clears when the phone queues the ACK.
- Return to the vessel integration. Ack received at [time], full round trip confirmed! appears only after the boat radio receives the matching BoatKit application ACK.
The phone's Test ACK queued for the phone radio message is an intermediate state, not confirmation that the vessel received it. Challenges expire after ten minutes; start a new test instead of relying on an old cached request. The test notification is not a Critical Alert; only actual alarm-severity LoRa alerts use that path when authorized.
Test multi-fragment reception locally
Keep the phone receiver connected to BoatKit and open that vessel in LoRa Only mode. Tap the top-right LoRa Only status to open its recent packet log. On the vessel integration, select Send 3-fragment test. BoatKit sends three numbered, 222-byte diagnostic packets over the selected Meshtastic channel; they do not alter Power data, trigger a phone alert, or require a return link. The phone log should show Fragment test 1/3, 2/3, 3/3, then All 3 radio fragments received intact. The order may vary. If a part is missing, the log names the missing fragment after two minutes. A queued test only proves the BoatKit vessel service accepted the request, not that the radio transmitted or the phone received all three parts.
This isolates multi-packet radio delivery from Power serialization. If this test completes but Power remains at Requesting power system, inspect Power topology and Power measurements entries in the same log. A missing numbered Power fragment points to packet loss or radio congestion; assembled without a rendered topology points to translation or store application instead. The log is kept locally for the latest packets on each associated boat and is diagnostic, not permanent history. Repeat at the distance and channel settings you intend to use; the three large test packets consume real shared-channel airtime.
BoatKit reserves the selected serial interface while the integration is enabled so another integration cannot open the same radio.
Choose what BoatKit sends
Under Alert Messages, choose which normalized BoatKit severities should be copied to LoRa. Warnings and alarms are enabled by default; routine notifications are disabled by default to reduce radio traffic.
Routine state and non-alarm BoatKit notices use BoatKit's private application port. They do not appear as Meshtastic chat messages or make the receiver buzz. A true alarm is deliberately also sent as an ordinary Meshtastic text message: the receiver can attract attention and the standard Meshtastic app remains an emergency fallback after BoatKit releases the receiver connection. The text includes a compact BoatKit marker so the native app can associate it with the correct vessel, store it as a system message in the appropriate channel thread, and use the critical-alert presentation.
Read BoatKit stores over LoRa
While the integration is connected, BoatKit sends tiny fixed-unit safety reports on Meshtastic's private application port. A 16-byte BoatKit header adds the packet kind, a four-byte vessel discriminator, send time, sequence, and a CRC16 checksum. This first protocol version does not carry general RPCs or arbitrary control commands. Its only state-changing write is a compact, complete update to the geometry of an anchor watch that is already active.
The transport is deliberately hybrid:
- At the configured 30-second, 1-minute, 2-minute, 5-minute, or 15-minute interval, the vessel always broadcasts a 28-byte VesselInfo report: fixed-point position, heading, course over ground, speed over ground, validity bits, and bits indicating whether anchor or alarm detail exists. While anchor watch is enabled, the same report grows to 40 bytes by appending its center plus whole-foot warning and alarm radii; the phone calculates current anchor distance from the vessel position. A bounded one-packet Alarm report is sent only while warnings or alarms exist and contains compact identity, severity, source, and message. The packet send time supplies the freshness signal. This baseline needs no return path and repairs packet loss with the next complete report.
- When the phone can transmit back to the vessel, it sends a short subscription request for an allowlisted extra store that the open Viewer actually uses. The first extra store is PowerSystem, reduced to recognizable enabled items, their basic bus and connection topology, slow measurements, and operating state. Source identities, device registers, alert thresholds, and management configuration are omitted. Power topology is sent separately because it rarely changes; it uses short local references instead of normal BoatKit identifiers. Measurements use fixed units and packed validity and changed-field masks.
- Subscription requests and BoatKit application ACKs are broadcast on the shared encrypted channel, so they do not depend on asymmetric node-key state. Subscribed data returns on that channel. Power first sends a topology keyframe and a complete measurement keyframe. Later measurement packets include only changed values, based on the last measurement generation acknowledged by BoatKit rather than a radio routing ACK. Each stage carries the topology checksum so measurements cannot be applied to the wrong layout. Subscription renewal periodically repairs the keyframes. A missing uplink does not stop the broadcast baseline.
The native bridge continuously collects the compact baseline and persistently retains the latest valid packet plus the bounded delta chain for subscribed stores for every associated vessel. It also retains the newest 1,000 valid position reports per vessel, including delayed reports delivered out of order. The bundled Viewer expands those tiny packets into normal VesselInfo, AnchorAlarm, and Alarm store states. On the Chart it joins adjacent retained positions into a recent LoRa track using each report's vessel send time. Opening a vessel replays that retained state into the bundled limited Viewer, using the same normal Viewer pages and vessel-specific browser storage as its direct and BoatKit Cloud connections; returning to the vessel list does not discard it. A healthy authenticated LAN or BoatKit Cloud connection remains authoritative while it is available. When that path fails, the Viewer rehydrates from the native cache, requests subscribed-store state when a return path exists, and will not apply partials without a valid full-state base. A normal full snapshot automatically takes authority again after reconnect.
The normal Viewer shell does not make every BoatKit capability available over LoRa. Its navigation is limited to the Chart and the Power view. When anchor watch is active, the Chart shows its normal center and warning/alarm radius handles. Drag them into place and select Save to send one 28-byte geometry command. BoatKit first refreshes the two-way peer session, then sends the command on the shared encrypted channel. Queuing it to the phone radio does not prove vessel receipt; the app keeps showing the pending geometry until a fresh VesselInfo packet echoes the same center and radii. The vessel sends that confirmation immediately unless its radio queue is congested, in which case the next routine VesselInfo report provides confirmation. LoRa cannot use this control to start, stop, sleep, or otherwise configure anchor watch.
You can open Power before its slow subscription response arrives: it first shows that the topology is being requested, then renders the received topology while showing a separate progress indicator until the first matching readings keyframe arrives. The top-right LoRa panel reports VesselInfo packet age on the Chart and power-reading packet age on Power, separating when the phone received the packet from the age of the vessel data. On the Chart, a VesselInfo report becomes stale after 2 minutes 5 seconds: the boat marker and the panel's Data age turn red together. Settings, dashboards, other controls, and unrelated tools remain hidden, and unsupported URLs return to the Chart. Opening this limited view does not replace the last page saved for the vessel's full connection. Only the explicit projected stores contain data; general RPCs, events, data streams, and vessel-backed history queries remain unavailable. Chart track history is a special case synthesized from the phone's bounded cache of received LoRa positions; it is not the vessel's complete authoritative track. Alarm text continues alongside the binary stream so an alarm-severity event can wake the native app, use the critical-alert presentation, and remain readable in Meshtastic without waiting for the next keyframe.
BoatKit also listens to the radio's transmit-queue status. If that small queue fills, routine store frames pause and each peer/store keeps only its newest unsent update. This makes delay turn into lower update frequency instead of a growing backlog of stale vessel data.
Treat the Meshtastic channel key as authority to participate in this constrained link. Protect it like a shared control credential and give it only to people who may adjust the active anchor-watch geometry. BoatKit also requires a recent BoatKit subscription from the sending node, the configured channel slot, and the matching vessel discriminator before the vessel accepts the command.
Pair the receiver with this phone
Receiver pairing is app-wide rather than part of one vessel's settings. One phone can retain LoRa state for several associated BoatKit vessels, including while their normal network connections are unavailable.
- Open the BoatKit native app and return to the vessel list.
- Select LoRa beside the messages button, then select Scan and allow Bluetooth or nearby-device access when prompted.
- Choose the nearby receiver and select every account vessel whose BoatKit LoRa traffic this receiver should accept.
- Allow BoatKit notifications. On iOS or iPadOS, also allow Critical Alerts so alarm-severity LoRa messages can sound through silent mode and Focus.
- Keep the receiver powered, nearby, and configured for the same Meshtastic channel as the boat radio.
Open BoatKit's Messages panel and choose Meshtastic to use the receiver without giving up ordinary radio messaging. BoatKit stores plain-text messages in separate conversations for each configured channel and direct node. Known Meshtastic node names are used when available. The history is local to this app installation and paired receiver, capped at the newest 500 messages per conversation and 2,000 messages total. It does not sync through BoatKit Cloud.
Channel sends use the channel already configured on the radio. Direct sends request a Meshtastic routing acknowledgement. Routing acknowledged means the mesh reported successful routing; it does not mean that a person read the message. Rich media, reactions, and BoatKit Cloud messaging features are not available on this radio path. BoatKit does not copy or expose the channel key.
Ordinary Meshtastic messages are stored and counted as unread in BoatKit but do not create BoatKit vessel-alert notifications. Only BoatKit application frames and BoatKit-marked alarm messages whose vessel fingerprints match an associated vessel use the vessel notification path.
iPhone and iPad behavior
BoatKit uses iOS's standard Bluetooth-central background mode. Adding this mode does not require a special Apple entitlement or approval. When the receiver is connected, a matching LoRa message can wake the app in the background long enough to post a local notification.
The user must grant Bluetooth and notification permission. BoatKit requests Critical Alerts permission when the receiver is paired. An alarm-severity LoRa message uses BoatKit's approved Critical Alerts capability when the user has allowed it, including BoatKit's critical alarm sound. Warnings remain time sensitive, and routine notifications remain active. If Critical Alerts are not authorized, an alarm falls back to a time-sensitive notification rather than being discarded.
If the user force-quits BoatKit, iOS will not relaunch it for Bluetooth events until the app is opened again.
Android behavior
Android keeps the paired receiver connection in a foreground connected-device service. Android shows a persistent low-priority service notification while BoatKit is listening. Alarm-severity LoRa messages use BoatKit's Critical vessel alarms channel when its Do Not Disturb access and sound are enabled, with the normal alarm channel as a fallback. The user must grant nearby-device and notification permission, and device-specific battery restrictions can still interrupt the connection.
Test the complete path
Avoid creating an unsafe condition just to test an alarm.
- Temporarily enable Send notifications under Alert Messages if the notification test will use the routine notification level.
- Use BoatKit's delivery test on the Notifications settings page.
- Lock the phone and confirm that BoatKit posts and sounds a local notification.
- Open the notification and confirm that BoatKit selects the intended vessel.
- With the normal network path unavailable, open Tools > Power. Confirm that BoatKit first reports that it is requesting the topology, then renders the topology while it waits for current readings. Depending on radio airtime and mesh conditions, either stage can take more than one packet interval.
For the separate emergency-fallback check, use a safe BoatKit alarm test and first confirm that the readable alarm appears in the matching channel thread in BoatKit Messages. Then release BoatKit's Bluetooth connection before connecting the official Meshtastic app. Do not assume the radio will replay packets that BoatKit already drained from its client queue; send a fresh safe test after the official app connects. Routine notices and store updates should not appear as Meshtastic chat.
Repeat the test at the real separation and with the antenna installation you intend to use. A successful bench test does not establish range at a marina, through buildings, or across changing terrain.
Backups, privacy, and offline operation
The selected boat-side serial identity, channel slot, and alert policy are vessel configuration and are included in BoatKit's portable backup. Channel keys stay on the radios and are not included. The phone-side receiver pairing, vessel associations, retained store state, and 1,000-point LoRa track cache are local to that mobile app installation and are not part of a vessel backup. The same is true of Meshtastic message history, unread markers, known node names, and channel labels. Message history is retained only on that mobile app installation, up to 500 messages per conversation and 2,000 messages total.
Messages travel through the selected Meshtastic channel, not through BoatKit Cloud. Internet access is not required for this message path after the vessel and radios are configured. Normal BoatKit device registration still applies.
Troubleshooting
The boat radio does not appear
- Confirm that the cable carries data, not only power.
- Confirm that the radio runs Meshtastic firmware and exposes its USB serial interface.
- Disconnect other programs that may have opened the same serial port.
- Reconnect the radio, then reopen the integration settings and look for the device again.
BoatKit reports a handshake or reconnect error
- Confirm that the selected serial device is the Meshtastic radio.
- Confirm that another Meshtastic client is not holding the USB connection.
- Restart only the radio, then allow BoatKit to reconnect. Do not erase its channel configuration unless you intend to configure both radios again.
- Record the BoatKit and Meshtastic firmware versions if the error continues.
The phone does not find the receiver
- Keep the receiver awake, powered, and close to the phone during the scan.
- Disconnect the receiver from the official Meshtastic app or another phone.
- Confirm that Bluetooth is on and BoatKit has Bluetooth or nearby-device permission.
- On iOS, reopen BoatKit after a force-quit.
Text arrives in Meshtastic but BoatKit shows no notification
- Confirm that the intended vessel is selected under LoRa receiver on the vessel list.
- Confirm that BoatKit notification permission is enabled in system settings.
- Check Focus, silent, and per-app notification settings on iOS, or notification and battery settings on Android.
- Confirm that the received message ends with a BoatKit marker. Ordinary Meshtastic text is intentionally not turned into a BoatKit notification.
No message arrives on the receiving radio
- Recheck the region, private channel name, and key on both radios. Their slot numbers can differ.
- First test ordinary text between the radios with the official Meshtastic app.
- Check power, antenna connection and placement, distance, terrain, and nearby radio interference.
- Confirm that BoatKit reports Connected and shows a recent Last TX Request time after it transmits.
Meshtastic is a third-party project and trademark. BoatKit is not certified or endorsed by Meshtastic.