/* -----------------------------------------------------------------------
 * Title:    Module tracking humain (use PIR sensor for detection)
 * Author:   Samuel St-Aubin (samuel.st-aubin@sympatico.ca)
 * Date:     03.12.2008
 * Hardware: ATtiny13
 * Software: WinAVR 20060421
 -----------------------------------------------------------------------*/

#include "WProgram.h"

#define LED   PB0                   // Define Green Led
#define PIR   PB3                   // Define PIR sensor input

#define TOLERANCE_TIME  1000
const unsigned int MA_N_DETECTED = 100;
const unsigned int MA_TIME_DETECTED = 1000;

//const unsigned long SAMPLING_INTERVAL = 30*(60*1000); // 30 minutes
#define SAMPLING_INTERVAL 20000

unsigned long startTimeInterval;

unsigned int nDetected;
unsigned int totalTimeDetected;

//float meanDetected = 0.;
//float meanTimeDetected = 0.;
int meanDetected = 0;
int meanTimeDetected = 0;

//int i;

void setup() {
  DDRB |= (1 << LED);                 // Set output direction on LED (PB0) *2
  DDRB &= ~(1 << PIR);                // Set input direction on SWT (PB2) 

  PORTB |= (1 << PIR);              // Set 1 for pull 
  PORTB |= (1 << LED);

  nDetected = 0;
  totalTimeDetected = 0;
    
  startTimeInterval = millis();
}

//boolean detect() {
//  return (boolean)bit_is_clear(PINB, PIR);
//}

unsigned long detectOne(int toleranceTime) {
  unsigned long startTime = millis();
  unsigned long time = startTime;
  unsigned long intervalStartTime = startTime;
  boolean nothingDetected = true;

  while (time - intervalStartTime <= toleranceTime) {
    if (bit_is_clear(PINB, PIR)) {
      // reset start time
      time = intervalStartTime = millis();
      nothingDetected = false;
    } else {
      if (!nothingDetected) {
        time = millis();
      } else {
        break;
      }
    }
  }
  
  return (intervalStartTime - startTime);
}

#define MOVING_AVERAGE(oldValue, newValue, denominator) ((oldValue) * ((denominator) - 1) + (newValue)) / (denominator)

void updateStatistics() {
  meanDetected = MOVING_AVERAGE(meanDetected, nDetected, MA_N_DETECTED);
  meanTimeDetected = MOVING_AVERAGE(meanTimeDetected, totalTimeDetected, MA_TIME_DETECTED);
  nDetected = 0;
  totalTimeDetected = 0;
}

void blink(unsigned int time) {
  PORTB &= ~(1 << LED);
  delay(time);
  PORTB |= (1 << LED);
}

void loop() {
  unsigned long timeDetected = detectOne(TOLERANCE_TIME);
  if (timeDetected) {
    nDetected++;
    totalTimeDetected += timeDetected;
    blink(meanTimeDetected);
  }
  
  if (millis() - startTimeInterval > SAMPLING_INTERVAL) {
    updateStatistics();
    startTimeInterval = millis();
  }
}


#include "main.cxx"


