Marine electronics · Arduino UNO Q · Working
NMEA 2000 Boat Dashboard on Arduino UNO Q
In short
An Arduino UNO Q with a CAN shield listens, without ever transmitting, to a boat's NMEA 2000 network. It decodes engine, tank, battery and navigation data, finds every device on the network, and serves it all to a phone over WiFi and Bluetooth. It has been trialled on the boat with no problems and is now packaged up.
The problem
A boat's NMEA 2000 network carries live data from the engine, tanks, batteries and navigation instruments, but it is hard to see what is actually on it. Tools that can diagnose the network are expensive, and most of them can also send messages onto it, which is a risk on a boat you rely on.
This project is a cheap way for a boat owner or installer to see every device and every live value on the network, and to record raw traffic to track down a faulty sender, without any chance of interfering with the boat.
Receive-only by design
The most important rule is that the device never transmits. The CAN controller runs in listen-only mode, the transceiver's silent pin is held high, and the software has no way to send a frame. This is built into the design, not a setting someone could switch on by mistake.
It is also not a chartplotter or an engine control tool. It only watches and reports.
The hardware
The board is an Arduino UNO Q, which pairs a microcontroller with a small Linux computer. A CAN shield with an MCP2518FD controller connects it to the NMEA 2000 backbone at 250 kbit/s.
Getting it to receive took some digging: the controller needed a 40 MHz oscillator setting rather than the library's 20 MHz default, and frames only arrived when the controller was polled rather than interrupt-driven. The microcontroller passes frames in small batches to the Linux side, which does the decoding.
Reading the NMEA 2000 network
NMEA 2000 is built on CAN bus. Each device broadcasts messages called PGNs, and larger ones are split across several frames that have to be reassembled. The software reassembles these, decodes standard PGNs for engine, tank, electrical, navigation and device identity, and checks them against the open-source canboat reference.
Every raw frame is logged before it is decoded, every value records where it came from, and a value the network reports as unavailable stays empty rather than being guessed. The device also discovers each node on the network and shows its manufacturer and product details.
The dashboard
The dashboard is a web page designed for a phone first. It has cards for engine, tanks, electrical and navigation, with speed over ground and wind in knots, RPM and tank levels as whole numbers, and tank types by name. Stale cards can be removed with one tap.
It also works out remaining fuel, endurance and range from tank sizes set in a Boat settings panel. These are clearly marked as calculated and only shown when every input is known. A read-only Bluetooth service offers the same readings, including a plain-text summary that a generic Bluetooth scanner app can read.
If no data is arriving, the dashboard shows that it is disconnected. It never makes up a value.




How it was tested
The software is written in Python and runs and tests on a laptop with no hardware, using a traffic simulator and a library of recorded test captures. It has a large automated test suite with coverage gates.
On the bench, a Raspberry Pi with a CAN board generates traffic and the UNO Q receives real frames, with engine, tank, battery and navigation data showing on the dashboard.
A black box recorder keeps diagnostics safe through a sudden power cut, and a small bus status strip on the dashboard shows the health of the network.
The first trial on the boat worked fine. Connected to the real network, the dashboard showed the same live readings it had on the bench, and the whole thing is now packaged up.

What's next
The boat trial is done and the build is packaged up, so this project is finished for now.
Two loose ends remain. Under heavy traffic the link between the microcontroller and the Linux side can occasionally stall: a recovery service resets it and the dashboard comes back in about 20 seconds, but the root cause has not been found. Phone access away from the home WiFi and Bluetooth network also still needs testing with real traffic.
Videos
Source code
View the project on GitHub →