Logging someone in and out (IR)

Hi everyone

I'm trying to write a script that when someone walks past an IR beam, it triggers certain actions (turns on LEDs etc) and remembers that they're in. When they walk out and break the IR beam again it will switch off the LEDs.

Only one person will be going in and out at a time.

I've got a small amount of (incomplete) code to pinpoint the threshold for the IR. I just need to implement a code so that Arduino can remember if someone is in or not.

Would it also be possible to track the amount of time in?

int sensorPin = 0;
int ledPin = 12;

int sensorValue = 0;

void setup() {

  pinMode(sensorValue, INPUT);
  pinMode(ledPin, OUTPUT);
}


void loop() {
  {
  
sensorValue = analogRead(sensorValue);
  int threshold = 450;
  if(analogRead(sensorPin) > threshold)
  digitalWrite(ledPin, HIGH);       

}
}

Appreciate any help

This project might not be as easy as you imagine. What happens if a person breaks the OR beam, but does not end up going all the way through? Typically, this is handled by having two beams that must be broken in the proper order, and arranged in such a way that only one person at a time can possibly be in the entrance area, and by making it impossible to exit the area without breaking both beams in the proper order.

Then, the order of breaking the beams defines whether the person was entering or leaving.

In your case, you will need to increment a counter when the beam is broken.

If the counter is greater than 1, reset it ti 0.

If the counter is 0, the area is empty, and the LEDs should be turned off. If the counter is 1, the area is occupied, and the LEDs should be turned on.

Yes, you can keep track of how long the area was occupied. Each time the beam is broken, save the current time as the previous time, and use millis() to get the current time. When the counter gets reset to 0, the difference between the current time (when the beam was just broken) and the previous time (the time before this one) is the time the area was occupied.

Valid points.

I understand the process. Would it be possible to provide an example sketch of the counter and time? I'm relatively new to Arduino and learning all the time.

Thanks

Would it be possible to provide an example sketch of the counter and time?

Not compiled; not tested. But, something like this will be close to right. I think.

int peopleInRoom = 0;

unsigned long currTime;
unsigned long prevTime;

void setup()
{
   // Whatever you need to do
}

void loop()
{
  if(analogRead(sensorPin) > threshold)
  {
     prevTime = currTime;
     currTime = millis();
     peopleInRoom++;

    // Wait half a second for the person to completely pass the sensor
    // Adjust this time as necessary
    delay(500);
  }

  if(peopleInRoom > 1)
     peopleInRoom = 0;

  // At this point, peopleInRoom will contain either 0 or 1
  if(peopleInRoom == 0)
  {
     unsigned long usedFor = currTime - prevTime;
     // Room was occupied for usedFor milliseconds
     digitalWrite(ledPin, LOW); // Turn light(s) off
  }
  else
  {
    digitalWrite(ledPin, HIGH); // It's dark in here, turn the lights on
  }
}

Thanks Paul. All compiled and worked fine.

I've included an updated version of the sketch with Twitter integrated (theres probably a much easier method than the way i've done it, but it works). Would it be possible to add the time spent in the room into the tweet in seconds/minutes/hours?

#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>
#include <stdlib.h> 
// Ethernet Shield Settings
byte mac[] = { MAC ADDRESS };

// substitute an address on your own network here
byte ip[] = { IP ADDRESS };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("TWITTER ID");

int peopleInRoom = 0;

unsigned long currTime;
unsigned long prevTime;


int sensorPin = 0;
int ledPin = 6;
int sensorValue = 0;


void setup()
{
 delay(1000);
  Ethernet.begin(mac, ip);
  Serial.begin(9600);

  pinMode(sensorValue, INPUT);
  pinMode(ledPin, OUTPUT);
   
}

void loop()
{
  


  int sensorValue = analogRead(A0);

  
  int threshold = 300;
  if(analogRead(sensorPin) > threshold)
  {
 
     prevTime = currTime;
     currTime = millis();
     peopleInRoom++;
delay (4000);
    // Wait half a second for the person to completely pass the sensor
    // Adjust this time as necessary

  }

  if(peopleInRoom > 1)
     peopleInRoom = 0; 

  // At this point, peopleInRoom will contain either 0 or 1
  if(peopleInRoom == 0)
  {
     unsigned long usedFor = currTime - prevTime;
     // Room was occupied for usedFor milliseconds
     digitalWrite(ledPin, LOW); // Turn light(s) off
     
     //TWITTE CODE STARTS HERE, DIFFERENT PRE-COMPOSED MESSAGES
     
       int randNumber;
randNumber = random(5);
{
    
     if (randNumber == 1)
     {
       Serial.println("connecting ...");
  if (twitter.post("test")) {
    int status = twitter.wait(&Serial);
    if (status == 200) {
      Serial.println("OK.");
    } else {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  } else {
    Serial.println("connection failed.");
  }    

}
{
     if (randNumber == 2)
     {
      Serial.println("connecting ...");
  if (twitter.post("test2")) {
    int status = twitter.wait(&Serial);
    if (status == 200) {
      Serial.println("OK.");
    } else {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  } else {
    Serial.println("connection failed.");
  }    
     }


     if (randNumber == 3)
     {
       Serial.println("connecting ...");
  if (twitter.post("test3")) {
    int status = twitter.wait(&Serial);
    if (status == 200) {
      Serial.println("OK.");
    } else {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  } else {
    Serial.println("connection failed.");
  }
     }
     

    if (randNumber == 4)
    {
    Serial.println("connecting ...");
  if (twitter.post("test4")) {
    int status = twitter.wait(&Serial);
    if (status == 200) {
      Serial.println("OK.");
    } else {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  } else {
    Serial.println("connection failed.");
  }
    }    
}
}
}
  
//TWITTER END
  
  else 
  {

    digitalWrite(ledPin, HIGH); // It's dark in here, turn the lights on
    

}


  }
randNumber = random(5);
{
    
     if (randNumber == 1)
     {
       Serial.println("connecting ...");
  if (twitter.post("test")) {
    int status = twitter.wait(&Serial);
    if (status == 200) {
      Serial.println("OK.");
    } else {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  } else {
    Serial.println("connection failed.");
  }

Am I supposed to figure out which { goes with which }?

Put each { on its own line, and use Tools + Auto Format to make the code readable.

The only thing that changes in the 5 blocks of hard to read code is the text that is posted.

void uselessPost(char *textToPost)
{  
  if (twitter.post(textToPost))
  {
    int status = twitter.wait(&Serial);
    if (status == 200)
    {
      Serial.println("OK.");
    }
    else
    {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  }
  else
  {
    Serial.println("connection failed.");
  }
}

Then call this function:

       int randNumber = random(5);
       switch(randomNumber)
       {
          case 0:
             uselessPost("Testing");
             break;
         case 1:
             uselessPost("Goofing off");
             break;
          case 2:
             uselessPost("Whatever");
             break;
         case 3:
             uselessPost("The moon is on fire");
             break;
         case 4:
             uselessPost("Ouch");
             break;
       }

Would it be possible to add the time spent in the room into the tweet in seconds/minutes/hours?

Yes, it would. Convert the milliseconds value into seconds. Then convert seconds to hours, minutes, and seconds. Then, construct a string containing the time data, using sprintf. Then post it.

Ah sorry about that.

I've converted the time and works fine, however the only thing i'm slightly confused about is forming a string using sprintf and inserting it into the tweet.

Looking around I found something similar however when I compile it I get, "error: '"I was here for"' cannot be used as a function."

case 0:
        uselessPost(sprintf(buffer, "I was here for" (mins) "and" (secs));
        break;

Current code with converted time:

void loop()
{
  int sensorValue = analogRead(A0);
  int threshold = 300;

  if(analogRead(sensorPin) > threshold)

  {

    prevTime = currTime;
    currTime = millis();
    peopleInRoom++;
    delay (4000);
    // Wait half a second for the person to completely pass the sensor
    // Adjust this time as necessary

  }

  {
    if(peopleInRoom > 1)
      peopleInRoom = 0; 

    // At this point, peopleInRoom will contain either 0 or 1
    if(peopleInRoom == 0)
    {
      unsigned long usedFor = currTime - prevTime;
      {
        long days=0;
        long hours=0;
        long mins=0;
        long secs=0;

        secs = usedFor/1000;
        mins=secs/60;
        hours=mins/60;
        days=hours/24;
        secs=secs-(mins*60);
        mins=mins-(hours*60);
        hours=hours-(days*24);

        //Display results
        Serial.println("------------");
        if (days>0)
        {
          Serial.print(days);
          Serial.print(" days and :");
        }

        Serial.print(mins);
        Serial.print(" minutes");
        Serial.print(" and ");
        Serial.println(secs);
        Serial.println("seconds");
      }

 


      digitalWrite(ledPin, LOW); // Turn light(s) off

      //Beginning of Twitter time

      int randNumber = random(5);
      switch(randNumber)
      {
      case 0:
        uselessPost(sprintf(buffer, "I was here for" (mins) "and" (secs));
        break;
      case 1:
        uselessPost("Goofing off");
        break;
      case 2:
        uselessPost("Whatever");
        break;
      case 3:
        uselessPost("The moon is on fire");
        break;
      case 4:
        uselessPost("Ouch");
        break;
      }
    }

    //end of twitter time

    else 
    {
      digitalWrite(ledPin, HIGH); // It's dark in here, turn the lights on
    }
  }

}

Thanks for your help Paul, learning all the time :slight_smile:

It is the buffer written to by sprintf() that you want to pass to uselessPost().

char buffer[40];
sprintf(buffer, "Occupied for %d minutes and %d seconds", minutes, seconds);
uselessPost(buffer);

That works.

The LAST issue I have now is that its constantly outputting "Occupied for 0 minutes and 0 seconds" along with the other random cases. Because its situated within void loop? Any ideas?

Just test to see if you have non zero values in these parameters before sending the tweet.

I've had a look to the best of my ability - no joy

I would appreciate if someone could take 5 minutes to have a quick look through the code and try and pin-point why its constantly outputting to twitter as soon as arduino restarts.

#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>
#include <stdlib.h> 
// Ethernet Shield Settings
byte mac[] = { MY MAC };

// substitute an address on your own network here
byte ip[] = { IP };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("MY TOKEN");

int peopleInRoom = 0;

unsigned long currTime;
unsigned long prevTime;


int sensorPin = 0;
int ledPin = 6;
int sensorValue = 0;


void setup()
{
  delay(1000);
  Ethernet.begin(mac, ip);
  Serial.begin(9600);

  pinMode(sensorValue, INPUT);
  pinMode(ledPin, OUTPUT);

}


void uselessPost(char *textToPost)

{
  if (twitter.post(textToPost))
  {
    int status = twitter.wait(&Serial);
    if (status == 200)
    {
      Serial.println("OK.");
    }
    else
    {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  }
  else
  {
    Serial.println("connection failed.");
  }



}

void loop()
{

  int sensorValue = analogRead(A0);

  int threshold = 300;
  if(analogRead(sensorPin) > threshold)

  {

    prevTime = currTime;
    currTime = millis();
    peopleInRoom++;
    delay (4000);
    // Wait for the person to completely pass the sensor

  }

  {
    if(peopleInRoom > 1)
      peopleInRoom = 0; 

    // At this point, peopleInRoom will contain either 0 or 1
    if(peopleInRoom == 0)
    {

     digitalWrite(ledPin, LOW); // Turn lights off

      unsigned long usedFor = currTime - prevTime;

      {
        long days=0;
        long hours=0;
        long mins=0;
        long secs=0;

        secs = usedFor/1000;
        mins=secs/60;
        hours=mins/60;
        days=hours/24;
        secs=secs-(mins*60);
        mins=mins-(hours*60);
        hours=hours-(days*24);

      }

     //Twitter time

        int randNumber = random(4);
        switch(randNumber)
        {


        case 0:
          char buffer[40];
          sprintf(buffer, "I was here for %d minutes and %d seconds", mins, secs);
          uselessPost(buffer);
          break;
        case 1:
          sprintf(buffer, "Had a fun for %d minutes and %d seconds", mins, secs);
         uselessPost(buffer);
          break;
        case 2:
          sprintf(buffer, "Occupied for %d minutes and %d seconds", mins, secs);
         uselessPost(buffer);
          break;
        }

    }

      //end of twitter time

    else 
    {

      digitalWrite(ledPin, HIGH); // It's dark in here, turn the lights on

    }
  }

}

Try this:-

#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>
#include <stdlib.h> 
// Ethernet Shield Settings
byte mac[] = { MY MAC };

// substitute an address on your own network here
byte ip[] = { IP };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("MY TOKEN");

int peopleInRoom = 0;

unsigned long currTime;
unsigned long prevTime;


int sensorPin = 0;
int ledPin = 6;
int sensorValue = 0;


void setup()
{
  delay(1000);
  Ethernet.begin(mac, ip);
  Serial.begin(9600);

  pinMode(sensorValue, INPUT);
  pinMode(ledPin, OUTPUT);

}


void uselessPost(char *textToPost)

{
  if (twitter.post(textToPost))
  {
    int status = twitter.wait(&Serial);
    if (status == 200)
    {
      Serial.println("OK.");
    }
    else
    {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  }
  else
  {
    Serial.println("connection failed.");
  }



}

void loop()
{

  int sensorValue = analogRead(A0);

  int threshold = 300;
  if(analogRead(sensorPin) > threshold)

  {

    prevTime = currTime;
    currTime = millis();
    peopleInRoom++;
    delay (4000);
    // Wait for the person to completely pass the sensor

  }

  {
    if(peopleInRoom > 1)
      peopleInRoom = 0; 

    // At this point, peopleInRoom will contain either 0 or 1
    if(peopleInRoom == 0)
    {

     digitalWrite(ledPin, LOW); // Turn lights off

      unsigned long usedFor = currTime - prevTime;

      {
        long days=0;
        long hours=0;
        long mins=0;
        long secs=0;

        secs = usedFor/1000;
        mins=secs/60;
        hours=mins/60;
        days=hours/24;
        secs=secs-(mins*60);
        mins=mins-(hours*60);
        hours=hours-(days*24);

      }

     //Twitter time

        int randNumber = random(4);
        if(!(mins == 0 && secs == 0)) {
        switch(randNumber)
        {


        case 0:
          char buffer[40];
          sprintf(buffer, "I was here for %d minutes and %d seconds", mins, secs);
          uselessPost(buffer);
          break;
        case 1:
          sprintf(buffer, "Had a fun for %d minutes and %d seconds", mins, secs);
         uselessPost(buffer);
          break;
        case 2:
          sprintf(buffer, "Occupied for %d minutes and %d seconds", mins, secs);
         uselessPost(buffer);
          break;
        }

    }
    }
      //end of twitter time

    else 
    {

      digitalWrite(ledPin, HIGH); // It's dark in here, turn the lights on

    }
  }

}

if someone could take 5 minutes

30 seconds!

I got 'error: "mins' was not declared in this scope" so I moved the bracket like so,

{
        long days=0;
        long hours=0;
        long mins=0;
        long secs=0;

        secs = usedFor/1000;
        mins=secs/60;
        hours=mins/60;
        days=hours/24;
        secs=secs-(mins*60);
        mins=mins-(hours*60);
        hours=hours-(days*24);

     //BRACKET WAS HERE

     //Twitter time

        int randNumber = random(4);
        if(!(mins == 0 && secs == 0)) {
        switch(randNumber)
        {


        case 0:
          char buffer[40];
          sprintf(buffer, "I was here for %d minutes and %d seconds", mins, secs);
          uselessPost(buffer);
          break;
        case 1:
          sprintf(buffer, "Had a fun for %d minutes and %d seconds", mins, secs);
         uselessPost(buffer);
          break;
        case 2:
          sprintf(buffer, "Occupied for %d minutes and %d seconds", mins, secs);
         uselessPost(buffer);
          break;
        }
} //NOW HERE

That works to a point. As soon as you trigger the LED HIGH and then LOW again it starts infinitely outputting again. Also, it doesn't seem to be outputting the seconds, only minutes.

unsigned long usedFor = currTime - prevTime;

{
long days=0;
long hours=0;
long mins=0;
long secs=0;

secs = usedFor/1000;
mins=secs/60;
hours=mins/60;
days=hours/24;
secs=secs-(mins60);
mins=mins-(hours
60);
hours=hours-(days*24);

}
The highlighted braces are not required. They define a block of code, with variables local to that block that go out of scope when the block ends.

The right place to move them to is the bit bucket.

PaulS:
The right place to move them to is the bit bucket.

Bit Bucket?

I removed the braces and not a lot different happened.

Bit Bucket?

Sure. Bit bucket, round file, trash can...

I removed the braces and not a lot different happened.

The variable not in scope message went away, didn't it? That should be considered an improvement, shouldn't it?

Ah ok. Its defiantly an improvement as they were redundant.

Any more ideas on why the sketch is infinitely outputting to twitter after one loop?

You modified the code, and you'd like us to divine how. Sorry, it doesn't work that way. Post your code.

Sorry. Code below.

#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>
#include <stdlib.h> 
// Ethernet Shield Settings
byte mac[] = {  MY MAC };

// substitute an address on your own network here
byte ip[] = { MY IP };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("MY TOKEN");

int peopleInRoom = 0;

unsigned long currTime;
unsigned long prevTime;


int sensorPin = 0;
int ledPin = 6;
int sensorValue = 0;


void setup()
{
  delay(1000);
  Ethernet.begin(mac, ip);
  Serial.begin(9600);

  pinMode(sensorValue, INPUT);
  pinMode(ledPin, OUTPUT);

}


void uselessPost(char *textToPost)

{
  if (twitter.post(textToPost))
  {
    int status = twitter.wait(&Serial);
    if (status == 200)
    {
      Serial.println("OK.");
    }
    else
    {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  }
  else
  {
    Serial.println("connection failed.");
  }



}

void loop()
{

  int sensorValue = analogRead(A0);

  int threshold = 300;
  if(analogRead(sensorPin) > threshold)

  {

    prevTime = currTime;
    currTime = millis();
    peopleInRoom++;
    delay (4000);
    // Wait for the person to completely pass the sensor

  }

  {
    if(peopleInRoom > 1)
      peopleInRoom = 0; 

    // At this point, peopleInRoom will contain either 0 or 1
    if(peopleInRoom == 0)
    {

     digitalWrite(ledPin, LOW); // Turn lights off

      unsigned long usedFor = currTime - prevTime;

      
        long days=0;
        long hours=0;
        long mins=0;
        long secs=0;

        secs = usedFor/1000;
        mins=secs/60;
        hours=mins/60;
        days=hours/24;
        secs=secs-(mins*60);
        mins=mins-(hours*60);
        hours=hours-(days*24);

      

     //Twitter time

        int randNumber = random(4);
        if(!(mins == 0)) {
        switch(randNumber)
        {


        case 0:
          char buffer[50];
          sprintf(buffer, "I was here for %d minutes and %d seconds", mins, secs);
          uselessPost(buffer);
          break;
        case 1:
          sprintf(buffer, "Had a fun for %d minutes and %d seconds", mins, secs);
         uselessPost(buffer);
          break;
        case 2:
          sprintf(buffer, "Occupied for %d minutes and %d seconds", mins, secs);
         uselessPost(buffer);
          break;
        }
        }
    }
    
      //end of twitter time

    else 
    {

      digitalWrite(ledPin, HIGH); // It's dark in here, turn the lights on

    }
  }

}