Sensor node does not send info after wake up

Hi guys,

Trying to put sensor node to sleep and after sleep period send Atmega 328p- PU internal temperature sensor data to master.

Slave code here:

#include <RF24.h>
#include <SPI.h>
#include <nRF24l01.h>
#include <printf.h>
#include <avr/io.h>
#include "LowPower.h"
#include <avr/wdt.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

volatile char sleepCnt = 0;
char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//==============

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRxAckPayload Starting");
    radio.begin();
    radio.setDataRate(RF24_2MBPS);
    radio.openReadingPipe(1, thisSlaveAddress);

    radio.enableAckPayload();
    
    radio.startListening();
}

//==========

void loop() {
  system_sleep();
  getData();
  showData();
}

//============

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        updateReplyData();
        newData = true;
    }
}

//================

void showData() {
    if (newData == true) {
        int temperatura = GetTemp();
        int ackData[1] = {temperatura};
        Serial.print("Data received ");
        Serial.println(dataReceived);
        Serial.print(" ackPayload sent ");
        Serial.println(ackData[0]);
        newData = false;
    }
}

//================

void updateReplyData() {
    int temperatura = GetTemp();
    int ackData[1] = {temperatura};
    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
}


double GetTemp(void)
{
  unsigned int wADC;
  double t;

  // The internal temperature has to be used
  // with the internal reference of 1.1V.
  // Channel 8 can not be selected with
  // the analogRead function yet.

  // Set the internal reference and mux.
  ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
  ADCSRA |= _BV(ADEN);  // enable the ADC

  delay(20);            // wait for voltages to become stable.

  ADCSRA |= _BV(ADSC);  // Start the ADC

  // Detect end-of-conversion
  while (bit_is_set(ADCSRA,ADSC));

  // Reading register "ADCW" takes care of how to read ADCL and ADCH.
  wADC = ADCW;

  // The offset of 324.31 could be wrong. It is just an indication.
  t = (wADC - 324.31 ) / 1.22;

  // The returned temperature is in degrees Celcius.
  return (t);
}


 void system_sleep(){
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
    Serial.println("I`m awake!");

 }

This code results like this:
results

It looks like that chip does not have enough time to do tasks after sleeping, any ideas how to modify the code to let the node do all wake routines(send data)?

Hello,

writeAckPayload is a blocking function so it should send the data then go to sleep.

Is it only the Serial prints that are not showing correctly? Try add Serial.flush(); at the end of loop()

This helped to see “I`m awake” every 8s.
res2

If I understand you correctly I swapped function positions in loop() like this:

void loop() {
getData();
showData();
system_sleep();
}

Tried all combinations, still only getting - “I`m awake”

The position of system_sleep isn’t important, I was just saying that your code should work because writeAckPayload will wait until all the data is sent, then the code would continue, then back to the beginning of loop where it would go to sleep.

The only thing I can think is if radio.available(), for some reason, always return 0 so your code is doing nothing. Try print the value of radio.available() just after I'm awake!

Without system_sleep() it sends chip internal temperature.

I changed on both sides (Slave and Master)
radio.setDataRate(RF24_2MBPS);

Now I get results:
res4
res5

Is my logic right to ping slaves frequently not to miss out their data after sleep?
Maybe there is another more logical way?

I have never used RF24 things, but I think the obvious reason why it doesn’t work is, when the arduino is sleeping, the RF24 library cannot work, so it can’t receive, so available() will always be 0 (unless the data came right after the arduino is awaken, but it’s very unlikely).

I believe there is an INT pin on the RF24 module, that can be used to trigger an interrupt and wake up the arduino, when data is received.

Edit: this video might help:

Node wakes up with the help of Watchdog timer,
As previous results shows node sleeps for 8s then wakes up and sends the data.

First problem was solved simply by increasing DataRate.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.