ich arbeite gerade an einem Handshake-Sketch. Dieses soll verifizieren, dass die beiden Arduinos eine aktive Verbindung haben. Ich benutze zwei xBees(xBee S2C) mit den jeweiligen Shields auf einem Arduino MEGA 2560.
Hier einmal der Code der "Zentrale":
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
Serial.write(1); //Übertragung zum Start des Loops beim Empfänger
delay(100);
if(Serial.available()){
char start = Serial.read();//liest Char ein
switch(start){
case 'S':
Serial.println("Verbindung wird hergestellt"); //Fall S: Prüfe auf Verbindungsaufnahme
Serial.write("A");
delay(8000);
break;
case 'R':
Serial.println("Verbindung aktiv"); //Fall R: Antwort von Empfänger erhalten
Serial.write("C");
delay(8000);
break;
}
}
}//Loop
Und einmal der Code des "Empfängers":
boolean verbindung = false;
void setup() {
Serial.begin(9600);
}
void loop() {
if(Serial.available()){
verbindung = true;
}
if(verbindung == true ){ //falls ja: Handshake
char einlesen = Serial.read(); //liest Char ein
switch(einlesen){
case 'A':
Serial.println("Verbindung wird hergestellt");//Fall A: schickt Antwort zu Zentrale
Serial.write("R");
delay(8000);
break;
case 'C':
Serial.println("Verbindung aktiv"); //Fall C: Antwort von Zentrale erhalten
break;
default:
Serial.write("S"); //falls nichts zutrifft: Starte Verbindungsaufnahme
delay(8000);
break;
}
}
}//Loop
Mein Problem ist nun, wenn ich mir das Ganze am seriellen Monitor anzeigen lasse, der Empfänger, wie bei "default" geschrieben, sein S sendet um zu initalisieren. Die Zentrale startet darauf seinen case "A", schreibt mir Verbindung wird hergestellt und schickt ein A ab. Aber weiter kommt es nicht. Dieser Vorgang wird die ganze Zeit wiederholt. Selten kommt es vor, dass Case A beim Empfänger aktiv wird und mir die Zentrale "Verbindung aktiv" ausgibt. Die Antwort darauf bleibt beim Empfänger aber leider aus. Ich würde mich über Tipps und Anregungen sehr freuen, da ich hier gerade ein bisschen am verzweifeln bin.
Serial.println("Verbindung wird hergestellt"); //Fall S: Prüfe auf Verbindungsaufnahme
Serial.write("A");
Du gibst Deine Debugging-Meldungen auf der gleichen seriellen Schnittstelle aus, auf welcher Du die Kommunikation über die XBees aufzubauen scheinst. Da Du nicht schreibst, wie die Hardware angeschlossen ist, kann ich Dir nicht genau sagen, was Du ändern sollst. Ich würde die XBee-Kommunikation auf eine der anderen UARTs des Mega2560 verbinden, damit Du die Verbindung zum PC weiterhin über die dafür gedachte Schnittstelle leiten kannst.
Ich benutze ein Wireless SD Shield, welches ich auf dem Arduino aufgesteckt habe. Dieses ist aber über TX und RX 0 angeschlossen. Ist es möglich die anderen UARTS miteinzubinden, obwohl diese nicht mit dem Shield verbunden sind?
Ist es möglich die anderen UARTS miteinzubinden, obwohl diese nicht mit dem Shield verbunden sind?
Grundsätzlich ja, hängt noch etwas davon ab, wie das Shield genau realisiert wurde (Du hast keine Links gepostet, die auf die Hardware zeigen). Ein Miteinbinden wird schiefgehen, Du musst die Verbindung vom Shield zum Mega2560 kappen, wenn Du einen der anderen UARTs verwenden willst, sonst hast Du die ganzen Debugging-Ausgaben trotzdem auf dem Kommunikationskanal, was natürlich jedes Protokoll ad-absudum führt.
Versucht haben wir das ganze jetzt mithilfe von Kabeln zu verbinden. Jetzt habe ich gar keine Ausgaben mehr, wenn ich das Sketch mit Serial1 umschreibe.
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
Serial1.begin(9600);
}
void loop() {
Serial1.write(1); //Übertragung zum Start des Loops beim Empfänger
delay(100);
if(Serial1.available()){
char start = Serial1.read();//liest Char ein
switch(start){
case 'S':
Serial.println("Verbindung wird hergestellt"); //Fall S: Prüfe auf Verbindungsaufnahme
Serial1.write("A");
delay(8000);
break;
case 'R':
Serial.println("Verbindung aktiv"); //Fall R: Antwort von Empfänger erhalten
Serial1.write("C");
delay(8000);
break;
}
}
}//Loop
Versucht haben wir das ganze jetzt mithilfe von Kabeln zu verbinden. Jetzt habe ich gar keine Ausgaben mehr, wenn ich das Sketch mit Serial1 umschreibe.
Hast Du die Pins 0 und 1 am Shield abgetrennt (so dass sie keinen Kontakt mit dem Arduino mehr kriegen können)? Ohne diese Änderung prodzierst Du Kurzschlüsse, die den Arduino im schlimmsten Fall killen können.
Hier mal ein Bild von jeder Seite. Die Pins 0 & 1 habe ich weggeknickt, damit diese keinen Kontakt mehr haben. Die Kabel sind am Shield mit den Pins 2 & 3 des xBees verlötet, welche für die Kommunikation zuständig sind.
Wenn ich das richtig erkenne, ist XBee1 mit D18 und XBee2 mit D19 verbunden. Das ist genau verkehrt, XBee1 (DOut) sollte mit D19 (RX1) und XBee2 (DIn) mit D18 (TX1) gekoppelt sein.
Ich hätte Serial1 sowieso mit den Pins 0 und 1 des Shields verbunden, dann benutzt Du die Shield-Verbindung, die das TX-Signal nach 3V3 konvertiert. So wie Du's angeschlossen hast, könnte das XBee-Modul von den 5V der TX-Verbindung Schaden genommen haben.
Hab es jetzt so angeschlossen wie du es beschrieben hast. Scheint jetzt zu funktionieren.
Danke für deine Hilfe und Geduld mit mir!
EDIT: Ich habe das Gefühl die Delays erschweren die Kontaktaufnahme, da sie ja das komplette Programm stoppen. Somit antwortet manchmal der eine nicht auf den anderen wenn ein Signal ankommt. Ist es möglich die Delays zu ersetzen, ohne dass die Signale "gespammt" werden?
Ist es möglich die Delays zu ersetzen, ohne dass die Signale "gespammt" werden?
Ja, das ist sogar sehr empfehlenswert. Die Funktion millis() liefert Dir einen Zeitstempfel. Wenn Du den speicherst, wenn Du eine Meldung raus schickst, kannst Du im Falle, dass ein erneutes Senden angesagt wäre, einfach den aktuellen Wert von millis() mit dem gespeicherten vergleichen (Achtung, immer Subtraktion verwenden, damit ein Überlauf abgefangen wird) und dann entscheiden, ob schon die nächste Meldung geschickt werden soll.