Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pigpio will not run on a Pi 5 #1658

Closed
sailoog opened this issue Dec 21, 2023 · 42 comments
Closed

pigpio will not run on a Pi 5 #1658

sailoog opened this issue Dec 21, 2023 · 42 comments

Comments

@sailoog
Copy link
Contributor

sailoog commented Dec 21, 2023

joan2937/pigpio#589

Investigating gpiod and pinctrl as replacement...

@sailoog
Copy link
Contributor Author

sailoog commented Jan 13, 2024

My first search was unsuccessful, we need some library compatible with RPi5 capable of bitbanging. I'm still investigating...

@sailoog
Copy link
Contributor Author

sailoog commented Aug 21, 2024

OK it is done :)

We already have a new python script using gpiod library instead of pigpio that works on RPi 4 and 5.

5922320638155015324

Aug 21 20:55:43 2024-08-21T19:55:43.951Z signalk-server:events:connection:seatalk:nmea0183 $STALK,26,04,1A,08,00,00,10
Aug 21 20:55:43 2024-08-21T19:55:43.976Z signalk-server:events:connection:seatalk:nmea0183 $STALK,27,01,47,01
Aug 21 20:55:43 2024-08-21T19:55:43.997Z signalk-server:events:connection:seatalk:nmea0183 $STALK,52,01,D3,00
Aug 21 20:55:44 2024-08-21T19:55:44.018Z signalk-server:events:connection:seatalk:nmea0183 $STALK,53,30,14
Aug 21 20:55:44 2024-08-21T19:55:44.044Z signalk-server:events:connection:seatalk:nmea0183 $STALK,57,00,14
Aug 21 20:55:44 2024-08-21T19:55:44.072Z signalk-server:events:connection:seatalk:nmea0183 $STALK,50,02,2A,3F,00
Aug 21 20:55:44 2024-08-21T19:55:44.099Z signalk-server:events:connection:seatalk:nmea0183 $STALK,51,02,02,49,94
Aug 21 20:55:44 2024-08-21T19:55:44.215Z signalk-server:events:connection:seatalk:nmea0183 $STALK,58,25,2A,02,7A,02,CA,D8
Aug 21 20:55:44 2024-08-21T19:55:44.315Z signalk-server:events:connection:seatalk:nmea0183 $STALK,23,01,16,48
Aug 21 20:55:44 2024-08-21T19:55:44.818Z signalk-server:events:connection:seatalk:nmea0183 $STALK,89,F2,12,00,20
Aug 21 20:55:44 2024-08-21T19:55:44.847Z signalk-server:events:connection:seatalk:nmea0183 $STALK,89,32,13,00,20
Aug 21 20:55:44 2024-08-21T19:55:44.873Z signalk-server:events:connection:seatalk:nmea0183 $STALK,10,01,00,CA
Aug 21 20:55:44 2024-08-21T19:55:44.895Z signalk-server:events:connection:seatalk:nmea0183 $STALK,11,01,11,09
Aug 21 20:55:44 2024-08-21T19:55:44.920Z signalk-server:events:connection:seatalk:nmea0183 $STALK,20,01,D0,00
Aug 21 20:55:44 2024-08-21T19:55:44.948Z signalk-server:events:connection:seatalk:nmea0183 $STALK,26,04,1C,08,00,00,10
Aug 21 20:55:44 2024-08-21T19:55:44.971Z signalk-server:events:connection:seatalk:nmea0183 $STALK,27,01,47,01
Aug 21 20:55:44 2024-08-21T19:55:44.998Z signalk-server:events:connection:seatalk:nmea0183 $STALK,52,01,D4,00
Aug 21 20:55:45 2024-08-21T19:55:45.022Z signalk-server:events:connection:seatalk:nmea0183 $STALK,53,70,14
Aug 21 20:55:45 2024-08-21T19:55:45.527Z signalk-server:events:connection:seatalk:nmea0183 $STALK,57,00,14 

The script detects the GPIO chip and uses the same UI in Signal K server. Only the embedded python code should be replaced in pigpio-seatalk.js and modify the docs. Since pigpio will no longer be used, how should we handle references to pigpio in the file name?

@tkurki
Copy link
Member

tkurki commented Aug 22, 2024

Would it make more sense to create a new connection type rather than change the existing one? With NMEA2000 we have the data type and then source separately.

How would / should this affect the current users, with working systems? Do they keep using pigpio or are their systems silently switched over to the new way? As a user I might not want that...

@astuder
Copy link
Contributor

astuder commented Aug 22, 2024

I wrote the Python script that @sailoog tested. It works with gpiod 1.6.3 that comes preinstalled with Raspberry Pi OS Bookworm, and also with gpiod 2.2.1 that is installed when updating it with pip. I tested with Raspberry Pi OS Bookworm on Raspberry Pi 4 and 5 for both versions of gpiod.

I haven't tested with older versions of Raspberry Pi OS, or other Pi models.

Would it be possible to switch the .js silently when Bookworm and Pi 4 or Pi 5 is detected?

@astuder
Copy link
Contributor

astuder commented Aug 22, 2024

I apologize, I'm not familiar with Signal K Server.

Looking at the documentation, I can see how it may be easier to have a separate source for pigpio and gpiod. Otherwise it will be tricky to still cover the pigpio installation steps without confusing the user.

@sailoog
Copy link
Contributor Author

sailoog commented Aug 22, 2024

Agree. The change could be made silently to the user, but adding a new source could be more consistent. If I am not wrong we should add a new field "Seatalk Source" to the Data Type "Seatalk (GPIO)" form containing something like "pigpio" and "gpiod" as options but is it possible to make it silent for existing RPi4/pigpio users without any action on their side?

For non-OpenPlotter users:

As @astuder explained, his script works with both the outdated version of gpiod installed by default on Raspberry OS, and the new active version installed with pip:

sudo pip3 install gpiod --break-system-packages

Obviously active is the recommended one, but pip will complain that the package is being installed in a non-virtual environment, but you can ignore the warning.

I can update the documentation unless @MatsA wants to do it himself.

@astuder
Copy link
Contributor

astuder commented Aug 22, 2024

So I guess a separate .js is the way to go. I will submit a pull-request for st1rx.js later today.

For the UI: How about having a new source drop-down defaulting to "gpiod", allowing the user to select "pigpio (legacy)" if they run into problems with gpiod?

I do NOT recommend updating gpiod outside of very well controlled environments. It will introduce the unsuspecting user to Python's dependency hell as any other Python application using gpiod will break. Almost all APIs changed between 1.x.x and 2.x.x. I put some effort into supporting both versions, so no need for us to push users to update gpiod.

Anyone knows how far back the Python binding of gpiod was available on Raspberry Pi? And what is realistically supported by the current version of Signal K server?

Here's the standalone Python script if anyone wants to run some tests. Please report results here. May also be interesting to see how/whether it works on Orange Pi and similar.

I plan to test with a legacy Raspian on a Raspberry Pi 3 today.

@sailoog
Copy link
Contributor Author

sailoog commented Aug 22, 2024

https://packages.debian.org/search?keywords=gpiod

1.x.x has been there since buster and will still be there in trixie. OK then nothing about 2.x.x version in docs.

OpenPlotter has been using 2.x.x since the beginning of version 4 and no problems so far.

@astuder
Copy link
Contributor

astuder commented Aug 22, 2024

Tested on a Pi 3 with a freshly imaged Raspbian GNU/Linux 11 (bullseye):
The gpiod Python library was not installed, pip installs version 2.2.1
works as expected after adding Pi 3 to the model detection

I updated the gist with that change. I also split read() into version specific implementations to improve readability, and minimize overhead.

@MatsA
Copy link
Contributor

MatsA commented Aug 23, 2024

Thanks for charing the changes @sailoog . I don't fully understand the changes so would appreciate that you do the documentation update. Nice work @astuder. Thanks Mats.

@sailoog
Copy link
Contributor Author

sailoog commented Aug 23, 2024

Thanks for charing the changes @sailoog . I don't fully understand the changes so would appreciate that you do the documentation update. Nice work @astuder. Thanks Mats.

Ok, no problem, I will try to do it today in a parallel PR.

@sailoog
Copy link
Contributor Author

sailoog commented Aug 23, 2024

Tested on a Pi 3 with a freshly imaged Raspbian GNU/Linux 11 (bullseye): The gpiod Python library was not installed, pip installs version 2.2.1 works as expected after adding Pi 3 to the model detection

Raspbian is not the same as Raspberry OS. Raspberry OS is using the Debian repositories where gpiod was present since Buster, but Raspbian had its own repositories where gpiod was probably not present because it was not a popular library. If I am not wrong Raspbian became Raspberrry OS in bullseye but the 32bit version was still Raspbian.

It might be best to advise users to check if gpiod is installed first. If it is installed, do not touch it in case some program is using it. If not installed, install the latest version from pip.

@jimseng
Copy link

jimseng commented Aug 23, 2024

I just ran a test with the script from astuder. I'm not sure if the results are as expected. I get valid Seatalk data using my own script based around pigpiod, and seatalk_read.py (https://github.com/Thomas-GeDaD/Seatalk1-Raspi-reader).
I get multiple "invalid stop bits", "invalid idle state", "not a start bit" when I run st1rx.py My Seatalk network is connected to my pi via an opto with GPIO6 pulled up to 3.3v via a 10k resistor. Just thought I would see if I can contribute to this thread as I have been dying to migrate over to my Pi 5.
I have attached the output from st1rx.py
ST_GPIOD_Test.txt

I am running it on a Pi 4 and had to install gpiod with pip, which installed without any issues.

@astuder
Copy link
Contributor

astuder commented Aug 23, 2024

@jimseng Thanks for testing, that's the kind of results I was looking for / feared :)

Are you able to repeat the test with a fresh Raspberry Pi image? I suspect that the issue is reliability of the solution when the Pi is under load, but it would be a good test to rule out the hardware as a cause.

@sailoog Raspian / Raspberry Pi OS: That string is what the OS reports. I don't think there was a 64bit version to choose from in the Imager.

@jimseng
Copy link

jimseng commented Aug 23, 2024

Well for no reason other than to fiddle, I changed ST_BAUD = 4900 and now it works much better. I added a socket and am sending "$STALK" + st_msg via UDP to SignalK on my Pi 5 via ethernet and am getting my instruments displaying correctly in OpenCPN.
This is awesome work by astuder. I'll start wiring it to my Pi 5 shortly. I have attached the output with the baud rate set at 4900 in case anyone is interested.
4900_test.txt

@astuder
Copy link
Contributor

astuder commented Aug 23, 2024

Hmm, that's unexpected. Do you have multiple ST devices on the bus? If so, were all instruments not working, or only some?

Do you also get occasional invalid messages with pigpio? Like for example the single-byte messages.

I may be able to dynamically adjust the bit timing without too much overhead.

@astuder
Copy link
Contributor

astuder commented Aug 23, 2024

Oh, and occasional bit errors can happen with multiple instruments due to bus collisions.

I probably should make printing the bit errors a debug option. And add a mechanism to discard partial $STALK messages when bit errors are detected.

@sailoog
Copy link
Contributor Author

sailoog commented Aug 23, 2024

The socket could be affecting performance if it is located in the loop. Could you also try the original code without modifications and run it as?:

python3 st1rx.py GPIO06 true

and

python3 st1rx.py GPIO06 false

after checking what option works better try to stop all programs or services in your system to unload the CPU and check if the result improves.

@jimseng
Copy link

jimseng commented Aug 23, 2024

I don't think the socket is the problem as I tried it purely with the original script. I didn't get expected results until I changed the baud rate. I am talking purely about looking at the printed datagrams on the screen. When I say my instruments were working in OpenCPN, I first got the datagrams to look as expected by changing the baud rate to 4900. I then moved on to adding a socket to the script to see if I could get the $STALK string over UDP to my Pi 5 (which worked straight away).
For context, I read seatalk with pigpio and stream it back to a custom instrument display on my phone (plus I send autopilot commands back from my phone). That is why I know what a seatalk datagram looks like and why I recognized that it wasn't looking correct. This lead me to try changing the baud rate to 4900, for no other reason than just to try it. Immediately I recognized the datagrams and moved onto the UDP stuff. I hope this makes sense. I tried various baud rates from 4820 to 48900. Anything above 4820 produces "proper" data.
I can try a fresh image, probably not tonight though. Although I am pretty sure my Pi 4 isn't running anything other than a hotspot and my ssh session. I turned off other services (apache,mysqld etc) and there was no difference. CPU running at about 5% (see screen grab of ssh sessions)
Very happy to try and help. I am sailing Saturday afternoon UK time. Might have time in the morning.
ssh

@jimseng
Copy link

jimseng commented Aug 23, 2024

The screen grab above is with the baud rate set to 4900

@jimseng
Copy link

jimseng commented Aug 23, 2024

Oh and with pigpio the attached text file is the output from my own script. I don't think there are many errors, but I haven't looked that hard.
pigpio_seatalk.txt

@sailoog
Copy link
Contributor Author

sailoog commented Aug 23, 2024

OK thanks.

I have also repeated the stress test taking the Raspberry Pi 5 to 100% and I have no data loss. Even the blank space that can be seen in the Signal k log matches the Seatalk log:

Captura de 2024-08-23 20-28-56

Aug 23 19:25:27 2024-08-23T18:25:27.371Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,58,25,29,DE,1A,02,BC,3E
Aug 23 19:25:27 2024-08-23T18:25:27.471Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,23,01,18,4C
Aug 23 19:25:27 2024-08-23T18:25:27.970Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,89,22,0B,00,20
Aug 23 19:25:28 2024-08-23T18:25:27.999Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,89,22,0B,00,20
Aug 23 19:25:28 2024-08-23T18:25:28.024Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,10,01,02,C6
Aug 23 19:25:28 2024-08-23T18:25:28.044Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,11,01,04,03
Aug 23 19:25:28 2024-08-23T18:25:28.066Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,20,01,11,00
Aug 23 19:25:28 2024-08-23T18:25:28.097Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,26,04,A5,00,00,00,10
Aug 23 19:25:28 2024-08-23T18:25:28.117Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,27,01,5A,01
Aug 23 19:25:28 2024-08-23T18:25:28.137Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,52,01,1F,00
Aug 23 19:25:28 2024-08-23T18:25:28.156Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,53,20,0B
Aug 23 19:25:28 2024-08-23T18:25:28.470Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,57,00,14
Aug 23 19:25:28 2024-08-23T18:25:28.570Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,89,62,0B,00,20
Aug 23 19:25:28 2024-08-23T18:25:28.970Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,23,01,18,4C
Aug 23 19:25:28 2024-08-23T18:25:28.995Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,89,62,0B,00,20
Aug 23 19:25:29 2024-08-23T18:25:29.022Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,10,01,02,C5
Aug 23 19:25:29 2024-08-23T18:25:29.047Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,11,01,04,05
Aug 23 19:25:29 2024-08-23T18:25:29.067Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,20,01,11,00
Aug 23 19:25:29 2024-08-23T18:25:29.095Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,26,04,A7,00,00,00,10
Aug 23 19:25:29 2024-08-23T18:25:29.119Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,27,01,5A,01
Aug 23 19:25:29 2024-08-23T18:25:29.147Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,52,01,20,00
Aug 23 19:25:29 2024-08-23T18:25:29.173Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,53,20,0B
Aug 23 19:25:29 2024-08-23T18:25:29.198Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,57,00,14
Aug 23 19:25:29 2024-08-23T18:25:29.225Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,50,02,29,36,16
Aug 23 19:25:29 2024-08-23T18:25:29.247Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,51,02,02,D3,92
Aug 23 19:25:29 2024-08-23T18:25:29.470Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,58,25,29,DE,18,02,BC,3D
Aug 23 19:25:29 2024-08-23T18:25:29.769Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,89,A2,0B,00,20
Aug 23 19:25:29 2024-08-23T18:25:29.975Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,23,01,18,4C
Aug 23 19:25:30 2024-08-23T18:25:30.000Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,89,A2,0B,00,20
Aug 23 19:25:30 2024-08-23T18:25:30.002Z signalk-server:events:connection:seatalk1:nmea0183
Aug 23 19:25:30 2024-08-23T18:25:30.027Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,10,01,02,C5
Aug 23 19:25:30 2024-08-23T18:25:30.051Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,11,01,04,01
Aug 23 19:25:30 2024-08-23T18:25:30.071Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,20,01,11,00
Aug 23 19:25:30 2024-08-23T18:25:30.098Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,26,04,AD,00,00,00,10
Aug 23 19:25:30 2024-08-23T18:25:30.120Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,27,01,59,01
Aug 23 19:25:30 2024-08-23T18:25:30.144Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,52,01,20,00
Aug 23 19:25:30 2024-08-23T18:25:30.170Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,53,20,0B
Aug 23 19:25:30 2024-08-23T18:25:30.470Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,57,00,14
Aug 23 19:25:30 2024-08-23T18:25:30.980Z signalk-server:events:connection:seatalk1:nmea0183 $STALK,89,E2,0B,00,20 

@astuder
Copy link
Contributor

astuder commented Aug 23, 2024

Faster baudrate means that the bit gets sampled earlier, with the last bit having the biggest offset. I wonder if the spacing at the end of a byte is shorter than expected. What happens if you run at 4800 and set ST_STOP=0?

@sailoog can you run the same test with st1rx.py? Signal K may suppress non-NMEA output.

@sailoog
Copy link
Contributor Author

sailoog commented Aug 23, 2024

Done, same result. I am sure there is no data loss because I can compare at any time what is going out from the Raymarine MFD and what is going in in the SK log or the terminal. Look at my post.

I think that could be a hardware issue, remember the problems we had when developing the HAT using slow optocouplers or the wrong resistor.

@jimseng
Copy link

jimseng commented Aug 23, 2024

ST_INVERT = 1 # 0=idle high, 1=idle low
ST_BITS = 9
ST_STOP = 0
ST_BAUD = 4800

$STALK,26,04
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
$STALK,FF
not a start bit
$STALK,27,01
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
$STALK,FF
not a start bit
$STALK,60,0C
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
$STALK,FF
not a start bit
$STALK,00,02
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit
not a start bit

@astuder
Copy link
Contributor

astuder commented Aug 23, 2024

ah well, so much for that theory :)

@astuder
Copy link
Contributor

astuder commented Aug 23, 2024

@jimseng do you have multiple ST devices on the bus? Or just one?

@jimseng
Copy link

jimseng commented Aug 23, 2024

I have the wind, depth, speed plus a couple of St6000+ repeaters, not that I am pushing buttons.

@astuder
Copy link
Contributor

astuder commented Aug 23, 2024

Another idea: what happens if you remove halfbit_ns from this line:
remaining_ns = frame_ns + halfbit_ns
gpiod 1.x:
https://gist.github.com/astuder/c319cf955f6d651350222d36065981b3#file-st1rx-py-L110
gpiod 2.x:
https://gist.github.com/astuder/c319cf955f6d651350222d36065981b3#file-st1rx-py-L206

@jimseng
Copy link

jimseng commented Aug 23, 2024

sample_ns = e_ns + halfbit_ns
remaining_ns = frame_ns #+ halfbit_ns
b = 0
sb = False

Still no joy. However with the halfbit_ns commented out, 4900 baud rate still gives good results. So far that is the only thing that has made a difference. I'm trying to find an SD card.
Just a thought. It is a Pi 4 but I think I am running 32 bit OS. It's been on the boat for 6 years.

@jimseng
Copy link

jimseng commented Aug 24, 2024

So this morning I ran a test with a brand new 64 bit bookworm image. I only installed samba and I get exactly the same issue. (This is with the script unedited, except for the gpio pin number change from 20 to 6):
4800:
$STALK,90
$STALK,01
$STALK,00
$STALK,3E
$STALK,91
$STALK,01
$STALK,05
$STALK,05
$STALK,20,01,00,00
$STALK,23,01,13,42
$STALK,00,02,60,F0,00
$STALK,9C
$STALK,71
invalid stop bits
$STALK,07
$STALK,26,04,00,00,00,00,04
$STALK,27,01,24,01
invalid stop bits
$STALK,C4
$STALK,06
$STALK,00
$STALK,40
invalid stop bits
$STALK,00
$STALK,00
$STALK,06
$STALK,90
$STALK,01
$STALK,00
$STALK,00
$STALK,91
$STALK,01
$STALK,05
$STALK,05
$STALK,00,02,60,F0,00
$STALK,20,01,00,00
$STALK,23,01,13,42
invalid stop bits
$STALK,9C
invalid stop bits
$STALK,06
$STALK,26,04,00,00,00,00,04
$STALK,27,01,24,01
$STALK,90,00,03
invalid stop bits
$STALK,C4
invalid stop bits
$STALK,00
$STALK,60
invalid stop bits
$STALK,00
$STALK,00
$STALK,06
$STALK,90
$STALK,01
$STALK,00
$STALK,12
$STALK,91
$STALK,01
$STALK,05
$STALK,08
$STALK,00,02,60,EB,00
$STALK,20,01,00,00
$STALK,23,01,13,42
invalid stop bits
$STALK,DC
invalid stop bits
$STALK,06
$STALK,26,04,00,00,00,00,04
$STALK,27,01,24,01
invalid stop bits
$STALK,C4
invalid stop bits
$STALK,00
$STALK,40
invalid stop bits
$STALK,00
$STALK,00
$STALK,06
$STALK,D9
$STALK,00

And with 4900:
$STALK,84,B6,06,00,40,00,FD,00,06
$STALK,10,01,00,1D
$STALK,11,01,05,02
$STALK,9C,B1,06,FD
$STALK,00,02,60,F1,00
$STALK,20,01,00,00
$STALK,23,01,13,42
$STALK,26,04,00,00,00,00,04
$STALK,27,01,24,01
$STALK,84,B6,06,00,40,00,FD,00,06
$STALK,99,00,00
$STALK,10,01,00,2D
$STALK,11,01,05,05
$STALK,9C,B1,06,FD
$STALK,00,02,60,F1,00
$STALK,20,01,00,00
$STALK,23,01,13,42
$STALK,26,04,00,00,00,00,04
$STALK,27,01,24,01
$STALK,60,0C,01,00,00,00,00,00,00,00,00,00,00,00,01
$STALK,90,00,03
$STALK,84,F6,06,00,40,00,FD,00,06
$STALK,10,01,00,22
$STALK,11,01,05,05
$STALK,9C,F1,06,FD
$STALK,00,02,60,F1,00
$STALK,20,01,00,00
$STALK,23,01,13,42
$STALK,26,04,00,00,00,00,04
$STALK,27,01,24,01
$STALK,84,F6,06,00,40,00,FD,00,06
$STALK,10,01,00,17
$STALK,11,01,05,05
$STALK,9C,31,07,FD
$STALK,00,02,60,F4,00
$STALK,20,01,00,00
$STALK,23,01,13,42
$STALK,26,04,00,00,00,00,04
$STALK,27,01,24,01
$STALK,90,00,03
$STALK,84,36,07,00,40,00,FD,00,06
$STALK,10,01,00,14
$STALK,11,01,05,05
$STALK,9C,31,07,FD
$STALK,00,02,60,F4,00
$STALK,20,01,00,00
$STALK,23,01,13,42
$STALK,26,04,00,00,00,00,04

@sailoog
Copy link
Contributor Author

sailoog commented Aug 24, 2024

I did a test with something similar to your circuit. The resistor is 4.7 KΩ:

5931593940698513756

these are my settings:

ST_PIN = 16
ST_INVERT = 1 # 0=idle high, 1=idle low
ST_BITS = 9
ST_STOP = 1
ST_BAUD = 4800

It works fine. If I change to a 10KΩ resistor I get similar results to yours and changing the baud rate improves it a bit, but not as much as yours. Can you try with 4.7KΩ?

@jimseng
Copy link

jimseng commented Aug 24, 2024

Ok. So this looks like a hardware issue. Unfortunately I don't have any resistors on board and I am using a custom made PCB so it looks like I need to do a bit of tuning when I can get back with some resistors. Unless there are any more suggestions I will report back when I have had a chance to swap the resistor out, or try with the off the shelf opto module.

@astuder
Copy link
Contributor

astuder commented Aug 24, 2024

If the slow edge is the issue, the width of the positive and negative bits are not of equal size. You probably can fix that issue in software by moving the sample point closer to the start of a bit. Try replacing

halfbit_ns = int(fullbit_ns / 2)

with

halfbit_ns = int(fullbit_ns / 4)

I will have to think a bit about whether that's a good permanent fix or not.

@astuder
Copy link
Contributor

astuder commented Aug 24, 2024

Background: Your Seatalk signal looks something like this:
2022-12-11 seatalk4800

The Raspberry Pi recognizes 1 or 0 based on a threshold around 1V. Due to the shape of the transition, this results in shorter 0s than 1s. A smaller resistor will sharpen the transition, reducing the imbalance.

st1rx.py determines the state of a bit by sampling at the center of each bit. It is using the first transition to 0 (start bit) as a reference point. If the imbalance is greater than 75/25, the 0 bit gets shorter than the calculated halfbit duration, and the sample point will fall inside the wrong bit.

If the 0 period is too short, moving the sampling point to the right will improve the situation. With ST_INVERT=1, the bits are inverted, so the 0 period is too long, and moving the sampling point to the left is needed. (or the other way around, I need more coffee!)

On the downside, shifting sampling point will reduce the timing margin. Currently transmission speeds on both ends can mismatch by a bit less than 5% (half-bit shift over 11 bits). Moving the sample point off-center by 1/4 bit, reduces that to less than 2.5%.

In short, I may have to come up with a more robust algorithm if we want to avoid issues with non-ideal hardware.

@jimseng
Copy link

jimseng commented Aug 24, 2024

Thanks astuder. That has worked. I have it working reliably at 4800 and I can UDP stream from my pi 4 to my phone and Pi 5. I can't remember what opto I am using, perhaps the opto is slow. Anyway. This is excellent work. I am really grateful for all the help from you all.

@astuder
Copy link
Contributor

astuder commented Aug 25, 2024

I update the pull request and the st1rx.py gist based on the debugging above. The main change is shifting the sample point 1/4 bit earlier/later to accommodate for non-ideal opto-coupler circuits.

@jimseng can you test that this still works on your setup?

@sailoog can you check with SignalK / OpenPlotter?

@jimseng
Copy link

jimseng commented Aug 25, 2024

Hi.
That is working well on my Pi 4.
In case it is relevant, I believe this is the opto in my system:
https://www.rapidonline.com/kingbright-kb814-single-channel-photocoupler-58-0920

@sailoog
Copy link
Contributor Author

sailoog commented Aug 25, 2024

st1rx.py and SK plugin tested using the MacArthur HAT (transistor) and the external circuit (optocoupler + 4.7KΩ) on Raspberry Pi 5 under stressed and normal operation. No issues.

@sailoog
Copy link
Contributor Author

sailoog commented Sep 1, 2024

Everything is ready at OpenPlotter to implement this change when the next version of Signal K server is released. I know you have released one recently, do you have any idea when the next one will be?

@sailoog
Copy link
Contributor Author

sailoog commented Sep 1, 2024

Thanks!

Closed by #1779

@sailoog sailoog closed this as completed Sep 1, 2024
@MatsA
Copy link
Contributor

MatsA commented Sep 1, 2024

Great work ! 👍🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants