Problem with sequence

Hi, im some days doing a proyect of a auto door, but i having some problems with that.

Im using:

Dual-H L298N for up and down door.
x2 Adjustable IR Reflection Sensor, detect person down of door, and too use for auto open door.
x2 Micro Limit Switch, up and down.
The program detects motion up the door, after a while if it does not detect anything under proceeds to lower it, if at the time it detects something is dropping down, up and back down past the time.

The problem that I have, that makes me whole cycle well, but when the door to stay down low, instead of stopping, automatically rises, and when it comes up ignores the upper limit. Here I put the program to see if anyone could help me, thanks.

#include <WProgram.h>
#include <NECIRrcv.h> 
#include <SoftwareSerial.h> 

#define motor_arriba 7
#define motor_abajo 6

#define IR_obstaculo_1 12
#define IR_obstaculo_2 11

#define FC_arriba 10
#define FC_abajo 9

#define IR_mando 8

#define led_manual 5

#define pulsa_auto_man 4
#define pulsa_s_b 3

#define tiempo_arriba 5000 //time door up
#define tiempo_ir 2000 //timer door up extra when detect some down

int modo = 0; //mode 0 - auto, mode 1 - mode manual.

NECIRrcv ir(IR_mando);

long boton1 = 4278254850;  //Botton auto/manual
long boton2 = 4228119555;  //Botton up door
long boton3 = 4244831235;  //Botton down door

void setup() {
  pinMode(IR_obstaculo_1, INPUT);
  pinMode(IR_obstaculo_2, INPUT);
  pinMode(FC_arriba, INPUT);
  pinMode(FC_abajo, INPUT);
  pinMode(pulsa_auto_man, INPUT);
  pinMode(pulsa_s_b, INPUT);
 
  //Declaramos las salidas
  pinMode(motor_arriba, OUTPUT);
  pinMode(motor_abajo, OUTPUT);
  pinMode(led_manual, OUTPUT);

  Serial.begin(9600);
  ir.begin();
  Serial.println("Iniciando puerto serie") ; 
}

void loop(){

  unsigned long ircode;
  while (ir.available())
  {
    ircode = ir.read(); 
  
     if ( ircode == boton1 )
     {
       auto_on_off();
     }
    
        //UP
     if (modo == 1)
     {
        if ( ircode == boton2 && digitalRead(FC_abajo)==HIGH && digitalRead(FC_arriba)==LOW && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==LOW ) //MANDAMOS LA ORDEN DE SUBIR LA PUERTA
         {
         subidamanual:
         Serial.println("Mode auto: Go up") ;
         motoressubiendo(); 
         }
        //Start go down
        if ( ircode == boton3 && digitalRead(FC_abajo)==LOW && digitalRead(FC_arriba)==HIGH && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==LOW && digitalRead(IR_obstaculo_1)==HIGH && digitalRead(IR_obstaculo_2)==HIGH )
        {
          motoresbajando();
        }    
     }   
/////////////////////////////////
  }//END-WHILE
if (modo == 0)
{
     if ( digitalRead(IR_obstaculo_2)==LOW || digitalRead(IR_obstaculo_1)==LOW )
     {
       Serial.println("DETECT") ;
       if ( digitalRead(FC_abajo)==HIGH && digitalRead(FC_arriba)==LOW && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==LOW && digitalRead(IR_obstaculo_2)==LOW || digitalRead(IR_obstaculo_1)==LOW )
       {
       subida:
       Serial.println("Mode auto.. Starting") ;
       motoressubiendo();
       delay(5);
       }
     }//ENDBOTON
   }//END-MODO  


if (modo == 1)
{
        //STOP UP
        if ( digitalRead(FC_abajo)==LOW && digitalRead(FC_arriba)==HIGH && digitalRead(motor_arriba)==HIGH && digitalRead(motor_abajo)==LOW )
        {
          Serial.println("Mode auto: Door up, stop motor..") ;
          pararmotores(); //activamos la parada
        }
        
       
        //DOOR DOWN STOP
        if ( digitalRead(FC_abajo)==HIGH && digitalRead(FC_arriba)==LOW && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==HIGH )
          {
            pararmotores();
          }
         
         //GOING DOWN, AND DETECT SOME
        if ( digitalRead(FC_abajo)==LOW && digitalRead(FC_arriba)==LOW && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==HIGH ) 
         {
         if ( digitalRead(IR_obstaculo_1)==LOW || digitalRead(IR_obstaculo_2)==LOW ) //GOING DOWN, AND DETECT SOME
           {
             pararmotores();
             goto subidamanual;
           }
         }
}

if (modo == 0)
{
if ( digitalRead(FC_abajo)==LOW && digitalRead(FC_arriba)==HIGH && digitalRead(motor_arriba)==HIGH && digitalRead(motor_abajo)==LOW ) //Door up
{
  Serial.println("Mode auto.. Door up, stop motor..") ;
  pararmotores(); //Stop motor
  Serial.println("Mode auto.. Waiting") ;
  delay(tiempo_arriba); 
   irdetectado:
      Serial.println("Mode auto.. Waiting timer") ;
      delay(tiempo_ir);
  if ( digitalRead(FC_abajo)==LOW && digitalRead(FC_arriba)==HIGH && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==LOW && digitalRead(IR_obstaculo_1)==HIGH && digitalRead(IR_obstaculo_2)==HIGH)
    {
      motoresbajando(); //Start down motor
    }
  else
    {
      Serial.println("Mode auto... Some down of door") ;
      goto irdetectado; //
    }
}

//Going down and detect some
if ( digitalRead(FC_abajo)==LOW && digitalRead(FC_arriba)==LOW && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==HIGH )
{
   if ( digitalRead(IR_obstaculo_1)==LOW && digitalRead(IR_obstaculo_2)==LOW)
   {
      Serial.println("Mode auto... || IR object") ;
     pararmotores();
     goto subida;
   }
}
//
if ( digitalRead(FC_abajo)==HIGH && digitalRead(FC_arriba)==LOW && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==HIGH ) //Door down
{
  pararmotores();
}   
}

//Pulsador AUTO/MAN
if ( digitalRead(pulsa_auto_man)==HIGH ) //Change to mode auto or manual
{
delay(500);
auto_on_off();
}

if ( modo == 1 && digitalRead(pulsa_s_b)==HIGH && digitalRead(FC_abajo)==HIGH && digitalRead(FC_arriba)==LOW && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==LOW ) //MANDAMOS LA ORDEN DE SUBIR LA PUERTA
{
  motoressubiendo(); 
  }

if ( modo == 1 && digitalRead(pulsa_s_b)==HIGH && digitalRead(FC_abajo)==LOW && digitalRead(FC_arriba)==HIGH && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==LOW && digitalRead(IR_obstaculo_1)==HIGH && digitalRead(IR_obstaculo_2)==HIGH )
  {
   motoresbajando();
  }  
}//END-LOOP

//FUNCIONES
void pararmotores()
{
  digitalWrite(motor_abajo, LOW);
  digitalWrite(motor_arriba, LOW);
}

void motoressubiendo()
{
  digitalWrite(motor_abajo, LOW);
  delay(1);
  digitalWrite(motor_arriba, HIGH);
}

void motoresbajando()
{
  digitalWrite(motor_arriba, LOW);
  delay(1);
  digitalWrite(motor_abajo, HIGH);
}

void auto_on_off()
{
  if ( digitalRead(FC_abajo)==HIGH && digitalRead(FC_arriba)==LOW && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==LOW )
  {
    if (modo == 0)
        {
          modo = 1;
          digitalWrite(led_manual, HIGH);
        }   
       else
       {
         modo = 0;
         digitalWrite(led_manual, LOW);
       }
   }   
   else
   {
        Serial.println("Door need be down for change mode") ;
   }
}

Thanks again.

start with making these

long boton1 = 4278254850; //Botton auto/manual
long boton2 = 4228119555; //Botton up door
long boton3 = 4244831235; //Botton down door

unsigned long

so type is right.

Then, use the Tools + Auto Format
tool to stop the
code from jumping
all over
the page.

Then, get rid of all the labels and goto statements. They are completely unnecessary.

robtillaart:
start with making these

long boton1 = 4278254850; //Botton auto/manual
long boton2 = 4228119555; //Botton up door
long boton3 = 4244831235; //Botton down door

unsigned long

so type is right.

That not problem.

PaulS:
Then, use the Tools + Auto Format
tool to stop the
code from jumping
all over
the page.

Then, get rid of all the labels and goto statements. They are completely unnecessary.

Ill use auto format next time, and abount goto, i used for repeat some secuences, for example when IR Reflect, detect some, go to up program and repeat that part for up again door and check if some is on IR Reflect and go back door again.

After some test today, i change DUAL H BRIDGE for two leds, for simulator motor, and when two leds dont success that, maybe i need diode on output of motor for fix that problem??

thanks again for help.

and abount goto, i used for repeat some secuences,

No you never never never us a goto in C. If you do then you are doing it wrong and need to look at your code structure.

rmrmrm:

robtillaart:
start with making these

long boton1 = 4278254850; //Botton auto/manual
long boton2 = 4228119555; //Botton up door
long boton3 = 4244831235; //Botton down door

unsigned long

so type is right.

That not problem.

But it will be.
Programming is about getting the code exact right and that's why it is hard. If you don't care about visible bugs how to recognize the really hidden ones?

To get your code do what you want you must define a state machine. Mainly that can be implemented by one or more variables that reflect the state of your car door and only under exactly defined conditions the state is changed. And when the state is changed it is "mapped " upon the real door. To see the state change you need a current and a previous state.

you will not need so many of these -

if (ircode == boton2 && digitalRead(FC_abajo)==HIGH && digitalRead(FC_arriba)==LOW && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==LOW ) ...

FCabajo FC_arriba motor_arriba and motor_abajo are now pins but if you make state variables out of it: (abajo == down arriba == up)

if you use state variables you can guard that when FC_abajo == HIGH FC_Arriba == LOW. They cannot be HIGH simultaneously (If I understand your code)
Same for the motors the arriba and abajo motor cannot be HIGH both

e.g. Motor = { off, up, down } // both motors of or one of the two on, thats all the state the motors can have

with some rework your code becomes something like

if ( button2Pressed && FC == UP && Motor == OFF)

google on state-machines.

robtillaart:

rmrmrm:

robtillaart:
start with making these

long boton1 = 4278254850; //Botton auto/manual
long boton2 = 4228119555; //Botton up door
long boton3 = 4244831235; //Botton down door

unsigned long

so type is right.

That not problem.

But it will be.
Programming is about getting the code exact right and that's why it is hard. If you don't care about visible bugs how to recognize the really hidden ones?

To get your code do what you want you must define a state machine. Mainly that can be implemented by one or more variables that reflect the state of your car door and only under exactly defined conditions the state is changed. And when the state is changed it is "mapped " upon the real door. To see the state change you need a current and a previous state.

you will not need so many of these -

if (ircode == boton2 && digitalRead(FC_abajo)==HIGH && digitalRead(FC_arriba)==LOW && digitalRead(motor_arriba)==LOW && digitalRead(motor_abajo)==LOW ) ...

FCabajo FC_arriba motor_arriba and motor_abajo are now pins but if you make state variables out of it: (abajo == down arriba == up)

if you use state variables you can guard that when FC_abajo == HIGH FC_Arriba == LOW. They cannot be HIGH simultaneously (If I understand your code)
Same for the motors the arriba and abajo motor cannot be HIGH both

e.g. Motor = { off, up, down } // both motors of or one of the two on, thats all the state the motors can have

with some rework your code becomes something like

if ( button2Pressed && FC == UP && Motor == OFF)

google on state-machines.

Hi again, thanks for help, i do more easy program for try debug that, but problem continue:

#include <WProgram.h>
#include <NECIRrcv.h> //Libreria del protocolo NEC
#include <SoftwareSerial.h> //ARDUINO 1++

#define motor_arriba 4
#define motor_abajo 3

#define FC_arriba 10
#define FC_abajo 9

#define pulsa_auto_man 6
#define pulsa_s_b 5

void setup() {
  pinMode(FC_arriba, INPUT);
  pinMode(FC_abajo, INPUT);
  pinMode(pulsa_auto_man, INPUT);
  pinMode(pulsa_s_b, INPUT);

  pinMode(motor_arriba, OUTPUT);
  pinMode(motor_abajo, OUTPUT);
  Serial.begin(9600);

  Serial.println("Iniciando puerto serie") ; 
}

void loop()
{
  int fc_abajo = digitalRead(FC_abajo); 
  int Pulsa_auto_man = digitalRead(pulsa_auto_man);
  int Motor_arriba = digitalRead(motor_arriba);
  int Motor_abajo = digitalRead(motor_abajo);
  int fc_arriba = digitalRead(FC_arriba);

  if ( fc_abajo == HIGH ) {
    if ( Pulsa_auto_man == HIGH && Motor_arriba == LOW && Motor_abajo == LOW)
    {
      Serial.println("Pulsado") ;
      delay(200);
      digitalWrite(motor_arriba, HIGH);
    }
    if (Motor_abajo == HIGH){
      digitalWrite(motor_abajo, LOW);
      digitalWrite(motor_arriba, LOW);
    }
  }

  if ( fc_arriba == HIGH )
  {
    if( Motor_arriba == HIGH )
    {
      digitalWrite(motor_abajo, LOW);
      digitalWrite(motor_arriba, LOW);
      Serial.println("Arriba") ;
      delay(2000);
      digitalWrite(motor_abajo, HIGH);
    }
  }
}

Log of actions:

I press botton when the door is down.
Start to up door.
Push limit up, and stop door.
Waiting time..
Start go do down.
Push limit up, and stop door --> that is finish of button sequence, next step, i dont know because success.
Start to up door
Ignore limit up, and motor dont stop.

Someone know why can success that?? thanks again.

I find it impossible to make sense of the code, because all of the variable names are written in a foreign language and none of them are intelligible.

It would help if you could put an English comment next to each variable definition to explain what value it holds.

I notice that you have several variables and constants which have the same name just with different capitalisation. That's a very bad idea since it makes it harder to keep track of which is which - and also makes it more likely that you will use the wrong one somewhere by mistake. In this case it's even worse because you are not consistent about which ones use upper case.

I recommend that you get into the habbit of writing constant values all in UPPERCASE

#define FC_ABAJO_PIN 9

and write all your variable names in lowercase

int fc_abajo = digitalRead(FC_ABAJO_PIN);

Now if only I knew what FC meant and what ABAJO meant I would be able to work out what the value represented.

You have reason, I apologize, here I copy the translation yet and the advice he gave me I applied too, thanks again for your help. Excuse my low level in English.

#include <WProgram.h>
#include <NECIRrcv.h> //Libreria del protocolo NEC
#include <SoftwareSerial.h> //ARDUINO 1++

#define MOTOR_UP_PIN 4
#define MOTOR_DOWN_PIN 3

#define LIMIT_UP_PIN 10
#define LIMIT_DOWN_PIN 9

#define BUTTON_UP_PIN 6

void setup() {
  pinMode(LIMIT_UP_PIN, INPUT);
  pinMode(LIMIT_DOWN_PIN, INPUT);
  pinMode(BUTTON_UP_PIN, INPUT);

  pinMode(MOTOR_UP_PIN, OUTPUT);
  pinMode(MOTOR_DOWN_PIN, OUTPUT);
  Serial.begin(9600);

}

void loop()
{
  int limit_down = digitalRead(LIMIT_DOWN_PIN); 
  int button_up = digitalRead(BUTTON_UP_PIN);
  int motor_up = digitalRead(MOTOR_UP_PIN);
  int motor_down = digitalRead(MOTOR_DOWN_PIN);
  int limit_up = digitalRead(LIMIT_UP_PIN);

  if ( limit_down == HIGH ) { //DOOR STAY DOWN
    if ( button_up == HIGH && motor_up == LOW && motor_down == LOW) //PRESS BUTON AND NONE MOTOR IS ACTIVE
    {
      delay(200);
      digitalWrite(MOTOR_UP_PIN, HIGH); //Door start to up
    }
    if (motor_down == HIGH){ //When press limit down and is actived motor down, stop that and stop door on limit down.
      digitalWrite(MOTOR_DOWN_PIN, LOW); //Stop motor
      digitalWrite(MOTOR_UP_PIN, LOW); //Maybe that not necesary, but i put for secury of DUAL-H
    }
  }

  if ( limit_up == HIGH ) //Door on limit button (Door arrived up)
  {
    if( motor_up == HIGH ) //And motor for up door is active.
    {
      digitalWrite(MOTOR_UP_PIN, LOW); //Stop motor 
      digitalWrite(MOTOR_DOWN_PIN, LOW); //Maybe that not necesary, but i put for secury of DUAL-H
      delay(2000); //Wait some seconds...
      digitalWrite(MOTOR_DOWN_PIN, HIGH); //And start again to go down. Now need press again buton for do a new cycle of the door.
    }
  }
}

Thanks to all!

I continued trying things, to try to fix the problem, and I've noticed that if I turn down the door and the x seconds it stops, it stops and goes back up.? Maybe my problem comes from below limit? Can be software or hardware?

I think that it would help if you developed a state machine. Think about the states that the door can be in. Open, closed, opening, and closing come to mind.

There are actions that cause a transition from one state to another.

There is no reason to read all 5 switches on every pass through loop(). If the door is closed, the state of the limit switches doesn't matter, so don't read them. Only the state of the open switch matters.

Create functions to call when a transition needs to occur. If the door is closed, and the open switch is pressed, call the openTheDoor() function. If the door is open, and the close switch is pressed, call the closeTheDoor() function.

In those function, you need monitor only two switches. If the door is closing, use a while loop to monitor the is-closed limit switch and the open switch. Take appropriate action (return) if the open switch is pressed. Break out of the while loop if the is-closed switch is pressed.

Consider whether what is important about the switch is that it is pressed or that is became pressed. If what is important is that the switch became pressed, then you need to keep track of the previous state of the switch.

The new English code is much easier to follow, thank you.

You don't seem to have any code dealing with IR sensing.

The code is not structured in a way that makes it easy to follow the logic, but as far as I can see the logic would result in the sequence you want: where the door is initially closed and you press the 'up' button the door would start opening and would then stop when it reaches the fully-open position, delay briefly and then start closing again. When it reaches the fully-closed position it will stop.

I can't tell whether you have got the switches wired correctly (so that they actually read HIGH when they're pressed and LOW when they aren't pressed) and I can't tell whether the motor is wired correctly so that the door moves up when you set MOTOR_UP_PIN to HIGH and down when you set MOTOR_DOWN_PIN to HIGH. It's easy to imagine a collection of wiring faults which meant that the sketch appeared to work but actually had the reverse logic to what you intended so that when the sketch thinks the door is open it is actually closed - this would result in the sort of problem you had at the beginning.

I agree with PaulS's suggestion to use a finite state machine since this would make the logic much simpler and more robust. However, before doing that I suggest you create a test sketch that just prints out the switch positions and proves that when you try to move the control the motor is actually does what you intend. Unless the basic inputs and outputs are working correctly, nothing else is going to work no matter how you structure your sketch.

Hello again, thanks for the segurencias, the'll take out. But for now, I need to find where my problem, respecting the wiring is correct, HIGH when activated and engines also sense is correct, all that I have checked and it's fine. These days simplify the program, which only lowered the door and tapping the down limit stop. and the result was that the door began to fall, but when low, I play, but ignores the order, adding that the limit is not broken and that pressing perfectamete arduino and I detect it returns 1. Well, at the bottom, changes polarity and the door is infinitely fed.

Any idea? Thanks again to all and thanks for the I welcome your comments to improve my programming newbie. greetings to all!

Your English is still very challenging to understand but I get that when the door reaches the bottom it starts up all on its own and does not stop at the top.

The only code I can see that would make the door go up is at line 36:

digitalWrite(MOTOR_UP_PIN, HIGH); //Door start to up

I suggest you put a Serial.print statement here to tell you for certain that this line of code is executing when the problem starts.

If this statement is executing then it implies that (limit_down == HIGH ) and (button_up == HIGH) and (motor_up == LOW) and (motor_down == LOW).

Clearly if you have not pressed the 'up' button then we do not expect (button_up == HIGH) so this should not have happened. So, print out the actual value of button_up at this point and see whether it matches the physical state of the button. If it doesn't match then this implies a wiring fault or a faulty switch.