Go Down

Topic: RF12 Datenstruct senden, empfangen und wieder trennen (Read 4722 times) previous topic - next topic

MueThoS

Naja, wenn Du dir den mitschnitt anschaust siehst Du das er Sensor 1 anfragt
Sensor 1 sollte dann antworten aber bei der T-ID steht mal 1 und mal 2
Und genau das selbe bei Sensor 2
Mal gibt er mir als Antwort 2 und mal 1

Das mit dem timeout werde ich mal übernehmen!
Was mich wundert ist warum ich nicht im while auch direkt das warten prüfen kann.
Ich wollte uhrsprünglich folgendes machen:
Code: [Select]
While (!rf12_recvDone() && warten <= 20)
Aber irgendwie ging das nicht.


rz259

Hallo

sorry, das kann ich von dem von dir geposteten Auszug aber nicht nachvollziehen. Das einzige was man da sehen kann ist, dass manchal keine Antwort kommt - aber ansonsten sieht das ok aus.

Aber was mir aufgefallen ist: deine Sequenz gerät offensichtlich durcheinander und die Nr. 813 kommt sogar zweimal vor, einmal am Anfang, dann am Ende des nachfolgenden Beispiels:


<code>
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
</code>

Irgendwie scheinen da Pakete verloren zu gehen - experimentiere doch mal ein wenig mit der Wartezeit rum, ob es sich dann verbessert.

Rudi

MueThoS

Doch kann man schon sehen aber vielleicht nur wenn man weiss was ich da so gefummelt habe.
Zur Erklärung:

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

Schau mal auf die Farblich markierten Zahlen.
Rot: Sind statisch bzw werden einfach durch die Zentrale anhand von i ausgegeben. Das sagt erstmal nicht viel aus.
Wichtig sind die gelben Zahlen.
Die kommen von den Sensoren und entsprechen den IDs diese werden mit gesendet.
Und dort kannst du sehen das 4 mal die ID2 kommt und dann 3 mal die ID1
Und da ich die Sensoren ungefähr zur selben Zeit an den Strom gesteckt habe haben die in etwa die selbe Sequenz.
Nur wenn ich zb einen Sensor stromlos mache kommt trotzdem immer eine Antwort egal ob ich Sensor 1 oder Sensor 2 abfrage.

Hier frage ich sogar 3 Sensoren ab, es ist aber nur ein Sensor mit Strom versorgt und trotzdem bekomme ich immer Antwort

Anforderung senden an: 1  Empfang von 1  Daten: 726 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 2  Empfang von 2  Daten: 727 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 3  Empfang von 3  Daten: 728 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 1  Empfang von 1  Daten: 729 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 2  Empfang von 2  Daten: 730 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 3  Empfang von 3  Daten: 731 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 1  Empfang von 1  Daten: 732 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 2  Empfang von 2  Daten: 733 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 3  Empfang von 3  Daten: 734 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Der Sensor der Strom hat hat die ID 2 siehe hier: ------------^

Jetzt versuche ich gerade die ID die ich abfragen möchte mit in der Anforderung zu senden und im Sensor selber noch mal eine abfrage zu machen ob der Sensor auch wirklich gemeint ist.
Dies gelingt mir aber nicht da der Sendebefehl mein INT nicht akzeptiert.
Mache ich folgendes:
Code: [Select]
rf12_sendStart(i,  i, sizeof i);
Kommt folgender Fehler:
Code: [Select]
empf_nger1:56: error: invalid conversion from 'int' to 'const void*'
empf_nger1:56: error: initializing argument 2 of 'void rf12_sendStart(uint8_t, const void*, uint8_t)'

Dann habe ich versucht i umzuwandeln zb ich char* das geht zwar auf senderseite aber auf empfängerseite kommt dann:
Code: [Select]

0 22         // Wenn ID 1 abgefragt wird
22 160      // Wenn ID 2 abgefragt wird
160 247    // Wenn ID 3 abgefragt wird

Übrigens alles bei SensorID 2 obwohl der doch gar nicht reagieren dürfte er ist ja nicht gemeint.
Ich bekomme es also nicht hin die 1 oder 2 oder 3 zu senden und auch eine 1 oder 2 oder 3 zu empfangen.
Damit ich einfach noch mal als Sicherheit sowas machen kann:
Code: [Select]
if (rf12_data[0] == Sensor_ID) {dann sende sonst nicht}

rz259

#18
Mar 11, 2012, 11:13 am Last Edit: Mar 11, 2012, 11:21 am by rz259 Reason: 1
Du musst die Adresse von i übergeben, also

<code>
rf12_sendStart(i,  &i, sizeof i);
</code>


Irgendwie habe ich den Eindruck, dass deine Funkmodule immer senden, egal, ob sie eine Anforderung kriegen oder nicht.
Vielleicht solltest du auf der Empfängerseite IMMER checken, von wem du was empfangen hast. Wenn du auf einen bestimmten Sender wartest, solltest du das auch in der Schleife explizit angeben, sonst wartest du immer nur solange, bis irgendein Sender was schickst.

Kannst du nochmal deinen gesamten Code posten? So weiß man nicht mehr so genau, was du inzwischen alles machst.

MueThoS

Gibbet garnicht, auf das & bin ich echt nicht gekommen.
Aber genau das ist es was ich gebraucht habe.

Jetzt kann ich mit:
Code: [Select]
if (rf12_recvDone() && rf12_crc == 0 && rf12_data[0] == Sensor_ID) {
Sicherstellen das nur geantwortet wird wenn auch dieser Sensor gemeint ist.

Als Antwort kommt nun wenn nur ein Sensor dran ist:
Code: [Select]
Anforderung senden an: 1   Sensor 1 antwortet nicht
Anforderung senden an: 2  Empfang von 2  Daten: 11 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 3   Sensor 3 antwortet nicht
Anforderung senden an: 1   Sensor 1 antwortet nicht
Anforderung senden an: 2  Empfang von 2  Daten: 12 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 3   Sensor 3 antwortet nicht
Anforderung senden an: 1   Sensor 1 antwortet nicht
Anforderung senden an: 2  Empfang von 2  Daten: 13 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 3   Sensor 3 antwortet nicht


Als Antwort kommt nun wenn drei Sensoren dran sind:
Code: [Select]

Anforderung senden an: 1  Empfang von 1  Daten: 16 =T_ID: 1  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 2  Empfang von 2  Daten: 15 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 3  Empfang von 3  Daten: 5 =T_ID: 3  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 1  Empfang von 1  Daten: 17 =T_ID: 1  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 2   Sensor 2 antwortet nicht
Anforderung senden an: 3  Empfang von 3  Daten: 6 =T_ID: 3  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 1  Empfang von 1  Daten: 18 =T_ID: 1  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 2  Empfang von 2  Daten: 16 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 3  Empfang von 3  Daten: 7 =T_ID: 3  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 1  Empfang von 1  Daten: 19 =T_ID: 1  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 2  Empfang von 2  Daten: 17 =T_ID: 2  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0
Anforderung senden an: 3  Empfang von 3  Daten: 8 =T_ID: 3  light: 222  moved: 1  humi: 33  temp: 444  lowbat: 0

Ab und zu antwortet mal einer nicht aber das ist ja nicht so schlimm so lange es sich in grenzen hält.


DANKE schon mal

MueThoS

Aktuelle Version:
Sensor: (Werte sind derzeit statisch da es im Moment nur ums senden und empfangen geht!)
Code: [Select]
#include <RF12.h>
#include <Ports.h>
#include <JeeLib.h>

#define Sensor_ID 3
   
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[crypSend]");
    rf12_initialize(Sensor_ID, RF12_868MHZ, 47);
    rf12_encrypt(RF12_EEPROM_EKEY);
}

void loop () {
   if (rf12_recvDone() && rf12_crc == 0 && rf12_data[0] == Sensor_ID) {
      Serial.print("Anforderung erhalten  ..  ");
      rf12_recvDone();
      delay(100);
      if (rf12_canSend()) {
         payload.t_id = Sensor_ID;
         payload.light = 222;
         payload.moved = 1;
         payload.humi = 33;
         payload.temp =444;
         payload.lobat =rf12_lowbat();
         rf12_sendStart(10, &payload, sizeof payload);
         Serial.println(" Daten gesendet");
      }
   }
}


Zentrale: (Die Displayausgabe habe ich entfernt da die eh noch keinen nutzen hatte)
Code: [Select]

#include <RF12.h>
#include <Ports.h>
#include <JeeLib.h>
#include <avr/pgmspace.h>

MilliTimer sendTimer;
char incomingByte;      // a variable to read incoming serial data into
int warten=0;
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[4];

void setup () {
    Serial.begin(57600);
    Serial.println("\nZentrale");
    rf12_initialize(10, RF12_868MHZ, 47);
    rf12_encrypt(RF12_EEPROM_EKEY);   
}

void loop () {
   if (sendTimer.poll(5000)){
      for(int i=1; i<4 ; i++){
         rf12_recvDone();
         if (rf12_canSend()) {
            rf12_sendStart(i,  &i, sizeof i);
            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);
         }
      delay(100);
      }
       
   }   
}

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);

}

MueThoS

Update:
Der Bewegungssensor wird jetzt auch ausgelesen und mit gesendet.
Die Art wie gesendet wird soll sich noch mal ändern.
Später soll der Bewegungsmelder selbständig senden und die anderen Daten nur auf Abruf kommen.
Zentrale:
Code: [Select]
#include <RF12.h>
#include <Ports.h>
#include <JeeLib.h>
#include <avr/pgmspace.h>

#define max_Sensors 1

MilliTimer sendTimer;
char incomingByte;      // a variable to read incoming serial data into
int warten=0;
struct {
    byte t_id:4;    //
    byte light:8;     // light sensor: 0..255
    byte moved :1;  // motion detector: 0..1
    byte humi  :7;  // humidity: 0..100
    int temp   :13; // temperature: -500..+500 (tenths)
    byte lobat :1;  // supply voltage dropped under 3.1V: 0..1
} payload[4];

void setup () {
    Serial.begin(57600);
    Serial.println("\nZentrale");
    rf12_initialize(10, RF12_868MHZ, 47);
    rf12_encrypt(RF12_EEPROM_EKEY);   
}

void loop () {
   if (sendTimer.poll(5000)){
     Serial.println("");
      for(int i=1; i < max_Sensors+1 ; i++){
        warten=0;
        nochmal:
         rf12_recvDone();
         if (rf12_canSend()) {
            rf12_sendStart(i,  &i, sizeof i);
            Serial.print("Anforderung senden an: ");
            Serial.print(i);
         }
         
         while (!rf12_recvDone()){
            warten++;
            delay(100);
            if (warten == 10) {
               Serial.print("   Sensor ");
               Serial.print(i);
               Serial.println(" antwortet nicht nochmal");
               goto nochmal;
            }
            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);
         }
      delay(100);
      }
       
   }   
}

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((float)payload[nr].temp/100);
  Serial.print("  lowbat: ");
  Serial.println((int)payload[nr].lobat);

}

Sensor:
Code: [Select]
#include <RF12.h>
#include <Ports.h>
#include <PortsSHT11.h>
#include <JeeLib.h>
#include <util/atomic.h>

#define Sensor_ID 1
#define SHT11_PORT  1   // defined if SHT11 is connected to a port
#define LDR_PORT    4   // defined if LDR is connected to a port's AIO pin
#define PIR_PORT    4   // defined if PIR is connected to a port's DIO pin


#if LDR_PORT
    Port ldr (LDR_PORT);
#endif
#if SHT11_PORT
    SHT11 sht11 (SHT11_PORT);
#endif


#if PIR_PORT
   #define PIR_HOLD_TIME   5  // Status x Sekunden halten
   #define PIR_PULLUP      1  // Pull-Up für den InputPin
   #define PIR_FLIP        1  // 0 oder 1, wann meldet der PIR
   class PIR : public Port {
      volatile byte value, changed;
      volatile uint32_t lastOn;
    public:
       PIR (byte portnum)
          : Port (portnum), value (0), changed (0), lastOn (0) {}

       // Wird durch den Interrupt ausgeführt
       void poll() {
         byte pin = digiRead() ^ PIR_FLIP;
         // wenn pin auf high geht setze changed
         if (pin) {
            if (!state())
            changed = 1;
            lastOn = millis();
          }
          value = pin;
       }
       byte state() const {
          byte f = value;
          if (lastOn > 0)
             ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
                if (millis() - lastOn < 1000 * PIR_HOLD_TIME)
                   f = 1;
             }
          return f;
       }
       // Gibt true wenn neue Bewegung
       byte triggered() {
          byte f = changed;
          changed = 0;
          return f;
       }
   };
   PIR pir (PIR_PORT);
   // PIR-Signal per Interrupt
   ISR(PCINT2_vect) { pir.poll(); }
#endif

struct {
    byte t_id:4;    //
    byte light:8;   // light sensor: 0..255
    byte moved :1;  // motion detector: 0..1
    byte humi  :7;  // humidity: 0..100     7
    int temp   :13; // temperature: -500..+500 (tenths)   10
    byte lobat :1;  // supply voltage dropped under 3.1V: 0..1
} payload;

void setup () {
    Serial.begin(57600);
    Serial.print("\nSensor: ");
    Serial.println(Sensor_ID);
    rf12_initialize(Sensor_ID, RF12_868MHZ, 47);
    rf12_encrypt(RF12_EEPROM_EKEY);
     // omit this call to avoid linking in the CRC calculation code
    sht11.enableCRC();
    #if PIR_PORT
    pir.digiWrite(PIR_PULLUP);
    bitSet(PCMSK2, PIR_PORT + 3);
    bitSet(PCICR, PCIE2);
  #endif
}

void loop () {
   if (rf12_recvDone() && rf12_crc == 0 && rf12_data[0] == Sensor_ID) {
      Serial.print("Anforderung erhalten  ..  ");
      rf12_recvDone();
      delay(100);
      if (rf12_canSend()) {
         payload.t_id = Sensor_ID;
         #if LDR_PORT
            ldr.digiWrite2(1);  // enable AIO pull-up
            payload.light = ~ ldr.anaRead() >> 2;
            ldr.digiWrite2(0);  // disable pull-up to reduce current draw
         #endif
         #if PIR_PORT
            if (pir.triggered()) {
               payload.moved = pir.state();
            }else{
               payload.moved = 0;
            }
         #else
            payload.moved = 0;
         #endif
         sht11.measure(SHT11::HUMI);       
         sht11.measure(SHT11::TEMP);
         float h, t;
         sht11.calculate(h, t);
         int humi = h + 0.5, temp = 100 * t + 0.5;
         payload.humi = humi;
         payload.temp =temp;
         payload.lobat =rf12_lowbat();
         rf12_sendStart(10, &payload, sizeof payload);
         Serial.println(" Daten gesendet");
      }
   }
}

MueThoS

200 Puls hab ich, gleich  :)
Folgende Problematik:(tausendfach besprochen aber in dem Forum findet man ja nix)
Ich übertrage die Temperatur als int vierstellig.
Über Serial gebe ich die einfach als FLOAT aus und es ist alles super.
Auf dem Display geht's natürlich nicht so leicht.
Nu habe ich rum probiert.
Und bekomme es nicht hin. Ich weiß das es das letzend noch gab aber ich finde es nicht mehr. (BLIND?)

Code: [Select]
void printFloat(int x, int y, int intWert){
  int vorWert = intWert/100;
  int nachWert = intWert-vorWert*100;
  char vor[2];
  char nach[2];
  itoa (vorWert, vor, 10);
  itoa(nachWert,nach,10);
  glcd.drawString(x, y, vor);
  glcd.drawString(x, y+15, nach);
}

Mal abgesehen davon das es im Moment eh noch nicht richtig funktioniert habe ich noch ein zweites Problem!
Sobald diese beiden Zeilen aktiv sind:
Code: [Select]
itoa (vorWert, vor, 10);
  itoa(nachWert,nach,10);

Bekomme ich Probleme mit meinem Poll:
Normal: alle 5 Sekunden wird gepollt
Code: [Select]
-> 1 -> (179) ID: 1  light: 212  moved: 1  humi: 49  temp: 22.76  lowbat: 0

-> 1 -> (180) ID: 1  light: 212  moved: 0  humi: 49  temp: 22.76  lowbat: 0

-> 1 -> (181) ID: 1  light: 212  moved: 0  humi: 49  temp: 22.78  lowbat: 0

-> 1 -> (182) ID: 1  light: 212  moved: 1  humi: 49  temp: 22.78  lowbat: 0

-> 1 -> (183) ID: 1  light: 212  moved: 1  humi: 49  temp: 22.75  lowbat: 0

-> 1 -> (184) ID: 1  light: 212  moved: 0  humi: 49  temp: 22.80  lowbat: 0

-> 1 -> (185) ID: 1  light: 212  moved: 0  humi: 49  temp: 22.80  lowbat: 0

Mit den beiden Zeilen: innerhalb von 5 Sekunden
Code: [Select]
-> 1 -> (219) ID: 1  light: 210  moved: 0  humi: 48  temp: 22.84  lowbat: 0
-> -612 -> (220) ID: 1  light: 213  moved: 0  humi: 48  temp: 22.85  lowbat: 0
-> -611 -> (221) ID: 1  light: 211  moved: 0  humi: 48  temp: 22.86  lowbat: 0
-> -610 -> (222) ID: 1  light: 211  moved: 0  humi: 48  temp: 22.86  lowbat: 0
-> -609 -> (223) ID: 1  light: 213  moved: 0  humi: 48  temp: 22.87  lowbat: 0
-> -608 -> (224) ID: 1  light: 211  moved: 0  humi: 48  temp: 22.87  lowbat: 0
-> -607 -> (225) ID: 1  light: 211  moved: 0  humi: 48  temp: 22.88  lowbat: 0
-> -606 -> (226) ID: 1  light: 213  moved: 0  humi: 48  temp: 22.88  lowbat: 0
-> -605 -> (227) ID: 1  light: 211  moved: 0  humi: 48  temp: 22.88  lowbat: 0
-> -604 -> (228) ID: 1  light: 212  moved: 0  humi: 48  temp: 22.88  lowbat: 0
-> -603 -> (229) ID: 1  light: 213  moved: 0  humi: 48  temp: 22.87  lowbat: 0
-> -602 -> (230) ID: 1  light: 211  moved: 0  humi: 48  temp: 22.88  lowbat: 0
-> -601 -> (231) ID: 1  light: 212  moved: 0  humi: 48  temp: 22.89  lowbat: 0
-> -600 -> (232) ID: 1  light: 213  moved: 0  humi: 48  temp: 22.89  lowbat: 0

Der scheint durch den Stoa mir meinen Politier zu schießen.

Der restCode ist im Prinzip noch so wie der im Post vorher nur mit der Funktion dabei!

Hat da jemand einen Tip für mich?

-Holger-

Hi,

Schaut mir nach nem Überlauf aus.
Zumindest NachWert hat ja im Normalfall 2 Stellen. 0-terminiert brauchst du also mindestens einen char[3].

Viele Grüße
Holger

MueThoS

Ich bin da jetzt gerade verwirrt, weil ich dachte das terminieren währe bei nem array in ein char.
Aber wenn ich hier auch terminieren muss bekomme ich dann nicht probleme mit nem Wert der nullen enthält?
Z.B. 2005 ist ja 20.05 und würde ja schon nach der 2 terminieren oder.

Also früher zu QuickBasic-Zeiten war das alles egal  :)
Die wahren nicht so empfindlich wie die heutigen uC  :smiley-eek-blue:

MaFu

#25
Mar 18, 2012, 02:37 am Last Edit: Mar 18, 2012, 02:40 am by MaFu Reason: 1
Du bringst das durcheinander.
Strings in C (was ja einfache char Arrays sind), müssen immer mit einem Nullbyte abschließen.
Diese Nullterminierung erfolgt durch den Wert 0.
Das Zeichen (Ziffer) '0' hat den Wert 48 (Stichwort: ASCII-Tabelle).
Wenn Du also einen String mit zwei Zeichen speichern willst, muss Dein Array mindestens 3 Stellen haben.
Wenn itoa() die Zahl in den String (das Array) schreibt, wird automatisch der terminierende 0-Wert angehängt. Ist Dein Array zu klein wird somit der nachfolgende Speicherbereich überschrieben.
_______
Manfred

MueThoS

#26
Mar 18, 2012, 11:55 am Last Edit: Mar 18, 2012, 12:22 pm by MueThoS Reason: 1
Ihr hattet natürlich recht.
Jetzt kann es weiter gehen.....

Ah noch was:
Ich würde gerne einen Drehender verwenden.
Ich hätte aber gerne einen den man gut einbauen kann.
So mit Gewinde zum in die Frontplatte ein schrauben.
Hat da jemand einen Tip?

Edit:
Noch eine Frage:
Ich habe ja bei den Sensoren und bei der Zentrale ein Datenstruct
Code: [Select]
struct {
   byte t_id:4;    //
   byte light:8;     // light sensor: 0..255
   byte moved :1;  // motion detector: 0..1
   byte humi  :7;  // humidity: 0..100
   int temp   :13; // temperature: -500..+500 (tenths)
   byte lobat :1;  // supply voltage dropped under 3.1V: 0..1
} payload[max_Sensors+1];

Ist es möglich dieses Struct einfach zu erweitern und zwar nur auf Zentralen Seite?
Also das ich vom Sensor das oben beschriebene Struct bekomme aber in der Zentrale zb folgendes benutze:
Code: [Select]
struct {
   byte t_id:4;    //
   byte light:8;     // light sensor: 0..255
   byte moved :1;  // motion detector: 0..1
   byte humi  :7;  // humidity: 0..100
   int temp   :13; // temperature: -500..+500 (tenths)
   byte lobat :1;  // supply voltage dropped under 3.1V: 0..1
   int raumID : 1; // die ID des Raumnamens
   byte empfang : 1; // 1 wenn empfang gut war und 0 wenn kein empfang
} payload[max_Sensors+1];

Ich mache ja folgendes:
Code: [Select]
memcpy(&payload[i], (byte*) rf12_data, sizeof payload);
Ich werde das jetzt ausprobieren nur wollte ich auch fragen weil es ja sein kann das es zwar erstmal funktioniert aber vielleicht später auch Speicherüberschreibungen gibt die ich zunächst vielleicht gar nicht merke.

MueThoS

Also erstmal zum Struct:
Es scheint kein Problem zu sein wenn ich das Empfängerstruct etwas größer habe wie das Senderstruct.
Zumindest bei meinen Tests nicht.

Aber ich hänge schon wieder an einer Stelle wo ich jedes mal hänge.
VariablenTypen!
Ich habe eine RTC die ich auch auslesen und schreiben kann.
Ausgabe auf der Konsole klappt auch super.
Nur das Display will wieder nicht.
Das Display braucht ein char*
Ausgelesen wird so:
Code: [Select]
static void getDate (byte* buf) {
   rtc.send();
   rtc.write(0);
   rtc.stop();
   
   rtc.receive();
   buf[5] = bcd2bin(rtc.read(0));
   buf[4] = bcd2bin(rtc.read(0));
   buf[3] = bcd2bin(rtc.read(0));
   rtc.read(0);
   buf[2] = bcd2bin(rtc.read(0));
   buf[1] = bcd2bin(rtc.read(0));
   buf[0] = bcd2bin(rtc.read(1));
   rtc.stop();
}

bcd2bin sieht so aus:
Code: [Select]
static byte bcd2bin (byte val) {
    return val - 6 * (val >> 4);
}

Ich möchte die zahlen als int haben zum rechnen und zum anzeigen umwandeln in char*
Ich bekomme das aber schon wieder nicht hin.
Was habe ich denn jetzt in buf[]?
in der Konsole sieht ja alles super aus!
Wollte erstmal sowas machen:
Code: [Select]
year =(int) now[0];
Dann habe ich versucht sowas da hinter zu packen:
Code: [Select]
char* lcdTime(int intWert){
  Serial.println(intWert);
   char charWert[3];
   itoa (intWert, charWert, 10);
   Serial.println(charWert);
return charWert;
}

Und dann mit
Code: [Select]
glcd.drawString(13, 44, lcdTime(hour));
auks Display schieben.
In der Konsole wie immer alles super auf dem Display:
1,th,> oder so ähnlich
Das bringt mich noch mal ins Grab!

rz259

Nee, also so geht das natürlich nicht;-)

Aber zuerst habe ich einige andere Fragen:

Bist du sicher, dass deine Methode getDate() richtig ist? Sieht mir irgendwie chaotisch aus, was das Auslesen aus den verschiedenen Zeichen angeht? Irgendwie ist die Reihenfolge, was die Parameter von rtc.read() angeht - überraschend... Zuerst immer 0, und dann 1? Kommt mir komisch vor..

Und was soll
Code: [Select]

year =(int) now[0];


Das habe ich nicht verstanden, was das sein soll. Ist now ein Array von int-Werten?

Jetzt zu deinem Problem:

Code: [Select]

char* lcdTime(int intWert){
  Serial.println(intWert);
   char charWert[3];
   itoa (intWert, charWert, 10);
   Serial.println(charWert);
return charWert;
}


funktioniert nicht, weil charWert nur lokal existiert. Du versuchst eine Adresse zurückzugeben, die längst mit was anderem gefüllt sein kann.
Wenn du diese Signatur beibehalten willst, dann musst du charWert dynamisch reservieren, z. B. mit malloc(). Aber dann musst du den Wert auch wieder selbst freigeben.

Besser wäre es, charWert als Parameter mitzugeben, also sowas:

Code: [Select]

void lcdTime(int intWert, char charWert[3]){
  Serial.println(intWert);
   itoa (intWert, charWert, 10);
   Serial.println(charWert);
return charWert;
}


und dann den Buffer von deiner übergeordeten Funktion mit übergeben.

Rudi


MueThoS

So ganz habe ich den Kram noch nicht verstanden mit den Mikrokontrollern.

Zu deinen Rückfragen:
Erstmal - Ich weiß es selber noch nicht.
Das ganze ist eine Lib von JeeNode:
Code: [Select]
#include <JeeLib.h>
Die RTC wird so Initialisiert:
Code: [Select]
PortI2C myport (2 /*, PortI2C::KHZ400 */); // RTC
DeviceI2C rtc (myport, 0x68);


Ich poste mal den Code der im Beispiel ist und auch Funktioniert (allerdings eben nur in der Konsole:
Code: [Select]
// Hooking up a DS1307 (5V) or DS1340Z (3V) real time clock via I2C.
// 2009-09-17 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php

// the real-time clock is connected to port 2 in I2C mode (AIO = SCK, dIO = SDA)

#include <JeeLib.h>

PortI2C myport (2 /*, PortI2C::KHZ400 */);
DeviceI2C rtc (myport, 0x68);

static byte bin2bcd (byte val) {
    return val + 6 * (val / 10);
}

static byte bcd2bin (byte val) {
    return val - 6 * (val >> 4);
}

static void setDate (byte yy, byte mm, byte dd, byte h, byte m, byte s) {
    rtc.send();
    rtc.write(0);
    rtc.write(bin2bcd(s));
    rtc.write(bin2bcd(m));
    rtc.write(bin2bcd(h));
    rtc.write(bin2bcd(0));
    rtc.write(bin2bcd(dd));
    rtc.write(bin2bcd(mm));
    rtc.write(bin2bcd(yy));
    rtc.write(0);
    rtc.stop();
}

static void getDate (byte* buf) {
rtc.send();
rtc.write(0);
    rtc.stop();

rtc.receive();
    buf[5] = bcd2bin(rtc.read(0));
    buf[4] = bcd2bin(rtc.read(0));
    buf[3] = bcd2bin(rtc.read(0));
    rtc.read(0);
    buf[2] = bcd2bin(rtc.read(0));
    buf[1] = bcd2bin(rtc.read(0));
    buf[0] = bcd2bin(rtc.read(1));
    rtc.stop();
}

void setup() {
    Serial.begin(115200);
    Serial.println("\n[rtc_demo]");

    // test code:
   // setDate(12, 3, 26, 16, 17, 0);
}

void loop() {   
    byte now[6];
    getDate(now);
   
    Serial.print("rtc");
    for (byte i = 0; i < 6; ++i) {
        Serial.print(' ');
        Serial.print((int) now[i]);
    }
    Serial.println();
       
delay(1000);
}

Uhrzeit stellen und auslesen geht. Er zeigt mir die Werte an:
Code: [Select]
[rtc_demo]
rtc 12 3 26 20 17 55
rtc 12 3 26 20 17 56
rtc 12 3 26 20 17 57
rtc 12 3 26 20 17 58
rtc 12 3 26 20 17 59
rtc 12 3 26 20 18 0
rtc 12 3 26 20 18 1
rtc 12 3 26 20 18 2
rtc 12 3 26 20 18 3
rtc 12 3 26 20 18 4

Im Serial.print wird das now
  • einfach mit (int) ausgegeben.
    Leider ist das beim Display nicht so einfach.

    Ich verstehe auch nicht wie die Werte in now[] rein kommen.
    Aufgerufen wird mit
    Code: [Select]
    byte now[6];
    getDate(now);


    Dann wird ja folgendes gemacht:
    Code: [Select]
    static void getDate (byte* buf) {
    rtc.send();
    rtc.write(0);
        rtc.stop();

    rtc.receive();
        buf[5] = bcd2bin(rtc.read(0));
        buf[4] = bcd2bin(rtc.read(0));
        buf[3] = bcd2bin(rtc.read(0));
        rtc.read(0);
        buf[2] = bcd2bin(rtc.read(0));
        buf[1] = bcd2bin(rtc.read(0));
        buf[0] = bcd2bin(rtc.read(1));
        rtc.stop();
    }

    Da werden die Variablen doch in buf[] geschoben.
    Aber es gibt kein return oder so.
    Das versteh ich nicht, wieso die Daten dann in now sein sollen.

    Und wie Du sagtest mit charWert mit übergeben macht doch keinen Sinn oder?
    Ich will chartert ja garnicht haben. Den habe ich nur zum umrechnen.
    Die Funktion soll mir den Inhalt von charWert zurück geben damit ich sowas machen kann:
    Code: [Select]
    glcd.drawString(13, 44, lcdTime(year));
    char*year auf dem Display ausgeben, danach kann er den char wieder vergessen behalten will ich den int year zum rechnen.
    Also die Umwandlung in ein char ist wirklich immer nur für die Ausgabe danach egal.
    So denke ich mir das zumindest, aber es geht nicht.

Go Up