ubuntuusers.de

serielle Verbindung zu einem Arduino via pyserial

Status: Gelöst | Ubuntu-Version: Ubuntu 11.10 (Oneiric Ocelot)
Antworten |

thomasic

Avatar von thomasic

Anmeldungsdatum:
24. März 2009

Beiträge: 92

Wohnort: Bonn

Hallo Community,

Ich arbeite an einem Projekt, bei dem ich auf meinem Rechner ein python-server-skript laufen lasse, das auf den Output eines Arduino-Duemilanove-Board reagiert. Das Programm auf dem Arduino und das Python-Skript laufen beide einwandfrei. Allerdings habe ich ein wirklich kritisches (und verdammt seltsames) Problem mit der seriellen Schnittstelle: Zunächst waren die Ergebnisse unzuverlässig. Heißt, mal hatte ich akkuraten Datentransfer, dann wieder einen arg verstümmelten. Derzeit kommen überhaupt keine Daten mehr beim Python-Skript an, obwohl es sich mit dem seriellen Schnittstelle verbindet. Wenn ich allerdings (und das ist das eigentlich seltsame) zunächst die Arduino-IDE (open-source-prog für die Arbeit mit einem Arduino) starte, funktioniert die Verbindung einwandfrei. Und zwar mittels der IDE selbst, aber auch -nachdem ich die IDE wieder geschlossen habe- mit meinem Skript. Bitte schaut euch folgenden Post an, den ich bereits im Arduino-Forum gepostet habe, und der die Problematik detailiert beschreibt: http://arduino.cc/forum/index.php/topic,91291.0.html

Es gibt also irgendetwas, was das Arduino-IDE mit der Verbindung macht, was mein Skript nicht kann, wovon es aber schließlich profitiert, selbst wenn die Arduino-IDE nicht mehr läuft.

Die Verbindung funktioniert mittels eines Konverters von Seriell auf USB. Folgende Treiber sind hierfür zuständig: usbserial, ftdi_sio. Beim booten (oder einstecken des Boards) wird das Board als serieller USB-Port erkannt und das device /dev/ttyUSB0 erzeugt. Ebenso wie es sein soll. Ich habe keine Ahnung, wo das Problem liegt; ob man vielleicht beim Aufbau einer Verbindung mit einer seriellen Schnittstelle besondere Dinge zu beachten hat. Bei allem was ich im Netz gefunden habe, wird die Verbindung stets mit den allereinfachsten Schritten via pyserial hergestellt. Kein Hinweis auf die Notwendigkeit spezieller Konfigurationen. Nun weiß ich wirklich nicht weiter. Es wäre einfach großartig, wenn mir hier jemand helfen könnte. Was immer ihr an Code oder Log-Einträgen braucht, werde ich euch gerne hier posten. Die Programme selbst sind in verkürzter Fassung schon im oben verlinkten Post zu sehen. (Allerdings laufen die Programme selbst im Grunde wunderbar, wenn nur der Datentransfer funktioniert. Beispielsweise habe ich das gleiche Problem, wenn ich die Verbindung in einer Python-Console herstelle (via pyserial oder einfach als Datei geöffnet). Ein weiteres Python-Skript http://lemonodor.com/archives/2008/02/arduino_serial.html, das nicht auf pyserial aufzusetzen scheint, bringt ebenfalls keine Abhilfe...)

Also besten Dank für jedwede Hilfe!!!

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Hi,

das was du schreibst, klingt so, als wenn

die Übertragungsrate nicht stimmt

und/oder

die Parity / Wortbreite nicht stimmt

Es gibt aber auch Fälle, da ist der USB-Serial-Adapter dran Schuld, weil ... die "billigen" Adapter nicht den korrekten Signalpegel für serielle Interfaces RS232C liefern, sondern einfach nur in etwa die USB-Versorgungsspannung als Output haben.

thomasic

(Themenstarter)
Avatar von thomasic

Anmeldungsdatum:
24. März 2009

Beiträge: 92

Wohnort: Bonn

Hi theinlein

theinlein schrieb:

das was du schreibst, klingt so, als wenn

die Übertragungsrate nicht stimmt

Ich nutze 9600 baud und mit dieser Baud-Zahl funktioniert die Verbindung mit dem Arduino-IDE wunderbar.

und/oder

die Parity / Wortbreite nicht stimmt

Die default-Einstellungen bei pyserial sind: bytesize = EIGHTBITS, parity = PARITY_NONE, stopbits = STOPBITS_ONE

Falls es eine andere Konfiguration braucht, wie bekomme ich dann heraus welche?

Es gibt aber auch Fälle, da ist der USB-Serial-Adapter dran Schuld, weil ... die "billigen" Adapter nicht den korrekten Signalpegel für serielle Interfaces RS232C liefern, sondern einfach nur in etwa die USB-Versorgungsspannung als Output haben.

Das glaube ich eher nicht, da die Kommunikation sonst mit dem Arduino-IDE wohl auch nicht funktionieren würde...

Vielen Dank für die Antwort. Falls du mir einen Rat geben kannst, wie ich die richtigen Einstellungen herausfinden kann, würde ich mich freuen.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

thomasic schrieb:

Ich nutze 9600 baud und mit dieser Baud-Zahl funktioniert die Verbindung mit dem Arduino-IDE wunderbar.
...
Die default-Einstellungen bei pyserial sind: bytesize = EIGHTBITS, parity = PARITY_NONE, stopbits = STOPBITS_ONE

Das heißt aber auch, dass die theoretisch mögliche Datenrate maximal 960 Byte/s ist !

Falls es eine andere Konfiguration braucht, wie bekomme ich dann heraus welche?

Seriellen Schnittstellen führen keine Meta-Informationen. Das heißt, so etwas kannst Du entweder der Gerätedoku entnehmen, oder eventuell einfach ausprobieren was geht. (manche Geräte probieren nämlich nach dem einschalten automatisch verschiedene Datenraten durch)

LG,

track

thomasic

(Themenstarter)
Avatar von thomasic

Anmeldungsdatum:
24. März 2009

Beiträge: 92

Wohnort: Bonn

Danke für die Antwort, track.

track schrieb:

Das heißt aber auch, dass die theoretisch mögliche Datenrate maximal 960 Byte/s ist !

Ich weiß, das ist erstmal kein Problem. Solange es zuverlässig funktioniert ist alles gut.

Seriellen Schnittstellen führen keine Meta-Informationen. Das heißt, so etwas kannst Du entweder der Gerätedoku entnehmen, oder eventuell einfach ausprobieren was geht. (manche Geräte probieren nämlich nach dem einschalten automatisch verschiedene Datenraten durch)

Ok. Ich habe das mal als Anregung genommen in der Python-Console ein bisschen mit möglichen Einstellungen herum zu spielen. Und siehe da, ich habe ein -wenn auch recht seltsames- Ergebnis:

Wenn ich nämlich statt der default-Einstellung (PARITY_NONE) PARITY_ODD einsetze, so bekomme ich einen Datentransfer hin. Allerdings kann der String nicht mehr in seine original-Buchstaben umgesetzt werden. Ich habe ein Ergebnis, das nicht wieder richtig dekodiert wird. Schließe ich aber dann die Verbindung und setze wieder PARITY_NONE ein, funktioniert alles wunderbar.

Damit es funktioniert scheint also ein vorheriger Zugriff mit einer im Grunde falschen parity-Einstellung nötig zu sein. Ziemlich seltsam... 😕

Jedenfalls habe ich meinen Code dementsprechend angepasst:

1
2
3
4
5
self.port.parity = serial.PARITY_ODD
self.port.open()
self.port.close()
self.port.parity = serial.PARITY_NONE
self.port.open()

und, ob man's glaubt oder nicht, seit dem funktioniert er tadellos... Das fühlt sich jetzt zwar ein bisschen nach dreckigem Hack an, trotzdem bin ich erstmal froh, dass es funktioniert.

Wenn jemand eine Idee hat, was es damit auf sich haben könnte, dann lasst mich doch bitte daran teilhaben...

Beste Grüße und einen guten Start in die Woche...

thomasic

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Hi,

funktioniert es nicht, wenn du ALLE Einstellungen explizit setzt, du dich also nicht auf die Default-Werte verlässt?

self.port.bytesize = EIGHTBITS
self.port.stopbits = STOPBITS_ONE
self.port.parity = serial.PARITY_NONE
self.port.open()
...
 

... oder ggf. NUR ein open+close vorweg? Sprich: der Adapter muss erst "aufgeweckt" werden ?

thomasic

(Themenstarter)
Avatar von thomasic

Anmeldungsdatum:
24. März 2009

Beiträge: 92

Wohnort: Bonn

hab ich beides ausprobiert... reicht nicht

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

... ein paar neue "Verschwörungstheorien" ... ☺

a) der Treiber hat einen kleinen Fehler

b) der Adapter hat einen kleinen Fehler

c) der Adapter ignoriert die Baudrate-Settings und findet von selbst sie selbst raus. Das macht er erst nach einem 'open' und benötigt etwas Zeit. Das open/close gewinnt hier die Zeit.

thomasic

(Themenstarter)
Avatar von thomasic

Anmeldungsdatum:
24. März 2009

Beiträge: 92

Wohnort: Bonn

theinlein schrieb:

a) der Treiber hat einen kleinen Fehler

mhh. Ist der Distributions-eigene Treiber, ftdi_sio. Vielleicht ist dieser Treiber (in dieser speziellen Version) nicht 100% kompatibel mit der speziellen Version des Arduino-Boards, das ich einsetze. Ich wundere mich nur, dass ich im Netz bisher keinerlei Hinweise auf meine Problematik gefunden habe...

b) der Adapter hat einen kleinen Fehler

Könnte ich mir auch vorstellen. Ich werde in absehbarer Zeit das ganze "System" mit einem anderen Arduino-Board testen können. Bin mal gespannt, ob es die gleichen Symptome zeigen wird...

c) der Adapter ignoriert die Baudrate-Settings und findet von selbst sie selbst raus. Das macht er erst nach einem 'open' und benötigt etwas Zeit. Das open/close gewinnt hier die Zeit.

Kann eigentlich nicht sein. Schließlich brauchte es das explizite setzen einer falschen parity-Option. Nur open-close hatte nicht gereicht, um die Verbindung zu "heilen" (s.o.)

Danke jedenfalls für die Mithilfe...

uLukai

Anmeldungsdatum:
24. Juni 2012

Beiträge: Zähle...

Ich hab das selbe Problem mit identischen Symptopmen mit:

Arch Linux auf einem Raspberry Py (ARM) mit einem JeeLink am USB port.

Schon was neues rausgefunden?

thomasic

(Themenstarter)
Avatar von thomasic

Anmeldungsdatum:
24. März 2009

Beiträge: 92

Wohnort: Bonn

Hi uLukai, ist schon was her, dass ich mich damit beschäfitgt habe. Mittlerweile arbeite ich mit einem Arduino-Uno, und habe keine Probleme damit. Damals war es ein Duemillenove, und wie ich es schließlich zum laufen gebracht habe, kannst du hier: http://arduino.cc/forum/index.php/topic,91291.0.html nachlesen. viel Erfolg...

Antworten |