arduino Serielle Kommunikation über rx/tx

Hallo,

ich versuche eine serielle Kommunikation mit einem Pi herzustellen. Dazu habe ich den Arduino Uno mit den Uart-Pins (RX/TX) über einen Pegelwandler (5V vs. 3,3V) mit dem Pi verbunden (jeweils TX->RX).

prinzipiell funktioniert es schon, aber wenn ich am pi etwas Richtung Arduino sende kommt der irgendwie komplett aus dem Tritt.

habe mein Programm mal rangehängt

  • arduino soll alles,was er bekommt wieder zurück schicken als Bestätigung
  • arduino soll bei bestimmten Aktionen natürlich was machen (hier LEDON/LEDOFF)

am Pi mache ich das Auslesen so:

#!/bin/bash
while read line; do
    echo "["$(date "+%Y-%m-%d %H:%M:%S")"] vom Arduino: "$line
done < <(cat /dev/ttyAMA0)

das Senden einfach mit echo "">/dev/ttyAMA0

in dem Moment, wo etwas über die Serielle Schnittstelle geht (entweder das Keepalive vom Arduino) oder ich sende etwas vom Pi aus, kommt sowas (unendlich lang):

[2017-12-21 11:25:14] vom Arduino: �KEEPALIVE
[2017-12-21 11:25:14] vom Arduino: 
[2017-12-21 11:25:14] vom Arduino: RX:RX:RX:RX:RX:RX:RX:R:RX:RX:RX:R
[2017-12-21 11:25:14] vom Arduino: 
[2017-12-21 11:25:14] vom Arduino: RX:RX:RX:RX:RX:RX:RX:RX:R^@:RX:RX:RX:R
[2017-12-21 11:25:14] vom Arduino: 
[2017-12-21 11:25:14] vom Arduino: RX:RX:RX:RX:RX:RX:RX:RX:RX:R^@:RX:RX:RX:R
[2017-12-21 11:25:14] vom Arduino: 
[2017-12-21 11:25:14] vom Arduino: RX:RX:RX:RX:RX:RX:RX:RX:RX:RX:R^@:RX:RX:RX:R
[2017-12-21 11:25:14] vom Arduino: 
.....

habe schon extra ein flush und die String-Längen-Prüfung rein, aber trotzdem kommt dieses gefloode

evtl. sieht jemand, wo der Fehler in meinem Code ist...

kurze Erklärung, was der Arduino-code machen soll:

  • er soll in bestimmten Zeitabständen ein "keepalive" zum Pi schicken (sich halt melden, dass er noch da ist)
  • und wenn etwas rein-kommt soll er bis zum Zeilenumbruchzeichen (\r bzw. \n) den "Befehl" zusammenbauen und dann in handle_command verarbeiten (in dem Beispiel bei LEDON/LEDOFF die LED ein/ausschalten), diese Befehle soll er als Quittierung an den Pi zurücksenden

edit: sketch im Anhang nochmal in code-tags:

//disable serial console with raspi-config
//level-shifter between rpi (3.3V) and arduino (5V)!

#include <SoftwareSerial.h>

#define ALIVE_INTERVAL 60000 //timer-interval (milliseconds)

String s="";
unsigned long alivetimer=0;

void setup() {
   Serial.begin(9600);
   while(!Serial);
   Serial.println("Setup complete");
}

void keepalive()
{
  //sending keepalive
  if (alivetimer==0) alivetimer=millis();
  if (millis()-alivetimer >= ALIVE_INTERVAL)
  {//so check every minute
    Serial.println("KEEPALIVE");
    alivetimer=millis();
  }
}

void handle_command(String cmd)
{
  Serial.print("RX:");
  Serial.println(cmd);
  Serial.flush();
  if (cmd == "LEDON"){      // turn LED on
    digitalWrite(13,HIGH);
  }else
  if (cmd == "LEDOFF"){      // turn LED on
    digitalWrite(13,LOW);
  }else
  if (cmd == "KEEPALIVE"){      // turn LED on and off
    digitalWrite(13,HIGH);
    delay(2000);
    digitalWrite(13,LOW);
  }
}

void loop() {
  keepalive();
  char incoming;
  //serial data from PI
  if (Serial.available() > 0) {
    while(Serial.available() > 0)
    {
      incoming = Serial.read();
      if ((incoming != '\n') && (incoming != '\r'))
        s+=incoming;
      else //command complete on linebreak
      {
        if (s.length())
        {
          handle_command(s);
          s="";
        }
      }
    }
  }
}

Danke

Frank

uarttest.ino (1.31 KB)

Um auch den mobilen Usern die die Möglichkeit zu geben, den Sketch richtig zu lesen, solltest du den wie deine anderen Codes hier im Forum posten.

Setze den bitte in Code-Tags.

Verwende dazu die Schaltfläche </> oben links im Editorfenster.
Das kannst du auch nachträglich machen.
Dazu den Sketch markieren und die Schaltfläche klicken.

Damit wird dieser für alle besser lesbar.

Was mir spontan auffällt:

#include <SoftwareSerial.h>

Da hast Du eine vermeintlich gute Idee nicht zu Ende geführt.

das ist die Vorbereitung, um einen 2.Seriellen Port nutzen zu können...oder beißt sich die SoftwareSerial mit dem Hardware-Serial-Port?

frank-w:
das ist die Vorbereitung, um einen 2.Seriellen Port nutzen zu können...oder beißt sich die SoftwareSerial mit dem Hardware-Serial-Port?

Nein, beißt sich nicht, wenn du es richtig machst.

Und nochmal....verwende Code-Tags für deinen Sketch.
Den kann so nicht jeder lesen und deine Chance für Lösung wird größer.

Standardfrage: hast Du GND verbunden?

über den Levelshifter, ja (habs nochmal via Durchgagngsprüfer sichergestellt, dass er auch verbunden ist und nicht beide Seiten "autark" laufen)

RPI Levelshifter Arduino
1 (3V3) ------- LV HV -------- 5V
6 (GND) ------- GND -------- GND
8 (TX) -------- LV2 HV2 --------RX
10 (RX) ------- LV1 HV1 ---------TX

Ich befürchte Probleme mit deiner Seriellen auf dem Uno.
Du verwendest diese gleichzeitig für den seriellen Monitor und für den Empfang von Pi.
Das beißt sich.

Beim UNO hängt Serial am USB für neue Sketche und den seriellen Monitor. Der ist dann parallel zum Pi, was nicht unbedingt gut ist. Daher dachte ich, SoftwareSerial hast Du für den Pi vorgesehen, was ich für eine gute Idee halten würde, weil Du dann den seriellen Monitor zur Fehlersuche nutzen kannst.

Wenn Du das nicht mehr benötigst, kannst Du ja zurückfallen auf Serial.

ich habe herausgefunden, dass, wenn ich den arduino am Rechner habe, funktioniert das Programm am seriellen Monitor, in dem Moment, funktioniert aber der RX-Pin nicht (wenn ich was vom Pi sende kommts nicht an)

ich habe daher den Arduino nur mit strom versorgt (Handy-Ladegerät am USB), jetzt empfängt der arduino vom pi, aber spuckt dann diesen mist aus

frank-w:
ich habe herausgefunden, dass, wenn ich den arduino am Rechner habe, funktioniert das Programm am seriellen Monitor, in dem Moment, funktioniert aber der RX-Pin nicht (wenn ich was vom Pi sende kommts nicht an)

ich habe daher den Arduino nur mit strom versorgt (Handy-Ladegerät am USB), jetzt empfängt der arduino vom pi, aber spuckt dann diesen mist aus

Das bestätigt unsere Aussage, beides zur selben Zeit, geht nicht.

Das Problem mit den Daten kann ein Protokoll oder Einstellungsfehler sein.

Edit:
Da ich den Pi nicht kenne, nur eine Vermutung.
Kann es sein, dass dieser zu schnell antwortet ?
Also direkt nach dem ersten Zeichen ?
Dann die Antwort erst speicher und nach einer kleinen Paus komplett senden.

ich mache doch nicht beides...arduino hängt am Handy-Ladegerät...der serielleMonitor der Arduino-IDE ist ja nicht mit drin

am rpi habe ich den Port ttyAMA0 auch mit stty auf 9600 baud gestellt

Hallo,

Ich habe den Skatch nicht analysiert, hier nur ein paar Gedanken.

Das senden und empfangen eines Byte/Int und String hast du auch schon mal mit festen werten getestet?
Lass dir mal die Werte die du sendest und empfängst auf beiden Seiten in HEX anzeigen. Also jedes Byte das kommt in Hex umwandeln und dann Anzeigen.
Dadurch kannst du sehen ob das was der eine sendet, Raw auch das ist was der andere empfängt.
Es ist auch wichtig das beide in sachen ASCII auch das gleiche machen. Da gibts UT8 etc und solche sachen. Die einen Char als 2 Byte darstellen . Du musst sicher stellen das beide Seiten das selbe benutzen.
Dann kann es noch Probleme geben weil die Daten zu schnell kommen. Bei 57K Serieler Verbindung sind etwa 6 Byte pro 1/1000 möglich.
Die Funktion Serial.println() sendet bei einem String "Test" 6 Byte anstelle von 4. Die müssen natürlich auch mit Serial.read() abgeholt werden und beim erstellen des Empfangenen Strings ingnoriert werden. Sonst liegen die noch im Puffer.

Bist du denn sicher das der Pi mit dem echo mit LR zurückschickt. Hänge doch mal an die nachricht ein chr(13) + chr(10) ran. So wie das der Serial.println() automatisch macht. Ich glaube nämlich das deine Variable s immer weiter zusammen gebaut wird.

Gruss Turgut

gegen das wiedereinlesen des eigenen Strings auf Arduino-seite habe ich eigentlich das flush drin...die Endlos-schleife kommt ja auch, wenn der arduino nichts sendet (beim Keepalive des Arduinos) und auch nur über die RX/TX-Pins des Arduino...in der Seriellen Konsole sieht alles hübsch aus

echo macht standard-mäßig in linux einen Zeilumbruch (\n) rein...nur "echo -n" läst diesen weg...ich habe die Vermutung, dass das Hardware-Serial des Nano nicht so ganz sauber läuft...vielleicht sollte ich auch dafür Software-Serial nehmen...

habe softwareserial mal probiert...da kommt auch ziemlich viel müll mit, aber es hört irgendwann auf

habe natürlich beides auf 9600 gesetzt, das was ich vom pi zum arduino sende kommt auch nicht zurück...

Kommt es am Arduino an?

Gruß Tommy

weis ich nicht...habe ja alles serial in myserial geändert...die LED geht schonmal nicht an...somit kommt es zumindest nicht sauber an

irgendwann hat sich die serialle schnittstelle zumindest soweit gefangen, dass nur noch mein keepalive ohne Murks drumherum ankommt

[2017-12-21 14:19:25] vom Arduino: 
[2017-12-21 14:19:25] vom Arduino: �a�+KU�:)a
[2017-12-21 14:19:25] vom Arduino: 
[2017-12-21 14:19:25] vom Arduino: RX:)i��U�:)a
[2017-12-21 14:19:25] vom Arduino: 
[2017-12-21 14:19:25] vom Arduino: RX:�a�J��:)a
[2017-12-21 14:19:25] vom Arduino: 
[2017-12-21 14:19:25] vom Arduino: RX:)a����:)a
[2017-12-21 14:19:25] vom Arduino: 
[2017-12-21 14:19:25] vom Arduino: RX:)a
[2017-12-21 14:19:25] vom Arduino: 
[2017-12-21 14:19:26] vom Arduino: RX:��R��X:)a
[2017-12-21 14:19:26] vom Arduino: 
[2017-12-21 14:20:13] vom Arduino: KEEPALIVE
[2017-12-21 14:20:13] vom Arduino: 
[2017-12-21 14:21:13] vom Arduino: KEEPALIVE
[2017-12-21 14:21:13] vom Arduino: 


[2017-12-21 14:22:13] vom Arduino: KEEPALIVE
[2017-12-21 14:22:13] vom Arduino: 
[2017-12-21 14:23:13] vom Arduino: KEEPALIVE
[2017-12-21 14:23:13] vom Arduino: 
[2017-12-21 14:24:13] vom Arduino: KEEPALIVE
[2017-12-21 14:24:13] vom Arduino: 
[2017-12-21 14:25:13] vom Arduino: KEEPALIVE
[2017-12-21 14:25:13] vom Arduino: 
[2017-12-21 14:26:13] vom Arduino: KEEPALIVE
[2017-12-21 14:26:13] vom Arduino: 
[2017-12-21 14:27:13] vom Arduino: KEEPALIVE
[2017-12-21 14:27:13] vom Arduino: 
[2017-12-21 14:28:13] vom Arduino: KEEPALIVE
[2017-12-21 14:28:13] vom Arduino: 
[2017-12-21 14:29:13] vom Arduino: KEEPALIVE
[2017-12-21 14:29:13] vom Arduino:

ich habe jetzt mal aus Spaß mal auf dem rpi minicom genutzt...da sieht das ganze recht sauber aus...offensichtlich ist die cat-variante nicht ganz so sauber...ich brauche aber etwas script-fähiges auf dem pi...

das echo funktioniert auch sauber...was ich als echo wegschicke kommt im minicom mit RX: vom arduino zurück

so sind die einetellungen im minicom (scheinbar muss ich da für cat noch etwas setzen):

9600 8N1 | NOR | Minicom 2.7 | VT102 | Offline | ttyAMA0

habs jetzt so gesetzt:

stty -F /dev/ttyAMA0 9600 cs8 -cstopb -parenb

jetzt siehts soweit gut aus...

pi@raspberrypi:~ $ stty -F /dev/ttyAMA0 9600 cs8 -cstopb -parenb
pi@raspberrypi:~ $ ./showserial.sh
von zweiter console aus: echo "test">/dev/ttyAMA0
[2017-12-21 15:06:58] vom Arduino: RX:LEDON
[2017-12-21 15:07:07] vom Arduino: RX:LEDOFF
[2017-12-21 15:07:13] vom Arduino: KEEPALIVE
[2017-12-21 15:08:12] vom Arduino: KEEPALIVE
[2017-12-21 15:08:18] vom Arduino: RX:LEDON
[2017-12-21 15:08:21] vom Arduino: RX:LEDOFF
[2017-12-21 15:09:12] vom Arduino: KEEPALIVE

Somit doch ein Einstellungsfehler. (Post #10).
Danke für die Rückmeldung.

habe nicht gesagt, dass ich das auschließe :wink:

habe das Ganze jetzt auf den BananaPi rübergezogen...dort reicht die EInstellung so offensichtlich nicht...da kommen bei dem cat weiterhin wilde zeichen...gibt es noch eine Einstellung, die ich damit nicht abgedeckt habe?

mit minicom gehts dort auch...

Hi

Was mir in Deinem Sketch nicht schmeckt, ist das delay() in keepalive() - wenn der Arduino Seine LED aufblinken lässt, macht Der zwei Sekunden Nichts - komme Da, was wolle.

Soll Das so?

MfG