8N1 serielle Kommunikation einstellen

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hallo zusammen,

    ich versuche meinen Arduino mit dem Raspberry Pi zu verbinden. Das klappt momentan nur über folgenden Code:

    Code
    minicom -b 9600 -o -D /dev/ttyACM1

    Da ich aber nicht immer minicom starten möchte um eine serielle Kommunikation zu starten, suche ich nach einem Befehl für das Terminal um die Kommunikation auf 8N1 9600 Baud zu stellen.
    Ich habe es nun schon mit zig Varianten folgenden Codes probiert


    leider ohne Erfolg. Die Daten kommen nicht korrekt beim Arduino an.
    Erst wenn ich wieder

    Code
    minicom -b 9600 -o -D /dev/ttyACM1


    eingebe, werden die Daten durch

    Code
    echo '50T' >/dev/ttyACM1


    korrekt übertragen.

    Ich würde mich freuen wenn mich jemand auf meinen Fehler hinweisen würde.

  • Die Option raw bei stty wirkt meist gut, denn sie schaltet alle
    moeglichen Sonderbehandlungen ab.

    Zumindest in C-Programmen ist clocal zu empfehlen, sonst wartet
    der Driver auf die Modemsignale.

    Und es gibt die Option -g, mit der man die Einstellungen ausgeben
    kann ! Zuerst mit minicom richtig stellen und dann mal checken,
    welche Optionen gewaehlt sind.

    Einmal editiert, zuletzt von Tell (12. Februar 2015 um 17:23)

  • Vielen Dank Tell für den Tipp, leider funktioniert es immer noch nicht.

    Code
    pi@raspberrypi ~ $ stty -F /dev/ttyACM0 -g
    1:0:80000cbd:0:0:0:0:0:0:5:1:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

    Ich bekomme folgende Ausgaben für stty -F /dev/ttyACM0 9600 -parenb -parodd cs8 -cstopb:

    Code
    pi@raspberrypi ~ $ stty -F /dev/ttyACM0 -a
    speed 9600 baud; rows 0; columns 0; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
    lnext = ^V; flush = ^O; min = 1; time = 0;
    -parenb -parodd cs8 hupcl -cstopb cread clocal crtscts
    -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
    opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

    Gebe ich minicom -b 9600 -o -D /dev/ttyACM0 erhalte ich:

    Code
    pi@raspberrypi ~ $ minicom -b 9600 -o -D /dev/ttyACM0
    pi@raspberrypi ~ $ stty -F /dev/ttyACM0 -a
    speed 9600 baud; rows 0; columns 0; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
    lnext = ^V; flush = ^O; min = 1; time = 5;
    -parenb -parodd cs8 hupcl -cstopb cread clocal crtscts
    ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
    -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke

    Die Einstellung unterscheidet sich nur in folgenden Punkten
    time = 5, ignbrk, -icrnl, -ixon, -opost, -onlcr, -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke

    Ich habe daraufhin ohne Erfolg folgendes ausprobiert:

    Code
    pi@raspberrypi ~ $ stty -F /dev/ttyACM0 9600 time 5 -parenb -parodd cs8 hupcl -cstopb cread clocal crtscts ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8 -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke

    Im übrigen funktioniert die serielle Verbindung anscheinend nur wenn minicom UNTERBROCHEN wird (es läuft also scheinbar im Hintergrund weiter)
    Wenn ich Minicom Beende [Strg+A Z X/Q] dann speichert sich die Einstellung nicht und es entsteht keine korrekte serielle Verbindung.

    :helpnew: :helpnew: :helpnew:

  • Hi,
    ziemlich viele Nullen drin bei Dir :s
    probier's mal mit:

    Code
    1:0:80000cbd:0:3:1c:7f:15:4:5:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0


    das hab' ich jetzt mal bei mir ausgelesen, also mit

    Code
    stty -F /dev/ttyACM0 1:0:80000cbd:0:3:1c:7f:15:4:5:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

    Ansonsten gäb's da noch das Paket setserial:

    Code
    sudo apt-get install setserial

    cu,
    -ds-

  • Ich kenne jetzt das Problem :^^: aber noch nicht den Grund dafür :s

    Die Einstellungen die ich vorgenommen habe über stty waren korrekt.
    Das Problem ist, dass die Ausgaben vom Arduino irgendwohin geschrieben werden müssen. Das nimmt mir minicom ab wenn ich es aufrufe.

    Eine andere Möglichkeit die ich gefunden habe funktioniert folgendermaßen:

    Code
    pi@raspberrypi ~ $ cat < /dev/ttyACM0 > antwort.dat &                            
    pi@raspberrypi ~ $ echo '50T' >/dev/ttyACM0

    Ich Antwort des Arduino wird in die antwort.dat geschrieben und meine LED blinkt. (Vergleich Programmcode Arduino: serielle Warteschlange zwischen Arduino und Raspberry löschen)

    Ich verstehe aber nicht aus welchen Grund ich die Ausgabe des Arduino speichern muss :denker:

    Hat jemand einen Lösungsansatz parat, wie ich auf den zusätzlichen Prozess (cat < /dev/ttyACM0 > antwort.dat & ) verzichten kann?

  • Vielen Dank dreamshader für deine Unterstützung. :danke_ATDE:
    setserial werde ich mir mal anschauen.

    Code
    pi@raspberrypi ~ $ stty -F /dev/ttyACM0 1:0:80000cbd:0:3:1c:7f:15:4:5:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
    stty: ungültiges Argument „1:0:80000cbd:0:3:1c:7f:15:4:5:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0“
    „stty --help“ gibt weitere Informationen.


    hat leider nicht funktioniert.

    Ich bin aber schon froh, dass ich jetzt weiß wie ich meine Kommunikation funktionstüchtig bekomme bzw. mein Programm auf dem Arduino woran in meine funktionierende Verbindung festgemacht habe.

    Ich frage mich aber noch weshalb die Antwort gespeichert werden muss damit alles funktioniert wie es soll...

  • Hi,
    sonderbar ... hatte ich extra noch bei mir ausprobiert:

    na gut ... sei's drum ...
    Die Antwort muss ja nicht gespeichert sondern lediglich abgeholt werden.
    Mal ne blöde Frage ... wenn Du keinen Response vom Arduino brauchst ... warum schickst Du denn überhaupt einen?

    cu,
    -ds-

  • Vielen Dank Tell für deine Antwort. Ich glaube diese Idee kann ich auch später mal nutzen.

    Code
    Die Litze am Empfangspin durchschneiden (resp. gar nicht anloeten/verbinden)


    Ich wusste aber nicht dass man die Antwort immer abholen muss :blush:.
    Würde das bedeuten, dass wenn der Arduino noch Daten sendet, ich über den Raspberry keine neue Kommunikation starten kann bis die komplette Antwort ausgelesen wurde? Oder gibt es einen Befehl wie ich die aktuelle serielle Kommunikation abbrechen kann?

    dreamshader

    Code
    Mal ne blöde Frage ... wenn Du keinen Response vom Arduino brauchst ... warum schickst Du denn überhaupt einen?

    Ich habe die Antwort eingebaut um zu testen, ob das Arduino-Programm und die Kommunikation in beide Richtungen funktioniert.

    Zukünftig würde ich auch gerne eine Antwort vom Arduino überprüfen und je nach Wert eine entsprechende Behandlung auf dem Raspberry durchführen.

    Vielen Dank euch beiden für eure Antworten


  • ...
    Würde das bedeuten, dass wenn der Arduino noch Daten sendet, ich über den Raspberry keine neue Kommunikation starten kann bis die komplette Antwort ausgelesen wurde? Oder gibt es einen Befehl wie ich die aktuelle serielle Kommunikation abbrechen kann?
    ...

    das kommt auf Deinen Arduino-sketch an und hat nicht nur was mit dem Raspi zu tun.
    Wenn der Arduino erst wieder was empfängt, wenn er seine Daten komplett abgeschickt hat kannst Du da nicht so ohne Weiteres dazwischenfunken.
    Da musst Du Dir halt ein eigenes Protokoll definieren ... so mit timeout usw.
    Ist aber auch kein Hexenwerk :angel:

    Du hast da eh einen, für mich eher exotisch wirkenden, Lösungsansatz gewählt. Das meine ich jetzt absolut nicht wertend. Im Gegenteil: ich finde es spannend, auf was für Ideen manche Leute so kommen.

    cu,
    -ds-


  • Da musst Du Dir halt ein eigenes Protokoll definieren ... so mit timeout usw.
    Ist aber auch kein Hexenwerk :angel:


    Ich glaube das muss ich wirklich machen. Ich versuche nämlich zurzeit meinen Arduino über den lokalen Server auf dem Raspberry über php die Kommunikationsbefehle zu senden und da kommt es wieder zu einigen Fehlern und Abstürzen die hervorgerufen werden wenn der Arduino antwortet oder noch Befehle in seiner loop ausführt und gleichzeitig neue Anfragen über die serielle Verbindung eintreffen. :X
    Hast du dazu ggf. ein paar Links die ich nutzen könnte?


    Du hast da eh einen, für mich eher exotisch wirkenden, Lösungsansatz gewählt. Das meine ich jetzt absolut nicht wertend. Im Gegenteil: ich finde es spannend, auf was für Ideen manche Leute so kommen.


    Ich bin einfach (noch) ein totaler Noob :blush: und versuche meine Idee irgendwie zum Laufen zu bekommen
    Ich freue mich aber immer wenn mir jemand neue Lösungsansätze oder Wege aufzeigt.

    Vielen Dank nochmal für die Hilfen

  • Hallöle,


    ...
    Ich versuche nämlich zurzeit meinen Arduino über den lokalen Server auf dem Raspberry über php die Kommunikationsbefehle zu senden und da kommt es wieder zu einigen Fehlern und Abstürzen die ...
    ...


    nun, eine Link ... hm ...
    ich gehe da immer so ran, indem ich einfach den Ablauf definiere:
    Arduino sendet xy und wartet auf Antwort
    Raspi empfängt xy und sendet ok
    ...
    Raspi sendet "tschüssi" und wartet auf keine Antwort
    Arduino empfängt "tschüssi" und geht dann in den Ausgangs-Zustand
    ...
    Damit weisst Du, wann Du was zurückschicken musst bzw. Du auf eine Antwort warten musst - sowohl beim Raspi als auch auf der Arduino Seite.
    Wenn Du dann noch so was wie in der, mittlerweile sicher bekannten, "gettingstarted" der RF24 Lib des Arduino ( -> click <- ) einbaust, hast du auch eine Timeout-Variante. da kannst Du dann entscheiden die Daten noch mal zu schicken, die Verbindung als unterbrochen zu betrachten oder was auch immer.
    ... ich hoffe, das war das, was Du eigentlich wissen wolltest (das Stichwort dazu wäre "Handshake").


    ...
    Ich freue mich aber immer wenn mir jemand neue Lösungsansätze oder Wege aufzeigt.
    ...


    Naja ... ich hätte das z.B. über einen Prozess im Hintergrund realisiert, der eine sog. "named pipe" verwendet, die Daten daraus liest und an die rs232 weitergibt. Ein zweiter thread würde die Daten der rs232 lesen und auswerten. Schreiben würde ich das wiederum in C ... ( logisch :) ). Schlangen-Kot ginge aber auch ... da wäre ich aber, was das koten angeht, raus :) ... den Scheiss können andere besser ( :lol: Super Wortspiel ... dbv: ich will ein gefällt mir! )

    Das können wir gerne mal en detail durchgehen ... im Augenblick würde das aber imho den Rahmen sprengen. Und Dein Lösungsansatz funktioniert ja so weit, oder?



    ...
    Vielen Dank nochmal für die Hilfen

    gerne (ich denke, da spreche ich für alle) ... dafür sind wir hier ;)

    cu,
    -ds-

  • Genau die Infos die ich gebraucht habe :thumbs1:


    Naja ... ich hätte das z.B. über einen Prozess im Hintergrund realisiert, der eine sog. "named pipe" verwendet, die Daten daraus liest und an die rs232 weitergibt. Ein zweiter thread würde die Daten der rs232 lesen und auswerten. Schreiben würde ich das wiederum in C ... ( logisch :) ). Schlangen-Kot ginge aber auch ... da wäre ich aber, was das koten angeht, raus :) ... den Scheiss können andere besser ( :lol: Super Wortspiel ... dbv: ich will ein gefällt mir! )


    :D gibt aufjedenfall ein Gefällt von mir


    Das können wir gerne mal en detail durchgehen ... im Augenblick würde das aber imho den Rahmen sprengen. Und Dein Lösungsansatz funktioniert ja so weit, oder?

    Es läuft da bin ich auch echt froh drüber aber wenn ich meine PHP-Datei im Webbrowser öffne dann gibt er mir folgenden Fehler aus: No stty availible, unable to run. (Habe dazu einen alten Beitrag ausgegraben: https://www.forum-raspberrypi.de/Thread-php-php-serial)



    gerne (ich denke, da spreche ich für alle) ... dafür sind wir hier Icon_wink


    Bin echt froh mich hier im Forum angemeldent zu haben :thumbs1:

    • Offizieller Beitrag
    Zitat von dreamschader

    . Schlangen-Kot ginge aber auch ... da wäre ich aber, was das koten angeht, raus Icon_smile ... den Scheiss können andere besser (... dbv: ich will ein gefällt mir! )

    Eigentlich hättest du ein "5€ in die Schlechte Wortwitzkasse" Smilie verdient, da wir das aber nicht haben...kriegst du dein Like :)

  • Hm, muss es denn unbedingt bash sein?

    Ich hab solch eine Kommunikation für mein Roboter Projekt realisiert, allerdings in dem von dreamshader verspotteten Python-kot :D
    Das läuft sehr gut und auch schnell. Aber ich nutze halt auch Threads damit ich nicht son kuddelmuddel veranstalten muss um parallele Abläufe/Verarbeitungen umzusetzen.


    Muss gestehen das ich nicht alles in diesem Thread gelesen habe - aber steht hier irgendwo was das Ziel sein soll und welcher Sketch auf dem Arduino läuft :huh: :s

  • Ach wieso?
    Der TE hat da zwar eine ziemlich unkonventionelle Lösung gewählt ... aber die ist auf seinem Mist gewachsen und die hat er auch konsequent zu Ende gedacht und duchgezogen. Ich finde, so etwas sollte man schon unterstützen denn daraus entstehen imho Innovationen.
    Wenn er irgendwann feststellt, dass ihm seine Lösung nicht (mehr) ausreicht, dann kann/wird er umschwenken.
    Also, wie gesagt, ich find' so was klasse :thumbs1:

    cu,
    -ds-

  • Wollen wir den Thread doch endlich mal beenden :D

    Die Klasse php_serial funktioniert für meinen Fall nicht. Hat mich einige Tage und Nerven gekostet aber irgendwann habe ich eingesehen, dass es auch andere Lösungen gibt.

    Ich habe mir daher wieder eine schön unkonventionelle Lösung ausgedacht :cool:

    Zunächst wie am Anfang des Threads beschrieben minicom geöffnet und die korrekte Einstellung durch stty -g notieren
    Diese Einstellung schreibe ich in ein Bash-Skript
    Und lasse meine Ausgabe vom Arduino in irgendeine Datei auslagern (z.B. ArduinoLog.sh)

    [PHP]
    #!/bin/sh
    stty -F /dev/ttyACM0 9600 time 5 -parenb -parodd cs8 hupcl -cstopb cread clocal crtscts ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8 -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke

    cat /dev/ttyACM0 > /var/log/ArduinoSeriell.txt&

    [/PHP]

    Dieses Bash-Skript lasse ich bei jedem start automatisch ausführen
    sudo bash ./ArduinoLog.sh.sh

    Wenn ich jetzt eine Kommunikation zum Arduino aufbauen möchte, dann lösche ich zunächst die ArduinoSeriell.txt und sende daraufhin meine Anfrage [PHP] echo '50T' >/dev/ttyACM0 [/PHP] an den Arduino.
    Darauf folgt ein kurzer Sleep...

    Die Antwort kann ich dann aus meiner ArduinoSeriell.txt auslesen und mit der gesendeten vergleichen.

    Ist vermutlich nicht die optimalste Methode aber sie funktioniert ;)


    Vielen Dank nochmal an dreamshader, dbv und meigrafd für die Hilfen :danke_ATDE:.
    :thumbs1:

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!