Pages: [1]   Go Down
Author Topic: Where am I going wrong?  (Read 613 times)
0 Members and 1 Guest are viewing this topic.
Just past the last tree on the left
Offline Offline
Full Member
***
Karma: 0
Posts: 125
Ó Fithcheallaigh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
#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;
    }
  }
}

Logged

Ná bac le mac an bhacaigh is ní bhacfaidh mac an bhacaigh leat.

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 178
Posts: 8064
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
#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);
  }
}
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Just past the last tree on the left
Offline Offline
Full Member
***
Karma: 0
Posts: 125
Ó Fithcheallaigh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Ná bac le mac an bhacaigh is ní bhacfaidh mac an bhacaigh leat.

New Jersey
Offline Offline
Faraday Member
**
Karma: 48
Posts: 3402
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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".
Logged

Just past the last tree on the left
Offline Offline
Full Member
***
Karma: 0
Posts: 125
Ó Fithcheallaigh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah ok, that's handy! Thanks a lot! I'll report back on how I get on.

Thanks again!

Seán
Logged

Ná bac le mac an bhacaigh is ní bhacfaidh mac an bhacaigh leat.

Just past the last tree on the left
Offline Offline
Full Member
***
Karma: 0
Posts: 125
Ó Fithcheallaigh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
#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
Logged

Ná bac le mac an bhacaigh is ní bhacfaidh mac an bhacaigh leat.

Pages: [1]   Go Up
Jump to: