Showing posts with label sleep mode. Show all posts
Showing posts with label sleep mode. Show all posts

Wednesday, May 20, 2015

Reducing the Power Consumption of the nRF24L01 Transceiver

In this video we take a look at the power needs or power profile of the nRF24L01+ Transceiver. We discuss how much power it draws in each mode and how to reduce or optimize its power consumption for battery powered projects or designs. Finally we pair the nRF24L01 with an Arduino utilizing sleep mode and look at their combined power profile.



************Arduino and nRF24L01 Low Power Example Sketch*************
#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <avr/sleep.h>
#include <avr/wdt.h> 

/*WDT BYTE variables for setting timer value
     WDTO_15MS, WDTO_30MS, WDTO_60MS, WDTO_120MS, WDTO_250MS, WDTO_500MS, WDTO_1S, WDTO_2S, WDTO_4S, WDTO_8S */

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t wAddress = 0xB00B1E50D2LL;              // Pipe to write or transmit on
const uint64_t rAddress = 0xB00B1E50B1LL;  //pipe to recive data on

void setup() {
  randomSeed(analogRead(0)); //create unique seed value for random number generation
  wirelessSPI.begin();            //Start the nRF24 module
  wirelessSPI.setRetries(15,10);
  wirelessSPI.openWritingPipe(wAddress);        //open writing or transmit pipe
  wirelessSPI.openReadingPipe(1,rAddress);  //open reading or recieve pipe
  wirelessSPI.stopListening(); //go into transmit mode
}

void loop() {
   byte randNumber = (byte)random(11); //generate random guess between 0 and 10 
    if (!wirelessSPI.write(&randNumber, 1)){  //if the write fails
      // delivery failed      
     }
     
   delay(30); //delay for short time in normal mode
   wirelessSPI.powerDown(); //put nRF24L01 into power down mode
   delayWDT(WDTO_30MS);   // Use WDT sleep delay function, argument is byte variable from WDT Library
   wirelessSPI.powerUp(); //power up the nRF24
}

//This function serves as a power saving delay function. The argument is a Byte type variable that is used to set the delay time
//The function sets up sleep mode in power down state. The function then sets up the WDT timer in interrupt mode and sets it.
//It then puts the Arduino to sleep for the set time. Upon wake up the WDT and sleep mode are shut off
void delayWDT(byte timer) {
  sleep_enable(); //enable the sleep capability
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set the type of sleep mode. Default is Idle
  ADCSRA &= ~(1<<ADEN); //Turn off ADC before going to sleep (set ADEN bit to 0)
  WDTCSR |= 0b00011000;    //Set the WDE bit and then clear it when set the prescaler, WDCE bit must be set if changing WDE bit   
  WDTCSR =  0b01000000 | timer; //Or timer prescaler byte value with interrupt selectrion bit set
  wdt_reset(); //Reset the WDT 
  sleep_cpu(); //enter sleep mode. Next code that will be executed is the ISR when interrupt wakes Arduino from sleep
  sleep_disable(); //disable sleep mode
  ADCSRA |= (1<<ADEN); //Turn the ADC back on
}

//This is the interrupt service routine for the WDT. It is called when the WDT times out. 
//This ISR must be in your Arduino sketch or else the WDT will not work correctly
ISR (WDT_vect) 
{
  wdt_disable();
   MCUSR = 0; //Clear WDT flag since it is disabled, this is optional

}  // end of WDT_vect

Tuesday, November 18, 2014

Reducing Arduino’s Power Consumption Part 1

In part 1 of this 3 part series we look at how to use Arduino's built-in sleep modes to drastically cut down on power consumption to help you build projects with longer battery life. In part 2 of this series we will look at how to use power reduction registers and in part three we will look at some other ways to wake an Arduino up from sleep mode.


<avr/sleep.h> library: http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html

//**********************Arduino Code***********************************
/*
Example program for using sleep modes in Arduino. This example code was used in a sleep mode tutorial video on the ForceTronics YouTube Channel.
This code is open for anybody to use at their own risk

The 5 different modes are:
     *     SLEEP_MODE_IDLE         -the least power savings
     *     SLEEP_MODE_ADC
     *     SLEEP_MODE_PWR_SAVE
     *     SLEEP_MODE_STANDBY
     *     SLEEP_MODE_PWR_DOWN
These are the arguments used to set the sleep mode in the function set_sleep_mode()
     */
     
#include <avr/sleep.h>

int led = 13; //variable for pin that the LED is on
int count = 0; //variable to control how many times LED blinks before sleep

void setup() {
   sleep_enable(); //enable the sleep capability
   set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set the type of sleep mode. Default is Idle
   pinMode(led, OUTPUT); //set up the LED pin to output
}

void loop() {
  
  if(count < 4) { //For first four loops blink the LED
    digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(900);               // wait 
    digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
    delay(900);       // wait 
    count++; //increment count
  }
  else { //after blinking LED setup interrupt and then go to sleep. Note that sleep will only happen once since it is disabled in ISR
    attachInterrupt(0, interruptFunction, HIGH); 
    sleep_cpu(); //enter sleep mode. Next code that will be executed is the ISR when interrupt wakes Arduino from sleep
    count = 0; //Set the count back to zero 
  }
   
}

//This is the function called when the interrupt occurs (pin 2 goes high)
//this is often referred to as the interrupt service routine or ISR
//This cannot take any input arguments or return anything
void interruptFunction() {
 detachInterrupt(0); //this function call will turn the interrupt off
 sleep_disable(); //Disable the sleep mode so even if call to sleep is executed again it will be ignored
}