an event triggers a behaviour until another event stops it

Hello!
I have a code with the following loop:

void loop()
{
    stop1 = digitalRead(butee1);
    stop2 = digitalRead(butee2);

    PG = analogRead(porte_glis);
    
if(PG > 850)
  {
    if(stop1 == HIGH)
    {
      digitalWrite(treuil1, LOW);
      digitalWrite(treuil2, LOW);
      }else{ 
      digitalWrite(treuil1, LOW);
      digitalWrite(treuil2, HIGH);
      }
    }else{
    if(stop2 == HIGH)
    {
      digitalWrite(treuil1, LOW);
      digitalWrite(treuil2, LOW);
      }else{ 
      digitalWrite(treuil1, HIGH);
      digitalWrite(treuil2, LOW);
      }
}
}

it drives a single motor which opens a door. Two switches stop the motor when the door is fully closed or fully open. The movement is triggered when IR transistor (porte_glis) get enough light to get beyond the 850 threshold. It works fine but it requires to have the IR source next to the IR transistor all the time required for the door to open. Now, I would like to be able to light the IR transistor only for a short period (few seconds) and then have the motor continuing to open the door until it reaches the full opening and the switch stops it. Then the door stays open for a while (a delay() should do it) and the motor starts in the reverse direction to close the door.
It looks simple but I don't know how to do it despite all my years with Arduino!!!!

The state change detection example in the IDE (File, Examples, Digital) shows how to detect when the IR signal becomes over the threshold (as opposed to is over).

Frogeraie:
it drives a single motor which opens a door. Two switches stop the motor when the door is fully closed or fully open. The movement is triggered when IR transistor (porte_glis) get enough light to get beyond the 850 threshold. It works fine but it requires to have the IR source next to the IR transistor all the time required for the door to open. Now, I would like to be able to light the IR transistor only for a short period (few seconds) and then have the motor continuing to open the door until it reaches the full opening and the switch stops it. Then the door stays open for a while (a delay() should do it) and the motor starts in the reverse direction to close the door.
It looks simple but I don't know how to do it despite all my years with Arduino!!!!

something like this maybe:

#define butee1 2
#define butee2 3
#define treuil1 4
#define treuil2 5
#define porte_glis A0
#define IR_THRESHOLD 850
#define T_DOOR_OPEN 10000 //door remains open for 10s (10000ms)

uint8_t stop1;
uint8_t stop2;
uint16_t PG;
uint8_t op=0; //new variable used to record IR threshold has been exceeded
unsigned long oldtime;
void setup() {
  // put your setup code here, to run once:
  pinMode(butee1, INPUT);
  pinMode(butee2, INPUT);
  pinMode(treuil1, OUTPUT);
  pinMode(treuil2, OUTPUT);

}

void loop()
{
  uint8_t stop1;
  uint8_t stop2;
  uint16_t PG;
  stop1 = digitalRead(butee1);
  stop2 = digitalRead(butee2);

  PG = analogRead(porte_glis);

  if (PG > IR_THRESHOLD && op==0){
    op==1;
  }

  if(op==0){
    oldtime = millis();
  }
  else if(op==1){
    if (stop1 == HIGH) //stop -> Fully Open
    {
      digitalWrite(treuil1, LOW);
      digitalWrite(treuil2, LOW);
      op=2;
    } else { //Opening door
      digitalWrite(treuil1, LOW);
      digitalWrite(treuil2, HIGH);
    }
    oldtime = millis();
  }
  else if(millis()-oldtime > T_DOOR_OPEN) { //close door
    if (stop2 == HIGH) //stop -> fully closed
    {
      digitalWrite(treuil1, LOW);
      digitalWrite(treuil2, LOW);
      op=0;
    }
    else { //Closing door
      digitalWrite(treuil1, HIGH);
      digitalWrite(treuil2, LOW);
    }
  }
}

I've used a variable to create a kind of state machine and millis() to determine how long the door remain open.
op=0 //door close and IR not triggered
op=1 //IR trigerred door opening
op=2 //door is fully open

Always show your full sketch.

Always comment your code if you want comments from us.

Use CTRL T to format your sketch.

.

Frogeraie:
Now, I would like to be able to light the IR transistor only for a short period (few seconds) and then have the motor continuing to open the door until it reaches the full opening and the switch stops it. Then the door stays open for a while (a delay() should do it) and the motor starts in the reverse direction to close the door.
It looks simple but I don’t know how to do it despite all my years with Arduino!!!

enum State { CLOSED, OPENING, OPENED, CLOSING } state = CLOSED;

const uint32_t checkInterval_ms = 5000; // check every 5 seconds
uint32_t  most_recent_check_ms;

void loop() {
  if(millis() - most_recent_check_ms >= checkInterval_ms) {
    turn on the IR unit
    wait a few millis for the IR to warm up
    PG = analogRead(porte_glis);
    turn off the IR unit     
  }

  switch(state) {
    case CLOSED:
      if(PG > IR_THRESHOLD) {
        turn on the motor to open the doors
        state = OPENING;
      }
      break;

    case OPENING:
      if(the door has hit the open stop button) {
        turn off the motor to open the doors
        state = OPEN;
      }
      break;

    case OPEN:
      if(PG < IR_THRESHOLD) {
        turn on the motor to close the doors
        state = CLOSING;
      }
      break;

    case CLOSING:
      if(the door has hit the close stop button) {
        turn off the motor to close the doors
        state = CLOSED;
      }
      break;

  }
}

The main problem with this sketch is that it will open/close/open the door when your porte_glis input is floating at around the threshhold value. Improvements to this sketch would include:

1 - have separate opening and closing thresholds, with the opening threshold a few points greater than the closing threshhold

2- have a timeout. It’s not enough for the light to drop, it must drop for more than (say) five seconds. To do this, you’d have to count the amount of times that PG was above/below threshhold, and only trigger an open or close when that hit some number.

Thanks to PaulMurrayCbr I have something which works fine for one door:

int treuil1 = 11;
int treuil2 = 12;
int porte_glis = 1;

 int PG;
 int butee1 = 7;
 int butee2 = 8;
 int stop1 = 0;
 int stop2 = 0;

enum State { CLOSED, OPENING, OPENED, CLOSING } state = OPENED;

const uint32_t checkInterval_ms = 5000; // check every 5 seconds
uint32_t  most_recent_check_ms;
int IR_THRESHOLD = 850;

void setup() {
  pinMode(treuil1, OUTPUT);
  pinMode(treuil2, OUTPUT);
} 

void loop() {
    stop1 = digitalRead(butee1);
    stop2 = digitalRead(butee2);
        PG = analogRead(porte_glis);

  /*if(millis() - most_recent_check_ms >= checkInterval_ms) {
    //turn on the IR unit
   // wait a few millis for the IR to warm up
    PG = analogRead(porte_glis);
    //turn off the IR unit     
  }*/

  switch(state) {
    case CLOSED:
      if(PG < IR_THRESHOLD) {
        //turn on the motor to open the doors
        digitalWrite(treuil1, HIGH);
        digitalWrite(treuil2, LOW);
        state = OPENING;
      }
      break;

    case OPENING:
      if(stop2 == HIGH)//the door has hit the open stop button 
      {
      //turn off the motor to open the doors
      digitalWrite(treuil1, LOW);
      digitalWrite(treuil2, LOW);
      delay(10000);
      state = OPENED;
      }
      break;

    case OPENED:
      if(PG > IR_THRESHOLD) {
        //turn on the motor to close the doors
        digitalWrite(treuil1, LOW);
        digitalWrite(treuil2, HIGH);
        state = CLOSING;
      }
      break;

    case CLOSING:
      if(stop1 == HIGH) //the door has hit the close stop button
      {
        //turn off the motor to close the doors
        digitalWrite(treuil1, LOW);
        digitalWrite(treuil2, LOW);
        state = CLOSED;
      }
      break;

  }
}

Unfortunately it doesn’t extend nicely for the two doors case. When I try to run the following code only one door responds:

int treuil1 = 11;
int treuil2 = 12;
int treuil3 = 9;
int treuil4 = 10;
int porte_glis = 1;
int porte_bat = 0;
 int PB, PG;
 int butee1 = 7;
 int butee2 = 8;
 int stop1 = 0;
 int stop2 = 0;
 int butee3 = 2;
 int butee4 = 3;
 int stop3 = 0;
 int stop4 = 0;

enum State { CLOSED, OPENING, OPENED, CLOSING } state = OPENED;

int IR_THRESHOLD = 850;

void setup() {
   pinMode(treuil1, OUTPUT);
  pinMode(treuil2, OUTPUT);
   pinMode(treuil3, OUTPUT);
  pinMode(treuil4, OUTPUT);
} 

void loop() {
    stop1 = digitalRead(butee1);
    stop2 = digitalRead(butee2);
    stop3 = digitalRead(butee3);
    stop4 = digitalRead(butee4);

  PB = analogRead(porte_bat);
  PG = analogRead(porte_glis);

  switch(state) {
    case CLOSED:
      if(PG < IR_THRESHOLD) {
        //turn on the motor to open the doors
        digitalWrite(treuil1, HIGH);
        digitalWrite(treuil2, LOW);
        state = OPENING;
      }
      if(PB < IR_THRESHOLD) {
        //turn on the motor to open the doors
        digitalWrite(treuil3, HIGH);
        digitalWrite(treuil4, LOW);
        state = OPENING;
      }
      break;

    case OPENING:
      if(stop2 == HIGH)//the door has hit the open stop button 
      {
      //turn off the motor to open the doors
      digitalWrite(treuil1, LOW);
      digitalWrite(treuil2, LOW);
      delay(10000);
      state = OPENED;
      }
      
      if(stop4 == HIGH)//the door has hit the open stop button 
      {
      //turn off the motor to open the doors
      digitalWrite(treuil3, LOW);
      digitalWrite(treuil4, LOW);
      delay(10000);
      state = OPENED;
      }
      break;


    case OPENED:
      if(PG > IR_THRESHOLD) {
        //turn on the motor to close the doors
        digitalWrite(treuil1, LOW);
        digitalWrite(treuil2, HIGH);
        state = CLOSING;
      }
      if(PB > IR_THRESHOLD) {
        //turn on the motor to close the doors
        digitalWrite(treuil3, LOW);
        digitalWrite(treuil4, HIGH);
        state = CLOSING;
      }
      break;

    case CLOSING:
      if(stop1 == HIGH) //the door has hit the close stop button
      {
        //turn off the motor to close the doors
        digitalWrite(treuil1, LOW);
        digitalWrite(treuil2, LOW);
        state = CLOSED;
      }
     
      if(stop3 == HIGH) //the door has hit the close stop button
      {
        //turn off the motor to close the doors
        digitalWrite(treuil3, LOW);
        digitalWrite(treuil4, LOW);
        state = CLOSED;
      }
      break;

  }
}

When I tried to have different set of cases for each door:

int treuil1 = 11;
int treuil2 = 12;
int treuil3 = 9;
int treuil4 = 10;
int porte_glis = 1;
int porte_bat = 0;
 int PB, PG;
 int butee1 = 7;
 int butee2 = 8;
 int stop1 = 0;
 int stop2 = 0;
 int butee3 = 2;
 int butee4 = 3;
 int stop3 = 0;
 int stop4 = 0;

enum State { CLOSED, OPENINGg, OPENED, CLOSINGg, OPENINGb, CLOSINGb } state = OPENED;

int IR_THRESHOLD = 850;

void setup() {
   pinMode(treuil1, OUTPUT);
  pinMode(treuil2, OUTPUT);
   pinMode(treuil3, OUTPUT);
  pinMode(treuil4, OUTPUT);
} 

void loop() {
    stop1 = digitalRead(butee1);
    stop2 = digitalRead(butee2);
    stop3 = digitalRead(butee3);
    stop4 = digitalRead(butee4);

  PB = analogRead(porte_bat);
  PG = analogRead(porte_glis);

  switch(state) {
    case CLOSED:
      if(PG < IR_THRESHOLD) {
        //turn on the motor to open the doors
        digitalWrite(treuil1, HIGH);
        digitalWrite(treuil2, LOW);
        state = OPENINGg;
      }
      if(PB < IR_THRESHOLD) {
        //turn on the motor to open the doors
        digitalWrite(treuil3, HIGH);
        digitalWrite(treuil4, LOW);
        state = OPENINGb;
      }
      break;

    case OPENINGg:
      if(stop2 == HIGH)//the door has hit the open stop button 
      {
      //turn off the motor to open the doors
      digitalWrite(treuil1, LOW);
      digitalWrite(treuil2, LOW);
      delay(10000);
      state = OPENED;
      }
      break;
      
       case OPENINGb:
      if(stop4 == HIGH)//the door has hit the open stop button 
      {
      //turn off the motor to open the doors
      digitalWrite(treuil3, LOW);
      digitalWrite(treuil4, LOW);
      delay(10000);
      state = OPENED;
      }
      break;


    case OPENED:
      if(PG > IR_THRESHOLD) {
        //turn on the motor to close the doors
        digitalWrite(treuil1, LOW);
        digitalWrite(treuil2, HIGH);
        state = CLOSINGg;
      }
      if(PB > IR_THRESHOLD) {
        //turn on the motor to close the doors
        digitalWrite(treuil3, LOW);
        digitalWrite(treuil4, HIGH);
        state = CLOSINGb;
      }
      break;

    case CLOSINGg:
      if(stop1 == HIGH) //the door has hit the close stop button
      {
        //turn off the motor to close the doors
        digitalWrite(treuil1, LOW);
        digitalWrite(treuil2, LOW);
        state = CLOSED;
      }
      break;

    case CLOSINGb:
      if(stop3 == HIGH) //the door has hit the close stop button
      {
        //turn off the motor to close the doors
        digitalWrite(treuil3, LOW);
        digitalWrite(treuil4, LOW);
        state = CLOSED;
      }
      break;

  }
}

I do not get the expected response on each door.

Two doors?

Are talking about two completely separate doors, each with their own motor, pair of stop switches, and IR detectors? Two doors each driven off the same IR detector?

Looking at your code - those ten second delays are going to create trouble.

What you might want to do is to create a struct:

struct Door {
  const byte detectorPin;
  const byte openPin;
  const byte closePin;
  const byte openStopPin;
  const byte closeStopPin;
  State state = CLOSED;
};

Door doorA(A0, 11, 12, 7, 8);
Door doorB(A1, 9, 10, 2, 3);

This bundles all the variables for a single door into a - well - a bundle.

Your loop would then call a sub function, passing it a reference to the door:

void loop() {
  handleDoor(doorA);
  handleDoor(doorB);
}

The handleDoor function looks just about identical to the original loop() function, but rather than using global variables it uses variables taken from the reference that is passed to it:

void handleDoor(Door &door) {
   byte openStop = digitalRead(door.openStopPin);
   byte closeStop = digitalRead(door.closeStopPin);

   int porte = analogRead(door.detectorPin);

   switch(door.state) {
     case CLOSED:
       if(porte < IR_THRESHOLD) {
         //turn on the motor to open the doors
         digitalWrite(door.openPin, HIGH);
         digitalWrite(door.closePin, LOW);
         state = OPENINGg;
       }
       break;


// etc - similar code for OPENING, OPEN, CLOSED
   }
  
}

That way, you have two independent things running on two sets of pins. But you will need to get rid of those delays, otherwise one door will not do anything while the other door is sitting in a delay().

I first answer PaulMurrayCbr’s questions and then later in another post I will try to implement its proposal.
Yes, it is two separated doors, each with its own motor and switches and IR detector, teh PB and PG. But they are both drived by the same Atmega and hence should be run by the same arduino .ino.

When I try the following:

struct Door {
  const byte detectorPin;
  const byte openPin;
  const byte closePin;
  const byte openStopPin;
  const byte closeStopPin;
  State state = CLOSED;
};

Door doorA(A0, 11, 12, 7, 8);
Door doorB(A1, 9, 10, 2, 3);
enum State { CLOSED, OPENING, OPENED, CLOSING } state = OPENED;
int IR_THRESHOLD = 850;

void loop() {
  handleDoor(doorA);
  handleDoor(doorB);
}

void handleDoor(Door &door) {
   byte openStop = digitalRead(door.openStopPin);
   byte closeStop = digitalRead(door.closeStopPin);

   int porte = analogRead(door.detectorPin);

   switch(door.state) {
     case CLOSED:
       if(porte < IR_THRESHOLD) {
         //turn on the motor to open the doors
         digitalWrite(door.openPin, HIGH);
         digitalWrite(door.closePin, LOW);
         state = OPENING;
       }
       break;

  case OPENING:
      if(openStopPin == HIGH)//the door has hit the open stop button 
      {
      //turn off the motor to open the doors
      digitalWrite(openPin, LOW);
      digitalWrite(closePin, LOW);
      //delay(10000);
      state = OPENED;
      }
      break;

    case OPENED:
      if(porte > IR_THRESHOLD) {
        //turn on the motor to close the doors
        digitalWrite(openPin, LOW);
        digitalWrite(closePin, HIGH);
        state = CLOSING;
      }
      break;

    case CLOSING:
      if(closeStopPin == HIGH) //the door has hit the close stop button
      {
        //turn off the motor to close the doors
        digitalWrite(openPin, LOW);
        digitalWrite(closePin, LOW);
        state = CLOSED;
      }
      break;

  }
}

I get these errors:

sketch_jan26a.ino:4:17: error: variable or field ‘handleDoor’ declared void
sketch_jan26a.ino:4:17: error: ‘Door’ was not declared in this scope
sketch_jan26a.ino:4:23: error: ‘door’ was not declared in this scope
sketch_jan26a.ino:8:3: error: ‘State’ does not name a type
sketch_jan26a.ino:11:28: error: no matching function for call to ‘Door::Door(const uint8_t&, int, int, int, int)’
sketch_jan26a.ino:2:8: note: candidate: Door::Door()
sketch_jan26a.ino:2:8: note:   candidate expects 0 arguments, 5 provided
sketch_jan26a.ino:2:8: note: candidate: Door::Door(const Door&)
sketch_jan26a.ino:2:8: note:   candidate expects 1 argument, 5 provided
sketch_jan26a.ino:12:27: error: no matching function for call to ‘Door::Door(const uint8_t&, int, int, int, int)’
sketch_jan26a.ino:2:8: note: candidate: Door::Door()
sketch_jan26a.ino:2:8: note:   candidate expects 0 arguments, 5 provided
sketch_jan26a.ino:2:8: note: candidate: Door::Door(const Door&)
sketch_jan26a.ino:2:8: note:   candidate expects 1 argument, 5 provided
sketch_jan26a.ino: In function ‘void loop()’:
sketch_jan26a.ino:17:19: error: ‘handleDoor’ was not declared in this scope
sketch_jan26a.ino: In function ‘void handleDoor(Door&)’:
sketch_jan26a.ino:27:16: error: ‘struct Door’ has no member named ‘state’
sketch_jan26a.ino:38:10: error: ‘openStopPin’ was not declared in this scope
sketch_jan26a.ino:41:20: error: ‘openPin’ was not declared in this scope
sketch_jan26a.ino:42:20: error: ‘closePin’ was not declared in this scope
sketch_jan26a.ino:51:22: error: ‘openPin’ was not declared in this scope
sketch_jan26a.ino:52:22: error: ‘closePin’ was not declared in this scope
sketch_jan26a.ino:58:10: error: ‘closeStopPin’ was not declared in this scope
sketch_jan26a.ino:61:22: error: ‘openPin’ was not declared in this scope
sketch_jan26a.ino:62:22: error: ‘closePin’ was not declared in this scope

I suppose I forgot something…

Do you think you might need a setup() function?

You have left off door. form quite a few variables.

enum State { CLOSED, OPENING, OPENED, CLOSING } state = OPENED;

struct Door
{
  const byte detectorPin;
  const byte openPin;
  const byte closePin;
  const byte openStopPin;
  const byte closeStopPin;
  State state;
};

Door doorA = {A0, 11, 12, 7, 8, CLOSED};
Door doorB = {A1, 9, 10, 2, 3, CLOSED};

int IR_THRESHOLD = 850;

void setup()
{
  
}

void loop()
{
  handleDoor(doorA);
  handleDoor(doorB);
}

void handleDoor(Door &door)
{
//  byte openStop = digitalRead(door.openStopPin);
//  byte closeStop = digitalRead(door.closeStopPin);

  int porte = analogRead(door.detectorPin);

  switch (door.state)
  {
    case CLOSED:
      if (porte < IR_THRESHOLD)
      {
        //turn on the motor to open the doors
        digitalWrite(door.openPin, HIGH);
        digitalWrite(door.closePin, LOW);
        door.state = OPENING;
      }
      break;

    case OPENING:
      if (door.openStopPin == HIGH) //the door has hit the open stop button
      {
        //turn off the motor to open the doors
        digitalWrite(door.openPin, LOW);
        digitalWrite(door.closePin, LOW);
        //delay(10000);
        door.state = OPENED;
      }
      break;

    case OPENED:
      if (porte > IR_THRESHOLD)
      {
        //turn on the motor to close the doors
        digitalWrite(door.openPin, LOW);
        digitalWrite(door.closePin, HIGH);
        door.state = CLOSING;
      }
      break;

    case CLOSING:
      if (door.closeStopPin == HIGH) //the door has hit the close stop button
      {
        //turn off the motor to close the doors
        digitalWrite(door.openPin, LOW);
        digitalWrite(door.closePin, LOW);
        door.state = CLOSED;
      }
      break;

  }
}

I have tried larryd proposal:

struct Door {
  const byte detectorPin;
  const byte openPin;
  const byte closePin;
  const byte openStopPin;
  const byte closeStopPin;
  State state;
};
enum State { CLOSED, OPENING, OPENED, CLOSING } state = OPENED;

Door doorA(A0, 11, 12, 7, 8, CLOSED);
Door doorB(A1, 9, 10, 2, 3, CLOSED);
int IR_THRESHOLD = 850;
void handleDoor(Door &door);

void loop() {
  handleDoor(doorA);
  handleDoor(doorB);
}

void handleDoor(Door &door) {
  // byte openStop = digitalRead(door.openStopPin);
   //byte closeStop = digitalRead(door.closeStopPin);

   int porte = analogRead(door.detectorPin);

   switch(door.state) {
     case CLOSED:
       if(porte < IR_THRESHOLD) {
         //turn on the motor to open the doors
         digitalWrite(door.openPin, HIGH);
         digitalWrite(door.closePin, LOW);
         door.state = OPENING;
       }
       break;

  case OPENING:
      if(door.openStopPin == HIGH)//the door has hit the open stop button
      {
      //turn off the motor to open the doors
      digitalWrite(door.openPin, LOW);
      digitalWrite(door.closePin, LOW);
      //delay(10000);
      door.state = OPENED;
      }
      break;

    case OPENED:
      if(porte > IR_THRESHOLD) {
        //turn on the motor to close the doors
        digitalWrite(door.openPin, LOW);
        digitalWrite(door.closePin, HIGH);
        door.state = CLOSING;
      }
      break;

    case CLOSING:
      if(door.closeStopPin == HIGH) //the door has hit the close stop button
      {
        //turn off the motor to close the doors
        digitalWrite(door.openPin, LOW);
        digitalWrite(door.closePin, LOW);
        door.state = CLOSED;
      }
      break;

  }
}

and I get a whole bunch of errors:

religion_ganesh_larryd.ino:8:3: error: ‘State’ does not name a type
religion_ganesh_larryd.ino:12:36: error: no matching function for call to ‘Door::Door(const uint8_t&, int, int, int, int, State)’
religion_ganesh_larryd.ino:2:8: note: candidate: Door::Door()
religion_ganesh_larryd.ino:2:8: note:   candidate expects 0 arguments, 6 provided
religion_ganesh_larryd.ino:2:8: note: candidate: Door::Door(const Door&)
religion_ganesh_larryd.ino:2:8: note:   candidate expects 1 argument, 6 provided
religion_ganesh_larryd.ino:13:35: error: no matching function for call to ‘Door::Door(const uint8_t&, int, int, int, int, State)’
religion_ganesh_larryd.ino:2:8: note: candidate: Door::Door()
religion_ganesh_larryd.ino:2:8: note:   candidate expects 0 arguments, 6 provided
religion_ganesh_larryd.ino:2:8: note: candidate: Door::Door(const Door&)
religion_ganesh_larryd.ino:2:8: note:   candidate expects 1 argument, 6 provided
religion_ganesh_larryd.ino: In function ‘void handleDoor(Door&)’:
religion_ganesh_larryd.ino:28:16: error: ‘struct Door’ has no member named ‘state’
religion_ganesh_larryd.ino:34:15: error: ‘struct Door’ has no member named ‘state’
religion_ganesh_larryd.ino:45:12: error: ‘struct Door’ has no member named ‘state’
religion_ganesh_larryd.ino:54:14: error: ‘struct Door’ has no member named ‘state’
religion_ganesh_larryd.ino:64:14: error: ‘struct Door’ has no member named ‘state’

I guess I did something wrong in building the struct, but I don’t know how to do it right!

That is not the sketch I posted.

Try copying it again. :wink:

That is your proposed sketch:

enum State { CLOSED, OPENING, OPENED, CLOSING } state = OPENED;

struct Door
{
  const byte detectorPin;
  const byte openPin;
  const byte closePin;
  const byte openStopPin;
  const byte closeStopPin;
  State state;
};

Door doorA = {A0, 11, 12, 7, 8, CLOSED};
Door doorB = {A1, 9, 10, 2, 3, CLOSED};

int IR_THRESHOLD = 850;

void setup()
{
 
}

void loop()
{
  handleDoor(doorA);
  handleDoor(doorB);
}

void handleDoor(Door &door)
{
//  byte openStop = digitalRead(door.openStopPin);
//  byte closeStop = digitalRead(door.closeStopPin);

  int porte = analogRead(door.detectorPin);

  switch (door.state)
  {
    case CLOSED:
      if (porte < IR_THRESHOLD)
      {
        //turn on the motor to open the doors
        digitalWrite(door.openPin, HIGH);
        digitalWrite(door.closePin, LOW);
        door.state = OPENING;
      }
      break;

    case OPENING:
      if (door.openStopPin == HIGH) //the door has hit the open stop button
      {
        //turn off the motor to open the doors
        digitalWrite(door.openPin, LOW);
        digitalWrite(door.closePin, LOW);
        //delay(10000);
        door.state = OPENED;
      }
      break;

    case OPENED:
      if (porte > IR_THRESHOLD)
      {
        //turn on the motor to close the doors
        digitalWrite(door.openPin, LOW);
        digitalWrite(door.closePin, HIGH);
        door.state = CLOSING;
      }
      break;

    case CLOSING:
      if (door.closeStopPin == HIGH) //the door has hit the close stop button
      {
        //turn off the motor to close the doors
        digitalWrite(door.openPin, LOW);
        digitalWrite(door.closePin, LOW);
        door.state = CLOSED;
      }
      break;

  }
}

and that is the errors I get when I try to run it on Arduino 2:1.0.5:

sketch_jan28a.ino:4:17: error: variable or field ‘handleDoor’ declared void
sketch_jan28a.ino:4:17: error: ‘Door’ was not declared in this scope
sketch_jan28a.ino:4:23: error: ‘door’ was not declared in this scope
sketch_jan28a.ino: In function ‘void loop()’:
sketch_jan28a.ino:25:19: error: ‘handleDoor’ was not declared in this scope

No errors seen when you use IDE 1.69.

.

Compiled with IDE ver. 1.8.5.

OK. It compiles alright with version 1.8.5.
I still have a question. How can I define openPin and closePin as output? Generally we do it in setup() with

pinMode(openPin, OUTPUT);

here openPin "was not declared"...

You read the pin with:

digitalWrite(door.openPin, HIGH);

Wouldn't you set the pinMode the same way (door.openPin)?

Yes, that is the good way to do it, but you have to place

pinMode(door.openPin, OUTPUT);
  pinMode(door.closePin, OUTPUT);

in void handleDoor(Door &door) and not in setup().