ATTiny, Counting with interupts

Robin2:
I think you would need to use the internal (1.1v?) reference for the ADC when measuring the device's own battery voltage.

The battery voltage indication may be a mixed blessing if used with non-rechargeable batteries. Should you design the threshold so that "good" batteries are discarded or set it lower with a risk of failure in service? Yours is not a safety critical project.

...R

Thanks Robin, I think I will look at that later. Unsurprisingly I have hit another snag. :astonished: I thought I had come up with a good plan for hit testing, using a combination of duration and count.

The first part works, and if a long tone of 0.5, 1 or 1.5 seconds (depending on the sensitivity setting), occurs it triggers immediately. If it's a short beep then the plan was to see if 3 occurred in either a 3,4 or 5 second period (depending on the sensitivity setting). This is where it fails because sleeping stops the millis() count until woken.

Here's the relevant bits of code...

void CountBeeps()
{
  // if the output is on
  if (onTimer != 0)
  {
    // check for output time out
    if ( millis() - onTimer > outTime * 1000)
    {
       // if time is up - turn off output, reset vars/flags & sleep
       digitalWrite(outPin, LOW);
       onTimer = 0; 
       beepCount = 0; 
       beepTime = 0;
       lastBeepTime = 0;  
       goToSleep();
    }
  }
  else // output off
  {
    unsigned long beepLength = TimeBeep ();
    Debug.print("Beep length: ");
    Debug.println(beepLength);
    // if the beep is longer than sensitivity * 500 (500,1000,1500)
    if (beepLength >= sensitivity * 500)
    {
      // turn on output
      TurnOnOutput();
    }
    else
    {
      // increment counter
      beepCount +=1;
      Debug.print("Beeps: ");
      Debug.println(beepCount);
      Debug.print("Time: ");
      Debug.println(millis());
      // if time is longer than 2 seconds + sensitivity (1,2,3)
      if (millis() - beepTime >= (2 + sensitivity) * 1000)
      {
        // if count equal or more than 3
        if ( beepCount >= 3)
        {
          // turn on output
          TurnOnOutput();
        }
        else
        {
          // count not met so reset and sleep
          beepCount = 0;
          beepTime = 0;
          goToSleep();
        }  
      }
      else
      {
        // time not up so sleep
        goToSleep();
      }
    }
  }
}

void TurnOnOutput()
{
  // turn on output
  digitalWrite(outPin, HIGH);
  // set output timer
  onTimer = millis();  
}

unsigned long TimeBeep()
{
  while (!digitalRead(inPin))
  {
    if ( millis() - lastBeepTime >= sensitivity * 500)
    {
      break;
    }
  }
  // return beep length
  return millis() - lastBeepTime;
}

void wake()
{
  // set timers
  if (beepTime == 0)
  {
    beepTime = millis();
    lastBeepTime = beepTime;    
  }
  else
  {
    lastBeepTime = millis();
  }
}

Note. sensitivity values are now 1 to 3, with 1 being most sensitive.

So I either need to keep it awake during the count time period or find an alternative way of timing. (I am guessing that all timers are disabled in SLEEP_MODE_PWR_DOWN sleep mode though)

EDIT: I just realised I was being stupid and this would never work if sleeping, so I have to keep it awake during the time period.

Regards,

Les