Sending engine RPMs to the NMEA bus, 1/x

Whilst Dad was visiting, we put his portable oscilloscope across the two terminals on the back of the tachometer, and found a very nice mV signal that changes frequency with engine revolutions. This means that a bit of circuitry plus a microcontroller will enable me to push the rev count to the boat data network.

Of course, it’s never quite that simple. My first attempt last night, at just simulating ERRPM over the network didn’t go quite as well as I hoped. I could see the data on the network, but iNavX refused to render it.

The attempt was a bit of Python on my laptop, talking TCP (or UDP) to the MiniPlex3. I scrounged some NMEA checksum code from Dosch-man’s blog, and read the NMEA 0183 sentence specification, and crafted a little python program that could send a sentence to the MiniPlex.

#!/usr/bin/env python3

import socket
import re
import time
import random

HOST = "10.0.0.1"
PORT = 10110

src = "E"
engine = "1"
pitch = "100"

def checksum_for(sentence: str) -> str:
	# Sample sentence is $XXXXX,data,goes,here*
	# No checksum present, this calculates it.
	chksumdata = re.sub(
		"(\n|\r\n)",
		"", 
		sentence[sentence.find("$")+1:sentence.find("*")]
	)
	csum = 0 
	for c in chksumdata:
		csum ^= ord(c)
	# Mangle the result appropriately
	return str(hex(csum)).lstrip("0x").upper()
	

# Talk UDP to the MiniPlex, because it can only handle one
# TCP client connection. 1Hz is sufficient. Debateable whether this
# code should hold the socket and loop, or loop opening sockets each
# time.
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
	while True:
		rpm = random.randint(1000, 2500)
		sentence = f"$ERRPM,{src},{engine},{rpm},{pitch},A*"
		checksum = checksum_for(sentence)
		print(f"Sending {sentence}{checksum}")
		s.sendto(f"{sentence}{checksum}\r\n".encode(), (HOST, PORT))
		time.sleep(1)

The MiniPlex3 routing table needs to be modified for this sentence to be sent to other listeners on the network, because by default there is no routing of host port (USB/Ethernet/WiFi) input to the NMEA outputs – the outputs are only 4800 baud, and a host port could be receiving data at a far higher speed. Simple routing entry of ERRPM from H to ST, PC, W (since I have a WiFi enabled unit) ensures that iNavX and other WiFi clients see the data. ST doesn’t hurt, though there’s nothing on the SeaTalk1 side that will read the sentence.

Tonight’s iteration will be to turn on the autopilot, snaffle some sentences, and run them through the checksum code to see if I’m actually generating the right checksum. If I am, then the next step is to send known-to-render sentences, and see if iNavX shows those.