π‘ TL;DR
- The brains are free. pypilot (autopilot core) + Signal K (NMEA 2000 data hub) + OpenCPN (charts/UI) all run happily on your existing Linux computer.
- The only hardware you must buy is a CANβUSB adapter and NMEA 2000 cabling: roughly $130β210 for the DIY route.
- Spend $0 first. Whether the HARMO actually accepts steering/throttle commands over NMEA 2000 from a non-Yamaha device is the make-or-break question. Verify it (Step 0 below) before buying anything.
- If the HARMO won't listen to the bus, a $50β170 mechanical tiller-pilot (servo/actuator + pypilot) gets you a working Linux autopilot anyway.
π§ Target Architecture
[GNSS antenna] [IMU sensor (IΒ²C / USB)]
β β
βΌ βΌ
βββββββββββββββββββββββββββββββββββββββββββββββ
β BOAT LINUX COMPUTER (you have it) β
β β
β pypilot ............ autopilot brain β
β Signal K ........... N2K decode + hub β
β OpenCPN ............ charts + AP UI (opt.)β
β control shim ....... emits HARMO PGNs β
ββββββββββ¬ββββββββββββββββββββββββββββ¬βββββββββ
β SocketCAN (can0) β web UIs :3000 / :8000
β 250 kbit/s β via your existing reverse SSH
ββββββββββΌββββββββββββ βΌ
β NMEA 2000 bus β [ You, anywhere ]
β micro-C Β· 12 V Β· β
β 2 Γ 120Ξ© terms β
ββββββββββ¬ββββββββββββ
βΌ
[ Yamaha HARMO ]
- pypilot fuses IMU + GPS and computes steering commands.
- Signal K decodes the NMEA 2000 bus (via
canboatjs) and exposes everything as a web API β perfect for remote monitoring over your SSH tunnel. - OpenCPN (optional) adds chart-based "track mode": click a waypoint, boat follows.
- A small control shim translates pypilot's rudder commands into whatever PGNs the HARMO understands (see Step 0).
β Step 0 β Verify HARMO Control Before Spending Money
Yamaha advertises NMEA 2000 connectivity on the HARMO, and community reports confirm telemetry (battery %, range, RPM-equivalent) reaching third-party displays. What is not guaranteed is bidirectional control β whether the motor accepts steering or throttle commands from a device that isn't made by Yamaha.
- Ask Yamaha / your dealer in writing: βDoes the HARMO accept autopilot steering and throttle commands via NMEA 2000 from third-party devices? Please send the PGN implementation list.β
- Search for prior art: Cruisers Forum threads, GitHub issues on
canboat/canboatjs, and Signal K forums for βHARMOβ. If anyone has already decoded it, you're done. - Sniff the bus yourself (works even before you commit):
plug a CAN adapter in listen-only mode, operate the Yamaha remote /
display, and log everything:
# listen-only so you can't disturb the bus sudo ip link set can0 type can listen-only on sudo ip link set can0 up type can bitrate 250000 candump -L can0 | tee harmo.log # decode later with canboat: analyzer -json < harmo.log | less
Look for bursts of PGN 126720 (proprietary B) that correlate with your remote inputs. If control actions never appear on the bus, the remote talks over a private RF link and N2K control is a dead end β go Plan B. - Dealer demo: if Yamaha claims autopilot compatibility, ask to see it driving a HARMO from a Garmin/Simrad/Raymarine system. That proves the door is open.
π Hardware Options
Path A β DIY CAN adapter cheapest
| Item | Role | Est. USD |
|---|---|---|
| CANable 2.0 / candleLight USB-CAN (or Waveshare MCP2515 hat if your box is a Pi) |
NMEA 2000 β Linux can0, no drivers needed | $35β55 |
| NMEA 2000 micro-C backbone kit (2Γ T-connector, 2Γ terminator, power cable) |
The physical bus | $70β110 |
| Drop cable + field-attachable connector | Adapter β backbone | $15β25 |
| IMU: MPU-9250 breakout (or BNO085 for easier calibration) |
Heading for pypilot | $10β35 |
Total β $130β210. Tip: pay a little extra for an isolated adapter (CANable Pro class) to protect your computer from ground-loop surprises on a 48 V boat.
Path B β Commercial gateway less friction
| Item | Role | Est. USD |
|---|---|---|
| Digital Yacht iKonvert (USB, isolated) | Plug-and-play N2KβUSB | ~$170 |
| or Yacht Devices YDWG-02 (Wi-Fi) | No drivers at all; feeds OpenCPN & Signal K over UDP | ~$340 |
| Backbone kit + drop cable | As Path A | $85β135 |
Total β $250β430. You buy galvanic isolation, ruggedness and mature drivers. Functionally identical to Path A once running.
Path C β Mechanical fallback if Step 0 fails
| Item | Role | Est. USD |
|---|---|---|
| 20β35 kgΒ·cm digital servo or 12 V linear actuator | Moves the tiller | $20β100 |
| Clamp-on bracket (3D-printed / aluminum) | Quick-release mount | $10β30 |
| Drive electronics: RC PWM direct, or BTS7960 H-bridge | pypilot β motor | $0β20 |
| Same IMU as Path A | Heading | $10β35 |
Total β $50β170. The classic proven DIY autopilot. An electric outboard like the HARMO steers with very little force, so a modest actuator is plenty.
π οΈ Software Setup (all free)
- Bring up the CAN interface (NMEA 2000 is fixed at 250 kbit/s):
sudo ip link set can0 down sudo ip link set can0 type can bitrate 250000 sudo ip link set can0 up # persist across reboots with systemd-networkd / NetworkManager, # or on a Raspberry Pi with: # dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
- Install Signal K and add a CAN provider
(Admin UI β Data connections β Canbus direct):
{ "id": "n2k", "enabled": true, "pipeElements": [ { "type": "providers/canbus", "options": { "interface": "can0" } } ] }Within minutes you should see HARMO telemetry (battery status PGNs 127506/127508, position 129025, heading 127250β¦) flowing into Signal K. - Install pypilot and calibrate the IMU:
git clone https://github.com/pypilot/pypilot cd pypilot && sudo python3 setup.py install # run the IMU daemon + autopilot core, then open the # built-in web UI (default port 8000) and run the # calibration routine (figure-8 / motional alignment)
- Add OpenCPN + the pypilot plugin for chart-based control.
The plugin talks to pypilot's TCP interface (default port
20220) on localhost. - Wire up remote access using the reverse SSH you already have:
# on your home server, after SSH'ing in: firefox http://localhost:3000 # Signal K instruments firefox http://localhost:8000 # pypilot web UI
Everything runs locally on the boat β Starlink is only ever used for monitoring and tuning, never for the control loop. - Write the control shim (only after Step 0 confirms the PGNs).
Skeleton using python-can:
import can bus = can.interface.Bus(channel='can0', bustype='socketcan') def n2k_id(priority, pgn, src): return (priority << 26) | (pgn << 8) | src def send_rudder(angle_rad): # encode payload per the PGN spec you identified in Step 0 # (standard 127245, or Yamaha-private 126720 frames # captured from the remote) data = encode_rudder_payload(angle_rad) bus.send(can.Message(arbitration_id=n2k_id(3, 127245, 25), data=data, is_extended_id=True))Subscribe to pypilot's command stream (TCP 20220) and callsend_rudder()on each update. Add a heartbeat: if pypilot stops sending, stop transmitting.
π Deep dive: identifying the HARMO's control PGNs
- Filter your candump log for PGN 126720; the manufacturer-code field tells you it's Yamaha-originated.
- Record separate captures: idle, throttle-up, steer-left, steer-right, engage/release. Diff the frames β changing bytes reveal the encoded values.
- Bench-test safely: remove the propeller or lift the motor, then replay captured frames and observe the response.
- Feed interesting frames through
analyzer -jsonand consider upstreaming a decoder to canboatjs so everyone benefits.
π ±οΈ Plan B β Mechanical Tiller Pilot (skip the bus entirely)
If Step 0 shows the HARMO ignores third-party N2K commands, don't despair β this is how most DIY marine autopilots work anyway:
- Clamp a servo horn / linear actuator to the tiller arm with a quick-release pin (instant manual override).
- pypilot drives it directly: RC-servo output for small actuators, or a cheap H-bridge (BTS7960) for 12 V linear actuators.
- Same brain, same IMU, same OpenCPN/Signal K UI β you lose dashboard integration, not functionality.
- Throttle stays on the Yamaha remote (set cruise speed by hand). A second servo pressing the throttle lever can come later.
π° Cost & Risk Comparison
| Path | Hardware | Effort | Risk | Outcome |
|---|---|---|---|---|
| A DIY CAN | $130β210 | Medium | depends on Step 0 | Full integration β steering (and maybe throttle) over N2K |
| B Gateway | $250β430 | Low-Med | depends on Step 0 | Same as A, with isolation & bulletproof hardware |
| C Mechanical | $50β170 | Low-Med | low β proven design | Working heading-hold autopilot now; no dash integration |
Recommended sequence: do Step 0 β if control confirmed, build A (add B's isolated adapter if nervous) β if not, build C today and keep sniffing the bus for fun.
β οΈ Safety Notes (read twice)
- Physical override always wins. Quick-release on any tiller linkage; the Yamaha remote must instantly cancel the autopilot.
- Fuse every tap. Power the N2K backbone from boat 12 V through its own fuse; keep it separate from the 48 V traction system.
- Watchdogs everywhere: disengage if GPS/heading is stale > N seconds, if heading error exceeds a limit, or if the shim loses its heartbeat from pypilot.
- Test at the dock first (prop off), then calm water, low gains, short engagements. Tune gains gradually.
- Never route control through Starlink. Local loop only β the satellite link is for watching, not steering. A dropped packet should never equal a lost rudder command.
- An autopilot is assistance: keep a proper lookout (COLREGS Rule 5) and carry a kill switch / lanyard as usual.
π Gotchas & Quick Answers
- Bus won't communicate? With power off, measure ~60 Ξ© between CAN-H and CAN-L at any T β that confirms two 120 Ξ© terminators. Exactly two, no more, no fewer.
- Bitrate is always 250 kbit/s on NMEA 2000. Nothing else.
- While sniffing, stay in listen-only mode so a misbehaving adapter can't corrupt the bus your motor depends on.
- HARMO variants differ (tiller vs remote-control versions, power ratings) β confirm which ports and firmware your specific model has.
- Even with steering solved, assume throttle stays manual at first. Milestone 1 = reliable heading hold at fixed speed. Everything else is bonus.
- Prices are approximate street prices and drift; check current listings before ordering.