Power driving an NRF24L01 transmitter

Hi.
Can someone please guide me here on a layout I’ve drawn up for a transmitter to run outputs on an arduino. I’ve made a prototype board for the transmitter using the following:

  • A 12V 23A size battery
  • An L7805 voltage regulator to drop down to 5V
  • A 10uF electrolytic and 0.1uF on the input and output voltage lines
  • An atmega328 with crystal, caps, etc
  • A RNF24L01 transmitter and receiver
  • A breakout board - input 5V, output 3.3V
    (please take a look at the attached schematic for the transmitter)
    The problem I’ve found is that the battery drops very quickly from 12V to 10V making it inoperable. Can I save power usage by:
  • Removing the LM7805 voltage regulator and capacitors
  • Supplying the breakout board with 12V, for the ABS 1117 voltage regulator on board to drop to 3.3V
  • Use the 3.3V from this board to run the whole circuit
    Any suggestions would be appreciated.

NRF24L01_V1.pdf (35.3 KB)

Here is how the design decisions are made:
architecture-decisions

Ray

Hi Ray.

You know, each time I create a new circuit and choose a component, even after having done some research, there's always a better circuit or component that does the same thing better. Unfortunately it's taken me (a newbie to RF), a month or so researching, designing, testing and programming to get a remote that will change the led scores on my scoreboard.

I tried to read the link to the website you gave, but could work out what you're suggesting as an alternative.
Chris

The power source seems to be the biggest problem.
About 2/3 of the power of the battery is wasted by dropping it from 12volt to 5volt and 3.3volt.
An A23 battery can't provide the current for that transmitter.
You could try a 9volt alkaline battery.
Or no 5volt regulator and three alkaline AA batteries.
Leo..

Wawa:
The power source seems to be the biggest problem.
About 2/3 of the power of the battery is wasted by dropping it from 12volt to 5volt and 3.3volt.
An A23 battery can't provide the current for that transmitter.
You could try a 9volt alkaline battery.
Or no 5volt regulator and three alkaline AA batteries.
Leo..

Thanks Leo.

A 9V battery sounds like a good option (I think).
Is it worth then removing the LM7805 voltage regulator, connecting 9V direct to the atmega328 to run it, and then let the ABS1117 regulator on the NRF break-out board power up the transmitter (so only 1 regulator)?

Does this mean that when not used it doesn't use much power, or do I need an on / off switch?

If however opting for the 3 x AAA, are you saying it would power the atmega 328 and the breakoutboard (with 3.3V regulator? Which of the 2 options would you "guess" would last longer before they drained? Sorry for all the questions.

cjcj:
A 9V battery sounds like a good option (I think).

Is it worth then removing the LM7805 voltage regulator, connecting 9V direct to the atmega328 to run it, and then let the ABS1117 regulator on the NRF break-out board power up the transmitter (so only 1 regulator)?

Does this mean that when not used it doesn't use much power, or do I need an on / off switch?

If however opting for the 3 x AAA, are you saying it would power the atmega 328 and the breakoutboard (with 3.3V regulator? Which of the 2 options would you "guess" would last longer before they drained? Sorry for all the questions.

  1. More current available compared to a A23 battery, but even a 9volt battery can't power this setup long.

  2. No, AFAIK absolute max CPU voltage is 6volt.

  3. on/off switch is always needed.

  4. I said AA. Voltage range of a bare 328 running at 16Mhz is ~3.75 to 6volt.
    The 3.3volt regulator will have a ~1volt dropout, so needs ~4.3volt minimum.
    Four rechargeable NiMh batteries (~1.25volt each) or three alkaline batteries (~1.5volt each) could power the processor directly. Expect about 5x longer runtime from AA batteries compared to a good 9volt battery.
    Leo..

cjcj:
<…>
I tried to read the link to the website you gave, but could work out what you’re suggesting as an alternative.
Chris

@Chris,

I was just (too quickly, I suppose) trying to point out some of the areas that must be considered for a truly low-power design. Hardware selection, of course, is always the first place. Then there is stuff like sleeping the uC, etc.

But, power loss from DC regulation is almost always the spot where power is lost. Linear regulators often waste a significant amount of power just shunting excess voltage to ground… why they get hot.
The better solution is always a DC-DC switching module. Once very expensive, I buy these things in 50x quantities for under $0.50 each. You can get them for under a $1 in smaller quantities. Not a recommendation for a brand/vendor but something like this:
Buck DC-DC

Ray

Ray, shunting excess voltage to ground - now I see the problem. Thankyou.

The tiny DC to DC switching module looks great - didn't know they existed (and were so small). I'll put one of these in my setup to deliver the 5V to the 328 and RF unit.

Leo suggested 4xAA vs a 9V battery lasting possibly 5 times longer. I'm just trying to keep size down as well. Using the switching module, would this still be a problem? Could the 9V be ok now?

In regards to sleeping the UC, I assume you mean with something like the Monteino TPL5110 breakout-board? Is this an easy unit to hook up and would it save much power (given the use of the switching module I'll now be using)?

One thing is I do want to try keep costs down. Between the remote "box", keypad, board and components, it's starting to add up. Can I use something like a NE555 with some resistors to do the shut off timing? I remember fiddling with one of these in another project once.

Could someone please help me here with inserting some code from one program to another for my transmitter program. Not sure what part to use and how to add it in.

From everyone’s suggestions in this thread, I’ve now experimented with using a DC-DC switching module for the 3.3V supply, an Arudino Mini Pro 3.3V board along with caps and crystal. My original setup (Arduino only) was drawing around 30mA. This new setup with the code (video tutorial by Kevin Darrah) below (less the watchdog) consumes only 0.3uA when sleeping. :slight_smile:

So I’m guessing I might be able to keep the transmitter small by using the original 12V 23A battery I was originally planning, or maybe even a 9V alkaline battery. Here’s the code with the sleep modes noted above:

#define LED_PIN 4

void setup() {
   pinMode(LED_PIN, OUTPUT);
   for (int i = 0; i < 20; i++) {
     if (i != 2)
       pinMode(i, OUTPUT);
   }
   attachInterrupt(0, digitalInterrupt, FALLING);

  // WATCHDOG TIMER
  WDTCSR = (24); // change enable and WDE - also resets
  WDTCSR = (33); // prescalers only - get rid of the WDE and WDCE bit
  WDTCSR |= (1 << 6); // enable interrupt mode

  // Disable ADC
  ADCSRA &= ~(1 << 7);
  //ENABLE SLEEP
  SMCR |= (1 << 2); // power down mode
  SMCR |= 1;// enable sleep
}


void loop() {
  digitalWrite(LED_PIN, HIGH);
  delay(1000);
  digitalWrite(LED_PIN, LOW);

  for (int i=0; i<2; i++) { // gives ~16 seconds to wakeup time
    // BOD DISABLE
    MCUCR |= (3 << 5);
    MCUCR = (MCUCR & ~(1 << 5)) | (1 << 6);
    __asm__ __volatile__("sleep");
  }
}

void digitalInterrupt() {
}

ISR(WDT_vect) {
}

What I’m not sure of is what part of it I should or shouldn’t add to my existing code (see part code below). My intent is to:

  • Extend battery life by putting the arduino in a deep sleep automatically after say 30 seconds of pressing any of the transmitter buttons
  • If possible then waking the arduino with the pressing of any of the 12 transmitter buttons
  • Eventually write some code that measures the battery voltage when away and light a red LED if say 3.2V

Sorry, I know this is a big ask but I’m a little lost here.

/* This code transmits data from one nRF24L01 to another
via Arduino Unos.  The input on the transmitter is done via
a 3 column x 4 row keyap.  Inputs are as follows:
     0 = Siren off
     1 = Increment home score by 1
     2 = Nil
     3 - Increment away score by 1
     4 = Decrease home score by 1
     5 = start / pause / resume
     6 = Decrease away score by 1
     7 = Nil
     8 = Nil
     9 = Nil
     # = Nil
     *0 to *4 = 10's timer setting
     *5 & *6 = no such time for tens (over 45min not typical half time)
     *7# = Set timer to 20:00 minutes
     *8# = Set timer to 30:00 minutes
     *9# = Set timer to 45:00 minutes
     *x0# to *x9# = 1's timer setting and entry completion with #
     *#  = Reset scores to 00 and timer to 00:00 ready to start
     0 (hold) = siren set to play when time reached
     5 (hold) = reset timer to 00:00 ready to start

   nRF2401 setup:
   GND
   VCC  - to 3.3V !!! NOT 5V
   CE   - to Arduino pin 9
   CSN  - to Arduino pin 10
   SCK  - to Arduino pin 13
   MOSI - to Arduino pin 11
   MISO - to Arduino pin 12
   IRQ  - Not used
*/


#include <Keypad.h> // http://playground.arduino.cc/uploads/Code/keypad.zip
#include <SPI.h>    // Comes with Arduino IDE
#include "RF24.h"   // https://github.com/TMRh20/RF24

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {14, 15, 16, 17}; //connect to the row pinouts of the myKeypad
byte colPins[COLS] = {6, 5, 4}; //connect to the column pinouts of the myKeypad
Keypad myKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

// Data is sent with a ~ at the start and ! at the end to verify the data is valid
byte CmdStart = '~';    // ASCII value = 126
byte CmdEnd   = '!';    // ASCII value = 33

byte FlagKeyN = 0;      // flag the keypad number
byte FlagAsterix = 0;   // flag used when the asterix (*) key pressed
byte FlagHash = 0;      // flag used when the hash (*) key pressed
byte FlagTimer = 0;     // flag used to set the count down time
byte FlagUsed = 0;      // flag when character is used up in process
byte timerToggle = 0;   // variable used to toggle the timer from start to pause and reset

// When one of the following is transmitted, it is so as an ascii character
// On the receiver program, the ascii is read and program executed as listed in the "case" list

byte HomeCharP = 'A';   // variable used to increment Home score by 1 (ASCII of A = 65)
byte AwayCharP = 'B';   // variable used to increment Away score by 1 (ASCII of A = 66)
byte HomeCharS = 'C';   // variable used to decrease Home score by 1 (ASCII of D = 67)
byte AwayCharS = 'D';   // variable used to decrease Away score by 1 (ASCII of B = 68)
byte Timer45min = 'E';  // variable used to set the timer to 45 minute duration (ASCII of E = 69)

etc, etc

byte Hash = 'R';        // variable used to send a "hash" (ASCII of R = 82)
byte Asterix = 'S';     // variable used to send an asterix (ASCII of S = 83)
byte startPause = 'T';  // variable used to send a variable to start/pause the timer (ASCII of T = 84)
byte resetTimer = 'U';  // variable used to reset the timer to start (ASCII of U = 85)
byte sirenOff = 'V';    // variable used to reset the timer to start (ASCII of U = 86)
byte sirenActive = 'W'; // variable used to reset the timer to start (ASCII of U = 87)
byte ResetChar = 'Z';   // variable used to increment Away score by 1 (ASCII of Z = 90)


// (Create an instance of a radio, specifying the CE and CS pins. )
RF24 myRadio (9, 10);   // "myRadio" is the identifier you will use in following methods
byte addresses[][6] = {"1Node"}; // Create address for 1 pipe.

void setup()
{
  Serial.begin(115200);
  myKeypad.setHoldTime(1500);
  delay(1000);  // just gives some time for starting the serial monitor
  Serial.println(F("RF24/Simple Transmit data Test"));

  myRadio.begin();                        // Start up the physical nRF24L01 Radio
  myRadio.setChannel(108);
  myRadio.setPALevel(RF24_PA_MAX);
  myRadio.openWritingPipe( addresses[0]); // Use the first entry in array 'addresses' (Only 1 right now)
  delay(1000);

} //  end void setup


void loop() {
  keyPadCheck ();
} // end void loop



//----------------------------
void keyPadCheck () {
  //    Fills myKeypad.key[ ] array with up-to 10 active keys.
  //    Returns true if there are ANY active keys.
  if (myKeypad.getKeys()) {
    for (int i = 0; i < LIST_MAX; i++) {// Scan the whole key list.
      //    "kstate" can be used to check if a key is either PRESSED, HOLD, RELEASED OR IDLE
      //    "stateChanged" (not used below) can be called to see any of the states above have changed for a key
      if ( myKeypad.key[i].kstate == PRESSED ) {  // Only find keys that have changed state.
        FlagUsed = 0;  // this is used so that the program loops to this start after each stage below
        FlagKeyN = myKeypad.key[i].kchar;             // Set the FlagKeyN variable to the currently pressed key number

        // if a key has been pressed that is not an asterix or hash key, then carry out the following
        if ((FlagAsterix == 0) && (FlagHash == 0) && (FlagUsed == 0)) {
          switch (FlagKeyN) {
            case  48:
              // keypad 0 pressed turn off the siren from sounding
              SendCommand(sirenOff); // this transmits the value 'V' in ascii = 86
              break;
            case  49:
              // keypad 1 pressed to add 1 point to home score
              SendCommand(HomeCharP); // this transmits the value 'A' in ascii = 65
              break;
            case  50:
              // keypad 2 pressed - NOT PROGRAMMED
              break;

etc, etc

} // end void keyPadCheck


// Send Command via Radio
void SendCommand(byte KeyCmd) {

  myRadio.write(&CmdStart, sizeof(CmdStart));
  myRadio.write(&KeyCmd, sizeof(KeyCmd));
  myRadio.write(&CmdEnd, sizeof(CmdEnd));

  Serial.print(F("Command Sent = "));
  Serial.print(KeyCmd);
} // end void SendCommand

I would use 3xAAA (no regulator on the ATmega chip) and a low dropout 3.3V regulator for the NRF24L01.

For useful info on low power operation, see Nick Gammon's excellent tutorials:

solar powered NRF24L01 remote

power saving techniques

Why not run the whole thing from 2xAA cells and then no voltage regulator is needed. It worked fine for me.

...R

Why not run the whole thing from 2xAA cells

Problems with 16 MHz operation, but should be OK with 8MHz.

jremington:
Problems with 16 MHz operation, but should be OK with 8MHz.

Very true. I run all my standalone Atmega328s at 8MHz.

…R

jremington:
I would use 3xAAA (no regulator on the ATmega chip) and a low dropout 3.3V regulator for the NRF24l01

The 4.5V would be good, but I'm trying my best to keep the size of the remote small. With a DC-DC step down module, would a 12V or 9V not work?

Robin2:
Why not run the whole thing from 2xAA cells and then no voltage regulator is needed. It worked fine for me.

Are you suggesting 2 x 1.5V alkaline batteries? This would only be 3V and the nrf needs 3.3V and I thought the atmega needed the same. Then even with as little as a 0.1V power drop by use, it would no longer be strong enough???

Running at 8Mhz - absolutely agree. Nick Gammond's tutorials, yes - great tutorials on power saving. I came across them last night as well.

So still wondering if this would work on a single battery then. Also if sleeping is ok, and if it's possible to wake this by the press of any remote button. Should my coding question be in the programming section of this forum, or am I asking the wrong question?

the nrf needs 3.3V

No, it doesn't. It will run on 2.0 V.

jremington:
No, it doesn’t. It will run on 2.0 V.

I found that the NRF was really temperamental to voltage drop. Even at 3V, my breadboard version doesn’t transmit. (https://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo)??

I found that the NRF was really temperamental to voltage drop.

The manufacturer states that the NRF24L01 will work over the voltage range 1.9-3.6 V and this has been verified by others, see this example.

It is possible that your NRF24L01 is defective. The cheap Chinese clones are known to occasionally have problems, but it is more likely that your breadboard setup is not correct.

J, I stand corrected. Your absolutely correct. I've just changed my power source on the atmega and nfr to 2 x AA batteries (currently 2.78V) and it works without a problem.

Earlier in this thread it was suggested that the voltage range of an atmega328 also was 3.75 to 6V. Looking up the specs, it seems it lower - 1.8 to 5.5V. So running both off 2xAA should be fine then as you say.

Ok, so it's just the inclusion of the sleep software I need a hand with then. Should this be in another thread?

No need to start another thread.

The best tutorial on power saving and sleep modes with ATMegas is here.