Topic: Help with Programming Arduino Uno to sleep and wakeup with FSR sensor (Read 4435 times)previous topic - next topic

Hello Everyone, I m a newbie, and i m working on a small project using arduino Uno. I want my arduino to be on Idle mode to save power since i will be recharging my battery from time to time. I would also want to write a program that will put my arduino to sleep and then activate it with FSR sensor. Based on all my readings and research from this site, i came across with the code at below, but i did not fully understand the code and i hopping that someone will take a look at the code and tell me if the code is what i needed or if i need more code to add into it for it serve my purpose. I would also like to use LED to show the interrupt . For example; i would like my code to show LED red light on when it is on IDLE mode and when FSR sensor is pressed, the green LED will be on showing that arduino is fully active. I also understand that the code uses Interrupt on Pin 2 to wake up.

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

Exactly how depends on a number of factors. Generating a RISING, FALLING, or LOW interrupt all can be done, depending on how the switch is wired. Which type(s) of interrupt wake the Arduino is the question.

That's a cool project you got there. Well first I agree with PaulS, you should first convert the analog signal into a digital one,a simple comparator with a defined threshold may be used. If you want to avoid debouncing a Schmidt trigger or a latch are very useful. Regarding to your code it seems so be very complete, but I would rather prefer to call sleep_disable() before detachInterrupt(0). This way you can assure that your system will be awake and the CPU clock cycles will be running, and after the processor is awake then you call the detachinterrupt(0). Detaching the interrupt after it awakes is a good idea, this way the interrupt won't be called until your Arduino is sleeping. Nowtalking about you LED indicator you can set it as an output and modify it in your enterSleep() function. Set it LOW before it goes to sleep and set it HIGH when it wakes up. By the way,you can also use CHANGE for generating the interrupt. Here below I add the modificationes I would recommend for your code:

//***************************************************void setup(){pinMode(13,OUTPUT); //The LED indicator is in pin 13, change it to your needs}

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

//***************************************************// * Name: enterSleepvoid enterSleep(){ /* Setup pin2 as an interrupt and attach handler. */ attachInterrupt(0, pin2Interrupt, LOW); // << LOW, HIGH, FALLING, RISING I think are valid. Here you can also use GHANGE that it is a //combination of FALLING OR RISING (activated in both cases) delay(50); // need this? This depends how you want to deal with your sleep times /* 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 */ digitalWrite(13,LOW); // LED is turned off when it goes to sleep 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

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

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

digitalWrite(13,HIGH); //LED is turned off when it wakes up and it's fully active

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

Exactly how depends on a number of factors. Generating a RISING, FALLING, or LOW interrupt all can be done, depending on how the switch is wired. Which type(s) of interrupt wake the Arduino is the question.

Thanks for your help. There is no clock associated with the project, but all i wanted my arduino to do is to go to sleep (idle) when not in use, and i want to use FSR sensor to interrupt by waking up the arduino while pressing the FSR sensor, and as soon as FSR sensor is release, it will go back to sleep(idle) and move a motor to clockwise. Below is a code i have been working on for the past two days, please could you take a look at it and see if i m missing anything. thanks

}//void loop(void){// Stay awake for 1 second, then sleep.// LED turns off when sleeping, then back on upon wake.delay(100);sleepNow();}//void sleepNow(void){

/* Now is the time to set the sleep mode. In the Atmega8 datasheet* http://www.atmel.com/dyn/resources/prod ... oc2486.pdf on page 35* there is a list of sleep modes which explains which clocks and* wake up sources are available in which sleep modus.** In the avr/sleep.h file, the call names of these sleep modus are to be found:** 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 -the most power savings** the power reduction management <avr/power.h> is described in* http://www.nongnu.org/avr-libc/user-man ... power.html*/// Set pin 2 as interrupt and attach handler:attachInterrupt(0, pinInterrupt, LOW);delay(100);//// Choose our preferred sleep mode:set_sleep_mode(SLEEP_MODE_IDLE);//// Set sleep enable (SE) bit:sleep_enable();power_adc_disable();power_spi_disable();power_timer0_disable();power_timer1_disable();power_timer2_disable();power_twi_disable();//// Put the device to sleep:digitalWrite(13,LOW); // turn LED off to indicate sleep

sleep_mode();//// Upon waking up, sketch continues from this point.sleep_disable();digitalWrite(13,HIGH); // turn LED on to indicate awake

}//void loop(void){// Stay awake for 1 second, then sleep.// LED turns off when sleeping, then back on upon wake.delay(100);sleepNow();}//void sleepNow(void){

/* Now is the time to set the sleep mode. In the Atmega8 datasheet* http://www.atmel.com/dyn/resources/prod ... oc2486.pdf on page 35* there is a list of sleep modes which explains which clocks and* wake up sources are available in which sleep modus.** In the avr/sleep.h file, the call names of these sleep modus are to be found:** 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 -the most power savings** the power reduction management <avr/power.h> is described in* http://www.nongnu.org/avr-libc/user-man ... power.html*/// Set pin 2 as interrupt and attach handler:attachInterrupt(0, pinInterrupt, LOW);delay(100);//// Choose our preferred sleep mode:set_sleep_mode(SLEEP_MODE_IDLE);//// Set sleep enable (SE) bit:sleep_enable();power_adc_disable();power_spi_disable();power_timer0_disable();power_timer1_disable();power_timer2_disable();power_twi_disable();//// Put the device to sleep:digitalWrite(13,LOW); // turn LED off to indicate sleep

sleep_mode();//// Upon waking up, sketch continues from this point.sleep_disable();digitalWrite(13,HIGH); // turn LED on to indicate awake

Thank you very much for the site. Based on the example code from that site, i put together a code that will work for my small project, but i m not sure if i m on the right track. Please could you take a look at the code and see if i m doing it correct way. I m planning to use FSR sensor to interrupt from pin2 and it will stays on while someone is holding the sensor, and then arduino will go back to idle as soon as the FSR sensor is realeas.

Isn't an FSR a force sensitive resistor? Which is an analog device? Interrupts only work on digital changes (eg. high to low) so I wouldn't think an FSR is suitable, unless you hook it up to a comparator before the interrupt pin.

Quote

Please could you take a look at the code and see if i m doing it correct way.

Try it and see ...

Please post technical questions on the forum, not by personal message. Thanks!

Isn't an FSR a force sensitive resistor? Which is an analog device? Interrupts only work on digital changes (eg. high to low) so I wouldn't think an FSR is suitable, unless you hook it up to a comparator before the interrupt pin.

Quote

Please could you take a look at the code and see if i m doing it correct way.

Try it and see ...

Thanks Nick Gammon for your quick reply. Yes FSR is a force sensitve resistor. Please Nick Gammon, do you know or have a direction on how to connect FSR to comarator and then before connecting it to interrupt pin?

You can't use an analog device, like an FSR, to generate an input that wakes the Arduino. A digital device, yes.

Very much to my surprise, this can be done and it works exceedingly well! I have a project with several tactile button switches and an FSR. It sleeps in power down mode; I wanted any button or the FSR to wake it. I treat the FSR identically to the buttons, I have the internal pullups enabled and use pin change interrupts to wake the µC. I use the same library for debouncing and sensing the FSR and the buttons. Actually, for this project I never use the FSR as an analog device, since I just want to know if it's "pressed" or not.

Going in to the project, I of course assumed that I would have to treat the FSR as an analog device. But in a moment of weakness (and temporary insanity), I thought I'd try just treating it the same as the switches, nothing to lose really. I was amazed when it worked perfectly. Maybe I got lucky, maybe the characteristics of the FSR I chose, the way it's being loaded, and the hysteresis provided by the AVR all just lined up perfectly, so YMMV, but it works just great for me.

Thanks, Jack. I'm not totally surprised. If the voltage from the FSR when not pressed is quite high (eg. 4V) and when pressed is quite low (eg. 2V) then that effectively could be treated as a digital signal, because the digital inputs would have a "transition" zone (around 2.5V) where above that is considered high, and below is considered low.

Please post technical questions on the forum, not by personal message. Thanks!