Order in which two inputs change state

Hi,
Is there a way to analyze the order in which two inputs are go HIGH or LOW?

I'm using two IR sensors based on an L358 op-amp as digital inputs, these go HIGH when any object comes in front of them. These sensors are fixed at a distance from each other.

My primary goal is to get the order in which these sensors go HIGH. i.e. writing a function that returns the order. For example if the 1st sensor goes HIGH followed by the second one, the function returns some value; if the 2nd sensor goes HIGH followed by the 1st one another value should be returned.

I know how to achieve what I want but don't know how to implement it in code.

Thanks.

When each input changes state record the value of millis() or micros() in a variable. When both have gone HIGH compare the 2 variables. The input with the lowest value in its variable changed state first.

The code should be easy. Where are you stuck, what have you tried ?

No need for even that, just look at the inputs and see when one of them changes. The arduino is so fast that you will never see two inderpendant inputs change at the same time.

UKHeliBob, looks like a feasible solution. Going to try it out.
Grumpy_Mike, I tried doing that. What I want to do is detect the direction in which something moves i.e. if the motion is one way, the code does something it is the other way something else is done.

What I was doing was pretty complicated (now, I think It should be simplified); I would first check if any input goes high, wait till it comes low, then wait again for the other input to come high, record it in a variable and then get the wrong result!

Well, thanks both of you, will post my code and progress :slight_smile:

Grumpy_Mike, I tried doing that

Then you did not succeed because of the way you implemented it.
Try and write a minimum sketch that shows the problem and we can see where you went wrong.

Then you did not succeed because of the way you implemented it.
Try and write a minimum sketch that shows the problem and we can see where you went wrong.

There is no problem in the implementation, instead the problem lies in the logic itself. I don't want the required actions to happen if only one of the sensor observes something.

As I've mentioned before, I want to trigger action only when something moves in a particular direction (for a set distance). The method which I tried before (and the one you mentioned) would not work if the object returned back after coming to the first sensor (which is likely to happen if the sensors are quite far apart; in my case about 30 cm away from each other).

There is no problem in the implementation,

Yes there is especially if you leave it this late in the thread to to say what you actually want.
All you need to do is code it correctly. I will not code it for you but I can help show you where you have gone wrong if you give something to go on.
Basically all you need is a variable that stores what input is triggered first and then you wait for either the second input to appeare or the first to dissapeared.

I used the method UKHeliBob suggested and it works well.

Basically all you need is a variable that stores what input is triggered first and then you wait for either the second input to appeare or the first to dissapeared.

I used something similar in the process I was using before. I gave each sensor an ID and stored that in an array each time a sensor was triggered then compared it to the previous entry in the array to get the direction. It did stupid things at times so I turned to the forum. But anyway.... thanks :slight_smile:

In order to handle an input on one pin correctly, you need to know the time of the most recent event on the other pin. Once you realise that, the algorithm becomes very simple:

For each event on each pin, store the time of the event and work out how long ago the last event on the other pin was; if it's recent, this event constitutes a movement in the direction associated with this pin.

For each event on each pin, store the time of the event and work out how long ago the last event on the other pin was; if it's recent, this event constitutes a movement in the direction associated with this pin.

I'm using something similar. I save the time (using millis()). If both the variables are set to non-zero values the direction is read out and the values are set to zero. Else the sketch continues to look out for the next event to occur.

Will post the code on Github once my project reaches some level of stability.

Abhik:
If both the variables are set to non-zero values the direction is reasd out and the values are set to zero.

That's not a robust approach, because any situation where you have alternating signals on the two input pins can legitimately be interpreted as a sequence of left-to-right or right-to-left movements. You really need to check how long ago the event on the other pin was, to decide whether this input constitutes a movement.

Sorry, I forgot to mention, the variables store the time when the event has occurred. Here is the basic sketch that I used to test the logic.

const int irSns1 = 2;
const int irSns2 = 3;

unsigned long int irTime1 = 0;
unsigned long int irTime2 = 0;

void setup()
{
    pinMode(irSns1, INPUT);
    pinMode(irSns2, INPUT);

    Serial.begin(9600);
}

void loop()
{
    int state1 = digitalRead(irSns1);
    int state2 = digitalRead(irSns2);

    if((state1 == 1) || (state2 == 1))
    {
        if(state1 == 1)
        {
            while(state1)
            {
                state1 = digitalRead(irSns1);
                delay(1);
            }
            irTime1 = millis();
        }
        else if(state2 == 1)
        {
            while(state2)
            {
                state2 = digitalRead(irSns2);
                delay(1);
            }
            irTime2 = millis();
        }
    }

    if((irTime1 != 0) && (irTime2 != 0))
    {

        if(irTime1 > irTime2)
             Serial.println("Direction 1");
        else if(irTime1 < irTime2)
             Serial.println("Direction 2");
        else
            Serial.println("irTime1 = irTime2; Very Rare");

        irTime1 = 0;
        irTime2 = 0;

        delay(100);
    }
    delay(100);
}