Update: The underlying cause appears to be power related. The symptoms below only show up when running on battery; when running on a steady DC power supply, the system works as expected. I'm guessing the voltage regulator is to blame, but I'll do some tests to see.
---
The entire code is below, but the gist of it is that my sensor node won't come out of sleep properly when I try to sleep both the uC and the wireless. Four cases are presented below.
Hardware is ATmega328 (running on 8MHz internal clock) + RFM69HCW ( + HIH-6130 humidity/temperature sensor on an I2C bus). To maximize battery life, I'm taking a reading every 8 seconds and trying to put everything to sleep in between, but I'm missing something obvious, I fear.
A naive, non-sleeping sketch works just fine:
void loop()
{
uint8_t status = SendTemperatureRH(); //this calls RFM69::SendWithRetry();
delay(8000); //just to check that it all works
}
Sleeping the uC works fine:
void loop(void)
{
uint8_t status = SendTemperatureRH();
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
Sleeping the wireless works just fine:
void loop(void)
{
uint8_t status = SendTemperatureRH();
radio.sleep();
delay(8000);
radio.receiveDone(); //not sure if I really have to call this or not
}
But sleeping everything does not. It will report the temperature and humidity one time and then never again.
void loop(void)
{
uint8_t status = SendTemperatureRH();
radio.sleep();
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
radio.receiveDone(); //not sure if I need this or not, but I've tried it with and without
}
I haven't put any LEDs or other means to debug, because I'm assuming I'm missing something obvious. If not, I'm happy to entertain ideas for things to check.
Full code here:
#include <Wire.h>
#include <RFM69.h>
#include <sensor.h>
#include <hvac_defines.h>
#include "LowPower.h"
#define NETWORKID 0 // Must be the same for all nodes (0 to 255)
#define MYNODEID OUTDOOR_WIRELESS // My node ID (0 to 255)
// RFM69 frequency:
#define FREQUENCY RF69_915MHZ
// AES encryption (or not):
#define ENCRYPT false // Set to "true" to use encryption
#define ENCRYPTKEY "TOPSECRETPASSWRD" // Use the same 16-byte key on all nodes
// Create a library object for our RFM69HCW module:
RFM69 radio;
void setup(void)
{
Wire.begin();
// Initialize the RFM69HCW:
radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
radio.setHighPower(); // Always use this for RFM69HCW
radio.setPowerLevel(0); //tone it down a bit...
// Turn on encryption if desired:
if (ENCRYPT)
radio.encrypt(ENCRYPTKEY);
}
void loop(void)
{
uint8_t status = SendTemperatureRH();
radio.sleep();
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
radio.receiveDone();
}
#define HIH6130_ADDRESS 0x27
uint8_t SendTemperatureRH(void)
{
Wire.beginTransmission(HIH6130_ADDRESS);
Wire.endTransmission();
delay(50); //it take 36 ms for the reading...should I idle?
Wire.requestFrom(HIH6130_ADDRESS, 4);
uint8_t hum_H = Wire.read();
uint8_t hum_L = Wire.read();
uint8_t temp_H = Wire.read();
uint8_t temp_L = Wire.read();
uint8_t status = (hum_H >> 6) & 0x03;
if(status) return status;
uint16_t hum16 = hum_H & 0x3f;
hum16 <<= 8;
hum16 += hum_L;
uint16_t temp16 = temp_H;
temp16 <<= 8;
temp16 += temp_L;
temp16 >>= 2;
float humidity = hum16 * 0.0061039;
SensorReading humiditySensor(OUTDOOR_HUM_SENSOR, humidity);
SendReading(humiditySensor);
float temperature = -40. + temp16 * 1.00714e-2;
SensorReading temperatureSensor(OUTDOOR_TEMP_SENSOR, temperature);
SendReading(temperatureSensor);
return(status);
}
int SendReading(const SensorReading& reading)
{
String sensorString = reading.TransferString();
char buffer[24];
sensorString.toCharArray(buffer, sizeof(buffer));
radio.sendWithRetry(MASTER_WIRELESS, buffer, strlen(buffer));
return 0;
}