Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#include <lowpower.h>
#include <EEPROM.h>
int currentSessionId;
int humanCount = 0;
int eepromHumanCount = 0;
long eepromLastSyncAt = 0;
const int trigPin = 9;
const int echoPin = 10;
const int humanCountedLedPin = 11;
boolean iSeeHuman = false;
boolean iTrackHuman = false;
long lastTimeISawHuman;
// once we observe a person, we count number of times the person stays in front of our device
int numberOfPingsObsevedHumanIsInRange = 0;
// minimum count of hitting a "person" by ultrasonic sensor to accept it as a person
static int minPingCountToAcceptHuman = 2;
static float maxBlackoutInMillis = 500;
static int iSeeHumanThresholdInCm = 250;
// set to true to make the LED blink everytime we count a person
const boolean DEBUG = true;
void setup() {
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
detectCurrentSessionId();
if(DEBUG){
pinMode(humanCountedLedPin, OUTPUT);
blinkHumanCountedLed();
Serial.begin(9600);
delay(500);
printHistory();
}
}
void loop()
{
iSeeHuman = pingDistanceInCm() < iSeeHumanThresholdInCm;
if(iSeeHuman && !iTrackHuman) // we have first contact with human
{
numberOfPingsObsevedHumanIsInRange = 1;
iTrackHuman = true;
lastTimeISawHuman = millis();
}
else if(iSeeHuman && iTrackHuman) // we already recognized him and we keep tracking him
{
numberOfPingsObsevedHumanIsInRange++;
lastTimeISawHuman = millis();
}
else if(!iSeeHuman && iTrackHuman)
{
if((millis() - lastTimeISawHuman) < maxBlackoutInMillis)
{
// wo dont see him now, but we believe he may still be in sight
}
else
{ // we havent seen him for too long
iTrackHuman = false;
if(numberOfPingsObsevedHumanIsInRange >= minPingCountToAcceptHuman){
humanCount++;
if(DEBUG)
blinkHumanCountedLed();
}
}
}
else
{
// !iSeeHuman && !iTrackHuman - nothing to do
}
syncHumanCount();
LowPower.powerDown(SLEEP_15Ms, ADC_OFF, BOD_OFF);
}
long pingDistanceInCm(){
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long durationInMicroseconds = pulseIn(echoPin, HIGH, 15 * 1000);
long cm = durationInMicroseconds / 58;
if(cm == 0){
// when the background is too far away, the measurement may return distance = 0 cm
// in such case we want to avoid counting this ping as a human presence
cm = 500;
}
return(cm);
}
void detectCurrentSessionId(){
int previousSessionId = EEPROM.read(0);
if(previousSessionId == 255) // "Locations that have never been written to have the value of 255."
currentSessionId = 1;
else
currentSessionId = previousSessionId + 1;
EEPROM.write(0, currentSessionId);
}
int majorHumanCount;
int minorHumanCount;
int majorBytePosition;
int minorBytePosition;
// we dont want to write too ofter to eeprom:
// atmel warns the eeprom may die after 100.000 r&w cycles (per single eeprom byte)
// also the 1byte write takes cca 3.3ms
void syncHumanCount()
{
if((humanCount - eepromHumanCount) > 10){
majorHumanCount = humanCount / 256;
minorHumanCount = humanCount % 256;
majorBytePosition = currentSessionId * 2 - 1;
minorBytePosition = majorBytePosition + 1;
EEPROM.write(majorBytePosition, majorHumanCount);
EEPROM.write(minorBytePosition, minorHumanCount);
eepromLastSyncAt = millis();
eepromHumanCount = humanCount;
}
}
// session 1: 1,2
// session 2: 3,4
// session 3: 3*2 -1, 3*2
// session 100: [100*2 - 1, 100*2]
// majorBytePosition = sessionId*2 - 1
// minorBytePosition = sessionId*2
void printHistory()
{
Serial.write("History\n\n");
int sessionHumanCount;
for(int sessionId = 1; sessionId < currentSessionId; sessionId++)
{
majorBytePosition = sessionId * 2 - 1;
minorBytePosition = majorBytePosition + 1;
sessionHumanCount = 256 * ( EEPROM.read(majorBytePosition)) + EEPROM.read(minorBytePosition);
Serial.print("session id: ");
Serial.println(sessionId);
Serial.print("session count: ");
Serial.println(sessionHumanCount);
Serial.println();
}
}
void resetSessionInfoInEeprom(){
EEPROM.write(0, 0);
}
void blinkHumanCountedLed(){
for(int i = 0; i < 5; i++){
digitalWrite(humanCountedLedPin, HIGH);
delay(50);
digitalWrite(humanCountedLedPin, LOW);
delay(50);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.