I have 2 IR beams in our hallway.
Each is connected to a separate input pin.
Logic is that, in the morning, when the kids walk from the sleeping area to the living area, they break the beams and the PIR (and other) sensors in the living area are detected.
However, what is happening is that sometimes, only 1 of the IR beams is registering.
I have run some tests and get the following :
if the beams are both enabled, and I break one beam, either beam A or beam B seperately, it registers the correct beam as being broken ( for testing, displays in the Serial Monitor ) -- from this I assume that my wiring is all correct.
if I break both beams, either at the same time, or within a fraction of a second of each other, then only the first beam broken registers.
I even added (duplicated) a block of code in case beam B was broken first, and something in the rest of the main code loop was affecting the result before it got back to the section for beam A ( so the checking sequence in the code is : A - B - A )
What I am seeing often in the Serial Monitor is beam A ( 1st code block ) and then beam A ( 2nd code block ) so it is not even seeing beam B.
if I break both beams, either at the same time, or within a fraction of a second of each other, then only the first beam broken registers.
Then, you are not reading the sensors fast enough.
Diddling around writing to the Serial Monitor and your website will work only if you place the two beams about 50 feet apart. And travel between them at a crawl.
Next I will isolate all the code for these beams to a separate sketch to determine if the serial print is affecting the reading.
For testing, two LEDs with current limiting resistors are much faster than serial output. Presumably, the end product will not have debug output, so don't put it in to start with.
If I may suggest, put each beam on an interrupt input (see attachInterrupt). Those are handled very quickly. Inside the ISR make a note of the time (from millis() or micros() calls) and set a flag.
Then the main loop can just check those flags.
Purely as an example (I already had this written):
const byte LED = 12;
const float DISTANCE = 0.9; // m
unsigned long startTime;
volatile unsigned long elapsedTime;
volatile boolean done;
boolean started;
void ballPassesGate1 ()
{
startTime = micros ();
started = true;
digitalWrite (LED, HIGH);
} // end of ballPassesGate1
void ballPassesGate2 ()
{
if (!started)
return;
elapsedTime = micros () - startTime;
done = true;
started = false;
digitalWrite (LED, LOW);
} // end of ballPassesGate2
void setup ()
{
Serial.begin (115200);
Serial.println ("Timer sketch started.");
pinMode (LED, OUTPUT);
attachInterrupt (0, ballPassesGate1, FALLING);
attachInterrupt (1, ballPassesGate2, FALLING);
} // end of setup
void loop ()
{
if (!done)
return;
Serial.print ("Time taken = ");
Serial.print (elapsedTime);
Serial.println (" uS");
float secs = float (elapsedTime) / 1.0e6;
float velocity = DISTANCE / secs;
Serial.print ("Time taken = ");
Serial.print (secs);
Serial.println (" seconds.");
Serial.print ("Average velocity = ");
Serial.print (velocity);
Serial.println (" m/s.");
Serial.println ();
done = false;
} // end of loop
That times how long a marble takes to run down a ramp. Yours will be a bit different because you are timing the reverse direction as well, but it shows how you handle the interrupts. This was written for a Uno.
I don't totally agree with the reference on that point. In my own reference page:
A fair way down is a discussion about volatile variables.
I believe you only need to make volatile variables which are shared between ISRs and non-ISR code (main code). That is so that the compiler knows that the variables may change without warning, and not to cache them in registers.
But inside an ISR, the compiler has to load the variable every time (it can hardly be cached since last time) so variables only used inside an ISR don't need to be volatile. And I think I can safely say that if shared between one ISR and another (only) the same principle applies.