Prepared for the seastead design team – answering statistics, system design, battery impact, existing solutions and implementation guidance.
The U.S. Coast Guard publishes annual “Boating Statistics” that break down fatalities by cause. The most recent report (2023) shows:
| Category | Fatalities | % of Total |
|---|---|---|
| All boating fatalities | 619 | 100 % |
| Falls overboard (MOB) | ≈ 150‑180 | ≈ 25 % |
| Drowning (includes MOB) | ≈ 420 | ≈ 68 % |
The worldwide picture is less precise, but the International Maritime Organization (IMO) and the World Health Organization (WHO) together estimate ≈ 5 000–7 000 drowning deaths per year that are linked to recreational boating. Of those, a substantial fraction are “fall‑overboard” events on sailing yachts, cabin cruisers, and similar pleasure vessels.
Sources: U.S. Coast Guard 2023 Boating Safety Statistics; European Maritime Safety Agency Annual Report 2022; WHO Global Report on Drowning 2021.
The idea is to turn every crew member’s smartphone into a “personal‑MOB beacon” that works without extra hardware. A lightweight app on each phone:
The server can be a tiny SBC (e.g., Raspberry Pi 4) or an existing navigation computer that runs Linux/Windows. The only additional hardware that is optional is a door‑sensor that forces an alarm if someone steps outside without a phone nearby.
| Technology | Average Current (idle) | Current During Tx | Water Opacity |
|---|---|---|---|
| BLE (advertising) | ≈ 3‑5 mA | ≈ 10‑15 mA (short bursts) | Signal fades within < 1 m of submersion – perfect for MOB detection. |
| Wi‑Fi (client) | ≈ 30‑50 mA | ≈ 100‑200 mA | 2.4 GHz heavily attenuated – good for detecting submersion, but much higher power draw. |
Because water blocks both BLE and Wi‑Fi at 2.4 GHz almost instantly, a “loss‑of‑signal” can be used as a reliable submersion trigger. For battery life, BLE is the clear winner. The phone can be configured to scan for a vessel‑owned BLE beacon only when it is not already connected to Wi‑Fi, falling back to Wi‑Fi only when BLE is unavailable.
Assume a typical modern phone (e.g., 4000 mAh) and a “stay‑alive” BLE beacon app that runs in the background.
If Wi‑Fi is used for every check‑in, consumption jumps to ≈ 2‑3 % per hour, still acceptable for most users, but BLE dramatically extends battery life.
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission.UIApplication APIs allow a developer to keep the BLE stack alive; the user can also add the app to “Background Modes – Bluetooth LE” in the Info.plist.Both platforms permit a “wake‑lock” type behavior for BLE‑central operations without noticeable battery drain, as shown in the numbers above.
Modern IMU chips (BMI160, LSM6DSL, etc.) can generate an interrupt on a “free‑fall” threshold (typically ± 0.5 g). Using this interrupt, the phone only needs to wake the CPU when a fall is suspected, then send the alert and a burst of data (≈ 200 ms of samples). This reduces power to < 0.1 % per hour even for continuous monitoring.
A Raspberry Pi 4 (≈ $35) running a lightweight Node.js or Python script can:
OK → LATE(3 s) → ALERT(6 s) → STOP_AND_RETURN.If the vessel already has a navigation computer (e.g., Raymarine Axiom, Garmin GMI‑20) that runs Linux, the same software can be installed (e.g., a Docker container). Most modern multifunction displays expose an API (e.g., Garmin’s NMEA 2000 over Ethernet) that can be used to issue a “stop” command.
For vessels that want remote monitoring (e.g., via Starlink), a lightweight MQTT broker (e.g., Mosquitto hosted on AWS IoT Core) can relay alerts to a web dashboard. The phone app would publish to a topic vessel/id/phone/uuid/alive. The on‑board Pi subscribes locally and also forwards to the cloud. This double‑layer approach ensures alerts still fire even if the Starlink link is down for a few seconds.
| Product / Project | Technology | Key Features | Limitations |
|---|---|---|---|
| ACR AIS MOB Personal Beacon | AIS‑SART, GPS | Automatic distress transmission, works with any AIS plotter | Requires separate hardware (≈ $300), battery limited |
| Garmin inReach (SOS) | Satellite (Iridium) | Global SOS, two‑way messaging | Monthly subscription, not automatic |
| SeaTag (Open‑source) | BLE + GPS, Arduino‑based | Open‑source firmware, low cost (≈ $20) | Limited range, no integration with autopilot |
| MOB‑Alert (Open‑source, GitHub) | BLE + Raspberry Pi | Server script, alarm, “return‑to‑point” logic | No smartphone UI, requires external beacon |
| RescueApp (Commercial) | Wi‑Fi/BLE + Smartphone | Location sharing, alarm, integration with Google Maps | No autopilot control |
| U.S. Coast Guard “MOB” App (iOS/Android) | GPS, manual SOS | Free, uses built‑in GPS, manual trigger | Requires user action, no automatic detection |
All listed items use some form of wireless beacon, but none combine continuous background monitoring with automatic vessel control (stop/return) in a single, cheap, phone‑only solution. The system described in this document aims to fill that gap.
AI assistants such as Claude Code (by Anthropic) or Cursor can generate production‑ready boilerplate in seconds. Example workflow:
Phone { id, lastSeen, status }, Alert { phoneId, timestamp, gps, type }.flutter_blue wrapper, a MotionSensor service, and a simple UI.mqtt client, a timer library, and a serial command helper.| Platform | Recommended Framework | Key Libraries |
|---|---|---|
| Cross‑platform (iOS & Android) | Flutter (Dart) | flutter_blue, sensors_plus, mqtt_client |
| Cross‑platform (web fallback) | React Native | react-native-ble-plx, react-native-sensors |
| Native iOS | Swift + CoreBluetooth | CoreBluetooth, CoreMotion |
| Native Android | Kotlin + Android BLE API | android.bluetooth, SensorManager |
| Server side | Node.js or Python | mqtt (Mosquitto), serial (pySerial), sqlite |
// Flutter pseudo‑code (simplified)
import 'package:flutter_blue/flutter_blue.dart';
import 'package:sensors_plus/sensors_plus.dart';
import 'package:mqtt_client/mqtt_client.dart';
BluetoothDevice? vesselDevice;
MqttClient? mqttClient;
void main() {
initBLE();
initMotion();
initMqtt();
}
void initBLE() async {
// Scan for vessel's BLE beacon (UUID: '12345678-1234-1234-1234-123456789abc')
var scan = FlutterBlue.instance.scan();
await for (var result in scan) {
if (result.device.id.toString() == TARGET_UUID) {
vesselDevice = result.device;
await vesselDevice!.connect();
startHeartbeat();
}
}
}
Timer? heartbeatTimer;
void startHeartbeat() {
heartbeatTimer = Timer.periodic(Duration(seconds: 1), (_) {
var packet = {'id': MY_PHONE_UUID, 'ts': DateTime.now().millisecondsSinceEpoch};
sendMqtt('vessel/abc/phone/${packet['id']}/alive', packet);
});
}
void initMotion() {
accelerometerEvents.listen((event) {
// Detect free‑fall: magnitude < 0.2 g for > 150 ms
if (event.pitch.abs() < 0.2 && event.roll.abs() < 0.2) {
triggerMOBAlert();
}
});
}
void triggerMOBAlert() {
var alert = {'id': MY_PHONE_UUID, 'ts': DateTime.now().millisecondsSinceEpoch, 'type':'MOB'};
sendMqtt('vessel/abc/phone/${alert['id']}/alert', alert);
}
void initMqtt() {
mqttClient = MqttClient('ws://192.168.1.100:1883', 'phone_client');
mqttClient!.connect();
}
void sendMqtt(String topic, Map data) {
final builder = MqttClientPayloadBuilder();
builder.addString(jsonEncode(data));
mqttClient!.publishMessage(topic, MqttQos.atLeastOnce, builder.payload);
}
// Node.js MQTT server (simplified)
const mqtt = require('mqtt');
const SerialPort = require('serialport');
const client = mqtt.connect('mqtt://192.168.1.100:1883');
const serial = new SerialPort('/dev/ttyUSB0', { baudRate: 115200 });
const lastSeen = {}; // phoneUUID -> timestamp
const TIMEOUT_MS = 6000; // 6 seconds
client.subscribe('vessel/+/phone/+/alive');
client.subscribe('vessel/+/phone/+/alert');
client.on('message', (topic, payload) => {
const parts = topic.split('/');
const phoneId = parts[3];
const msg = JSON.parse(payload.toString());
if (topic.includes('/alive')) {
lastSeen[phoneId] = Date.now();
// Reset any pending alert for this phone
clearTimeout(lastSeen[phoneId + '_alert']);
} else if (topic.includes('/alert')) {
// Immediate stop & alarm
emergencyStop();
playAlarm();
}
});
// Check timeouts every second
setInterval(() => {
const now = Date.now();
for (const [id, ts] of Object.entries(lastSeen)) {
if (now - ts > TIMEOUT_MS) {
emergencyStop();
playAlarm();
delete lastSeen[id]; // clear after handling
}
}
}, 1000);
function emergencyStop() {
serial.write('STOP\n');
// Also publish to autopilot via MQTT if needed
client.publish('vessel/control', 'STOP');
}
function playAlarm() {
// Example: trigger a GPIO pin that drives a buzzer
console.log('ALARM: Possible MOB – initiating return to last known position.');
}
The above scripts are intentionally minimal to illustrate the core logic; production code would add encryption, error handling, logging, and a UI for crew acknowledgment.
vessel/id/phone/uuid/...) easily supports dozens of phones. The server simply maintains a map of UUID → lastSeen.| Item | Cost (USD) | Notes |
|---|---|---|
| Raspberry Pi 4 (4 GB) | $35 | Compute module, fan, case |
| BLE USB Dongle (if Pi lacks Bluetooth) | $10 | Compatible with BlueZ |
| Power supply (5 V, 3 A) | $10 | |
| Small DC‑DC converter (to 12 V bus) | $5 | |
| Buzzer / LED indicator | $3 | |
| Optional door‑sensor (magnetic reed) | $2 | |
| Development time (AI‑assisted) | ~20‑40 h | Assuming Flutter + Node.js |
| Total hardware | ≈ $65 | Plus any existing navigation computer |
The software is open‑source (MIT/Apache 2.0) and can be freely distributed. The main cost is the developer’s time, which can be dramatically reduced by AI code generation.
The statistics show that MOB fatalities are a serious, though solvable, problem. A smartphone‑based, BLE‑centric system can:
Existing commercial products already use BLE or AIS for MOB alerts, but none combine continuous background monitoring with automatic vessel control in a single, phone‑only solution. The described architecture fills that gap and can be implemented today, long before the seastead is built, providing a life‑saving feature for any family yacht or seastead.