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:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
OpenPlotter 4 roadmap
The new OpenCPN 5.10.0 is here.

For OpenCPN 5.10.0 to work properly on OpenPlotter v4 you need to update the openplotter-opencpn-installer app to its latest version 4.2.0.

Changes:

- Support for the new version numbering in Ubutu PPA.

- If you had OpenCPN 5.8.4 installed from Debian backports and you run a regular system update, OpenCPN will be updated to version 5.10.0 from the Ubuntu PPA. The openplotter-opencpn-installer 4.2.0 update also contains the necessary changes so that you can continue using the plugins you were using in OpenCPN 5.8.4 without problems.

- The Debian backports version will probably take a while to be released, but you should have no problem running the PPA version, but if you have it, install the flatpak version.
Reply
It seems that OpenCPN 5.10.0 for flatpak is broken and still needs some fix. PPA version is working using openplotter-opencpn-installer 4.2.0
Reply
Seatalk 1 working on Raspberry Pi 5: https://forum.openmarine.net/showthread.php?tid=5674
Reply
great, thank you
I'll try it ASAP and report back
- SV Haimana
Reply
looking good, thank you

   

   
- SV Haimana
Reply
Hello,

Bad news this time
After few days of running as expected, the Seatalk connection stop running

the errors:

Code:
Sep 10 11:35:14 Traceback (most recent call last): File "<string>", line 294, in <module> File "<string>", line 69, in open File "/usr/local/lib/python3.11/dist-packages/gpiod/__init__.py", line 53, in request_lines
Sep 10 11:35:14 with Chip(path) as chip: ^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/gpiod/chip.py", line 58, in __init__ self._chip = _ext.Chip(path) ^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory
Sep 10 11:35:14 |python -u -c ' import gpiod, sys, datetime ST_PIN = 20 ST_INVERT = 0 # 0=idle high, 1=idle low ST_BITS = 9 ST_STOP = 1 ST_BAUD = 4800 # detect version of gpiod, gpiod_v = int(gpiod.__version__.split(".")[0]) if gpiod_v != 1 and gpiod_v !=2: print("Error: gpiod version {} is not supported".format(gpiod.__version__)) sys.exit() # detect model of Raspberry Pi, tested with Pi 4 and Pi 5 running Bookworm with open("/proc/device-tree/model") as f: model = f.read() if "Pi 4" in model or "Pi 3" in model: gpio_chip = "gpiochip0" elif "Pi 5" in model: gpio_chip = "gpiochip4" else: print("Warning: Use of {} is untested".format(model)) gpio_chip = "gpiochip0" class st1rx: line = None pending_e = None def open(self, pin, baud=ST_BAUD, bits=ST_BITS, stop=ST_STOP, invert=ST_INVERT): self.baud = baud self.bits = bits self.stop = stop self.invert = invert # calculate timing based on baud rate self.fullbit_ns = int(1000000000 / self.baud) self.halfbit_ns = int(self.fullbit_ns / 2) self.frame_ns = int((1 + self.bits + self.stop) * self.fullbit_ns) # ideally we should sample at halfbit_ns, but opto-coupler circuit may have slow rising edge # sample at 1/4 bit pos with invert, and 3/4 bit without invert self.sample_ns = int(self.halfbit_ns / 2) if invert == False: self.sample_ns += self.halfbit_ns if gpiod_v == 1: # get pin with gpiod v1.x.x if self.invert == 0: pull = gpiod.LINE_REQ_FLAG_BIAS_PULL_UP else: pull = gpiod.LINE_REQ_FLAG_BIAS_PULL_DOWN chip = gpiod.Chip(gpio_chip) self.line = chip.get_line(pin) if self.line is None: print("Error connecting to pin ", pin) return False self.line.request( consumer="ST1RX", type=gpiod.LINE_REQ_EV_BOTH_EDGES, flags=pull) else: # get pin with gpiod v2.x.x if self.invert == 0: pull = gpiod.line.Bias.PULL_UP else: pull = gpiod.line.Bias.PULL_DOWN self.line = gpiod.request_lines( "/dev/" + gpio_chip, consumer="ST1RX", config={pin: gpiod.LineSettings(edge_detection=gpiod.line.Edge.BOTH, bias=pull)} ) self.pending_e = None return True def close(self): if self.line is not None: self.line.release() self.line = None def read_gpiod1(self): l = self.line level = 0 data = 0 bits = self.bits stop = self.stop pol = self.invert if self.pending_e is None: # wait for new gpio events, timeout after 0.5 seconds if l.event_wait(nsec=500000000) == False: # no activity, return None return e = l.event_read() else: # we got a pending event e = self.pending_e self.pending_e = None if e.type == e.FALLING_EDGE: level = 0^pol else: level = 1^pol e_ns = e.nsec fullbit_ns = self.fullbit_ns sample_ns = e_ns + self.sample_ns remaining_ns = self.frame_ns b = 0 sb = False while True: # wait for next event if l.event_wait(nsec=remaining_ns): e = l.event_read() e_ns = e.nsec if e_ns < sample_ns: e_ns += 1000000000 # process bits since previous event while sample_ns < e_ns: if sb == False: if level == 0: sb = True else: # not a start bit, return None print("not a start bit") return elif b < bits: # store data bits data |= level << b b += 1 elif stop > 0: # check stop bits if level == 1: stop -= 1 else: # invalid stop bit print("invalid stop bits") return sample_ns += fullbit_ns remaining_ns -= fullbit_ns # new level going forward if e.type == e.FALLING_EDGE: level = 0^pol else: level = 1^pol # check if we are done processing this event if remaining_ns < fullbit_ns: # if so, this event is already start of next frame self.pending_e = e break else: # timeout is end of frame if level == 0: # invalid idle state at end of frame print("invalid idle state") return # add remaining bits to byte while b < bits: data |= level << b b += 1 stop = 0 break if stop == 0 and b == bits: return data else: # missing stop or data bits print("missing stop or data bits") return def read_gpiod2(self): l = self.line level = 0 data = 0 bits = self.bits stop = self.stop pol = self.invert if self.pending_e is None: # wait for new gpio events, timeout after 0.5 seconds if l.wait_edge_events(datetime.timedelta(microseconds=500000)) == False: # no activity, return None return e = l.read_edge_events(1)[0] else: # we got a pending event e = self.pending_e self.pending_e = None if e.event_type == e.Type.FALLING_EDGE: level = 0^pol else: level = 1^pol e_ns = e.timestamp_ns fullbit_ns = self.fullbit_ns sample_ns = e_ns + self.sample_ns remaining_ns = self.frame_ns b = 0 sb = False while True: # wait for next event if l.wait_edge_events(datetime.timedelta(microseconds=remaining_ns/1000)): e = l.read_edge_events(1)[0] e_ns = e.timestamp_ns if e_ns < sample_ns: e_ns += 1000000000 # process bits since previous event while sample_ns < e_ns: if sb == False: if level == 0: sb = True else: # not a start bit, return None print("not a start bit") return elif b < bits: # store data bits data |= level << b b += 1 elif stop > 0: # check stop bits if level == 1: stop -= 1 else: # invalid stop bit print("invalid stop bits") return sample_ns += fullbit_ns remaining_ns -= fullbit_ns # new level going forward if e.event_type == e.Type.FALLING_EDGE: level = 0^pol else: level = 1^pol # check if we are done processing this event if remaining_ns < fullbit_ns: # if so, this event is already start of next frame self.pending_e = e break else: # timeout is end of frame if level == 0: # invalid idle state at end of frame print("invalid idle state") return # add remaining bits to byte while b < bits: data |= level << b b += 1 stop = 0 break if stop == 0 and b == bits: return data else: # missing stop or data bits print("missing stop or data bits") return def read(self): if self.line is None: print("Error: no pin connected") return if gpiod_v == 1: return self.read_gpiod1() else: return self.read_gpiod2() if __name__ == "__main__": gpio = ST_PIN if len(sys.argv) > 1: # Gpio, info as "GPIOnn", from GUI setup. Sensing the seatalk1 (yellow wire) gpio = int("".join(filter(str.isdigit, sys.argv[1]))) pol = ST_INVERT if len(sys.argv) > 2: # Invert, inverted input from ST1, selected in the GUI if sys.argv[2] == "true": pol = 1 st = st1rx() if st.open(pin=gpio, invert=pol) == False: print("Error: Failed to open Seatalk1 pin") sys.exit() try: st_msg = "" st_start = False while True: # read a byte from Seatalk pin d = st.read() # if error, timeout, or start flag is set if d is None or d > 255: # output pending seatalk data if st_start == True: print("$STALK" + st_msg) st_start = False st_msg = "" # if new data if d is not None: # if start flag is set, start a new msg if d > 255: st_start = True st_msg = "" # if a msg is in progress, append byte if st_start == True: st_msg += ",{:02X}".format(d & 0xff) except Exception as e: print(e) except KeyboardInterrupt: pass st.close() print("exit") ' GPIO04 true | exited with 1

   

In these days I occasionally made few updates for Bookworm and also for freeboard-sk but I don't know when this error appear (if it does after some updates or not)
Also, I noticed a very slow and almost unresponsive run of the OS if the Seatalk connection is enabled. Even the "top" command is unresponsive

Any advice will be very welcome

Thanks
- SV Haimana
Reply
I have been able to reproduce this issue after a system update. Investigating...
Reply
I have it: https://github.com/SignalK/signalk-server/issues/1788
Reply
thank you

I tried to "keep it simple" and I uninstalled pypilot (not used) and sdr-vhf
After that (and few reboots) I've got a new error message

   

Code:
[font=monospace][color=#ff0000]Sep 10 13:48:27[/color] Traceback (most recent call last): File "<string>", line 286, in <module> ValueError: invalid literal for int() with base 10: ''
[/font][font=monospace][color=#ff0000]Sep 10 13:48:27[/color] |python -u -c ' import gpiod, sys, datetime ST_PIN = 20 ST_INVERT = 0 # 0=idle high, 1=idle low ST_BITS = 9 ST_STOP = 1 ST_BAUD = 4800 # detect version of gpiod, gpiod_v = int(gpiod.__version__.split(".")[0]) if gpiod_v != 1 and gpiod_v !=2: print("Error: gpiod version {} is not supported".format(gpiod.__version__)) sys.exit() # detect model of Raspberry Pi, tested with Pi 4 and Pi 5 running Bookworm with open("/proc/device-tree/model") as f: model = f.read() if "Pi 4" in model or "Pi 3" in model: gpio_chip = "gpiochip0" elif "Pi 5" in model: gpio_chip = "gpiochip4" else: print("Warning: Use of {} is untested".format(model)) gpio_chip = "gpiochip0" class st1rx: line = None pending_e = None def open(self, pin, baud=ST_BAUD, bits=ST_BITS, stop=ST_STOP, invert=ST_INVERT): self.baud = baud self.bits = bits self.stop = stop self.invert = invert # calculate timing based on baud rate self.fullbit_ns = int(1000000000 / self.baud) self.halfbit_ns = int(self.fullbit_ns / 2) self.frame_ns = int((1 + self.bits + self.stop) * self.fullbit_ns) # ideally we should sample at halfbit_ns, but opto-coupler circuit may have slow rising edge # sample at 1/4 bit pos with invert, and 3/4 bit without invert self.sample_ns = int(self.halfbit_ns / 2) if invert == False: self.sample_ns += self.halfbit_ns if gpiod_v == 1: # get pin with gpiod v1.x.x if self.invert == 0: pull = gpiod.LINE_REQ_FLAG_BIAS_PULL_UP else: pull = gpiod.LINE_REQ_FLAG_BIAS_PULL_DOWN chip = gpiod.Chip(gpio_chip) self.line = chip.get_line(pin) if self.line is None: print("Error connecting to pin ", pin) return False self.line.request( consumer="ST1RX", type=gpiod.LINE_REQ_EV_BOTH_EDGES, flags=pull) else: # get pin with gpiod v2.x.x if self.invert == 0: pull = gpiod.line.Bias.PULL_UP else: pull = gpiod.line.Bias.PULL_DOWN self.line = gpiod.request_lines( "/dev/" + gpio_chip, consumer="ST1RX", config={pin: gpiod.LineSettings(edge_detection=gpiod.line.Edge.BOTH, bias=pull)} ) self.pending_e = None return True def close(self): if self.line is not None: self.line.release() self.line = None def read_gpiod1(self): l = self.line level = 0 data = 0 bits = self.bits stop = self.stop pol = self.invert if self.pending_e is None: # wait for new gpio events, timeout after 0.5 seconds if l.event_wait(nsec=500000000) == False: # no activity, return None return e = l.event_read() else: # we got a pending event e = self.pending_e self.pending_e = None if e.type == e.FALLING_EDGE: level = 0^pol else: level = 1^pol e_ns = e.nsec fullbit_ns = self.fullbit_ns sample_ns = e_ns + self.sample_ns remaining_ns = self.frame_ns b = 0 sb = False while True: # wait for next event if l.event_wait(nsec=remaining_ns): e = l.event_read() e_ns = e.nsec if e_ns < sample_ns: e_ns += 1000000000 # process bits since previous event while sample_ns < e_ns: if sb == False: if level == 0: sb = True else: # not a start bit, return None print("not a start bit") return elif b < bits: # store data bits data |= level << b b += 1 elif stop > 0: # check stop bits if level == 1: stop -= 1 else: # invalid stop bit print("invalid stop bits") return sample_ns += fullbit_ns remaining_ns -= fullbit_ns # new level going forward if e.type == e.FALLING_EDGE: level = 0^pol else: level = 1^pol # check if we are done processing this event if remaining_ns < fullbit_ns: # if so, this event is already start of next frame self.pending_e = e break else: # timeout is end of frame if level == 0: # invalid idle state at end of frame print("invalid idle state") return # add remaining bits to byte while b < bits: data |= level << b b += 1 stop = 0 break if stop == 0 and b == bits: return data else: # missing stop or data bits print("missing stop or data bits") return def read_gpiod2(self): l = self.line level = 0 data = 0 bits = self.bits stop = self.stop pol = self.invert if self.pending_e is None: # wait for new gpio events, timeout after 0.5 seconds if l.wait_edge_events(datetime.timedelta(microseconds=500000)) == False: # no activity, return None return e = l.read_edge_events(1)[0] else: # we got a pending event e = self.pending_e self.pending_e = None if e.event_type == e.Type.FALLING_EDGE: level = 0^pol else: level = 1^pol e_ns = e.timestamp_ns fullbit_ns = self.fullbit_ns sample_ns = e_ns + self.sample_ns remaining_ns = self.frame_ns b = 0 sb = False while True: # wait for next event if l.wait_edge_events(datetime.timedelta(microseconds=remaining_ns/1000)): e = l.read_edge_events(1)[0] e_ns = e.timestamp_ns if e_ns < sample_ns: e_ns += 1000000000 # process bits since previous event while sample_ns < e_ns: if sb == False: if level == 0: sb = True else: # not a start bit, return None print("not a start bit") return elif b < bits: # store data bits data |= level << b b += 1 elif stop > 0: # check stop bits if level == 1: stop -= 1 else: # invalid stop bit print("invalid stop bits") return sample_ns += fullbit_ns remaining_ns -= fullbit_ns # new level going forward if e.event_type == e.Type.FALLING_EDGE: level = 0^pol else: level = 1^pol # check if we are done processing this event if remaining_ns < fullbit_ns: # if so, this event is already start of next frame self.pending_e = e break else: # timeout is end of frame if level == 0: # invalid idle state at end of frame print("invalid idle state") return # add remaining bits to byte while b < bits: data |= level << b b += 1 stop = 0 break if stop == 0 and b == bits: return data else: # missing stop or data bits print("missing stop or data bits") return def read(self): if self.line is None: print("Error: no pin connected") return if gpiod_v == 1: return self.read_gpiod1() else: return self.read_gpiod2() if __name__ == "__main__": gpio = ST_PIN if len(sys.argv) > 1: # Gpio, info as "GPIOnn", from GUI setup. Sensing the seatalk1 (yellow wire) gpio = int("".join(filter(str.isdigit, sys.argv[1]))) pol = ST_INVERT if len(sys.argv) > 2: # Invert, inverted input from ST1, selected in the GUI if sys.argv[2] == "true": pol = 1 st = st1rx() if st.open(pin=gpio, invert=pol) == False: print("Error: Failed to open Seatalk1 pin") sys.exit() try: st_msg = "" st_start = False while True: # read a byte from Seatalk pin d = st.read() # if error, timeout, or start flag is set if d is None or d > 255: # output pending seatalk data if st_start == True: print("$STALK" + st_msg) st_start = False st_msg = "" # if new data if d is not None: # if start flag is set, start a new msg if d > 255: st_start = True st_msg = "" # if a msg is in progress, append byte if st_start == True: st_msg += ",{:02X}".format(d & 0xff) except Exception as e: print(e) except KeyboardInterrupt: pass st.close() print("exit") ' undefined true | exited with 1
[/font][font=monospace]Sep 10 13:49:05 GET /admin/fonts/fa-solid-900.1551f4f60c37af51121f106501f69b80.woff2 [color=#00aaaa]304[/color] 3.026 ms - -[/font]


hope it helps

it seems the last error appear if the seatalk connection is added through SK, not from OP4 GPIO app
- SV Haimana
Reply
Fixed: https://forum.openmarine.net/showthread.php?tid=5674
Reply


Forum Jump:


Users browsing this thread: 10 Guest(s)