Coordinating two photointerrupters?

Hi there,

Firstly, some background info on my project - I’m making a beehive that counts the number of bees that enter it and moves a servo motor as a dial to demonstrate this data. I’m using two photointerrupters as the input in the hope that I can discern which direction the bee is passing through them (whether they’re entering or exiting) by determining which photointerrupter was triggered first. I don’t want an exit to add to the count of total bees. I should also mention I’m using an Arduino Uno.

I’ve tried to follow the logic that:
if the first photointerrupter is triggered at an earlier time than the second, then the total number of bees = the total number of bees + 1
(and thus the servo being triggered to move one interval).

However, with the code I have at the moment, once the two photointerrupters are triggered in succession (1 then 2), the servo is set off like it should be, but continues to move through the intervals over and over regardless of neither photointerrupter being triggered again.

I think (?) this would be because if the code continues to loop, it continuously recognises that the timestamp for the first photointerrupter is recorded as happening before the second, and so it continuously adds 1 to the count of bees even though there’s only been a single instance of something passing through them. And so the servo continues to move to reflect this.

How can I make it so that instead of this happening, the arduino recognises that one pass through the first and second photointerrupter successively results in one bee being counted, and the servo moving one interval to reflect this, then hold off on adding any more counts until the two photo interrupters are passed through again (first then second)?

Below is my code. Any help would be very very appreciated!

#include <Servo.h>

int bees = 0;
int beesout = 0;
int Bees = 0;
int totalBees = 0;

const int photoInterruper = 7;
const int photoInterrupter2 = 13;
int servoPin = 8;

unsigned long beeEntryFirstGateTime;
unsigned long beeEntrySecondGateTime;
unsigned long timeInGate = 0;
unsigned long timeInGate2 = 0;
bool startedEntry = false;
bool startedExit = false;


Servo myservo;  // create servo object to control a servo

int val;    // variable to read the value from the analog pin



void setup() {
  // put your setup code here, to run once:

  myservo.attach(8);

  pinMode(photoInterruper, INPUT);
  pinMode(photoInterrupter2, INPUT);
  pinMode(servoPin, OUTPUT);
  
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  
//   Serial.println("loop");
   bees = digitalRead(photoInterruper);
   beesout = digitalRead(photoInterrupter2);
//   Serial.println(bees);
   
   if (bees == HIGH){
    Serial.println("CROSSED!");
    if( !startedEntry ){
      // only record the entry time if this is the first moment the beam was crossed
      beeEntryFirstGateTime = millis();
      startedEntry = true;
    }
    
   } else {
    
    // beam not crossed.... check time?
    if( startedEntry ){
      timeInGate = millis() - beeEntryFirstGateTime;
      Serial.print("Time spent in first gate: ");
      Serial.println( timeInGate / 1000.0 );
      startedEntry = false;
    }
    
   } // else



   if (beesout == HIGH){
    Serial.println("EXITING!");
    if( !startedExit ){
      // only record the exit time if this is the first moment the beam was crossed
      beeEntrySecondGateTime = millis();
      startedExit = true;
    }
    
   } else {
    
    // beam not crossed.... check time?
    if( startedExit ){
      timeInGate2 = millis() - beeEntrySecondGateTime;
      Serial.print("Time spent in second gate: ");
      Serial.println( timeInGate2 / 1000.0 );
      startedExit = false;
    }
    
   } // else


  if (beeEntryFirstGateTime < beeEntrySecondGateTime){
    totalBees = totalBees + 1;
    Serial.print("Total Bees: ");
    Serial.println(totalBees);
    delay(1000);

    } else {
      
    if (beeEntryFirstGateTime == beeEntryFirstGateTime){
  totalBees = totalBees;

 delay(1000);
  }

}
  
    //reset Bee coutner if bees are more than 10
    if(totalBees >= 10){
      totalBees = 0;
    }
  

    val = map(totalBees, 0, 10, 0, 180);     // scale it to use it with the servo (value between 0 and 180)
      myservo.write(val);                  // sets the servo position according to the scaled value
      Serial.println(" ");
      Serial.print("Servo Value: ");
      Serial.println(val);
      Serial.println(" ");
      delay(15);  
  
} // loop()

Others have done this. Try a site search on 'bee counter'.

I've come across many similar projects on here, but after looking over them I haven't been able to find any answers to the particular issue I was hoping to solve, so I ended up creating this post.

You don't seem to be doing state change detection (see the state change detection example in the IDE of how to do this). You just check the state and move the servo as long as there's a bee blocking the sensor.

Well I would set an activation delay of maybe 1/2 second to prevent variables getting out of hand. On a side note, the line int bees = 0; has got to be the funniest thing I've heard all day for some reason.
Maybe something like

if (//photosensor input) {bees = bees+1; delay(500);}

Delay can easily be replaced with something else if need be.

rowingtechinnovations:
Delay can easily be replaced with something else if need be.

Rule: you're NOT allowed to use delay() until you fully understand why.

There are very, very few good uses of delay() and this is one of the worst.

Drop the timing. Look at it as a quadrature problem. As the bee moves through the tube the sensors would create a signal similar to the top line at the link - as long as the bee blocks both sensors at some point. Notice how A goes high then B goes high then A goes low then B goes low? This sequence is what is decoded to determine a passage *and *the direction of the passage.

Have your bees been trained to not tailgate (maintain a minimum space between each other), if not you might count 3 or 4 bees packed head to tail as one.