Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Troubleshooting
  3. Sensor NRF24L01+ sleep current

Sensor NRF24L01+ sleep current

Scheduled Pinned Locked Moved Troubleshooting
16 Posts 5 Posters 7.9k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F flopp

    Hi I just finished my first MySensor setup.
    Everything is working but the uA(micro) for the NRF24L01+ is confusing me.

    I am using a Arduino Nano ATmega328(clone), removed LED and power regulator.

    Maybe to much information: I wake Arduino after 60 seconds and send the data to my Serial gateway. For controller I am using Domoticz.

    I have a BMP180 sensor for pressure and temperature.

    When my arduino is going to sleep it consume ~75uA when I remove 3.3V for the NRF it goes down to ~15uA.

    1. Shouldn't the NRF draw ~0,900 uA when sleeping?
    2. Is there any way to change the sleep mode for NRF? How?

    Any comment is welcome, if you found other error in my code.

    /**
     * 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.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     * 
     * DESCRIPTION
     * Pressure sensor example using BMP085 module  
     * http://www.mysensors.org/build/pressure
     *
     */
     
    #include <SPI.h>
    #include <MySensor.h>  
    #include <Wire.h>
    #include <Adafruit_BMP085.h>
    
    #define BARO_CHILD 0
    #define TEMP_CHILD 1
    #define BATT_CHILD 2
    
    const float ALTITUDE = 8; // <-- adapt this value to your own location's altitude.
    
    // Sleep time between reads (in seconds). Do not change this value as the forecast algorithm needs a sample every minute.
    const unsigned long SLEEP_TIME = 60000; 
    
    const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
    enum FORECAST
    {
    	STABLE = 0,			// "Stable Weather Pattern"
    	SUNNY = 1,			// "Slowly rising Good Weather", "Clear/Sunny "
    	CLOUDY = 2,			// "Slowly falling L-Pressure ", "Cloudy/Rain "
    	UNSTABLE = 3,		// "Quickly rising H-Press",     "Not Stable"
    	THUNDERSTORM = 4,	// "Quickly falling L-Press",    "Thunderstorm"
    	UNKNOWN = 5			// "Unknown (More Time needed)
    };
    
    Adafruit_BMP085 bmp = Adafruit_BMP085();      // Digital Pressure Sensor 
    
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    int oldBatteryPcnt = 0;
    
    MySensor gw;
    
    float lastPressure = -1;
    float lastTemp = -1;
    int lastForecast = -1;
    
    const int LAST_SAMPLES_COUNT = 5;
    float lastPressureSamples[LAST_SAMPLES_COUNT];
    
    // this CONVERSION_FACTOR is used to convert from Pa to kPa in forecast algorithm
    // get kPa/h be dividing hPa by 10 
    #define CONVERSION_FACTOR (1.0/10.0)
    
    int minuteCount = 0;
    bool firstRound = true;
    // average value is used in forecast algorithm.
    float pressureAvg;
    // average after 2 hours is used as reference value for the next iteration.
    float pressureAvg2;
    
    float dP_dt;
    boolean metric;
    MyMessage tempMsg(TEMP_CHILD, V_TEMP);
    MyMessage pressureMsg(BARO_CHILD, V_PRESSURE);
    MyMessage forecastMsg(BARO_CHILD, V_FORECAST);
    MyMessage battMsg(BATT_CHILD, V_VOLTAGE);
    
    void setup() 
    {
         // use the 1.1 V internal reference
    #if defined(__AVR_ATmega2560__)
       analogReference(INTERNAL1V1);
    #else
       analogReference(INTERNAL);
    #endif
    
    	gw.begin();
    
    	// Send the sketch version information to the gateway and Controller
    	gw.sendSketchInfo("Pressure Sensor", "1.1");
    
    	if (!bmp.begin()) 
    	{
    		Serial.println("Could not find a valid BMP085 sensor, check wiring!");
    		while (1) {}
    	}
    
    	// Register sensors to gw (they will be created as child devices)
    	gw.present(BARO_CHILD, S_BARO);
    	gw.present(TEMP_CHILD, S_TEMP);
      gw.present(BATT_CHILD, S_MULTIMETER);
    	metric = gw.getConfig().isMetric;
    }
    
    void loop() 
    {
       // get the battery Voltage
       int sensorValue = analogRead(BATTERY_SENSE_PIN);
       #ifdef DEBUG
       Serial.println(sensorValue);
       #endif
       
       // 1M, 470K divider across battery and using internal ADC ref of 1.1V
       // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
       // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
       // 3.44/1023 = Volts per bit = 0.003363075
       float batteryV  = sensorValue * 0.003363075;
       int batteryPcnt = sensorValue / 10;
    
       #ifdef DEBUG
       Serial.print("Battery Voltage: ");
       Serial.print(batteryV);
       Serial.println(" V");
    
       Serial.print("Battery percent: ");
       Serial.print(batteryPcnt);
       Serial.println(" %");
       #endif
      
    	float pressure = bmp.readSealevelPressure(ALTITUDE) / 100.0;
    	float temperature = bmp.readTemperature();
    
    	if (!metric) 
    	{
    		// Convert to fahrenheit
    		temperature = temperature * 9.0 / 5.0 + 32.0;
    	}
    
    	int forecast = sample(pressure);
    
    	Serial.print("Temperature = ");
    	Serial.print(temperature);
    	Serial.println(metric ? " *C" : " *F");
    	Serial.print("Pressure = ");
    	Serial.print(pressure);
    	Serial.println(" hPa");
    	Serial.print("Forecast = ");
    	Serial.println(weather[forecast]);
    
    
    	if (temperature != lastTemp) 
    	{
    		gw.send(tempMsg.set(temperature, 1));
    		lastTemp = temperature;
    	}
    
    	if (pressure != lastPressure) 
    	{
    		gw.send(pressureMsg.set(pressure, 1));
    		lastPressure = pressure;
    	}
    
    	if (forecast != lastForecast)
    	{
    		gw.send(forecastMsg.set(weather[forecast]));
    		lastForecast = forecast;
    	}
      //if (oldBatteryPcnt != batteryPcnt) {
       // Power up radio after sleep
       //gw.sendBatteryLevel(batteryPcnt);
       gw.send(battMsg.set(batteryV, 3));
       oldBatteryPcnt = batteryPcnt;
      //}
    	gw.sleep(SLEEP_TIME);
    }
    
    float getLastPressureSamplesAverage()
    {
    	float lastPressureSamplesAverage = 0;
    	for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
    	{
    		lastPressureSamplesAverage += lastPressureSamples[i];
    	}
    	lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
    
    	return lastPressureSamplesAverage;
    }
    
    
    
    // Algorithm found here
    // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
    // Pressure in hPa -->  forecast done by calculating kPa/h
    int sample(float pressure)
    {
    	// Calculate the average of the last n minutes.
    	int index = minuteCount % LAST_SAMPLES_COUNT;
    	lastPressureSamples[index] = pressure;
    
    	minuteCount++;
    	if (minuteCount > 185)
    	{
    		minuteCount = 6;
    	}
    
    	if (minuteCount == 5)
    	{
    		pressureAvg = getLastPressureSamplesAverage();
    	}
    	else if (minuteCount == 35)
    	{
    		float lastPressureAvg = getLastPressureSamplesAverage();
    		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    		if (firstRound) // first time initial 3 hour
    		{
    			dP_dt = change * 2; // note this is for t = 0.5hour
    		}
    		else
    		{
    			dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
    		}
    	}
    	else if (minuteCount == 65)
    	{
    		float lastPressureAvg = getLastPressureSamplesAverage();
    		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    		if (firstRound) //first time initial 3 hour
    		{
    			dP_dt = change; //note this is for t = 1 hour
    		}
    		else
    		{
    			dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
    		}
    	}
    	else if (minuteCount == 95)
    	{
    		float lastPressureAvg = getLastPressureSamplesAverage();
    		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    		if (firstRound) // first time initial 3 hour
    		{
    			dP_dt = change / 1.5; // note this is for t = 1.5 hour
    		}
    		else
    		{
    			dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
    		}
    	}
    	else if (minuteCount == 125)
    	{
    		float lastPressureAvg = getLastPressureSamplesAverage();
    		pressureAvg2 = lastPressureAvg; // store for later use.
    		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    		if (firstRound) // first time initial 3 hour
    		{
    			dP_dt = change / 2; // note this is for t = 2 hour
    		}
    		else
    		{
    			dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
    		}
    	}
    	else if (minuteCount == 155)
    	{
    		float lastPressureAvg = getLastPressureSamplesAverage();
    		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    		if (firstRound) // first time initial 3 hour
    		{
    			dP_dt = change / 2.5; // note this is for t = 2.5 hour
    		}
    		else
    		{
    			dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
    		}
    	}
    	else if (minuteCount == 185)
    	{
    		float lastPressureAvg = getLastPressureSamplesAverage();
    		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    		if (firstRound) // first time initial 3 hour
    		{
    			dP_dt = change / 3; // note this is for t = 3 hour
    		}
    		else
    		{
    			dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
    		}
    		pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
    		firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
    	}
    
    	int forecast = UNKNOWN;
    	if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval.
    	{
    		forecast = UNKNOWN;
    	}
    	else if (dP_dt < (-0.25))
    	{
    		forecast = THUNDERSTORM;
    	}
    	else if (dP_dt > 0.25)
    	{
    		forecast = UNSTABLE;
    	}
    	else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
    	{
    		forecast = CLOUDY;
    	}
    	else if ((dP_dt > 0.05) && (dP_dt < 0.25))
    	{
    		forecast = SUNNY;
    	}
    	else if ((dP_dt >(-0.05)) && (dP_dt < 0.05))
    	{
    		forecast = STABLE;
    	}
    	else
    	{
    		forecast = UNKNOWN;
    	}
    
    	// uncomment when debugging
    	//Serial.print(F("Forecast at minute "));
    	//Serial.print(minuteCount);
    	//Serial.print(F(" dP/dt = "));
    	//Serial.print(dP_dt);
    	//Serial.print(F("kPa/h --> "));
    	//Serial.println(weather[forecast]);
    
    	return forecast;
    }```
    YveauxY Offline
    YveauxY Offline
    Yveaux
    Mod
    wrote on last edited by
    #2

    @flopp How do you measure the small sleep currents?

    http://yveaux.blogspot.nl

    F 1 Reply Last reply
    0
    • YveauxY Yveaux

      @flopp How do you measure the small sleep currents?

      F Offline
      F Offline
      flopp
      wrote on last edited by
      #3

      @Yveaux
      With a multimeter

      1 Reply Last reply
      0
      • bjacobseB Offline
        bjacobseB Offline
        bjacobse
        wrote on last edited by
        #4

        True the NRF24L01+ shall use 900nA (0,9uA) in power down mode according to the spec.

        What do you mean when stating "when I remove 3.3V for the NRF it goes down to ~15uA." - is the NRF still connected with data pins to the arduino? (I hope that NO arduino pins are providing HIGH output, while there is no power to the NRF, since this will kill the NRF24L01+

        I understand that you are using a "good Quality" multimeter? else you can't trust your measured values.
        and the gw.sleep(SLEEP_TIME) should sleep both Arduino + NRF24L01+

        F 1 Reply Last reply
        0
        • tbowmoT Offline
          tbowmoT Offline
          tbowmo
          Admin
          wrote on last edited by tbowmo
          #5

          @flopp

          It could also be fake NRF chips, it's seen before.

          Also see this thread http://forum.mysensors.org/topic/1815/low-power-how-much-current-solved

          And perhaps this http://forum.mysensors.org/topic/1153/we-are-mostly-using-fake-nrf24l01-s-but-worse-fakes-are-emerging

          F 1 Reply Last reply
          0
          • bjacobseB bjacobse

            True the NRF24L01+ shall use 900nA (0,9uA) in power down mode according to the spec.

            What do you mean when stating "when I remove 3.3V for the NRF it goes down to ~15uA." - is the NRF still connected with data pins to the arduino? (I hope that NO arduino pins are providing HIGH output, while there is no power to the NRF, since this will kill the NRF24L01+

            I understand that you are using a "good Quality" multimeter? else you can't trust your measured values.
            and the gw.sleep(SLEEP_TIME) should sleep both Arduino + NRF24L01+

            F Offline
            F Offline
            flopp
            wrote on last edited by flopp
            #6

            @bjacobse said:

            What do you mean when stating "when I remove 3.3V for the NRF it goes down to ~15uA." - is the NRF still connected with data pins to the arduino? (I hope that NO arduino pins are providing HIGH output, while there is no power to the NRF, since this will kill the NRF24L01+

            While arduino and NRF is in sleep I was measuring ~75 uA I disconnected the positive power cable for NRF and uA droped down to 15uA, BMP180 and stepdown was still connected.

            I understand that you are using a "good Quality" multimeter? else you can't trust your measured values.
            and the gw.sleep(SLEEP_TIME) should sleep both Arduino + NRF24L01+

            I am using a Fluke 87V, not calibrated for a couple of years but I trust it within 5% that's ok for me at the moment
            OK, that's perfect, then I don't have to think about sleep modes

            1 Reply Last reply
            0
            • tbowmoT tbowmo

              @flopp

              It could also be fake NRF chips, it's seen before.

              Also see this thread http://forum.mysensors.org/topic/1815/low-power-how-much-current-solved

              And perhaps this http://forum.mysensors.org/topic/1153/we-are-mostly-using-fake-nrf24l01-s-but-worse-fakes-are-emerging

              F Offline
              F Offline
              flopp
              wrote on last edited by
              #7

              @tbowmo

              I have ordered 10 pcs NRF, lets see if they can go down lower then ~60uA when sleeping

              Today I only have 2 NRF :grin:

              bjacobseB 1 Reply Last reply
              0
              • F flopp

                @tbowmo

                I have ordered 10 pcs NRF, lets see if they can go down lower then ~60uA when sleeping

                Today I only have 2 NRF :grin:

                bjacobseB Offline
                bjacobseB Offline
                bjacobse
                wrote on last edited by
                #8

                @flopp
                Yes replace NRFL2401+ with another NRF24L01+ to see if this make the current draw smaller - I think you can trust your Fluke 87V :-)

                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  flopp
                  wrote on last edited by
                  #9

                  I change the NRF for sensor and now I measure 0,04mA(41,8uA) with all equipment connected

                  I am happy

                  1 Reply Last reply
                  1
                  • F Offline
                    F Offline
                    flopp
                    wrote on last edited by
                    #10

                    I tried, before I changed NRF, to have use a digital output to feed my NRF.

                    i put

                    digitalWrite(4,HIGH);
                    

                    at first row in SETUP

                    I also put

                    digitalWrite(4,LOW);
                    

                    just before it go to sleep

                    but I then got "radio init fail", is it even possible to to it this way or can I have this type of function anywhere else in the code/file,?

                    AWIA 1 Reply Last reply
                    0
                    • F flopp

                      I tried, before I changed NRF, to have use a digital output to feed my NRF.

                      i put

                      digitalWrite(4,HIGH);
                      

                      at first row in SETUP

                      I also put

                      digitalWrite(4,LOW);
                      

                      just before it go to sleep

                      but I then got "radio init fail", is it even possible to to it this way or can I have this type of function anywhere else in the code/file,?

                      AWIA Offline
                      AWIA Offline
                      AWI
                      Hero Member
                      wrote on last edited by
                      #11

                      @flopp When you power down the nRF you need to reinitialize it. But I doubt if it is worth the trouble as the radio consumes only a fraction of the total while sleeping.
                      Try making a node which powers up on interrupt only. The total consumption will go down to a little more than 1uA.

                      F 1 Reply Last reply
                      0
                      • AWIA AWI

                        @flopp When you power down the nRF you need to reinitialize it. But I doubt if it is worth the trouble as the radio consumes only a fraction of the total while sleeping.
                        Try making a node which powers up on interrupt only. The total consumption will go down to a little more than 1uA.

                        F Offline
                        F Offline
                        flopp
                        wrote on last edited by flopp
                        #12

                        @AWI said:

                        @flopp When you power down the nRF you need to reinitialize it. But I doubt if it is worth the trouble as the radio consumes only a fraction of the total while sleeping.
                        Try making a node which powers up on interrupt only. The total consumption will go down to a little more than 1uA.

                        It is a sensor(node?) that measures temp and pressure. Is it possible to have interrupt?
                        today I use timer, 60 seconds.
                        I also use a clone NRF(maybe) because firt one i tried did use much more than 1uA, more something like 60uA

                        1 Reply Last reply
                        0
                        • bjacobseB Offline
                          bjacobseB Offline
                          bjacobse
                          wrote on last edited by
                          #13

                          The timer can be set as an interupt
                          But sleep as MUCH as you can, this preserves your battery. So why measure every minute? if you can wait to measure every 5 minute, do so and prolong your battery :-) I know this depends on what you need the measurements to control, but "if its only" because you want to look at measurements in a graph, sleep for 5 min

                          1 Reply Last reply
                          0
                          • F Offline
                            F Offline
                            flopp
                            wrote on last edited by
                            #14

                            At the moment I am measuring every minute to verify that it works correctly.

                            Later I will measure every 5-15 minutes.

                            gw.sleep(sleeptime);
                            

                            is what I use, I have seen other have used Interrupt together with sleeptime, but it works fine for me, right now in sleep it is 40uA

                            Do I need to use interrupt for better power saving?

                            bjacobseB 1 Reply Last reply
                            0
                            • F flopp

                              At the moment I am measuring every minute to verify that it works correctly.

                              Later I will measure every 5-15 minutes.

                              gw.sleep(sleeptime);
                              

                              is what I use, I have seen other have used Interrupt together with sleeptime, but it works fine for me, right now in sleep it is 40uA

                              Do I need to use interrupt for better power saving?

                              bjacobseB Offline
                              bjacobseB Offline
                              bjacobse
                              wrote on last edited by
                              #15

                              @flopp
                              This is the correct way, to sleep and use interrupt for this :-) so you are using interrupt
                              http://forum.mysensors.org/topic/417/gw-sleep-and-milis

                              F 1 Reply Last reply
                              1
                              • bjacobseB bjacobse

                                @flopp
                                This is the correct way, to sleep and use interrupt for this :-) so you are using interrupt
                                http://forum.mysensors.org/topic/417/gw-sleep-and-milis

                                F Offline
                                F Offline
                                flopp
                                wrote on last edited by
                                #16

                                @bjacobse said:

                                @flopp
                                This is the correct way, to sleep and use interrupt for this :-) so you are using interrupt
                                http://forum.mysensors.org/topic/417/gw-sleep-and-milis

                                Thanks

                                1 Reply Last reply
                                0
                                Reply
                                • Reply as topic
                                Log in to reply
                                • Oldest to Newest
                                • Newest to Oldest
                                • Most Votes


                                25

                                Online

                                11.7k

                                Users

                                11.2k

                                Topics

                                113.1k

                                Posts


                                Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                • Login

                                • Don't have an account? Register

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • MySensors
                                • OpenHardware.io
                                • Categories
                                • Recent
                                • Tags
                                • Popular