Two Way Toggle IR Sensors

Hey everyone,
I am trying to write a code for four IR obstacle avoidance sensors (two zones with a left and right sensor). Right now, I am primarily focusing on getting one pair to work. Essentially I want the sensors to work as two way toggles for a digital output so assuming you have two sensors (let's call them A1 and A2) and digital output (pin 3):

If A1 is triggered first, the digital output will stay active until A2 is triggered

and

If A2 is triggered first, the digital output will stay active until A1 is triggered.
This is what I have so far:

boolean Active;
int Update;
int Exit;
void setup() 
{
  Serial.begin(9600);
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  pinMode(4, INPUT);
  int Update = 0;
  int Exit = 0;

}

void loop() 
{
  int Status;
  Active==false;
  int A1;
  int A2;
  if (Update == 0)
  {
  A1 = digitalRead(2);
  A2 = digitalRead(4);
  if(A1==0 | A2==0)
  {
  Active=true;
  Status = 1;
  Exit = 0;
  }
  if(A1==1 && A2==1)
  {
  Active=false;
  Status = 0;
  }
  switch (Status)
  {
    case 1:
    Run();
    break;
    case 0:
    Inactive();
    break;
    }
  }
  if (Update == 1)
{
  A1 = digitalRead(2);
  A2 = digitalRead(4);
  digitalWrite(3,HIGH);
  if(A1==0 | A2==0)
  {
  digitalWrite(3,LOW); // Turn Power Off
  Exit = 1;
  }
  if(A1==1 && A2==1)
  {
  digitalWrite(3,HIGH); // Turn Power On
  Exit = 0;
  }
  switch (Exit)
  {
    case 1:
    Run();
    case 0:
    Run();
    break;
    }
  }
}

void Run()
{

  if (Exit==0)
  {
  Update = 1;
  Serial.println("Running");
  delay(500);

  }
  if (Exit==1)
  {
  Update = 0;
 Serial.println("Exit");
 delay(500);

  return;
  }
  

}

void Inactive()
{
  Serial.println("Inactive");
}

One of the issues I am having here is the sensors occasionally are triggered more than once, as each sensor will be activated for anywhere from 150 ms to 1000 ms. So if sensor A1 is triggered, the code may check for the status of A1 and A2 again, realizing that A1 is still triggered, and shut off the digital output. Does anyone know of a different way to do this? I'm pretty new to the switch/case concept and have seen people use incrementing for similar uses, but I have not been able to produce anything that works better than this at the moment. Give me a shout, any help is appreciated.

You use the word triggered, it at a glance it looks like your code is looking at levels.

You might want to track the transition rather than the level.

See this

and try to apply the same principle to the sensors.

To see when the sensors go HIGH rather than when they are HIGH.

Or maybe LOW, dunno why the sense of your sensor is, so.

HTH

a7

Thanks, the state change detection was exactly what I was looking for:

const int I1 = 2;
const int O1 = 3;
const int I2 = 4;
int CounterZ1 = 0;
int I1_State = 0;
int I1_Last = 0;
int I2_State = 0;
int I2_Last = 0;
void setup() 
{
  Serial.begin(9600);
  pinMode(I1, INPUT);
  pinMode(O1, OUTPUT);
  pinMode(I2, INPUT);

}

void loop() {

  I1_State = digitalRead(I1);
  I2_State = digitalRead(I2);


  if ((I1_State != I1_Last)|(I2_State != I2_Last)) {

    if ((I1_State == LOW)|(I2_State == LOW)) {

      CounterZ1++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(CounterZ1);
    } else {

      Serial.println("off");
    }

    delay(50);
  }

  I1_Last = I1_State;
  I2_Last = I2_State;

  if (CounterZ1 % 2 == 0) {
    digitalWrite(O1, LOW);
  } else {
    digitalWrite(O1, HIGH);
  }

}

Also, I know it is a bit counter-intuitive but, with the way I have the circuit wired, the two sensors are ground active, so the default value on digitalRead is 1.

Yeah, you just gotta roll with that, what I meant about not knowing the sense of your sensors.

For some, HIGH means it sensed (whatever). For others, LOW might mean the thing happened or is happening, whatever it is.

It can be convenient to do some basic testing to see how your sensors work, first just by reading and reporting continuous as you try to activate them. See how well they do the job. See if HIGH means what you think and so forth.

In your code it can help to do something like this once at the top of your sketch:

# define ACTIVE HIGH

Later you can just

  if (digitalRead(theSensorPin) == ACTIVE) {
       // blah blah blah so something because sensor is sensing
  }

Use ACTIVE everywhere instead of HIGH or LOW.

Wrong? Just change the definition, viz:

# define ACTIVE LOW

and you are fixed everywhere.

New sensor operates "upside down" to the old one? Change the define to accommodate it.

You can also write

if (digitalRead(theSensorPin) != ACTIVE) {…

if you wanna do something if the sensor is not sensing. Whatever.

HTH

a7

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.