Calling two functions

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
sc1
 
Posts: 5
Joined: Fri Nov 11, 2011 5:59 pm

Calling two functions

Post by sc1 »

Hi

I'm trying to call two functions ("outside" and "inside") depending on an analog signal. However, the issue i'm having is that when peopleInRoom = 0 and calls the "outside" function it constantly loops infinitely when I only want it to run through once. Any ideas?

Code: Select all

void loop()
{

  int sensorValue = analogRead(A0);

  int threshold = 300;

  if(analogRead(sensorPin) > threshold)
   
  peopleInRoom++;
 delay(2000);
{
    if(peopleInRoom > 1)
      peopleInRoom = 0; 
    
    if(peopleInRoom == 0)

outside();

      else

          inside();
    
  }

}

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Calling two functions

Post by adafruit_support_bill »

if(peopleInRoom > 1)
peopleInRoom = 0;
Based on this code, you are saying that if there are more than one people in the room there are no people in the room.
Please explain what you expect this code to do.

It sounds like you want to trigger the inside/outside functions based on a change in the occupancy. To do that, you need to keep track of the last known occupancy value and compare it with the current occupancy value. But It is not clear how you are measuring current occupancy.

sc1
 
Posts: 5
Joined: Fri Nov 11, 2011 5:59 pm

Re: Calling two functions

Post by sc1 »

adafruit_support wrote:
It sounds like you want to trigger the inside/outside functions based on a change in the occupancy.
Thats Correct. To add, when someone leaves the space, it'll send a tweet out saying how long they were in.

Only one person will be entering/exiting at a time. The issue I have is that it keeps on looping the functions and thus infinitely sends tweets when in 'void outside' when I only need to send one per loop. My full code is here:

Code: Select all

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


byte ip[] = { MY IP };


Twitter twitter("TWITTER TOKEN");
char buffer[40];

int peopleInRoom = 0;
int peopleInRoomRecord = 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 outside()
{

  digitalWrite(ledPin, LOW);

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

void inside()
{

  digitalWrite(ledPin, HIGH);

}

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 peopleInRoomRecord =0;
  int sensorValue = analogRead(A0);

  int threshold = 300;

  if(analogRead(sensorPin) > threshold)
    peopleInRoom++;

  delay(2000);

  if(peopleInRoom > 1)
    peopleInRoom = 0; 

  if(peopleInRoom == 0)
  {
    outside();
  }
  else
  {
    inside();
  }
  
}

User avatar
deepz
 
Posts: 3
Joined: Sat Nov 12, 2011 4:56 am

Re: Calling two functions

Post by deepz »

Unless i am overlooking something, the program does what you told it to.

Are you sure the peopleInRoom variable actually gets increased?

If it stays on the default of 0, it will execute outside() over and over again, because loop() cycles over and over again.

When peopleInRoom equals 1, it will loop inside() over and over again, again because loop() cycles over and over again.

On the next increase of peopleInRoom, it is then reset to 0 again, causing outside() to be executed repeatedly again and so on.

From your description, it looks like you want to do something whenever a person leaves the room, so you would only be interested in changes of peopleInRoom and the direction of change, not the actual number of people (at this point anyway).

So it would then be along the lines of testing in loop() not for the value of peopleInRoom, but for changes to it compared to the last known value and only when there is a change call the appropriate function.

Hope this helps,
Guido

sc1
 
Posts: 5
Joined: Fri Nov 11, 2011 5:59 pm

Re: Calling two functions

Post by sc1 »

DeepZ wrote:
From your description, it looks like you want to do something whenever a person leaves the room, so you would only be interested in changes of peopleInRoom and the direction of change, not the actual number of people (at this point anyway).
I only want to do something whenever one person ENTERS and leaves a room, so yes.
DeepZ wrote: So it would then be along the lines of testing in loop() not for the value of peopleInRoom, but for changes to it compared to the last known value and only when there is a change call the appropriate function.
Thats exactly right. Any tips on how I would go about that?

Thanks a lot!

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Calling two functions

Post by adafruit_support_bill »

Code: Select all

if (peopleInRoom > lastCount)
{
  // someone entered the room - do something.
}
else if (peopleInRoom < lastCount)
{
  // someone left the room - do something
}
lastCount = peopleInRoom;

sc1
 
Posts: 5
Joined: Fri Nov 11, 2011 5:59 pm

Re: Calling two functions

Post by sc1 »

That works. However I need to only call a function once. Its tweeting when someone left the room. If the tweet code is linked in the loop then it sends out an infinite about of tweets when I only want one.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Calling two functions

Post by adafruit_support_bill »

If your tweets are inside the 'if' statements, the last statement in the snippet I posted takes care of that. If peopleInRoom is equal to lastCount, neither of the 'if' conditions will be true.

sc1
 
Posts: 5
Joined: Fri Nov 11, 2011 5:59 pm

Re: Calling two functions

Post by sc1 »

Ah yes, that works great. Thanks a lot!

Last issue I have is that its not tracking the seconds time in the tweets. I've basically got the code so that it would track how long someone was in the room and post that time into the tweet. Its tracking the minutes fine, however not the seconds. Any ideas?

Full code below:

Code: Select all


#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;

int lastCount = 0;

unsigned long currTime;
unsigned long prevTime;


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

int threshold = 300;

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

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

void twitterPost(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 inside()
{

  digitalWrite(ledPin, HIGH);
}

void outside()
{

}

void loop()
{


  int sensorValue = analogRead(A0);


  if(sensorValue > threshold)

     {

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

  }
  Serial.println(sensorValue);



  if(peopleInRoom > 1)
    peopleInRoom = 0; 

  Serial.println(lastCount);


  if (peopleInRoom > lastCount)
  {
    inside();

  }
  else if (peopleInRoom < lastCount)
  {

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

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


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

  }


  lastCount = peopleInRoom;

}


}

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”