Probleme mit pyserial

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
holgie
User
Beiträge: 12
Registriert: Sonntag 18. Januar 2015, 16:55

Hallo zusammen,
ich möchte mit Python Daten an die serielle Schnittstelle eines Atmega8 schicken und von dort empfangen. Dafür verwende ich untenstehenden Code. Das Versenden funktioniert einwandfrei aber leider bekomme ich keine Daten eingelesen. Die globale Variable Werte ist immer leer. Das lesen läuft in einem extra thread weil ich ja nicht weiß wann der Atmega etwas verschickt. Der PC muss ständig lesebereit sein.
Ich hatte zuerst ser.readline() gewählt und vom Atmega \n als Abschluss senden lassen, was auch nicht funktionierte.
Die Übertragung vom Atmega funktioniert, dies habe ich mit hterm getestet.
Wäre nett wenn mir jemand weiterhelfen würde. Ich komme leider nicht auf die Lösung.
Gruß
Holger

Code: Alles auswählen

import serial
import time, _thread

def empfang():
    global werte
    id = _thread.get_ident()
    print("Empfangstherad lauft, id={0}.".format(id))
    while 1:
            try:
                werte = ser.read(5).decode('ascii')
            except:
                print("Lesefehler im Thread",id)
                ser.close()

ser = serial.Serial('COM1', 9600, timeout=0, parity=serial.PARITY_NONE, rtscts=0)
werte = 0
_thread.start_new_thread(empfang,())
time.sleep(0.5)

while 1:


    print ("Gebe den Befehl ein")
    text = input()
    ser.write(format(text).encode('ascii')+b'\r\n')
    print(werte)
    print (len(werte))
Zuletzt geändert von Anonymous am Dienstag 8. Dezember 2015, 21:16, insgesamt 2-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
holgie
User
Beiträge: 12
Registriert: Sonntag 18. Januar 2015, 16:55

Hallo,
bei timeout=3 funktioniert es manchmal. Es ist aber kein sicherer Empfang möglich.
Gruß
Holger
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Namen, die mit einem Unterstrich beginnen, bedeuten: das ist ein Implementationsdetail und sollte nicht von außen verwendet werden. Wenn man das Inhaltsverzeichnis zur Dokumentation der Standardbibliothek von uben nach unten liest, stößt man zuerst auf das threading-Modul, welches man verwenden sollte, anstatt _thread. Ich wundere mich ja schon seit Jahren darüber, dass Anfänger immer von unten nach oben zu lesen scheinen...

So, wie du das programmiert hast, wird es nicht funktionieren. Wenn man aus verschiedenen Threads auf dieselben Daten zugreift, wickelt man das normalerweise in einen Monitor, oder verwendet wenigstens ein Lock. Es ist aber alles andere als trivial, das fehlerfrei hinzubekommen. Deswegen verwendet man in Python gerne eine Queue, die einem das Locking abnimmt. queue.Queue aus der Standardbibliothek ist genau dafür gemacht. Außerdem bedeutet der ser.read(5) Aufruf "lies bis zu fünf Bytes". Ggf. musst du mehr als einen Aufruf durchführen und die empfangenen Bytes konkatenieren.

Globale Variablen sollte es in einem vernünftig geschriebenen Programm nicht geben. Werte betreten Funktionen als Argumente und verlassen sie als Rückgabewerte. Alles andere ist Mist.

Ach ja: Python hat einen eingebauten bool Datentyp mit den Konstanten True und False. Statt while 1: solltest du while True: verwenden. Python ist nicht C.
In specifications, Murphy's Law supersedes Ohm's.
Antworten