Hello,
I hope someone can give me some advice ...I think I am just doing something silly with my code, but I can't see it.
I am able to put my system into sleep (Sleeping I) after ten seconds of inactivity. When it is in sleep mode, when I get a reading on the analog input it wakes up and takes a reading ....I want it to go back into sleep (Sleeping II) after more inactivity, but it isn't doing that. Where am I going wrong?
Also, when it wakes, I want it to take readings for as long as the pressure is applied, with 10ms gaps, but I can't get it to do that either.
Thanks in advance.
Seán
#include <avr/sleep.h>
#include <avr/power.h>
int fsr = 0;
int count = 0;
int analogPin = 0;
void setup()
{
Serial.begin(9600);
pinMode(analogPin, INPUT);
ACSR =
(0<<ACD) | //Comparator, Enabled
(0<<ACBG) | //AIN0 is applied to the positive input
(0<<ACO) | // Analog Comparator Output: Off
(1<<ACI) | //Clear Pending Interrupt
(1<<ACIE) | //Analog Comparator Interrupt, Enabled
(0<<ACIC) | //Analog Comparator Input Capture, Disabled
(1<<ACIS1) | (1<ACIS0); //Capture on Rising Edge
}
void sleepNow()
{
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_enable(); //enables the sleep mode bits in the register
power_spi_disable();
power_timer0_disable();
power_timer1_disable();
power_timer2_disable();
power_twi_disable();
sleep_mode();
sleep_disable();
power_all_enable();
}
void loop()
{
count++;
delay(1000);
if(count >= 10)
{
Serial.println("Sleeping I");
sleepNow();
}
}
ISR(ANALOG_COMP_vect)
{
if(analogRead(analogPin) > 100)
{
count = 0;
fsr = analogRead(analogPin);
Serial.println("The reading is ");
Serial.println(fsr);
delay(10);
count = 0;
if(count >= 10)
{
Serial.println("Sleeping II");
sleepNow();
count = 0;
}
}
}
You can't use delay() in an ISR because it relies on interrupts for timing and the interrupts are disabled during an ISR.
If you declare 'count' as volatile and just set it to 0 in the ISR then loop() will put the processor back to sleep in 10 seconds.
#include <avr/sleep.h>
#include <avr/power.h>
int fsr = 0;
volatile int count = 0;
int analogPin = 0;
[...]
ISR(ANALOG_COMP_vect)
{
if(analogRead(analogPin) > 100)
{
count = 0;
fsr = analogRead(analogPin);
Serial.println("The reading is ");
Serial.println(fsr);
}
}
Hey,
Thanks a lot! I'll give that a go when I get back home.
Can I ask, what does volatile mean in this context?
Thanks.
Seán
Ordinarily, the compiler tries to optimize your code for you. That may mean some fairly trivial thing like not bothering to read a variable from RAM because it already has it in a register from previous activity. Alternatively, it may move code out of loops if the calculation doesn't change for each iteration, or ignore if tests because it can calculate the result at compile time.
Volatile warns the compiler that it cannot make assumptions about the variable so labelled because you touch it in an interrupt routine or because it references a memory location that may be changed by other hardware. It tells the compiler: "I don't care what you think you know about what that memory location contains, go and get it again anyway every time you want to use it".
Ah ok, that's handy! Thanks a lot! I'll report back on how I get on.
Thanks again!
Seán
johnwasser:
You can't use delay() in an ISR because it relies on interrupts for timing and the interrupts are disabled during an ISR.
If you declare 'count' as volatile and just set it to 0 in the ISR then loop() will put the processor back to sleep in 10 seconds.
#include <avr/sleep.h>
#include <avr/power.h>
int fsr = 0;
volatile int count = 0;
int analogPin = 0;
[...]
ISR(ANALOG_COMP_vect)
{
if(analogRead(analogPin) > 100)
{
count = 0;
fsr = analogRead(analogPin);
Serial.println("The reading is ");
Serial.println(fsr);
}
}
Hey, just wanted to let you know this worked a treat. Many thanks!!
Seán