RFM12B - sending AND receiving

Hi all,

I’m trying to get node to receive data from another node, then report some other data back again.

I understand from the emonGLCD that this should be possible. The emonGLCD receives data from power nodes (and time from the hub), then transmits temperature back to the hub.

Have I understood correctly?



Basically, it sits in a loop waiting for a received signal (so it cannot sleep - bad news for battery operation) and then handles it. Clashes between listening and transmitting are avoided by never initiating a transmission of its own volition, but only immediately after receiving something, the assumption being there won’t be another transmission immediately following the one it’s responding to.

Thanks Robert. However I can’t see how this is implemented in the emonGLCD sketch. It appears that the send command appears simply further in the loop than the code that checks for received data. Can you explain?

void loop()
  if (rf12_recvDone())
    if (rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0)  // and no rf errors
      int node_id = (rf12_hdr & 0x1F);
      if (node_id == 9) {emontx = *(PayloadTX*) rf12_data; last_emontx = millis();}  //Assuming 10 is the emonTx NodeID
      if (node_id == 5)			//Assuming 15 is the emonBase node ID
        RTC.adjust(DateTime(2012, 1, 1, rf12_data[1], rf12_data[2], rf12_data[3]));
        last_emonbase = millis();
        Serial.println("Time Recieved");

  // Display update every 200ms
  if ((millis()-fast_update)>200)
    fast_update = millis();
    DateTime now = RTC.now();
    int last_hour = hour;
    hour = now.hour();
    minute = now.minute();

    usekwh += (emontx.power1 * 0.2) / 3600000;
    if (last_hour == 23 && hour == 00) usekwh = 0;                //reset Kwh/d counter at midnight
    cval_use = cval_use + (emontx.power1 - cval_use)*0.50;        //smooth transitions
    draw_power_page( "POWER" ,cval_use, "USE", usekwh);
    draw_temperature_time_footer(temp, mintemp, maxtemp, hour,minute);

    int LDR = analogRead(LDRpin);                     // Read the LDR Value so we can work out the light level in the room.
    int LDRbacklight = map(LDR, 0, 1023, 50, 250);    // Map the data from the LDR from 0-1023 (Max seen 1000) to var GLCDbrightness min/max
    LDRbacklight = constrain(LDRbacklight, 0, 255);   // Constrain the value to make sure its a PWM value 0-255
    if ((hour > 22) ||  (hour < 5)) glcd.backLight(0); else glcd.backLight(LDRbacklight);  
  if ((millis()-slow_update)>10000)
    slow_update = millis();

    temp = (sensors.getTempCByIndex(0));
    if (temp > maxtemp) maxtemp = temp;
    if (temp < mintemp) mintemp = temp;
    emonglcd.temperature = (int) (temp * 100);                          // set emonglcd payload
    rf12_sendNow(0, &emonglcd, sizeof emonglcd);                     //send temperature data via RFM12B using new rf12_sendNow wrapper -glynhudson


Chris - Are you looking for an explanation on the send code?

rf12_sendNow(0, &emonglcd, sizeof emonglcd);

or something else?

Having checked back, emonGLCD_SolarPV.ino works as I said - it transmits temperature having just received the time from the base; emonGLCD_HEM.ino and HomeEnergyMonitor.ino do as you say (i.e. not tied to having just received the time from the base) every 10 s on the ‘slow update’ branch of the loop.

Edited thread title - BT, Moderator