Posts: 3,038
Threads: 63
Joined: Mar 2016
Reputation:
289
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.
Posts: 3,038
Threads: 63
Joined: Mar 2016
Reputation:
289
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
Posts: 3,038
Threads: 63
Joined: Mar 2016
Reputation:
289
Posts: 73
Threads: 7
Joined: Jan 2020
Reputation:
6
great, thank you
I'll try it ASAP and report back
███ - SV Haimana
Posts: 73
Threads: 7
Joined: Jan 2020
Reputation:
6
looking good, thank you
███ - SV Haimana
Posts: 73
Threads: 7
Joined: Jan 2020
Reputation:
6
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
Posts: 3,038
Threads: 63
Joined: Mar 2016
Reputation:
289
I have been able to reproduce this issue after a system update. Investigating...
Posts: 3,038
Threads: 63
Joined: Mar 2016
Reputation:
289
Posts: 73
Threads: 7
Joined: Jan 2020
Reputation:
6
2024-09-10, 12:00 PM
(This post was last modified: 2024-09-10, 12:40 PM by sebba.)
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
Posts: 3,038
Threads: 63
Joined: Mar 2016
Reputation:
289
|