January 03, 2024

SeaTalk1 to NMEA 0183 converter, DIY

Updated 2024-01-03 !  Not for RPi 5 !!

Thanks to Thomas, (the guy with the nice marine interface board)it's now possible to decode, one way, the SeaTalk1(ST1) sentences in a pretty simple way. You just use OpenPlotter(OP) and/or SignalK(SK) and an Optocoupler.

The thing that made it, is that Thomas has released a "how to" and Python source code, that will read the data from a GPIO pin on the Raspberry Pi, (RPi), and format it so the standard parser in SignalK can translate it to SignalK delta format. It is then available as NMEA 0183. It's even possible to send the data in to a NMEA 2000 network, with a proper hardware interface.


Hardware
Prerequisites is a Raspberry Pi up and running OpenPlotter and/or Signal K and an interface circuit according to the picture.

The circuit is referring to this optocoupler board, but a similar product can of course be used. The LED in the circuit will flicker when there is ST1 traffic. Choosing an optocoupler as the hardware interface is a smart way to avoid ground loops and creates electrical isolation from hazardous voltages. This interface is not inverting the signal.

If you are building the interface yourself use the second circuit instead. If you don't want any flickering just drop the LED at the input. 

The most simple interface, works well on our boat, is where You use a small signal NPN transistor which shifts the DC level, from 12 V DC to 3,3 V DC, and inverts the signal.

Software
Install
Start, in a terminal/ssh session, with an update and install 

sudo apt-get update && sudo apt-get install pigpio python-pigpio python3-pigpio

and check with

pigpiod -v

which will return something like

79

which is the version number, 7.9. Go on getting the Python code with

wget https://raw.githubusercontent.com/MatsA/seatalk1-to-NMEA0183/master/STALK_read.py

The program is set up to match the opto circuit above.

pigpio
The Python program is dependent on that the "pigpio" library is launched as a demon. Start it with 

sudo pigpiod Which starts a socket interface on port 8888 !! which is used by the Python program.

then start the program wit

sudo python STALK_read.py

if You succeeded You will see something like

STALK,11,1,4,5 
STALK,25,4,e8,51,12,33,3
STALK,24,2,0,0,20 
STALK,26,4,0,0,0,0,20   
STALK,9c,31,13,fe 
showing the decoded ST1 messages. Next step is to check that the messages is sent out as an UDP stream at local host, port 4141. This is done with opening a new terminal/ssh session and issue the command
nc -ulkw 0 127.0.0.1 4041
and the same list of ST1 messages will appear. Terminate with "Ctrl + c".

SignalK
Connection
To get the ST1 messages into SignalK, using the optocoupler setup, You have to set up a new connection in SignalK. Setup according to the picture below. After restarting SK, check out the ST1 messages in the "Data Browser".













Terminate the Python process with "Ctrl + c" and kill the "pigpio" daemon with


sudo killall pigpiod

Prepare for "production"
Move the Python program to a better place 

sudo mv STALK_read.py /usr/local/sbin

systemd service
We will set up "STALK_read.py" as a systemd service, autostart at boot and restart at failure, which also will start the "pigpio" daemon. Get the service file

wget https://raw.githubusercontent.com/MatsA/seatalk1-to-NMEA0183/master/SeaTalk.service

and move it to the right place with

sudo mv SeaTalk.service /etc/systemd/system

then activate it with 

sudo systemctl daemon-reload && sudo systemctl enable SeaTalk && sudo systemctl restart SeaTalk

Check ST 1 messages
Check with


sudo systemctl status SeaTalk

and something like this will be listed

sudo systemctl status SeaTalk
SeaTalk.service - SeaTalk daemon
   Loaded: loaded (/etc/systemd/system/SeaTalk.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2020-06-14 11:04:50 CEST; 44s ago
     Docs: http://pysselilivet.blogspot.com/2020/06/seatalk1-to-nmea-0183-converter-diy.html
  Process: 534 ExecStartPre=/usr/local/bin/pigpiod (code=exited, status=0/SUCCESS)
 Main PID: 544 (python)
    Tasks: 8 (limit: 4035)
   Memory: 7.1M
   CGroup: /system.slice/SeaTalk.service
           ├─539 /usr/local/bin/pigpiod
           └─544 /usr/bin/python /usr/local/sbin/STALK_read.py

Jun 14 11:05:29 zest SeaTalk[544]: $STALK,9c,31,18,ff
Jun 14 11:05:29 zest SeaTalk[544]: $STALK,57,70,2
Jun 14 11:05:29 zest SeaTalk[544]: $STALK,58,25,38,1b,64,c,8d,d0
Jun 14 11:05:29 zest SeaTalk[544]: $STALK,84,36,98,88,40,0,ff,2,17
Jun 14 11:05:29 zest SeaTalk[544]: $STALK,25,4,e8,51,12,33,3
Jun 14 11:05:29 zest SeaTalk[544]: $STALK,24,2,0,0,20
Jun 14 11:05:29 zest SeaTalk[544]: $STALK,26,4,0,0,0,0,20
Jun 14 11:05:29 zest SeaTalk[544]: $STALK,20,1,0,0

and then check the ST1 messages in "Data Browser". 

If You don't want to clutter Your log with the ST1 sentences, just edit the Python code 

sudo nano /usr/local/sbin/STALK_read.py

and make the "print (data)" line start with an "#" and reactivate the service with the above commands.

Now You are ready for "production" !

Remarks
Change port
If You want to change the daemon to another port You have to change the pigpiod.service file with the -p option, and the Python program

Signal K
Please note ! With help from @tkurki I added this conversion feature to the standard SK server, V1.32. Documentation found here.

Open plotter
This setup will soon be added to the documentation but in the meantime please check this post in the OP forum.

Fixes
2020-08-18 The "STALK_read.py" program is updated with 2 bug fixes !! These are also applied to the SK server version.
2021-02-18 The "STALK_read.py" updated.
2022-11-03 SeaTalk.service updated.
2023-07-29 Hardware interface updated at input to the optocoupler board. 

WiFi converter
Why don't use the above setup with a Raspberry Zero W, with the one transistor interface, to get ST1 input, via WiFi, to Your SK server ?

Hardware tuning
The mentioned hardware solution worked in my environment but Marco have done a deeper analyze, with an oscilloscope, which can be checked out here. This post update, done 2023-07-29, is taken that info in consideration.

34 comments:

  1. Just curious about the CPU load of pigpiod. Could I run it on the same machine as e.g. OpenCPN or does pigpiod take up to many cycles, doing bitbanging and all?

    ReplyDelete
    Replies
    1. It's no problem to just use one machine. Less than 10% load for one core after the fix mentioned here https://forum.openmarine.net/showthread.php?tid=2774&pid=15534#pid15534

      Delete
    2. I still have a pretty big CPU load with pigpiod 7.8 on a pi3 model b. Python 2.7 - could that be a problem?

      PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
      700 root 20 0 21500 8236 5620 S 77.8 0.9 5:01.99 python
      492 root 20 0 12480 1616 1416 S 43.4 0.2 5:00.66 pigpiod

      Delete
    3. I used Pigpiod 7.1 and Python 3+. I'm no Python guy, but I should move to 3+. I didn't test, but some fine tuning can be done with "time.sleep(0.01)". Slowly increasing the value. Unfortunately the boat is ashore and the setup is dismantled....

      Delete
  2. Thanks for your post. However, your optocoupler diagram confuses me. For me it slems like it is inverting the signal (which is similar behavior as the NPN situp) where as Thomas in his GitHub page has an optocoupler diagram that (to the best of my knowledge) does NOT invert the signal. Am I correct or not? How come the difference?

    ReplyDelete
    Replies
    1. You are right, both my HW solutions are inverting the signal, but on the other hand I have added code in the Python program which handles this. Why ? This is my way.

      Delete
    2. Thanks a lot for your prompt reply. Now I understand. Especially after having seen the code you added to the signalk-server software. Good work!

      Delete
  3. I adapted your script so it now directly outputs NMEA0183 messages for selected values, without the need for SignalK. It's uploaded to github - I hope I did justice to your excellent pioneering work! https://github.com/marcobergman/seatalk_convert

    ReplyDelete
    Replies
    1. Nice further development !! And the code was not mine, just did some fine tuning. ;-) Another way could be piping the output to => | nmea0183-signalk. https://github.com/SignalK/nmea0183-signalk#command-line. Saw that you tuned the pgm with "time.sleep(0.5)". Was it max value before the output got garbled ? Cpu load low ?

      Delete
    2. It might be that the 0.5s sleep is too much; indeed a value too high results in garbled output. This is the copy I took before I tested it on the boat, and I might have tuned it down again. Setting that timer higher did not get the cpu load on the python process down, strangely enough. The load is not really a big thing - it only affects one of the 4 cpu's.

      Delete
    3. Just solved the cpu load problem! It was a pesky little python thing. I did have the sleep command in the code, but it just did not have the right indentation. The sleep command was simply never executed, because it was at the same level as the while (True) loop. Just a few extra spaces solved my problem. I'm under 10% load now.

      Delete
    4. Thanks ! Really appreciate the time you are spending giving me feedback. Will check it out later today.

      Delete
  4. I want to send data from a pmu9250 to a seatalkng autopilot (p70) and also exchange data between a nmea0183 plotter and VHF. Preferably via SignalK. I am not sure if the message format of seatalkng is the same as in nmea2000. Thanks in advance for any help from a newbie.

    ReplyDelete
    Replies
    1. Thought that the P70 setup included sensors ? Otherwise check the SenseESP project https://github.com/SignalK/SensESP. STNG and NMEA 2000 is the same protocol but differs in connectors. You have to use a HW interface to connect STNG to SK. Please check this link https://github.com/SignalK/signalk-server/wiki/FAQ:-Frequently-Asked-Questions#how-do-i-integrate-with-nmea2000-can-bus Plotter to VHF is "simple", connect, NMEA0183, plotter out to VHF in.

      Delete
  5. can this be used for two seatalk inputs? I have a problem with my wind instrument-it works but is not talking to the other seatalk instruments.
    thinking of getting this output separately from the other seatalk instruments. Putting two pi's at the helm station seems overkill, but would be nice if I could use one pi to read both.
    any ideas?

    ReplyDelete
    Replies
    1. Yes, having 2 daemons running on different ports would solve it. Mentioned below "Remark". Little confused that the wind gauge works but not talking to the other instruments. Are you sure the output is working ?

      Delete
  6. no, I'm not. May be wishful thinking. Boat still on hard, but will check over next few weeks

    ReplyDelete
  7. Hi!

    I'm desperate about making the Seatalk work on my Raspberry, so may be someone here will have an idea about what is wrong.

    I have build the optocoupler interface described at https://github.com/SignalK/signalk-server/blob/master/Seatalk(GPIO).md
    (same as yours)

    with a similar optocoupler circuit. I measured with an ohmmeter the resistances on the optocoupler board and they are 3K as well.


    I have at least 4 Seatalk instruments daisy-chained with official cables. On one of the cable there is a splice that connect to the autopilot course computer ST100/300 where I took out the Seatalk input signal to the Optocoupler.I also tried to connect the optocoupler directly to another instrument ST output, with the same results.


    I connected the circuit with a 4660 Ohm resistor to a Raspberry Pi zero W (headless, running Signalk server) and created the connection as describer in Github (GPIO 4 / inverted).

    I have no signal in Signalk, nor with the tool STALK_read.p.


    Then I measured the voltage (with a voltmeter, I don't have an osciloscope) at the Seatalk connector (with the optocoupler disconnected): I can see a fluctuating voltage between 11V and 12V so I conclueded that that was actually ST data (plus as the autopilot ST100/300 works fine, I guess it can be concluded that it receives correct ST data).


    Then I measured the voltage when the optcouper is connected at the same point: I can see fluctuating voltage around 5V to 6V.

    Then I measured the voltage at the GPIO pin and could see a fluctuating voltage of 1.5-1.7 V.


    So I imagined that for some reason, the voltage at the GPIO was not suffisant to pull the signal down (I've read somewhere on line that you need at least 1.8V to change GPIO inputs). So I replaced the 4660 resistor with 4000, then 3000 to see what happens. With 3000 the STALK_read.p started to display STALK messages (that I'm unable to decode) and the SIgnalK server started to show only 2 data (Magnetic deviation and depth). Nothing else (on top of that the only instrument which is not connected is the depth sounder ;-), so it looks to me as garbage.


    I tried to remove the invert setting but it didn't change anything (Is there a possibility that I burnt the GPIO doing that?).




    - Is the optocoupler functioning correctly? (I tried another one from the same batch with same results). Why haven't I fluctuating 12V at the input?

    - Is the Raspberry pi zero fast enought to decode the ST data flow ? (I believe 4.8 kbauds is not that fast for a pi zero.


    Any help welcome!







    ReplyDelete
    Replies
    1. Hi! Could be that the optocoupler, together with your ST devices, will be a to heavy load. Check the link above below "Hardware tuning". (Haven't tested the method since the "original" setup worked for me) Is the input LED flickering?

      Delete
    2. Yss the LED is flickering (between intense red and light red, it doesn't really switch off). As far as too many devices, I switched some off to check it and it didn't change anything. As far as the "hardware tuning", I don't understand anything but it looks interesting ;-)

      Delete
    3. The LED doesn't really turn off so thats seems OK. Decrease the load are disconnecting devices. Regarding HW tuning, one idea was to test the first circuit.

      Delete
  8. Hi,
    Not sure if anyone is monitoring this.
    I have a bunch of $STALK sentences, but how can I convert them into readable NMEA0183 sentences like $IIMTW - water temp $IIDBT - depth, etc.
    Thanks

    ReplyDelete
    Replies
    1. Nice you succeeded ! As said in the beginning of this post, use OpenPlotter or Signal K to decode to NMEA. But please note that you have to add a matching interface.

      Delete
    2. How do I add the matching interfaces?

      Delete
    3. Don't no your use case, but depending on which equipment you want to send data to you need a USB to RS 232 or a USB to RS 422 hardware. Google and learn more.

      Delete
  9. Thanks for this! do you know if this will also work on a Orangepi Zero ?

    ReplyDelete
    Replies
    1. Sorry to say but I have never tested that HW, but on the other hand it's just a digital input so it should work.

      Delete
  10. Has anyone tried to (or is there a reason not to) use this with Thomas Knauf's bidirectional ST1-to-RS232 circuit (http://www.thomasknauf.de/rap/seabidi.GIF) from his guide (http://www.thomasknauf.de/rap/seatalk3.htm)?

    ReplyDelete
    Replies
    1. Haven't tested it, but it would probably work nice. The "if" is that it lacks an isolated in/out -put and you need software to send data which is not included in Signal K.

      Delete
  11. Thank you for project
    It's easy to make all the seatalk equipment connected to raspberry pi and make it much way easier, also the good thing when using raspberry pi you can do a logger and that you can have all the data in charts or anything like that

    ReplyDelete

Feel free to leave a comment ! ... but due to a lot of spam comments I have to moderate them. Will reply ASAP !