Hallo,
ich bin neu hier.
Ich möchte in Ubuntu mit Python 3 gerne den Serialport
das Signal RTS abfragen.
Aber getRTS() geht ja nicht.
Hat da jemand eine Idee?
Danke und Gruß
Jürgen
Python3 Serial Port Signale
Laut https://pyserial.readthedocs.io/en/late ... Serial.rts ein simples
Code: Alles auswählen
print(serial_connection.rts)
serial_connection.rts Habe ich probiert. Aber geht nicht.
Hier ein Auszug aus meinem Programm:
import serial
PTT = 0
SQL = 0
ser = serial.Serial(port='/dev/ttyUSB0')
if ser.isOpen():
if ser.rts:
PTT = 1
else:
PTT = 0
if ser.getCTS():
SQL = 0
else:
SQL = 1
Abfrage CTS funktioniert.
Abfrage RTS ist IMMER False, egal ob RTS an oder aus ist.
Kann mir jemand sagen warum????
Danke und Gruß
Jürgen
PS: es gibt zwei Programme:
das 1. Programm setzt und löscht das RTS-Signal.
das 2. Programm will nur das RTS-Siganl abfragen
Hier ein Auszug aus meinem Programm:
import serial
PTT = 0
SQL = 0
ser = serial.Serial(port='/dev/ttyUSB0')
if ser.isOpen():
if ser.rts:
PTT = 1
else:
PTT = 0
if ser.getCTS():
SQL = 0
else:
SQL = 1
Abfrage CTS funktioniert.
Abfrage RTS ist IMMER False, egal ob RTS an oder aus ist.
Kann mir jemand sagen warum????
Danke und Gruß
Jürgen
PS: es gibt zwei Programme:
das 1. Programm setzt und löscht das RTS-Signal.
das 2. Programm will nur das RTS-Siganl abfragen
RTS ist ja ein gesendetes Signal. Siehe https://onlinedocs.microchip.com/pr/GUI ... 560AACDBB4
Das kannst du setzen. Du kannst auch abfragen, wie du es gesetzt hast. In deinem Programm. Nicht notwendigerweise woanders!
Das mit den zwei Programmen ist also im Zweifel die Crux. Warum hast du zwei, statt einem?
Das kannst du setzen. Du kannst auch abfragen, wie du es gesetzt hast. In deinem Programm. Nicht notwendigerweise woanders!
Das mit den zwei Programmen ist also im Zweifel die Crux. Warum hast du zwei, statt einem?
Also ich bin Funkamateur.
Das erste Programm steuert einen Tranceiver.
Mit dem RTS-Signal wird der Tranceiver auf Senden geschaltet.
Das zweite Programm soll eine Art Watchdog sein
Wenn das erste Programm spinnt und auf Dauersenden (RTS-Signal immer an) geht,
soll das zweite Programm nach einer bestimmten Zeit das Funkgerät abschalten, damit kein Dauerträger gesendet wird.
Ich hoffe, jetzt ist die Sache klar.
Also ich muss im zweiten Programm irgendwie das RTS-Signal (vom ersten Programm) abfragen.
Gruß
Jürgen
Das erste Programm steuert einen Tranceiver.
Mit dem RTS-Signal wird der Tranceiver auf Senden geschaltet.
Das zweite Programm soll eine Art Watchdog sein
Wenn das erste Programm spinnt und auf Dauersenden (RTS-Signal immer an) geht,
soll das zweite Programm nach einer bestimmten Zeit das Funkgerät abschalten, damit kein Dauerträger gesendet wird.
Ich hoffe, jetzt ist die Sache klar.
Also ich muss im zweiten Programm irgendwie das RTS-Signal (vom ersten Programm) abfragen.
Gruß
Jürgen
- __blackjack__
- User
- Beiträge: 14053
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@juelin: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase). Die Namen aus dem `serial`-Modul die nicht diesen Konventionen folgen sollten nicht mehr verwendet werden, die werden auf absehbare Zeit verschwinden. Und `PTT` und `SQL` sind keine Konstanten, sollten also auch nicht so geschrieben werden als wären es welche.
Die Zuweisung von 0 an `PTT` und `SQL` werden nirgends verwendet, also sollte man die einfach weglassen.
Namen sollten keine kryptischen Abkürzungen enthalten, oder gar nur daraus bestehen. `ser` ist kein guter Name.
`isOpen()` ist durch `is_open` ersetzt, allerdings hier völlig unnötig weil das auf jeden Fall `True` ist. Wäre die Verbindung nicht offen, dann hätte das Erstellen des `Serial`-Objekts eine Ausnahme ausgelöst.
`getCTS()` ist durch das `cts`-Attribut ersetzt.
Die beiden ``if``/``else`` sind überflüssig, denn die Attribute `rts` und `cts` liefern ja bereits entsprechende Werte. Selbst wenn das `bool`-Objekte sein sollten: die sind von `int` abgeleitet und haben die numerischen Werte 0 und 1.
Womit der Auszug auf das hier zusammenschrumpft:
Die Zuweisung von 0 an `PTT` und `SQL` werden nirgends verwendet, also sollte man die einfach weglassen.
Namen sollten keine kryptischen Abkürzungen enthalten, oder gar nur daraus bestehen. `ser` ist kein guter Name.
`isOpen()` ist durch `is_open` ersetzt, allerdings hier völlig unnötig weil das auf jeden Fall `True` ist. Wäre die Verbindung nicht offen, dann hätte das Erstellen des `Serial`-Objekts eine Ausnahme ausgelöst.
`getCTS()` ist durch das `cts`-Attribut ersetzt.
Die beiden ``if``/``else`` sind überflüssig, denn die Attribute `rts` und `cts` liefern ja bereits entsprechende Werte. Selbst wenn das `bool`-Objekte sein sollten: die sind von `int` abgeleitet und haben die numerischen Werte 0 und 1.
Womit der Auszug auf das hier zusammenschrumpft:
Code: Alles auswählen
serial_port = serial.Serial("/dev/ttyUSB0")
ptt = serial_port.rts
sql = serial_port.cts
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Ich habe mir mal die Quellen angeschaut. Hier https://github.com/pyserial/pyserial/bl ... il.py#L457 sieht man, dass der RTS-Zustand aus einem gespeicherten Zustand des Objektes stammt, NICHT irgendwie aus dem System abgerufen wird. Damit hat - zumindest mit pyserial - man keine Chance, das so zu verwirklichen, wie du dir das vorstellst.
Stattdessen kann aber natuerlich auch anders verfahren werden, zB kann der Watchdog via IPC den anderen Prozess ueberwachen, und wenn man zum RTS-Zustand entsprechende Nachrichten verschickt, genauso reagieren. Und da noch viel mehr Gesundheitsdaten pruefen.
Stattdessen kann aber natuerlich auch anders verfahren werden, zB kann der Watchdog via IPC den anderen Prozess ueberwachen, und wenn man zum RTS-Zustand entsprechende Nachrichten verschickt, genauso reagieren. Und da noch viel mehr Gesundheitsdaten pruefen.
Hallo __deets__,
Danke für Deine Hilfe.
Leider hat es nicht geholfen mein Problem zu lösen.
Das erste Programm, das das Signal RTS setzt oder löscht ist nicht von mir
und ich kann da nix ändern (SVXLINK).
Muss mir irgendwie einen anderen Weg überlegen.
Gruß
Jürgen
Danke für Deine Hilfe.
Leider hat es nicht geholfen mein Problem zu lösen.
Das erste Programm, das das Signal RTS setzt oder löscht ist nicht von mir
und ich kann da nix ändern (SVXLINK).
Muss mir irgendwie einen anderen Weg überlegen.
Gruß
Jürgen
Du mußt halt über die vom jeweiligen Betriebssystem vorgesehene Funktion diesen Status abfragen.
Wenn man in den Code von pyserial reinschaut, müßte das einfach das sein:
Wenn man in den Code von pyserial reinschaut, müßte das einfach das sein:
Code: Alles auswählen
TIOCMGET = getattr(termios, 'TIOCMGET', 0x5415)
TIOCM_RTS = getattr(termios, 'TIOCM_RTS', 0x004)
TIOCM_zero_str = struct.pack('I', 0)
flags = fcntl.ioctl(fd, TIOCMGET, TIOCM_zero_str)
rts = struct.unpack('I', flags)[0] & TIOCM_RTS != 0
- __blackjack__
- User
- Beiträge: 14053
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Edit: Ups, viel zu spät. 
Da es Linux betrifft, könntest Du als erstes mal schauen ob Du die gewünschte Information mit ``statserial`` bekommst (https://linux.die.net/man/1/statserial). Falls ja, weisst Du schon mal, dass es grundsätzlich möglich ist.
Falls das möglich ist, wäre der nächste Schritt diesen Low-Level-Kram in Python selbst zu schreiben. Mehr oder weniger ungetestet:
Da es Linux betrifft, könntest Du als erstes mal schauen ob Du die gewünschte Information mit ``statserial`` bekommst (https://linux.die.net/man/1/statserial). Falls ja, weisst Du schon mal, dass es grundsätzlich möglich ist.
Falls das möglich ist, wäre der nächste Schritt diesen Low-Level-Kram in Python selbst zu schreiben. Mehr oder weniger ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import os
from fcntl import ioctl
from struct import Struct
from termios import TIOCM_RTS, TIOCMGET
INTEGER = Struct("I")
ZERO = INTEGER.pack(0)
def main():
file_descriptor = os.open("/dev/ttyUSB0", os.O_RDONLY)
try:
status = INTEGER.unpack(ioctl(file_descriptor, TIOCMGET, ZERO))[0]
print(
f"{status:016b}",
"RTS",
"set" if status & TIOCM_RTS != 0 else "unset",
)
finally:
os.close(file_descriptor)
if __name__ == "__main__":
main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Der Code von __blackjack__ sollte eigentlich nichts setzen. Woran machst du das fest? Siehst du den tatsaechlichen Logik-Level von RTS? Wenn das der Fall ist, dann erklaert das auch, warum pyserial RTS 'cached' verwendet, statt es einfach einzulesen - denn dann scheint das nicht nebenwirkungsfrei zu gehen.
laut Doku (https://docs.python.org/3/library/fcntl.html) file descriptor
_______________________________________________________________________________
https://www.python-kurs.eu/index.php
https://learnxinyminutes.com/docs/python/ https://learnxinyminutes.com/docs/de-de/python-de/
https://quickref.me/python https://docs.python-guide.org/
Das gleiche, wie __blackjack__ gezeigt hat. Wenn das also nicht geht, hilft auch Sirius3 Hinweis nicht weiter.juelin hat geschrieben: Mittwoch 23. August 2023, 13:20 Hallo Sirius3,
Danke für die Antwort.
Leider weiss ich nicht was 'fd' in flags = fcntl.ioctl(fd, TIOCMGET, TIOCM_zero_str) bedeutet.
Bitte kläre mich auf.
Danke und Gruß
Jürgen
- __blackjack__
- User
- Beiträge: 14053
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Also ich habe mein Programm gerade mal probiert. RTS auf ON scheint der Normalzustand zu sein. Wenn ich ein Terminalprogramm starte und RTS umschalte, dann sieht mein Beispielcode weiter oben das aber auch als OFF. Das umschalten kann also nicht nur der Prozess sehen der diese Leitung schaltet. Getestet unter Ubuntu mit einem USB→UART mit einem üblichen FTDI-Chip drauf.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari