This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Garbled nmea0183 (from Garmin gps) on pi boot
#1
Hi community, I'm in the middle of troubleshooting a wall of issues with getting my Garmin gps-17 data into signalk. On a fresh openplotter install I've got the serial all configured (uart2 on pi5, MacArthur hat). On boot, the nmea0183 1 LED blinks normally. But if I cat ttyAMA2, I get completely garbled data consisting of the characters f, x, ~ and ` and  忘 (a Japanese character). Sometimes a restart of signalk fixes it, other times not. Sometimes two signalk restarts fixes it. I've tried udev rules and rc.local to "stty - F /dev/ttyAMA2 4800" (which fixes when run from bash, but does not fix it when in udev or rc.local). A complete raspi reboot sometimes fixes it (warm boot). I've also long had a 15s startup delay set in signalk.

I have exceeded my ability to troubleshoot and gratefully seek any guidance from experts here.
Reply
#2
You’re definitely close — the characters you’re seeing (f, x, ~, `, and even multibyte symbols like 忘) almost always mean the UART is running at the wrong speed or is being reconfigured after boot. To help narrow this down, a few key details will make the diagnosis much easier.

Could you share the following right after a cold boot (before starting Signal K)?

stty -F /dev/ttyAMA2
sudo dmesg | grep tty
grep -i uart /boot/firmware/config.txt

These three outputs tell us whether:

the Pi 5 has put UART2 into mini‑UART mode,

another service is grabbing the port,

the baud rate is being overridden during boot.

Also helpful:
1. MacArthur HAT configuration

DIP switch positions

Which port the GPS‑17 is wired to

Whether the HAT is powering the GPS or it’s externally powered

2. Your Signal K serial settings

Baud set to 4800, 8N1, no flow control

Auto‑detect disabled

“Open on startup” enabled or disabled

3. When you run this manually, does it always produce clean NMEA sentences?

Code
stty -F /dev/ttyAMA2 4800
cat /dev/ttyAMA2

If this always works, something later in the boot sequence is reconfiguring the UART.

One more quick test
Unplug the GPS‑17’s data wires (leave ground connected) and run:

cat /dev/ttyAMA2

If garbage continues, the UART is misconfigured.
If garbage stops, the GPS is outputting valid 4800‑baud but the Pi is reading it wrong.

Your symptoms — especially “sometimes two Signal K restarts fixes it” — strongly suggest a UART initialization race condition or a baud override happening after boot. The info above will pinpoint which one.
Skipper Don

AtMyBoat.com
skipperdon@atmyboat.com

I watched enough Gilligan’s Island as a kid to explain this
 
Reply
#3
Hi Don,

Thanks for the in depth troubleshooting! To clarify, I get valid NMEA1083 on about 2 out of every 3 pi boot-ups. The port speed is consistently 4800 and I never see anything else.

Code:
pi@openplotter:~ $ stty -F /dev/ttyAMA2
speed 4800 baud; line = 0;
min = 1; time = 0;
-brkint -icrnl -imaxbel
-opost -onlcr
-isig -icanon -iexten -echo -echoe -echok -echoctl -echoke

Code:
pi@openplotter:~ $ sudo dmesg | grep tty
[    0.000000] Kernel command line: reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe cgroup_disable=memory numa_policy=interleave nvme.max_host_mem_size_mb=0  numa=fake=8 system_heap.max_order=0 iommu_dma_numa_policy=interleave smsc95xx.macaddr=88:A2:9E:71:15:61 vc_mem.mem_base=0x3fc00000 vc_mem.mem_size=0x40000000  console=tty1 root=PARTUUID=7ac8abd8-02 rootfstype=ext4 fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles cfg80211.ieee80211_regdom=CA
[    0.000095] printk: legacy console [tty1] enabled
[    0.012520] 107d001000.serial: ttyAMA10 at MMIO 0x107d001000 (irq = 16, base_baud = 0) is a PL011 AXI
[    0.274901] 107d50c000.serial: ttyS0 at MMIO 0x107d50c000 (irq = 33, base_baud = 6000000) is a Broadcom BCM7271 UART
[    0.274939] serial serial0: tty port ttyS0 registered
[    0.430966] 1f00038000.serial: ttyAMA2 at MMIO 0x1f00038000 (irq = 143, base_baud = 0) is a PL011 AXI
[    0.431215] 1f00040000.serial: ttyAMA4 at MMIO 0x1f00040000 (irq = 145, base_baud = 0) is a PL011 AXI
[    2.045081] systemd[1]: Created slice system-getty.slice - Slice /system/getty.

Code:
pi@openplotter:~ $ grep -i uart /boot/firmware/config.txt
dtoverlay=uart2-pi5
dtoverlay=uart4-pi5 (there's a wind sensor here which works great)

I haven't touched any dip switches on the HAT. I wasn't aware there were any (are there? I can't see any). I know of one jumper to terminate NMEA2k (which I have jumpered as my pi is a termination).

GPS is on NMEA0183 RX1+ (with a ground jumper from RX1- to the system ground) as the GPS-17 doesn't have a data- line.

GPS is powered by NMEA2k power (which also triggers a power module on the HAT to cause the pi to boot). So they boot up together each time.

SignalK data connection is serial, 3800, 8n1 (this is not configurable), no flow control (it's NMEA0183 - no handshake). Validate checksum: YES; Remove NULL characters: NO.


Code:
3. When you run this manually, does it always produce clean NMEA sentences?

Code
stty -F /dev/ttyAMA2 4800

It does not...

But when I run:
Quote:stty -F /dev/ttyAMA2 4800 raw -echo

It fixes it right up. I have this in a UDEV rule, and it appears to run every boot; and manually running "sudo udevadm test /sys/class/tty/ttyAMA2" shows that it fires. And then valid NMEA.

I'll reboot a few times til it fails and then try the hot disconnect and will report back.

Thanks again!

(2026-05-16, 01:06 AM)SkipperDon Wrote: One more quick test
Unplug the GPS‑17’s data wires (leave ground connected) and run:

cat /dev/ttyAMA2

If garbage continues, the UART is misconfigured.
If garbage stops, the GPS is outputting valid 4800‑baud but the Pi is reading it wrong.

Your symptoms — especially “sometimes two Signal K restarts fixes it” — strongly suggest a UART initialization race condition or a baud override happening after boot. The info above will pinpoint which one.

Done. If I pull the whole phoenix strip (D+ and the gnd jumper), catting the ttyAMA2 gives no output.
If I hot reconnect it; it's back to garbage until I either:
  • Restart SignalK (actually this doesn't seem to work anymore...?) OR;
  • Restart the Pi OR;
  • stty -F /dev/ttyAMA2 4800 raw -echo
Reply
#4
Great detective work — you've basically solved your own mystery with that last test.
Root cause: Signal K is reconfiguring the UART after your udev rule runs

Your udev rule fires correctly and sets 4800 raw -echo — but then Signal K opens the port and resets it back to cooked/canonical mode. That's why the udev rule "works" in isolation, Signal K restarts are hit-or-miss (race condition on who configures the port last), and a manual stty ... raw -echo after everything settles always fixes it.
The raw -echo flags are the critical piece — raw disables input processing/line buffering and -echo stops the kernel echoing received bytes back out. Without them the tty layer mangles your NMEA into garbage.

The fix: a systemd oneshot that runs after Signal K
Create /etc/systemd/system/fix-ttyAMA2.service:

[Unit]
Description=Fix ttyAMA2 UART settings for GPS-17
After=signalk.service
Requires=signalk.service

[Service]
Type=oneshot
ExecStart=/bin/stty -F /dev/ttyAMA2 4800 raw -echo
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
Then:

sudo systemctl daemon-reload
sudo systemctl enable fix-ttyAMA2.service

This runs after Signal K has already opened and misconfigured the port. Since Signal K only touches port settings on open, the correction sticks for the session.
Note: first confirm your Signal K service name with systemctl list-units | grep -i signal — it may be signalk-server.service rather than signalk.service.
Also — you mentioned baud set to 3800 in Signal K. Almost certainly a typo, but worth double-checking it's 4800 in the connection settings.
Let us know how it holds up across a few cold boots!

One heads-up: if Signal K restarts mid-session ever break it again, add ExecStartPre=/bin/sleep 2 to the service file to give SK time to fully open the port before stty runs.
Skipper Don

AtMyBoat.com
skipperdon@atmyboat.com

I watched enough Gilligan’s Island as a kid to explain this
 
Reply
#5
Well I'm not holding my breath but 5 consecutive boots with the new service have resulted in valid data each time, a new record! I'll open a Github issue about it, as it seems like it might be a signalk bug.
Reply
#6
I understand. I had the same problem with bookworm so I moved to trixie. No problem eh.
Skipper Don

AtMyBoat.com
skipperdon@atmyboat.com

I watched enough Gilligan’s Island as a kid to explain this
 
Reply
#7
Thanks a million!
Reply
#8
Seems I spoke too soon. Seems to work *more* often than before but it still gives garbage on perhaps one in 6 boot up's. Same behaviour as before. Trixie has solved this for you? Exact same issue? I think openplotter is still on Bookworm, did you do a dist-upgrade from within open plotter (and revert to x11)?
Reply
#9
Glad it's better but 1-in-6 is still not good enough for navigation data — you're right to keep pushing.

To answer your question: yes, exact same issue, and Trixie did solve it for me. But here's the honest backstory — about six months ago I started building on Trixie specifically because I kept hitting walls like this on Bookworm. That experience is actually what led me to build d3kOS, which runs on a modern Debian base from the ground up rather than trying to dist-upgrade an existing OpenPlotter install.

The pattern I keep seeing — and you're a perfect example — is that OpenPlotter is excellent software but it's carrying a lot of Bookworm baggage, and the Pi 5 with newer UARTs is just exposing race conditions and kernel behaviour that didn't exist on older hardware.

If you want to stay on OpenPlotter, a clean Trixie install is probably your cleanest path. I wouldn't dist-upgrade from within OpenPlotter — too many things can go sideways. A fresh install gives you a known-good base.

The X11 question is worth a separate thread — there are some quirks but nothing that should stop you.
Skipper Don

AtMyBoat.com
skipperdon@atmyboat.com

I watched enough Gilligan’s Island as a kid to explain this
 
Reply
#10
I think I fixed it, in a hacky way unfortunately. No amount of system services or udev rules worked. I have 14 out of 14 successful boots with an edit to etc/udev/rules.d/10-openplotter.rules

KERNEL=="ttyAMA*", KERNELS=="1f00040000.serial:0.0",SYMLINK+="ttyOP_wind",MODE="0666"
KERNEL=="ttyAMA*", KERNELS=="1f00038000.serial:0.0",SYMLINK+="ttyOP_gps",MODE="0666",RUN+="/bin/stty - F /dev/ttyOP_gps 4800 raw -echo -echoe -echok -iexten - isig -hupcl"

Will check out your dstro. Thanks again!
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)