NRW
Offline
Sr. Member
Karma: 1
Posts: 373
|
 |
« on: March 01, 2012, 10:04:51 am » |
Hallo zusammen, ich brauche mal ein paar Tips. Ich habe zwei RF12 Module. Senden und empfangen geht schon mal  Nun habe ich mal wieder eine Wissenslücke. Und zwar sammle ich an einem Modul verschiedene Daten. Diese wollte ich in einem Struct speichern. Senden würde ich das ja in etwa so: rf12_sendStart(0, &payload, sizeof payload); Leider kann ich nicht ganz nachvollziehen was am ende raus kommt. Wenn mein zusammengesetztes Payload eigentlich 12345 sein müsste kommt komischer weise 12950 am anderen ende raus. Ausgelesen wird das ganze ja durch folgenden code: if (rf12_recvDone() && rf12_crc == 0) { for (byte i = 0; i < rf12_len; ++i) { Serial.print((int) rf12_data[i]); } Deshalb zwei Fragen: 1. Wieso kommt so was komisches an? Übersehe ich etwas? 2. Wie kann ich am besten den Empfangenen String wider in das Construct bekommen. Das Struct: struct { byte t_id; byte light; // light sensor: 0..255 byte moved :1; // motion detector: 0..1 byte humi :7; // humidity: 0..100 int temp :10; // temperature: -500..+500 (tenths) byte lobat :1; // supply voltage dropped under 3.1V: 0..1 } payload;
|
|
|
|
|
Logged
|
|
|
|
|
Bavaria Germany
Offline
Full Member
Karma: 0
Posts: 121
Arduino rocks
|
 |
« Reply #1 on: March 03, 2012, 12:28:35 am » |
Kommt auch bei mehreren Versuchen immer "12950" statt "12345" an ?? Falls ja, bitte den kompletten Programmcode für Sender und Empfänger zeigen.
Gruß, mmi.
|
|
|
|
« Last Edit: March 03, 2012, 12:33:04 am by mmi »
|
Logged
|
|
|
|
|
NRW
Offline
Sr. Member
Karma: 1
Posts: 373
|
 |
« Reply #2 on: March 03, 2012, 03:33:03 am » |
Ja es kommt immer 12950 an: [crypRecv] 31 =12950 32 =12950 33 =12950 34 =12950 35 =12950 36 =12950 37 =12950 Sender: #include <RF12.h> #include <Ports.h> #define T_ID 10
MilliTimer sendTimer; byte sendSize; struct { byte t_id; byte light; // light sensor: 0..255 byte moved :1; // motion detector: 0..1 byte humi :7; // humidity: 0..100 int temp :10; // temperature: -500..+500 (tenths) byte lobat :1; // supply voltage dropped under 3.1V: 0..1 } payload;
void setup () { Serial.begin(57600); Serial.println("\n[crypSend]"); rf12_initialize(T_ID, RF12_868MHZ, 47); rf12_encrypt(RF12_EEPROM_EKEY); }
void loop () { rf12_recvDone(); if (rf12_canSend() && sendTimer.poll(1000)) { // jede sekunde senden payload.t_id = 1; payload.light = 2; payload.moved = 3; payload.humi = 4; payload.temp =5; rf12_sendStart(0, &payload, sizeof payload); } } Empfänger: #include <RF12.h> #include <Ports.h>
struct { byte t_id; byte light; // light sensor: 0..255 byte moved :1; // motion detector: 0..1 byte humi :7; // humidity: 0..100 int temp :10; // temperature: -500..+500 (tenths) byte lobat :1; // supply voltage dropped under 3.1V: 0..1 } payload;
void setup () { Serial.begin(57600); Serial.println("\n[crypRecv]"); rf12_initialize(1, RF12_868MHZ, 47); rf12_encrypt(RF12_EEPROM_EKEY); }
void loop () { if (rf12_recvDone() && rf12_crc == 0) { // good packet received Serial.print(' '); Serial.print(rf12_seq); Serial.print(" ="); for (byte i = 0; i < rf12_len; ++i) { Serial.print((int) rf12_data[i]); } Serial.println(); } } Der Code soll noch nicht viel machen! Muss mich da jetzt erstmal einarbeiten und schritt für schritt erweitern. Was hab ich für Möglichkeiten und so. Möchte zb noch wissen ob ich die Versender-ID am Empfänger auslesen kann. Dann würde ich die nicht im Payload mit senden sondern so erkennen, fände ich besser. Was ich auch noch nicht verstehe (steht auch nicht in der Referenz : Beim Struct byte moved :1; <- was bedeutet die 1 oder die 7 oder die 10 bei meinem Struct
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 1
Posts: 29
|
 |
« Reply #3 on: March 03, 2012, 07:44:23 am » |
Hallo MueThoS, (und hallo Forum, ich fange nach langem mitlesen mal an, mitzuschreiben) Meine Vermutung: Schau dir mal http://www.c-howto.de/tutorial-strukturierte-datentypen-bitfelder.html oder http://en.wikipedia.org/wiki/Bit_field an. Dein Struct orientiert sich nicht an Bytegrenzen ... Und daher kommen beim byteorientierten Ausgeben (beim Serial.print) deines Empfangs-code auch komische Daten raus. Versuche bei der Ausgabe auch wieder die Elemente des Structs zu verwenden und anzusprechen, wie du es beim befüllen machst ... Oder lasse die Doppelpunkt-angaben einfach weg (das macht aber deine Nachrichten unnötig groß). Viele Grüße, Holger
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #4 on: March 03, 2012, 08:22:31 am » |
Hallo MueThoS, wie Holger schon richtig bemerkte, ist das eine Struktur mit Bitfeldern. Die Zahl hinter dem Doppelpunkt gibt an, wieviele Bits das Attribut belegt. struct { byte t_id; byte light; // light sensor: 0..255 byte moved :1; // motion detector: 0..1 byte humi :7; // humidity: 0..100 int temp :10; // temperature: -500..+500 (tenths) byte lobat :1; // supply voltage dropped under 3.1V: 0..1 } payload; Das Attribut "moved" z. B. hat nur eine Länge von einem Bit, da versuchst du, den Wert 3 reinzuschreiben - bei einem Bit geht aber nur 0 oder 1. Du solltest also erst mal da nur vernünftige Werte reinschreiben, die 3 kriegst du so nie wieder raus. Auch ist es schwierig, die Werte direkt von der empfangenen Struktur so anzuzeigen, das stimmt ja vom Speicherlayout her nicht mit deiner Struktur "Payload" überein. Die in meinen Augen einfachste Vorgehensweise wäre es, die empfangenen Bytes in einer eigenen Struktur zu übertragen (byte [5]) und dann die Daten in deine payload-Struktur zu kopieren, also z. B: byte buffer[sizeof(payload)]; memcpy(&payload, &buffer, sizeof(payload));
Danach kannst du deine Daten aus der payload-Struktur ausgeben, indem du die einzelnen Attribute ansprichst, also z. B. Serial.println (payload.temp); Serial.println (payload.humi);
Ich hoffe, dass das dann bei dir so klappt. Ciao, Rudi
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1299
|
 |
« Reply #5 on: March 03, 2012, 08:29:39 am » |
Du brauchst die Daten nichtmal kopieren. Es reicht am Ende den Puffer auf den Datentyp "payload" zu casten.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #6 on: March 03, 2012, 08:42:26 am » |
Du brauchst die Daten nichtmal kopieren. Es reicht am Ende den Puffer auf den Datentyp "payload" zu casten.
Daran hatte ich auch schon gedacht, aber payload ist kein Datentyp, sondern nur eine Struktur. Man kann natürlich mit typedef auch einen Typ daraus machen, aber dann braucht man wieder eine Variable mit diesem Typ,um diesen Cast durchführen zu können. Ob das für den TE einfacher zu durchschauen ist? Rudi
|
|
|
|
|
Logged
|
|
|
|
|
NRW
Offline
Sr. Member
Karma: 1
Posts: 373
|
 |
« Reply #7 on: March 03, 2012, 10:51:47 am » |
Erstmal natürlich Danke für die Antworten. Mein Wunsch währe es es so zu machen wie rz259 vorgeschlagen hat. Ich würde gerne über Serial.println (payload.humi); wieder drauf zugreifen können. Zunächst die erste frage hierzu: Ist es möglich dies noch als Array zu machen? Also so in etwa? Serial.println (payload[0].humi); Dann die Frage zu der Umsetzung: Verstehe ich das richtig das ich meine Daten die ja in rf12_data mit der länge rf12_lenin eine zusammenhängende Variable bekommen muss? Ich habe das schon mal gesehen verstehe aber noch nicht so ganz woher die Daten kommen für Buffer byte buffer[sizeof(payload)]; Ist Buffer eine Variable von mir oder ist das etwas spezielles welches mir vom MC zur Verfügung gestellt wird? Wenn es nur ein Platzhalter für eine von mir angelegte Variable sein soll müsste ich nun in dieser Schleife: for (byte i = 0; i < rf12_len; ++i) { incomingByte = rf12_data[i]; } So etwas machen? und danach byte incomingByte[sizeof(payload)]; memcpy(&payload, &incomingByte, sizeof(payload)); So wie ich es jetzt hier geschrieben habe geht's natürlich nicht  Ich probiere weiter. Das mit den Zahlen hinter dem : im Struct hab ich aber verstanden, Danke schon mal dafür.
|
|
|
|
|
Logged
|
|
|
|
|
NRW
Offline
Sr. Member
Karma: 1
Posts: 373
|
 |
« Reply #8 on: March 03, 2012, 11:23:58 am » |
Wow, jetzt hatte ich einen Riesen Text geschrieben weil ich etwas weiter gekommen bin und es aber noch Probleme gab. Und während ich so schrieb viel es mir ein! Ich bin auf jeden Fall ein ganzes stück weiter: #include <RF12.h> #include <Ports.h> char incomingByte; // a variable to read incoming serial data into struct { byte t_id:8; // byte light:8; // light sensor: 0..255 byte moved :1; // motion detector: 0..1 byte humi :7; // humidity: 0..100 int temp :10; // temperature: -500..+500 (tenths) byte lobat :1; // supply voltage dropped under 3.1V: 0..1 } payload;
void setup () { Serial.begin(57600); Serial.println("\n[crypRecv]"); rf12_initialize(1, RF12_868MHZ, 47); rf12_encrypt(RF12_EEPROM_EKEY); }
void loop () { if (rf12_recvDone() && rf12_crc == 0) { // good packet received memcpy(&payload, (byte*) rf12_data, sizeof payload); debug(); } }
void debug(){ Serial.print(rf12_seq); Serial.print(" ="); Serial.print("T_ID: "); Serial.print((int) payload.t_id); Serial.print(" light: "); Serial.print((int) payload.light); Serial.print(" moved: "); Serial.print((int)payload.moved); Serial.print(" humi: "); Serial.print((int)payload.humi); Serial.print(" temp: "); Serial.print((int)payload.temp); Serial.print(" lowbat: "); Serial.println((int)payload.lobat); }
Zeigt mir folgendes: 744 =T_ID: 111 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 745 =T_ID: 111 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 746 =T_ID: 111 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 747 =T_ID: 111 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0
Das gefällt mir schon mal ganz gut. Damit kann ich jetzt weiter arbeiten....
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #9 on: March 03, 2012, 03:07:56 pm » |
Das sieht eigentlich ganz gut aus - aber ob die Daten stimmen, kann ich natürlich nicht beurteilen, das kannst nur du...
Rudi
|
|
|
|
|
Logged
|
|
|
|
|
NRW
Offline
Sr. Member
Karma: 1
Posts: 373
|
 |
« Reply #10 on: March 03, 2012, 04:47:38 pm » |
Die Daten stimmen so weit. Zumindest in der aktuallen konfiguration klappt das wunderbar. Eventuel muss ich noch Typen anpassen aber eins nach dem anderen. Im groben bekomme ich die übertragung jetzt hin. Jetzt schaue ich erstmal welche Daten ich an den standorten sammeln will/kann.
|
|
|
|
|
Logged
|
|
|
|
|
NRW
Offline
Sr. Member
Karma: 1
Posts: 373
|
 |
« Reply #11 on: March 08, 2012, 05:54:29 am » |
Weiter geht's.... Folgendes Problem: Ich möchte die Daten einzelne abholen. Deshalb versuche ich die einzelnen Stationen an zu funken und eine Antwort ab zu warten. Deshalb habe ich im Sender/Zentrale folgendes gemacht: void loop () { for(int i=1; i<2 ; i++){ rf12_recvDone(); if (rf12_canSend() && sendTimer.poll(2000)) { rf12_sendStart(i, "*", 1); Serial.println("Anforderung gesendet .. "); } if (rf12_recvDone() && rf12_crc == 0) { // good packet received Serial.print("Daten wurden empfangen .. "); memcpy(&payload[i], (byte*) rf12_data, sizeof payload); //debug(); } } } Er sendet das *chen. Das sehe ich daran das der Empfänger/Station etwas bekommt und auch seine Antwort gibt bzw hoffentlich gibt. Der Empfänger/Station hat folgenden Code: void loop () { if (rf12_recvDone() && rf12_crc == 0) { Serial.print("Anforderung erhalten .. "); rf12_recvDone(); delay(100); if (rf12_canSend()) { payload.t_id = T_ID; payload.light = 222; payload.moved = 1; payload.humi = 33; payload.temp =444; payload.lobat =0; rf12_sendStart(10, &payload, sizeof payload); Serial.println("Daten gesendet"); } } } Die Meldung "Anforderung erhalten" kommt und die Meldung "Daten gesendet" auch. Ich gehe also mal davon aus das er auch sendet. Nur leider bekomme ich laut Sender/Zentrale keine Antwort. Ich habe hier irgendwie eine Blockade, da ich im Moment nicht weiß woran es liegen kann. Hat da einer einen Tip für mich? Oder vielleicht auch eine Möglichkeit wie ich einen request starten kann ohne so ein "*" oder sonst ein Zeichen zu schicken. Ob meine Vorgehensweise so ideal ist.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #12 on: March 09, 2012, 05:33:56 pm » |
Hm,
da gibt es natürlich mehrere Möglichkeiten zur Fehlersuche:
a) Stimmt die Id der Basisstation (10)? b) Kann es sein, dass du zu viele Daten sendest? Bevor du die Rückgabe entgegennimmst, schickst du schon wieder neue Anforderungen c) Kommen überhaupt gültige Daten zurück? Du prüfst ja auf rf12_recvDone und crc == 0, kann es sein, dass zwar rf12_recvDone TRUE zurückliefert, aber der crc-Wert nicht passt? d) evtl. mit ACKNOWLEDGE arbeiten und sehen, ob du das Ack-Signal zurückbekommst e) Wenn du mit einem Empfänger anfangen und dort zuerst einen * senden, um zu sehen, ob das auch an der Basisstation ankommt
evtl. gibt's ja noch weitere Ursachen - einfach mal prüfen...
Ciao,
Rudi
|
|
|
|
|
Logged
|
|
|
|
|
NRW
Offline
Sr. Member
Karma: 1
Posts: 373
|
 |
« Reply #13 on: March 10, 2012, 01:09:58 pm » |
So, ich bin ein Stück weiter. Aber ich kann nicht sagen das es Gut läuft. Ich habe zumindest hin bekommen das Daten zurück kommen. Sogar von zwei Modulen. Nur die Auflösung ins Array funktioniert irgendwie nicht: entrale Anforderung senden an: 1 Sensor 1 antwortet nicht Anforderung senden an: 2 Empfang von 2 Daten: 802 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 1 Empfang von 1 Daten: 813 =T_ID: 2 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 2 Empfang von 2 Daten: 814 =T_ID: 2 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 1 Empfang von 1 Daten: 818 =T_ID: 2 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 2 Empfang von 2 Daten: 819 =T_ID: 2 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 1 Empfang von 1 Daten: 809 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 2 Empfang von 2 Daten: 810 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 1 Empfang von 1 Daten: 813 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 2Anforderung senden an: 1 Sensor 1 antwortet nicht Anforderung senden an: 2 Sensor 2 antwortet nicht Anforderung senden an: 1 Sensor 1 antwortet nicht Anforderung senden an: 2 Empfang von 2 Daten: 818 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 1 Sensor 1 antwortet nicht Anforderung senden an: 2 Sensor 2 antwortet nicht Anforderung senden an: 1 Empfang von 1 Daten: 821 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 2 Empfang von 2 Daten: 822 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 1 Sensor 1 antwortet nicht Anforderung senden an: 2 Empfang von 2 Daten: 824 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 1 Empfang von 1 Daten: 826 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 2 Empfang von 2 Daten: 827 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 1 Empfang von 1 Daten: 831 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 2 Empfang von 2 Daten: 842 =T_ID: 2 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 1 Empfang von 1 Daten: 833 =T_ID: 1 light: 222 moved: 1 humi: 33 temp: 444 lowbat: 0 Anforderung senden an: 2Anforderung senden an: 1 Sensor 1 antwortet nicht Anforderung senden an: 2 Sensor 2 antwortet nicht Anforderung senden an: 1 Sensor 1 antwortet nicht
Der Code: void loop () { if (sendTimer.poll(3000)){ for(int i=1; i<3 ; i++){ rf12_recvDone(); if (rf12_canSend()) { rf12_sendStart(i, "*", 1); Serial.print("Anforderung senden an: "); Serial.print(i); } warten=0; while (!rf12_recvDone()){ warten++; delay(100); if (warten >= 20) { Serial.print(" Sensor "); Serial.print(i); Serial.println(" antwortet nicht"); goto out; } } out: if (rf12_crc == 0) { // good packet received Serial.print(" Empfang von "); Serial.print(i); Serial.print(" Daten: "); memcpy(&payload[i], (byte*) rf12_data, sizeof payload); debug(i); } } } }
void debug(int nr){ Serial.print(rf12_seq); Serial.print(" ="); Serial.print("T_ID: "); Serial.print((int) payload[nr].t_id); Serial.print(" light: "); Serial.print((int) payload[nr].light); Serial.print(" moved: "); Serial.print((int)payload[nr].moved); Serial.print(" humi: "); Serial.print((int)payload[nr].humi); Serial.print(" temp: "); Serial.print((int)payload[nr].temp); Serial.print(" lowbat: "); Serial.println((int)payload[nr].lobat); } Eigentlich sollte immer abwechselnd Sensor 1 und Sensor 2 ausgegeben werden aber naja das macht er irgendwie nicht. Warum jetzt Daten kommen und vorher nicht liegt irgendwie an dem Teil: warten=0; while (!rf12_recvDone()){ warten++; delay(100); if (warten >= 20) { Serial.print(" Sensor "); Serial.print(i); Serial.println(" antwortet nicht"); goto out; } } Ich muss an der Stelle warten bis Daten auch da sind. Allerdings will ich nicht ewig warten. Hab jetzt keine schönere Variante hin bekommen als die Goto out. Jetzt muss ich raus bekommen warum er die Daten nicht sauber ins Array schiebt.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #14 on: March 10, 2012, 02:58:24 pm » |
Was meinst du damit, dass die Auflösung der Daten ins Array nicht richtigh funktioniert?
Dein Goto kannst du folgendermaßen elimieren: <code> boolean timeout = FALSE; warten=0; while (!rf12_recvDone() && !timeout){ warten++; delay(100); if (warten >= 20) { Serial.print(" Sensor "); Serial.print(i); Serial.println(" antwortet nicht"); timeout = TRUE; } } </code>
|
|
|
|
|
Logged
|
|
|
|
|
|