Serial Port Programmierung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
bd3m
User
Beiträge: 3
Registriert: Samstag 22. März 2014, 15:43

Hey,

ich bin dabei ein kleines Programm zu schreiben, dass
-einen Seriellen Port öffnet
-eine Textdatei an einen Seriellen Prt schicken kann
-Daten die vom Seriellen Port kommen in eine log-Datei speichern.

Was ich bisher habe:

Code: Alles auswählen

 import serial
    ser = serial.Serial("/dev/ttyACM0", 921600)
    text_file = open("log.txt", 'w')
    send_file=open("10_mb_file.txt",'r')
    while true:
         x=ser.read(1024)
         print(x)    
         text_file.write(x)
         text_file.flush()
    text_file.close()
    ser.close()
Problem:
Ich weiß nicht, wie ich das Textfile an meinen Seriellen Port schicken kann...

Code: Alles auswählen

ser.write(send_file)
geht nicht..

Könnte mir bitte jemand helfen?
(Das Gerät am Seriellem Port ist so programmiert, dass es 1024 Bytes empfängt und anschließend gleich wieder zurück sendet (Ping Server).)
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Tut mir leid, meine Glaskugel geht grad nicht. Hab deshalb auch im Internet nach "geht nicht" gesucht, geht aber auch nicht. Kann mir wer weiterhelfen?

Setz mal ein Timeout und schau ob es geht.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
bd3m
User
Beiträge: 3
Registriert: Samstag 22. März 2014, 15:43

Für meine späteren Verwendungszwecke brauche ich kein timeout.
Aber selbst mit geht es nicht.
BlackJack

@bd3m: Was Du bisher hast ist Quelltext der nicht einmal kompiliert wird weil er falsch eingerückt ist. Wenn man das behebt läuft er immer noch nicht, weil `true` nirgends definiert ist. Das ist also nicht der Code den Du tatsächlich ausprobiert hast.

Ansonsten sagt man zwar umgangssprachlich man schickt eine Datei irgend wo hin, aber was man tatsächlich macht, ist den *Inhalt* der Datei zu versenden. Also die Datei auslesen, in diesem Fall wohl am besten in der Blockgrösse die von der anderen Seite erwartet wird, und diese Daten dann mit dem `ser`-Objekt schreiben. Und zwar bevor Du das Echo liest, denn im gezeigten Quelltext ist ja das erste das Du auf ein Echo wartest, für Daten die nirgends gesendet wurden. Das bleibt da (ohne Timeout) natürlich beim `read()`-Aufruf hängen.

Die zu sendende Datei sollte ausserdem im Binärmodus geöffnet werden, denn Du sendest da ja Bytes über die serielle Leitung und keinen Text.

Edit: Nochmal: „geht nicht” ist keine ausreichende oder hilfreiche Fehlerbeschreibung. Zeige den *tatsächlichen* relevanten Quelltext und den Fehler inklusive Traceback. Sollte keine Ausnahme kommen, beschreibe was Du erwartest und warum, und was Du stattdessen bekommst. Sonst kann man nur raten wo das Problem liegt.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Funktioniert denn überhaupt die Gegenseite?
Muss irgendein spez. Protokoll gefahren werden, damit das Teil mit der Übertragung beginnt?

Und herjemine, streich "das geht nicht" aus dem Wortschatz und sag wie sich das äußert, was auf dem Bildschirm steht, ob Logs was aussagen.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
bd3m
User
Beiträge: 3
Registriert: Samstag 22. März 2014, 15:43

Also die Gegenseit funktioniert. Ich habe doch oben schon geschrieben, dass mein Gerät als Ping-Server programmiert ist.
Es nimmt bis zu 1024 bytes aufeinmal auf und sendet sie wieder zurück.

Ich habe auch schon eine 10.5mb große Textdatei gesendet via gtkterm und es funktioniert.
Die Log-Datei ist identisch mit der Orginaldatei.

Mein eigentliches Problem ist, dass gtkterm keine Zeit stoppt und gtkterm auch nicht unter der Konsole
aufrufbar ist und man die Zeit mit time messen kann...
Ich habe schon zig SerialTerminal Programme ausprobiert unter Windows/Linux.
Manche hängen sich auf, manche haben eben diese gewünschte Zeitfunktion sind aber dreimal so langsam wie
gtkterm... Ich habe auschon in eltichen Foren nach gefragt, ob es nicht einfach Programm gibt, dass ein File an einen
COmPort sendet mit Zeitstempeln. Nie kam eine Antwort zurück.

Da ich eigentlich nur Java und C kann, aber nicht ewig viel Zeit aufweden wollte, weil es ja eigentlich schon Programme dafür gibt,
habe ich mich ein wenig im Internet rumgestöbert und Python sah nicht schwer aus.
Nur das Problem hier, die meisten lesen von ihrer Schnittstelle nur Daten aus.
ich möchte aber eine Datei senden.

Mir war schon klar dass ich von der Text-Datei ein paar bytes lesen muss diese zum ComPort schicken muss,
nur wie ist die Frage.
Gibts ein Tutorial, ohne dass man sich ganz python aneignen muss nur damit ich ein Textfile an einen ComPort senden kann?
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Irgendwie antwortest du nicht auf die Fragen. Kommt ein Timeout bei gesetzten Timeout Zeit, stimmen die Verbindungseinstellungen nicht. Mal vorrausgesetzt die Gegenseite kommuniziert korrekt, kannst du an den Verbindungseinstellungen herumspielen.
Achja, das Programm sollte natürlich auch die Rechte haben über den seriellen Port zu kommunizieren.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@bd3m: Du hattest zwar geschrieben das die Gegenseite als Echo-Server konfiguriert ist, aber nicht dass Du überprüft hast, dass die auch tut was sie soll.

Also ich weiss nicht wie man ohne die Sprachgrundlagen zu kennen irgendwas vernünftiges programmieren können soll. Also so etwas wie das Tutorial in der Python-Dokumentation sollte man schon mal durcharbeiten. Da OOP hier nicht gebraucht wird, kann man da sicher nur drüberfliegen.

Und wenn Du C kannst, dann solltest Du mit `file`-Objekten eigentlich auch keine Probleme haben. Da würdest Du doch auch nicht versuchen den Dateideskriptor mit `write()` in eine andere Datei zu schreiben, sondern den Inhalt der ersten Datei lesen und in die zweite schreiben. Das die entsprechenden Methoden auf Datei- und ”dateiähnlichen” Objekten `read()` und `write()` heissen weisst Du doch auch schon. Dann gibt es auch die Referenzdokumentation von Python wo die Typen und Methoden beschrieben sind.

Letztlich sehe ich bei Dieser Aufgabe zu C auch gar nicht so viele Unterschiede. Python hat eine (IMHO) schönere Syntax und `read()` bei Dateien gibt nur weniger als die angeforderte Byteanzahl zurück wenn man am Dateiende ist, man hat keinen expliziten Compileraufruf, und aussagekräftige(re) Tracebacks wenn das Programm auf die Nase fällt, aber ansonsten hat man vom fachlichen hier genau die selben Probleme zu lösen wie in einem C-Programm auch.

Zum Beispiel: Sind die Verbindungsparameter die per Default verwendet werden überhaupt das was die Gegenseite erwartet? Was genau erwartet die Gegenseite an Daten und was liefert sie zurück? Also Echo-Server ist ja grundsätzlich schon mal klar, aber kommt das Echo nur wenn die Gegenseite 1024 Bytes empfangen hat? Oder kann es sein dass sie auch schon mal früher was zurück schickt? Und wenn sie etwas zurück schickt, sind das dann genau 1024 Bytes? Oder hat die vielleicht zu senden auch einen Puffer und ”flusht” den nicht garantiert immer gleich? Muss man erst die Antwort komplett auslesen bevor die Gegenseite weitere Daten verarbeiten kann oder nicht? Was ich hier also eigentlich wohl frage ist, wie sieht das Protokoll aus und ist das Halbduplex oder Vollduplex?

Falls letzteres, beziehungsweise so ganz generell wäre es sicherer wenn man gleichzeitig sendet und empfängt, also Threads (`threading`-Modul) verwendet oder das `select`-Modul. Also auch hier wieder, genau das selbe Problem in C.
Antworten