Go Down

Topic: RFM69HW not sleeping as RFM69W do. (Read 2878 times) previous topic - next topic

pereskjo

Oct 16, 2016, 12:14 pm Last Edit: Oct 16, 2016, 04:11 pm by peres
My RFM69HW from ebay is great. But they dont sleep as well as my RFM69W do.
RFM69HW sleeps at 450uA.
RFM69W sleeps at 5.6uA.
Im running on Arduino pro mini. Anybody else have this issue?
I believe this problem is the same for the mysensors.org also. Help is greatly appreciated.





Im using RFM69.h library from LowPowerLab. with modified example from https://learn.sparkfun.com/tutorials/rfm69hcw-hookup-guide.

here is my example sender code who sleeps for 5 seconds.
I use radio.sleep(); to put RFM69 in low power sleep mode, but the RFM69HW uses way to much current. I suspect there is som hardware issue with RFM69HW, as my RFM69W works fine.
Code: [Select]
// RFM69HW tested to 500m with coil antenna.
// RFM69HCW Example Sketch
// Send serial input characters from one RFM69 node to another
// Based on RFM69 library sample code by Felix Rusu
// http://LowPowerLab.com/contact
// Modified for RFM69HCW by Mike Grusin, 4/16

// This sketch will show you the basics of using an
// RFM69HCW radio module. SparkFun's part numbers are:
// 915MHz: https://www.sparkfun.com/products/12775
// 434MHz: https://www.sparkfun.com/products/12823

// See the hook-up guide for wiring instructions:
// https://learn.sparkfun.com/tutorials/rfm69hcw-hookup-guide

// Uses the RFM69 library by Felix Rusu, LowPowerLab.com
// Original library: https://www.github.com/lowpowerlab/rfm69
// SparkFun repository: https://github.com/sparkfun/RFM69HCW_Breakout

// Include the RFM69 and SPI libraries:
#include <RFM69.h>
#include <SPI.h>
#include <LowPower.h> //get library from: https://github.com/LowPowerLab/LowPower
//#include <JeeLib.h>  // Include library containing low power functions https://github.com/jcw/jeelib
//ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup for low power waiting

// Addresses for this node. CHANGE THESE FOR EACH NODE!
#define NETWORKID     0   // Must be the same for all nodes
#define MYNODEID      2   // My node ID
#define TONODEID      1   // Destination node ID

// RFM69 frequency, uncomment the frequency of your module:

#define FREQUENCY   RF69_433MHZ
//#define FREQUENCY     RF69_915MHZ

// AES encryption (or not):

#define ENCRYPT       true // Set to "true" to use encryption
#define ENCRYPTKEY    "TOPSECRETPASSWRD" // Use the same 16-byte key on all nodes

// Use ACKnowledge when sending messages (or not):

#define USEACK        true // Request ACKs or not

// Packet sent/received indicator LED (optional):

#define LED           13 // LED positive pin
#define GND           8 // LED ground pin

// Create a library object for our RFM69HCW module:

RFM69 radio;

void setup()
{
  Serial.begin(9600);
  Serial.print("Sparkfun RFM69 network node demosender");
  Serial.print("Node ");
  Serial.print(MYNODEID,DEC);
  Serial.println(" ready"); 

  // Set up the indicator LED (optional):
 
  pinMode(LED,OUTPUT);
  digitalWrite(LED,LOW);
  pinMode(GND,OUTPUT);
  digitalWrite(GND,LOW);

  // Initialize the RFM69HCW:
 
  radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
  radio.setHighPower(); // Always use this for RFM69HCW
  //radio.setPowerLevel(14); //i stedet for setHighPower for H model kan denne justeres 14-20.

  // Turn on encryption if desired:
 
  if (ENCRYPT)
    radio.encrypt(ENCRYPTKEY);
}

void loop()
{
  // Set up a "buffer" for characters that we'll send:
  static char sendbuffer[] = "Hello Sparkfun!";
 
  // SENDING
      Serial.print("sending to node ");
      Serial.print(TONODEID, DEC);
      Serial.print(", message ");
      Serial.println((char*)sendbuffer);

      // There are two ways to send packets. If you want
      // acknowledgements, use sendWithRetry():
      if (USEACK)
      {
        if (radio.sendWithRetry(TONODEID, sendbuffer, sizeof(sendbuffer)))
          Serial.println("ACK received!");
        else
          Serial.println("no ACK received");
      }

      // If you don't need acknowledgements, just use send():
      else // don't use ACK
      {
        radio.send(TONODEID, sendbuffer, sizeof(sendbuffer));
      }

   
      Blink(LED,10);
     
      Serial.flush();
      radio.sleep(); //you can comment out this line if you want this node to listen for wireless programming requests
      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
      //Sleepy::loseSomeTime(5000); //JeeLib. Instead of delay(5000);

} //end main loop


void Blink(byte PIN, int DELAY_MS)
// Blink an LED for a given number of ms
{
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}

brice3010

Very interesting project. I started looking into Lora projects and found your message. Did you get this solved?

pereskjo

#2
Jun 07, 2017, 04:32 pm Last Edit: Jun 07, 2017, 04:48 pm by pereskjo
Very interesting project. I started looking into Lora projects and found your message. Did you get this solved?

No, I have not sorted this out yet. If you or anybody else know about a solution to this, plese give a note here.

MarkT

#3
Jun 07, 2017, 10:51 pm Last Edit: Jun 07, 2017, 10:52 pm by MarkT
Perhaps the extra PA stage bias circuitry is to blame - the HW version has extra PA stage.  Most likely
to be the difference between the two.

Actually read up that section there is stuff about registers that set current level for the PA I think
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

pereskjo

Perhaps the extra PA stage bias circuitry is to blame - the HW version has extra PA stage.  Most likely
to be the difference between the two.

Actually read up that section there is stuff about registers that set current level for the PA I think
Yes, as the datashet says sleep current between 0.1 and 1 micro Amp.
I suspect something not turned off in radio.sleep().
As you mention, I see there are some registers about sleep, but at the moment I'm not educated enough to test them, but I will look into it.

pereskjo

#5
Jun 09, 2017, 05:25 pm Last Edit: Jun 09, 2017, 06:01 pm by pereskjo
For the record, here is part 1/2 of my test setup:
Arduino pro mini v2 with low power setup here.
RFM69W and RMF69HW datasheet
MySensors 2.1.1 library here.

GatewaySerial RFM69 example:
Code: [Select]
/*
Mysensors 2.0 RFM69 start help
Serial Gateway.
Set defines for RFM69. se også MyConfig.h.
#define MY_RADIO_RFM69
#define MY_RFM69_FREQUENCY   RF69_433MHZ //set your frequency
#define MY_IS_RFM69HW //only for high power version
comment MY_RADIO_NRF24 og RF24_PA_LEVEL
test gateway with Myscontroller 1.0 https://forum.mysensors.org/topic/838/windows-gui-controller-for-mysensors

* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* DESCRIPTION
* The ArduinoGateway prints data received from sensors on the serial link.
* The gateway accepts input on seral which will be sent out on radio network.
*
* The GW code is designed for Arduino Nano 328p / 16MHz
*
* Wire connections (OPTIONAL):
* - Inclusion button should be connected between digital pin 3 and GND
* - RX/TX/ERR leds need to be connected between +5V (anode) and digital pin 6/5/4 with resistor 270-330R in a series
*
* LEDs (OPTIONAL):
* - To use the feature, uncomment any of the MY_DEFAULT_xx_LED_PINs
* - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
* - ERR (red) - fast blink on error during transmission error or recieve crc error
*
*/

// Enable debug prints to serial monitor
//#define MY_DEBUG

// Enable and select radio type attached
//#define MY_RADIO_NRF24
#define MY_RADIO_RFM69
#define MY_RFM69_FREQUENCY   RF69_433MHZ  //set your frequency
//#define MY_IS_RFM69HW  //only for high power version

// Set LOW transmit power level as default, if you have an amplified NRF-module and
// power your radio separately with a good regulator you can turn up PA level.
//#define MY_RF24_PA_LEVEL RF24_PA_LOW

// Enable serial gateway
#define MY_GATEWAY_SERIAL

// Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
#if F_CPU == 8000000L
#define MY_BAUD_RATE 38400
#endif

// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
//#define MY_INCLUSION_BUTTON_FEATURE

// Inverses behavior of inclusion button (if using external pullup)
//#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP

// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN  3

// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300

// Inverses the behavior of leds
//#define MY_WITH_LEDS_BLINKING_INVERSE

// Flash leds on rx/tx/err
// Uncomment to override default HW configurations
//#define MY_DEFAULT_ERR_LED_PIN 4  // Error led pin
//#define MY_DEFAULT_RX_LED_PIN  6  // Receive led pin
//#define MY_DEFAULT_TX_LED_PIN  5  // the PCB, on board LED

#include <MySensors.h>

void setup()
{
 // Setup locally attached sensors
}

void presentation()
{
 // Present locally attached sensors
}

void loop()
{
 // Send locally attached sensor data here
}

Sensor example is in next post

pereskjo

#6
Jun 09, 2017, 05:36 pm Last Edit: Jun 11, 2017, 12:15 pm by pereskjo
Part 2/2 of my setup.
SoilMoistSensor RFM69HW example:
Code: [Select]
/*
Mysensors 2.0 RFM69 start help
Sensor.
Set defines for RFM69. more info in MyConfig.h.
#define MY_RADIO_RFM69
#define MY_RFM69_FREQUENCY   RF69_433MHZ
#define MY_IS_RFM69HW //only for high power version
comment MY_RADIO_NRF24 og RF24_PA_LEVEL

 * The MySensors Arduino library handles the wireless radio link and protocol
 * between your home built sensors/actuators and HA controller of choice.
 * The sensors forms a self healing radio network with optional repeaters. Each
 * repeater and gateway builds a routing tables in EEPROM which keeps track of the
 * network topology allowing messages to be routed to nodes.
 *
 * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
 * Copyright (C) 2013-2015 Sensnology AB
 * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
 *
 * Documentation: http://www.mysensors.org
 * Support Forum: http://forum.mysensors.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 *******************************
 *
 * DESCRIPTION
 *
 * Arduino soil moisture based on gypsum sensor/resistive sensor to avoid electric catalyse in soil
 *  Required to interface the sensor: 2 * 4.7kOhm + 2 * 1N4148
 *
 * Gypsum sensor and calibration:
 * DIY: See http://vanderleevineyard.com/1/category/vinduino/1.html
 * Built: Davis / Watermark 200SS
 * http://www.cooking-hacks.com/watermark-soil-moisture-sensor?_bksrc=item2item&_bkloc=product
 * http://www.irrometer.com/pdf/supportmaterial/sensors/voltage-WM-chart.pdf
 * cb (centibar) http://www.irrometer.com/basics.html
 * 0-10 Saturated Soil. Occurs for a day or two after irrigation
 * 10-20 Soil is adequately wet (except coarse sands which are drying out at this range)
 * 30-60 Usual range to irrigate or water (except heavy clay soils).
 * 60-100 Usual range to irrigate heavy clay soils
 * 100-200 Soil is becoming dangerously dry for maximum production. Proceed with caution.
 *
 * Connection:
 *  D6, D7: alternative powering to avoid sensor degradation
 * A0, A1: alternative resistance mesuring
 *
 *  Based on:
 *  "Vinduino" portable soil moisture sensor code V3.00
 *   Date December 31, 2012
 *   Reinier van der Lee and Theodore Kaskalis
 *   www.vanderleevineyard.com
 * Contributor: epierre
 */

// Copyright (C) 2015, Reinier van der Lee
// www.vanderleevineyard.com

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Enable debug prints to serial monitor
//#define MY_DEBUG

// Enable and select radio type attached
//#define MY_RADIO_NRF24
#define MY_RADIO_RFM69
#define MY_RFM69_FREQUENCY   RF69_433MHZ
//#define MY_IS_RFM69HW //only for high power version

#include <math.h>       // Conversion equation from resistance to %
#include <MySensors.h>

// Setting up format for reading 3 soil sensors
#define NUM_READS 10    // Number of sensor reads for filtering
#define CHILD_ID 0

MyMessage msg(CHILD_ID, V_LEVEL);
unsigned long SLEEP_TIME = 10000; // Sleep time between reads (in milliseconds)

long buffer[NUM_READS];
int index;

/// @brief Structure to be used in percentage and resistance values matrix to be filtered (have to be in pairs)
typedef struct {
 int moisture; //!< Moisture
 long resistance; //!< Resistance
} values;

const long knownResistor = 4700;  // Constant value of known resistor in Ohms

int supplyVoltage;                // Measured supply voltage
int sensorVoltage;                // Measured sensor voltage

values valueOf[NUM_READS];        // Calculated moisture percentages and resistances to be sorted and filtered

int i;                            // Simple index variable

void setup()
{
 // initialize the digital pins as an output.
 // Pin 6,7 is for sensor 1
 // initialize the digital pin as an output.
 // Pin 6 is sense resistor voltage supply 1
 pinMode(6, OUTPUT);

 // initialize the digital pin as an output.
 // Pin 7 is sense resistor voltage supply 2
 pinMode(7, OUTPUT);
}

void presentation()
{
 sendSketchInfo("Soil Moisture Sensor Reverse Polarity", "1.0");
 present(CHILD_ID, S_MOISTURE);
}

void loop()
{

 measure(6,7,1);
 Serial.print ("\t");
 Serial.println (average());
 long read1 = average();

 measure(7,6,0);
 Serial.print ("\t");
 Serial.println (average());
 long read2= average();

 long sensor1 = (read1 + read2)/2;

 Serial.print ("resistance bias =" );
 Serial.println (read1-read2);
 Serial.print ("sensor bias compensated value = ");
 Serial.println (sensor1);
 Serial.println ();

 //send back the values
 send(msg.set((long int)ceil(sensor1)));
 // delay until next measurement (msec)
 sleep(SLEEP_TIME);
}

void measure (int phase_b, int phase_a, int analog_input)
{
 // read sensor, filter, and calculate resistance value
 // Noise filter: median filter

 for (i=0; i<NUM_READS; i++) {

 // Read 1 pair of voltage values
 digitalWrite(phase_a, HIGH);                 // set the voltage supply on
 delayMicroseconds(25);
 supplyVoltage = analogRead(analog_input);   // read the supply voltage
 delayMicroseconds(25);
 digitalWrite(phase_a, LOW);                  // set the voltage supply off
 delay(1);

 digitalWrite(phase_b, HIGH);                 // set the voltage supply on
 delayMicroseconds(25);
 sensorVoltage = analogRead(analog_input);   // read the sensor voltage
 delayMicroseconds(25);
 digitalWrite(phase_b, LOW);                  // set the voltage supply off

 // Calculate resistance
 // the 0.5 add-term is used to round to the nearest integer
 // Tip: no need to transform 0-1023 voltage value to 0-5 range, due to following fraction
 long resistance = (knownResistor * (supplyVoltage - sensorVoltage ) / sensorVoltage) ;

 delay(1);
 addReading(resistance);
 Serial.print (resistance);
 Serial.print ("\t");
 }
}



// Averaging algorithm
void addReading(long resistance)
{
 buffer[index] = resistance;
 index++;
 if (index >= NUM_READS) {
 index = 0;
 }
}

long average()
{
 long sum = 0;
 for (int i = 0; i < NUM_READS; i++) {
 sum += buffer[i];
 }
 return (long)(sum / NUM_READS);
}

Latest sleep current readings:
RFM69HW = 420micro Amp.
RFM69W = 5.2micro Amp.


Myscontroller 1.0.0beta readings:


For now I will stick to RFM69W for battery operation, and RFM69HW on the gateway and repeaters.

pereskjo

#7
Sep 17, 2017, 06:21 pm Last Edit: Sep 17, 2017, 06:30 pm by pereskjo
Finally got RFM69H to sleep!  :)
By removing the power regulator on Arduino pro mini, i got 6uA.
So now I'm removing power regulator + power led resistor + LED13 resistor on my nodes.

By the way, this only works on my example in the first post(RFM69.h by LowPowerLab).
The MySensors example, still has to high current. But that is ok, I can use LowPowerLab.

Extra sidenote: the original LowPowerLab example 'DeepSleep_usingLowPowerLibrary' do not work out of the box.
To get RFM69H to sleep, I had to add radio.initialize(FREQUENCY, MYNODEID, NETWORKID);, just above radio.sleep. The example now looks like this:
Code: [Select]
//***********************************************************************************************************
// Sample sketch that achieves the lowest power on a Moteino of ~6.5uA
// Everything is put to sleep including the MCU, the radio (if any) and the FlashMem chip
// Addded radio.initialize(FREQUENCY, MYNODEID, NETWORKID); to get 6.5uA. By Per.
//**** SETTINGS *********************************************************************************************
#define WITH_RFM69              //comment this line out if you don't have a RFM69 on your Moteino
//#define WITH_SPIFLASH           //comment this line out if you don't have the FLASH-MEM chip on your Moteino
//***********************************************************************************************************

// Addresses for this node. CHANGE THESE FOR EACH NODE!
#define NETWORKID     0   // Must be the same for all nodes
#define MYNODEID      2   // My node ID
#define TONODEID      1   // Destination node ID
// RFM69 frequency, uncomment the frequency of your module:
#define FREQUENCY   RF69_433MHZ
//#define FREQUENCY     RF69_915MHZ

#include <LowPower.h> //get library from: https://github.com/lowpowerlab/lowpower
                      //writeup here: http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/

#ifdef __AVR_ATmega1284P__
  #define LED           15 // Moteino MEGAs have LEDs on D15
  #define FLASH_SS      23 // and FLASH SS on D23
#else
  #define LED           9 // Moteinos have LEDs on D9
  #define FLASH_SS      8 // and FLASH SS on D8
#endif

#if defined(WITH_RFM69) || defined(WITH_SPIFLASH)
  #include <SPI.h>                //comes with Arduino IDE (www.arduino.cc)
  #if defined(WITH_RFM69)
    #include <RFM69.h>            //get it here: https://www.github.com/lowpowerlab/rfm69
    RFM69 radio;
  #endif
  #if defined(WITH_SPIFLASH)
    #include <SPIFlash.h>         //get it here: https://www.github.com/lowpowerlab/spiflash
    SPIFlash flash(FLASH_SS, 0xEF30); //EF30 for 4mbit  Windbond chip (W25X40CL)
  #endif
#endif


void setup () {
#ifdef WITH_RFM69
  radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
  radio.sleep();
#endif

#ifdef WITH_SPIFLASH
  if (flash.initialize())
    flash.sleep();
#endif

  for (uint8_t i=0; i<=A5; i++)
  {
#ifdef WITH_RFM69
    if (i == RF69_SPI_CS) continue;
#endif
#ifdef WITH_SPIFLASH
    if (i == FLASH_SS) continue;
#endif
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }
}

void loop ()
{
  //optional blink to know radio/flash sleeping went OK
  pinMode(LED, OUTPUT);
  digitalWrite(LED, HIGH);
  delay(30);
  digitalWrite(LED, LOW);

  
  //sleep MCU for 8seconds
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}

brice3010

Finally got RFM69H to sleep!  :)

(...)

By the way, this only works on my example in the first post(RFM69.h by LowPowerLab).
The MySensors example, still has to high current. But that is ok, I can use LowPowerLab.

Extra sidenote: the original LowPowerLab example 'DeepSleep_usingLowPowerLibrary' do not work out of the box.
To get RFM69H to sleep, I had to add radio.initialize(FREQUENCY, MYNODEID, NETWORKID);, just above radio.sleep.

(...)
+1 karma for your persistence and results.

Can you give a link to the LowPowerLibrary please?
Can you show the modification you made to the LowPowerLab example 'DeepSleep using LowPowerLibrary" please?

pereskjo

Sure Brice3010,
link to LowPowerLab library: https://github.com/LowPowerLab/RFM69.
Complete modified code for LowPowerLab example 'DeepSleep using LowPowerLibrary" is shown in post#7.
added radio.initialize(FREQUENCY, MYNODEID, NETWORKID); in setup() function.

original:
Code: [Select]
void setup () {
#ifdef WITH_RFM69
  radio.sleep();
#endif

modified:
Code: [Select]
void setup () {
#ifdef WITH_RFM69
  radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
  radio.sleep();
#endif


radio.initialize need three defines:
Code: [Select]
// Addresses for this node. CHANGE THESE FOR EACH NODE!
#define NETWORKID     0   // Must be the same for all nodes
#define MYNODEID      2   // My node ID
#define TONODEID      1   // Destination node ID



Go Up