Programing Arduino To Sleep

Hi, I'm having a little trouble on how to write a code in order to make the Arduino wake up when the FSR force sensor (valF>=thresHold && valFenabled) has been pressed and goes to sleep after valSenabled = 1;. Then turns the Arduino back on when the switch sensor(valS == HIGH && valSenabled) is pressed and then goes to sleep after valFenabled = 1;.

if (valF>=thresHold && valFenabled)

valFenabled isn't a boolean, and should not be used this way. How much extra effort is it to type " == n",where n is an explicit value?

Where is your code to put the Arduino to sleep?

      myservo.write(servoUnlock);  //
      delay(1000);  //
      myservo.write(servoUnlock);  //
      delay(1000); //

Move the servo to some position. Wait a second, and move it to where it is, then wait another second. Sounds useful.

Why do you want the Arduino to sleep?

I do'nt know how to rewrite or phrase the previous code I gave in order make the Arduino wake up and go to sleep.

The purpose of this is to save battery power because when it finishes the first loop and the second loop, the Arduino continues to stay on. So, I want it to turn on when the force sensor is pressed and turns off after the first loop. Then turns on again when the switch sensor is pressed and turns off after the second loop.

You're going to need more than a little code tweak to achieve that...

Sounds like you want one or more of these guys:

It’s a software activated switch you can use to turn your arduino off (for help, lookup reverse geocaches - always used here). While it won’t resume where you left off, you could always write a bit to EEPROM and then put a if GOTO at the start of your void loop() to jump to the second part of your code…

When you say sleep, there’s no ‘sleep’ mode for the arduino - it’s on or off unfortunately. I stand corrected… See post below.

You’ll need these elements. This uses Interrupt on Pin 2 to wake up with. Can your force sensor

#include <avr/sleep.h> // powerdown library
#include <avr/interrupt.h> // interrupts library

//***************************************************
// * Name: pin2Interrupt, “ISR” to run when interrupted in Sleep Mode
void pin2Interrupt()
{
/* This brings us back from sleep. /
}
//
**************************************************

//***************************************************
// * Name: enterSleep
void enterSleep()
{
/* Setup pin2 as an interrupt and attach handler. /
attachInterrupt(0, pin2Interrupt, LOW); // << LOW, HIGH, FALLING, RISING I think are valid
delay(50); // need this?
/
the sleep modes
SLEEP_MODE_IDLE - the least power savings
SLEEP_MODE_ADC
SLEEP_MODE_PWR_SAVE
SLEEP_MODE_STANDBY
SLEEP_MODE_PWR_DOWN - the most power savings
*/
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // setting up for sleep …
sleep_enable(); // setting up for sleep …
sleep_mode(); // now goes to Sleep and waits for the interrupt

/* The program will continue from here after the interrupt. */
detachInterrupt(0); //disable interrupts while we get ready to read the keypad

/* First thing to do is disable sleep. */
sleep_disable();

// then go to the void Loop()
}
//***************************************************

//***************************************************
// within void loop() call this …

enterSleep(); // call Sleep function to put us out
// THE PROGRAM CONTINUEs FROM HERE after waking up in enterSleep()

CR;

That looks really useful and understandable, thanks for the contribution. Have you used it much? Do you just apply a ground to pin 2 to wake up, and is any external or internal pull-up required? Have you measured board current consumption while in the different sleep modes Vs normal running?

Thanks;

Lefty

Very interesting, Crossroads!

I went to test that and had a laugh when I spotted the LED on the Uno board that is always on. So much for not drawing much current!

But taking that into account, and obviously you wouldn’t use one if you were trying to save current, I measured this:

  • Using the “sleep” code: 34 ma
  • Using a while loop, just testing pin 2: 49.6 ma

So it looks like you are saving 15.5 ma by using the sleep concept.

I have a GPS clock here on the wall, which tries to save battery power by sleeping for most of its duty cycle. I think it has a watchdog or similar timer that wakes it every second, so it can advance the second hand. That is a similar idea.

@Lefty,
This is the code that puts my RF remote control to sleep. I have the keypad rows diode ANDed to pin2 so that a keypress wakes it up, it reads the key that was pressed, sends it out and goes back to sleep. I had to write the column pins Low before going to sleep so that the diodes could be pulled low, and then write them High again upon wakeup for the keypad library to work. I’ll bring it home tonight after fencing class and make some measurements. I think it was drawing something 22-24 mA when transmitting, and dropped to half that when sleeping. Don’t have anything written down.

@Nick,
Yes, the power LED is on all the time drawing maybe 3mA? I never measured the drop across the LED. One could always take it off. The FTDI/AT8MU2 is also always on. I use this code with a 3.3V/8MHz Promini which has no USB, only the power LED. The RF Txmitter also draws some current while it is waiting for data to send out. I have a 1000mAH LiPO battery powering it, it goes at least a month on a charge. The MAX1811 battery charge control chip also draws some very small amount.

Simpler_remote.jpg

I am using the same code to put some flashing lights to sleep. A 5V Promini running on 3 AA batteries. The interrupt is created by the Sparkfun PIR Motion Sensor on pin 2. In that case I had to comment out this line (CodingBadly's suggestion):

/* The program will continue from here after the interrupt. */ detachInterrupt(0); //disable interrupts while we get ready to read the keypad

I got the impression that going into sleep mode set off the interrupt somehow, taking that line out fixed it. On a scope and while watching the lights which start flashing as soon as sleep is exited, the interrupt line went low as soon as a 3 second delay ended before the entersleep() call. Commenting out the line stopped that from happening.

This is the code that puts my RF remote control to sleep. I have the keypad rows diode ANDed to pin2 so that a keypress wakes it up, it reads the key that was pressed, sends it out and goes back to sleep. I had to write the column pins Low before going to sleep so that the diodes could be pulled low, and then write them High again upon wakeup for the keypad library to work.

Does that mean you enabled the internal pull-up resistor for pin 2 to create the wired-or 'gate' ?

Lefty

Yes, within void setup():

/* Setup the pin directions, write inputs High to turn on internal pullups */ pinMode(pin2, INPUT); // our sleep interrupt pin digitalWrite(pin2, HIGH);

technically it is wired-AND - all high for a high out, any low makes the output go low. Cathode-side of the diode causes the action. Common Anode. wired-OR would be all low for a low out, any high makes the output go hi. Anode-side of the diode causes the action, common cathode.

CrossRoads: @Nick, The FTDI/AT8MU2 is also always on.

Ah yes, of course the board has other chips on it. My Uno in fact has a ATmega8U2 on it as well for the USB functionality. So I suppose that will be awake, and drawing a few milliamps all the time.

Ok, so add in the pin2interrupt() ISR function, and the entersleep() function. I have them after the pin definitions and before void setup(). And, add some code to decide When to go to sleep and then call the entersleep() function. In my case, I go thru void loop() 1000 times checking for key presses, if I don't see one by then it goes to sleep.

thank you CrossRoads for this code it’s very understandabel

CrossRoads:
You’ll need these elements. This uses Interrupt on Pin 2 to wake up with. Can your force sensor

#include <avr/sleep.h> // powerdown library
#include <avr/interrupt.h> // interrupts library

//***************************************************
// * Name: pin2Interrupt, “ISR” to run when interrupted in Sleep Mode
void pin2Interrupt()
{
/* This brings us back from sleep. /
}
//
**************************************************

//***************************************************
// * Name: enterSleep
void enterSleep()
{
/* Setup pin2 as an interrupt and attach handler. /
attachInterrupt(0, pin2Interrupt, LOW); // << LOW, HIGH, FALLING, RISING I think are valid
delay(50); // need this?
/
the sleep modes
SLEEP_MODE_IDLE - the least power savings
SLEEP_MODE_ADC
SLEEP_MODE_PWR_SAVE
SLEEP_MODE_STANDBY
SLEEP_MODE_PWR_DOWN - the most power savings
*/
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // setting up for sleep …
sleep_enable(); // setting up for sleep …
sleep_mode(); // now goes to Sleep and waits for the interrupt

/* The program will continue from here after the interrupt. */
detachInterrupt(0); //disable interrupts while we get ready to read the keypad

/* First thing to do is disable sleep. */
sleep_disable();

// then go to the void Loop()
}
//***************************************************

//***************************************************
// within void loop() call this …

enterSleep(); // call Sleep function to put us out
// THE PROGRAM CONTINUEs FROM HERE after waking up in enterSleep()

Glad to share ejasoft.