LowPowerLab Forum

Hardware support => Low Power Techniques => Topic started by: gcl8a on January 02, 2017, 10:26:59 AM

Title: Trouble coming out of powerDown() on arduino Mini 8mhz [SOLVED]
Post by: gcl8a on January 02, 2017, 10:26:59 AM
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:

Code: [Select]
void loop()
{
  uint8_t status = SendTemperatureRH();  //this calls RFM69::SendWithRetry();
  delay(8000);  //just to check that it all works
}

Sleeping the uC works fine:

Code: [Select]
void loop(void)
{   
  uint8_t status = SendTemperatureRH();
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}

Sleeping the wireless works just fine:

Code: [Select]
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.

Code: [Select]
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:

Code: [Select]
#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;
}