Skip to content

Instantly share code, notes, and snippets.

@intrepidkarthi
Created February 7, 2017 19:36
Show Gist options
  • Select an option

  • Save intrepidkarthi/f82d5738986c3560ee3b8ebdf5143642 to your computer and use it in GitHub Desktop.

Select an option

Save intrepidkarthi/f82d5738986c3560ee3b8ebdf5143642 to your computer and use it in GitHub Desktop.

Revisions

  1. @petervojtek petervojtek revised this gist May 13, 2014. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion people-counter-v1.ino
    Original file line number Diff line number Diff line change
    @@ -20,7 +20,6 @@ int numberOfPingsObsevedHumanIsInRange = 0;
    // minimum count of hitting a "person" by ultrasonic sensor to accept it as a person
    static int minPingCountToAcceptHuman = 2;

    static int sleepBetweenTwoHumansInMillis = 300;
    static float maxBlackoutInMillis = 500;
    static int iSeeHumanThresholdInCm = 250;

  2. @petervojtek petervojtek revised this gist May 11, 2014. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions people-counter-v1.ino
    Original file line number Diff line number Diff line change
    @@ -24,6 +24,7 @@ static int sleepBetweenTwoHumansInMillis = 300;
    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() {
  3. @petervojtek petervojtek created this gist May 11, 2014.
    182 changes: 182 additions & 0 deletions people-counter-v1.ino
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,182 @@
    #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 int sleepBetweenTwoHumansInMillis = 300;
    static float maxBlackoutInMillis = 500;
    static int iSeeHumanThresholdInCm = 250;

    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);
    }
    }