Archiv verlassen und diese Seite im Standarddesign anzeigen : serielle Kommunikation über 2 xBee Module
MHeymann
29.09.2013, 14:16
Hallo Zusammen,
ich habe 2 Arduino UNO. Damit verbunden ist jeweils ein xBee Pro Serie 1 Modul. Beide Module sind mit X-CTU konfiguriert. Die Übertragung der beiden Module funktioniert auch.
An der einen Kombination(Arduino/xBee) ist ein Beschleunigungssensor (ADXL 335) angeschlossen. Dessen x und y Werte möchte ich einlesen und an die andere Kombination senden.
//Sender
void loop()
{
Serial.print(analogRead(x_pin); // z.B. 257
Serial.print(",");
Serial.println(analogRead(y_pin); // z.B. 321
delay(100);
}
Die Ausgabe am seriellen Monitor sieht dann z.B. so aus 257,321
Jetzt möchte ich am Empfänger die jeweiligen Werte einlesen und einer Variablen übergebe.
// Empfänger
{
if (Serial.available() >0)
{
char ch = Serial.read();
Serial.println(ch);
}
}
Bei der Ausgabe im seriellen Monitor sind alle Zeichen untereinander geschrieben.
Jetzt hab ich keine Ahnung, wie ich die Werte wieder als int einlese und somit den jeweiligen Variablen zuordnen kann.
Währe echt super, wenn mir jemand helfen könnte.
Wenn dein Sensor den Wert "123" liefert, dann werden diese 3 Zeichen einzeln an den Uart übergeben.
Beim Empfänger liest du dann immer ein char ein und hast dann in der Ausgabe vermutlich
1
2
3
stehen.
Du musst alles in einer Schleife einlesen und in einem string speichern. Dann kannst du diesen Wert wieder in einen Int/whatever konvertieren.
mfg
MHeymann
29.09.2013, 16:34
Danke für deine Antwort, aber wie lese ich das denn in einer Schleife ein? Stehe da gerade voll aufm Schlauch.
So z.b.
char str[32];
int i = 0;
...
while(Serial.available() > 0) {
str[i] = Serial.read();
if(str[i] == /* Stop zeichen */) {
str[i] = '\0';
i = 0;
break;
}
i++;
}
...
Da dieser Teil vermutlich eh in einer Schleife läuft, kannst du vermutlich auch if() anstatt while() verwenden.
mfg
MHeymann
29.09.2013, 18:27
Danke für deine Hilfe. Habs jetzt hinbekommen.
Hier die Lösung:
char buffer[10];
int data[1];
int index_a = 0;
int index_b = 0;
void loop()
{
if(Serial.available() > 0)
{
//aktuelles Zeichen einlesen
buffer[index_a] = Serial.read();
//Trenner oder Zeilenende
if (buffer[index_a] == ',' || buffer[index_a] =='\n')
{
buffer[index_a] = 0;
//Umwandeln in eine Zahl
data[index_b] = atoi(buffer);
//Datenindex ändern
index_b = ++index_b % 2;
if(index_b == 0)
{
Serial.print(data[0]);
Serial.print(" ");
Serial.println(data[1]);
}
index_a = 0;
}
else
{
index_a ++;
}
}
}
MFG
Mal ganz davon abgesehen, dass int data[1] völliger Schwachsinn ist und du mit data[1] = ... oder höher ins Nirvana schreibst, kapier ich diesen Teil auch nicht
//Datenindex ändern
index_b = ++index_b % 2;
if(index_b == 0)
{
Serial.print(data[0]);
Serial.print(" ");
Serial.println(data[1]);
}
Zudem wird nirgends index_b resetet.
mfg
MHeymann
30.09.2013, 00:47
Du hast recht. Funktioniert doch nicht so richtig. Hast du eventuell einen besseren Vorschlag, wie die die beiden Werte eingelesen bekomme. So langsam bin ich nämlich am verzweifeln.
Gruß
Marko
Spontan würde ich vorschlagen C programmieren zu lernen. Ansonsten:
int i = 0;
char temp[4];
while(i <4)
{
temp[i] = readSerialChar(); //Hier die passende Serialport methode verwenden
i++;
}
int result = atoi(temp);
Ich bin mal von deinem Beispiel ausgegangen dass das Sensor Ergebnis immer 3 Stellig ist. Wenn es das nicht ist brauchst du natürlich immer noch ein eindeutiges Stopzeichen auf dass du in der while Bedingung abfragen kannst. Aber das wurde bereits von weiter oben gezeigt.
char str[32];
int i = 0, j = 0;
int val[2];
...
while(Serial.available() > 0) {
str[i] = Serial.read();
if(str[i] == '\n' || str[i] == ',') {
str[i] = '\0';
i = 0;
val[j] = atoi(str);
j++;
if(j > 1) {
j = 0;
/* flag etc setzen, dass 2 Werte empfangen wurden und verarbeitet werden können ... whatever... */
}
break;
}
i++;
}
...
mfg
oderlachs
30.09.2013, 14:21
Toll dieser Tread, da ich fast ein ähnliches Projekt bearbeite, meine Robosteuerung/Messdatenübertragung, werde ich mal fleissig mitlesen und mitprobieren.
Gruss
Gerhard
Also wenn Bedarf besteht könnte ich eine (interruptbasierte) Beispiel Komponente für einen Atmega erstellen, da ich bereits so etwas ähnliches umgesetzt habe, jedoch etwas allgemeiner und vielseitiger verwendbar. Ob der Code jedoch Arduino kompatibel wäre weis ich nicht, da ich direkt mit der avr-gcc lib arbeite (theoretisch sollte es jedoch funktionieren, da die Arduino Plattform auch nur darauf aufsetzt)
oderlachs
30.09.2013, 20:15
Also mich würde das schon mal interessieren, auf INT basierend habe ich das noch nie gemacht, würd gerne wissen wie sowas gemacht wird...da ist ein Source zum Anschauen und Lernen schon nicht schlecht, wenn er dann noch ok ist und man keine "Fehler lernt" ist es noch besser. das mit den Fehlern meine ich , das oft in englischsprachigen Foren ich oft es nicht mitbekomme, das der Code Fehler hat und darum ins Forum gesetzt wurde...denn so gut ist mein English auch wieder nicht :( , um alles zu richtig verstehen..
Achso ich nutze eine BT Verbindung, aber für das Serielle ist das auch egeal...
Gerhard
Uart über Interrupt ist keine Zauberrei. Du hast im Prinzip nur einen Puffer zum schreiben. Da schreibst du rein, der AVR schickt dann einfach jedes Zeichen über einen Interrupt raus. Wenn du hingegen ein Zeichen empfängst, dann wird wiederum ein Interrupt ausgelöst wo du das empfangene Zeichen in den Puffer schreibst. Coden könnt ihr das alles ganz leicht selber, sonst lernt ihr ja nie was :D
mfg
Hi, ich hab da mal ne kleine Beispiel komponente erstellt:
https://www.roboternetz.de/community/threads/63113-Beispiel-Komponente-UART-Interrupt-und-Datenpaket-%C3%9Cbertragung-parsen?p=587019#post587019
@Wsk8 auch ich fand die Interruptprogrammierung am Anfang nicht ganz einfach, und fand Beispiele sehr hilfreich.
Das Beispiel zeigt außerdem auch wie man Daten in Paketstruktur parst.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.