Ouvre porte automatique

Hello,

je m'amuse un peu avec l'Arduino.

Ici, je voudrais faire un ouvre porte automatique avec un Nema 17 (pour le couple et la précision) et des PIR pour la détection de mouvement de chaque côté de la porte.

Un ouvre-porte comme à l'entrée des grandes surfaces, quoi.
Mais applicable pour une moustiquaire dans mon cas. :grin:

Ca fonctionne nickel, je n'ai plus qu'à mettre une courroie sur le Nema pour entraîner la porte.

Mais pour que ce soit parfait, je dois encore entrer 2 paramètres :

  • un pot pour régler la vitesse d'ouverture
  • un paramètre pour lui dire que si le mouvement est interrompu par une nouvelle présence, il repart en mode ouverture.

J'ai mis le shéma de câblage ici : http://standon.be/WP3/ouvre-porte-automatique/

Si vous saviez me donner des pistes, ce serait génial.

#define stp 2
#define dir 3
#define MS1 4
#define MS2 5
#define EN  6
int PIRSensor = 9;
int ledOn = 13;
int ledOff = 12;
// Variables
char user_input;
int x;
int y;
int state;

void setup() {
  Serial.begin(9600);
  pinMode(PIRSensor, INPUT);
  pinMode(ledOn, OUTPUT);
  pinMode(ledOff, OUTPUT);
  digitalWrite(PIRSensor, HIGH);
  pinMode(stp, OUTPUT);
  pinMode(dir, OUTPUT);
  pinMode(MS1, OUTPUT);
  pinMode(MS2, OUTPUT);
  pinMode(EN, OUTPUT);
  resetEDPins(); // Remise a zero des pas
  Serial.begin(9600); // Fenetre Serial pour debug
  Serial.println("Systeme OK.");
  Serial.println("Led Verte.");    
  Serial.println("En attente de passage.");
  Serial.println("");
  digitalWrite(ledOn, LOW);
  digitalWrite(ledOff, HIGH);
 
}
 
void loop() {

  digitalWrite(EN, LOW);
  int buttonState = digitalRead(PIRSensor);
 
  if(buttonState==0) 
  {
        digitalWrite(ledOn, HIGH);
        digitalWrite(ledOff, LOW);
        ForwardBackwardStep();

  }
  else {
    digitalWrite(ledOn, LOW);
    digitalWrite(ledOff, HIGH);
    resetEDPins();

  }
}

// Reset de l'Easy Driver
void resetEDPins()
{
  digitalWrite(stp, LOW);
  digitalWrite(dir, LOW);
  digitalWrite(MS1, LOW);
  digitalWrite(MS2, LOW);
  digitalWrite(EN, HIGH);
}

// Fonction avance-recule
void ForwardBackwardStep()
{
    Serial.println("");
    Serial.println("Signal recu");
    Serial.println("Led Rouge.");
    Serial.println("Mouvement moteur 2000 pas a gauche = 10 tours.");
    Serial.println("");
  for(x= 1; x<3; x++)  // <3 = 1 tour a gauche un tour a droite
  {
    // lit la direction et la change
    state=digitalRead(dir);
    if(state == HIGH)
    {
      digitalWrite(dir, LOW);
      Serial.println("Porte ouverte 5 secondes.");
      delay (5000); //stop pendant 5 secondes
      Serial.println("");
      Serial.println("Mouvement moteur 2000 pas a droite = 10 tours.");
      Serial.println("");
    }
    else if(state ==LOW)
    {
      digitalWrite(dir, HIGH);
    }
    
    for(y=1; y<2000; y++) // nombre de pas
    {
      digitalWrite(stp,HIGH); // Mise en route du moteur
      delay(1);
      digitalWrite(stp,LOW); // Continue le mouvement
      delay(1);
    }
  }
  Serial.println("Porte fermee.");
  Serial.println("Led verte.");
  Serial.println("");
  Serial.println("En attente de passage.");
  Serial.println("");
  }

faut virer les delay() et faire une machine à états car il vous faudra lire les PIRs pendant que les moteurs bougent (faire un pas, lire les capteurs, si temps lié à la vitesse choisie expiré alors faire un pas, lire les capteurs,si temps lié à la vitesse choisie expiré alors faire un pas, lire les capteurs,si temps lié à la vitesse choisie expiré alors faire un pas, lire les capteurs etc)

Bonjour,

Il n'y a pas besoin de faire des microstep, il suffit de le faire tourner continuellement jusqu’à la fin de sa course, d’où l'utilisation d'un capteur "fin de course" dans ce genre d'automatisme.

Il faut tout de même faire attention a l'aspect sécurité.

Que se passe t-il si un objet bloque la porte durant la fermeture ?

Oui on peut aussi lancer le moteur mais dans ce cas faut pouvoir l'arrêter

(Je pensais à un servo pour qui la commande est bloquante)

OK, vous avez raison, il faut mettre des interrupteurs en fin de course de la porte.
1 à la fin de l’ouverture, attente de 3 secondes et fermeture.
1 a la fin de la fermeture qui stop le moteur et qui remet l’Arduino en attente d’un nouveau passage.
C’est plus simple en fait.

J’ai donc refait code.

La vitesse du moteur est réglée dans le code en microsecondes.
Plus besoin de potentiomètre.

Reste que si la porte est en mouvement de fermeture et qu’un nouveau passage est détecté, elle doit se rouvrir, attendre 3 secondes et se fermer.

Comment je peut faire ça ?
Avec un interrupts() ?

Merci pour votre éclairage :sweat_smile:

#define DISTANCE 200000

int StepCounter = 0;
int Stepping = false;
int ledverte = 12;
int ledrouge = 13;

void setup() {
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);

  pinMode(3, INPUT); // sensor
  pinMode(4, INPUT); // butee gauche
  pinMode(5, INPUT); // butee droite

  pinMode(ledverte, OUTPUT);
  pinMode(ledrouge, OUTPUT);
  digitalWrite(ledverte, HIGH); 
  digitalWrite(ledrouge, LOW); 
}

void loop() {

  if (digitalRead(4) == LOW && Stepping == true)
  {
  StepCounter = 0;
  delay (3000);
  digitalWrite(8, LOW);
  
  Stepping = true;
  }
  if (digitalRead(3) == LOW && Stepping == false)
  {
    digitalWrite(8, HIGH);
    Stepping = true;
    digitalWrite(ledrouge, HIGH);
    digitalWrite(ledverte, LOW);  
  }
  if (Stepping == true)
  {
    digitalWrite(9, HIGH);
    delayMicroseconds(50);
    digitalWrite(9, LOW);
    delayMicroseconds(50);

    StepCounter = StepCounter + 1;

    if (StepCounter == DISTANCE)
    {
      StepCounter = 0;
      Stepping = false;

     }
  if (digitalRead(5) == LOW && Stepping == true)
  {
   StepCounter = 0;
   Stepping = false;
   digitalWrite(ledrouge, LOW);
   digitalWrite(ledverte, HIGH);  
  }
  }
  }

Voilà, c'est terminé.
Il suffisait de lui donner une condition en plus.

Reste plus qu'à monter le mécanisme de la moustiquaire qui glissera latéralement sur un rail :wink:

Merci pour votre aide.

#define DISTANCE 200000 // nombre de tours = 200 pas = 1 tour
                        // ici la distance est très longue, peu importe, le moteur se coupera quand il arrivera sur une butée

int StepCounter = 0;    // déclaration et mise à 0 du compteur
int Stepping = false;   // declaration du nombre de pas = ne pas compter
int ledverte = 12;
int ledrouge = 13;

void setup() {
  pinMode(8, OUTPUT);   // direction
  pinMode(9, OUTPUT);   // moteur
  digitalWrite(8, LOW); // RAZ mouvement
  digitalWrite(9, LOW); // RAZ moteur

  pinMode(3, INPUT);    // sensor
  pinMode(5, INPUT);    // butee gauche
  pinMode(4, INPUT);    // butee droite

  pinMode(ledverte, OUTPUT);
  pinMode(ledrouge, OUTPUT);
  digitalWrite(ledverte, HIGH); // led verte allumee
  digitalWrite(ledrouge, LOW);  // led rouge eteinte
}

void loop() {

   if (digitalRead(3) == LOW && Stepping == false) // si détection de mouvement et moteur arrete
  {
    digitalWrite(8, HIGH); // le moteur se met en ouverture
    Stepping = true; // lancement du compteur
    digitalWrite(ledrouge, HIGH); // pour indiquer qu'il y a mouvement
    digitalWrite(ledverte, LOW);  
  }

  if (digitalRead(5) == LOW && Stepping == true) // si butee gauche ou nombre de pas pas atteint, le moteur continue le mouvement
  {
  StepCounter = 0; // met le compteur à 0 avant de recompter dans l'autre sens
  delay (3000); // attend 3 secondes
  digitalWrite(8, LOW); // part en fermeture
  Stepping = true; // lancement du compteur
  }

   if (digitalRead(3) == LOW && Stepping == true) // si mouvement détecte et lit le nombre de pas pendant la fermeture, le moteur repart en ouverture
   {
   digitalWrite(8, HIGH);
   }
   
  if (Stepping == true) // mouvement général du moteur
  {
    digitalWrite(9, HIGH);
    delayMicroseconds(50); // vitesse en microsecondes
    digitalWrite(9, LOW);
    delayMicroseconds(50); // vitesse en microsecondes
    StepCounter = StepCounter + 1; // incrémentation du nombre de tours

  if (StepCounter == DISTANCE)  // si le compteur atteind le nombre de tours
    {
    StepCounter = 0; // se remet a 0
    Stepping = false; // le moteur se coupe
     }

 if (digitalRead(4) == LOW && Stepping == true) // si arrive en butée droite
  {
   StepCounter = 0; // met le compteur à 0
   Stepping = false; // arrete de compter les tours
   delay (1000); // attente 1 seconde et...
   digitalWrite(ledrouge, LOW);
   digitalWrite(ledverte, HIGH); // met les leds en potion standby  
  }
  }
  }

Oui mais non.

J’suis bête, Il fallait ajouter un état des boutons.

Quand le moteur arrive en butée, le capteur de fin de course est appuyé mécaniquement.
Tout s’arrète jusqu’à sa libération.

Alors, il faut dire aux boutons qu’ils reçoivent juste une impulsion et puis qu’ils changent d’état.

J’ai modifié le câblage et le code.

#define DISTANCE 200000             // nombre de tours = 200 pas = 1 tour
                                    // ici la distance est tres longue, peu importe, le moteur se coupera quand il arrivera sur une butee


int StepCounter = 0;                // declaration et mise a 0 du compteur
int Stepping = false;               // declaration du nombre de pas = ne pas compter
int ledverte = 12; // Led verte temoin de standby
int ledrouge = 13; // Led rouge temoin de mouvement
const int BUTTON_GAUCHE = 5;        // butee gauche sur pin 5
const int BUTTON_DROIT = 4;         // butee droite sur pin 4
int val = 0;                        // valeur qui enreistre l'etat du bouton GAUCHE
int old_val = 0;                    // ancienne valeur du bouton - remise a zero si necessaire
int state = 0;                      // 0 off, 1 on
int val1 = 0;                        // valeur qui enreistre l'etat du bouton DROIT
int old_val1 = 0;                    // ancienne valeur du bouton - remise a zero si necessaire
int state1 = 0;                      // 0 off, 1 on


void setup() {
  pinMode(8, OUTPUT);                // direction
  pinMode(9, OUTPUT);                // moteur
  digitalWrite(8, LOW);              // RAZ mouvement
  digitalWrite(9, LOW);              // RAZ moteur


  pinMode(3, INPUT);                 // PIR pour détection de mouvement
  pinMode(BUTTON_GAUCHE,INPUT_PULLUP);      // definit la pin 5 comme entree (pull-up)
  pinMode(BUTTON_DROIT,INPUT_PULLUP);       // definit la pin 4 comme entree (pull-up)


  pinMode(ledverte, OUTPUT);
  pinMode(ledrouge, OUTPUT);
  digitalWrite(ledverte, HIGH);       // led verte allumee
  digitalWrite(ledrouge, LOW);        // led rouge eteinte
}


void loop() {


   if (digitalRead(3) == LOW && Stepping == false) // si détection de mouvement et moteur arrete
  {
    digitalWrite(8, HIGH);             // le moteur se met en ouverture
    Stepping = true;                   // lancement du compteur
    digitalWrite(ledrouge, HIGH);      // pour indiquer qu'il y a mouvement
    digitalWrite(ledverte, LOW);  
  }
  val = digitalRead(BUTTON_GAUCHE);    // lit l'etat du bouton gauche et enregistre cette valeur
   if ((val == LOW) && (old_val == HIGH )){
   state = 1 - state;                  // change l'etat de 1 a 0
   delay(100);                         // pour absorber l'effet rebond
 }
  old_val = val;                       // change la velaur pour l'ancienne precedemment enregistree
  if (state == 1){
  if (digitalRead(5) == LOW && Stepping == true) // si butee gauche ou nombre de pas pas atteint, le moteur continue le mouvement
  {
   state = 0;                           // remet le bouton gauche a 0
 } else {
   delay(100);                          // pour absorber l'effet rebond du bouton
  StepCounter = 0;                      // met le compteur a 0 avant de recompter dans l'autre sens
 }
  delay (3000);                         // attend 3 secondes avant de refermerla porte
  digitalWrite(8, LOW);                 // part en fermeture
  Stepping = true;                      // lancement du compteur
  }


   if (digitalRead(3) == LOW && Stepping == true) // si mouvement detecte et lit le nombre de pas pendant la fermeture, le moteur repart en ouverture
   {
   digitalWrite(8, HIGH);
   }
   
  if (Stepping == true)                 // mouvement general du moteur
  {
    digitalWrite(9, HIGH);
    delayMicroseconds(50);              // vitesse en microsecondes
    digitalWrite(9, LOW);
    delayMicroseconds(50);              // vitesse en microsecondes
    StepCounter = StepCounter + 1;      // incrementation du nombre de tours


  if (StepCounter == DISTANCE)          // si le compteur atteind le nombre de tours
    {
    StepCounter = 0;                    // se remet a 0
    Stepping = false;                   // le moteur se coupe
     }


 if (digitalRead(4) == LOW && Stepping == true) // si arrive en butee droite
  {
   StepCounter = 0;                     // met le compteur a 0
   Stepping = false;                    // arrete de compter les tours


 val1 = digitalRead(BUTTON_DROIT);      // lit l'etat du bouton droit et enregistre cette valeur
  if ((val1 == LOW) && (old_val1 == HIGH )){ // si le bouton est enfonce
  state1 = 1 - state;                   // change l'etat de 1 a 0
  delay (100);                          // effet rebond
 }
 old_val1 = val1;                       // change la velaur pour l'ancienne precedemment enregistree
 if (state1 == 1){
  state1 = 0;                           // remet le bouton droit a 0
  } else {
  digitalWrite(ledverte, HIGH);          // met les leds en potion standby
  digitalWrite(ledrouge, LOW);
  }
  }
  }
  }

Pour rappel, je voudrais faire une ouverture automatique de moustiquaire.
Pour remplacer celle-ci qui n’est vraiment pas pratique quand on a les mains occupées en été, à la saison des BBQ. Beaucoup de passage par cette moustiquaire…

Question mécanique, je prévois 5 rails en alu et autant de ‘lames’ moustiquaire qui se rabattront sur la droite en parallèle, les unes entrainant les autres.
Position ouvert = 60 cm de passage.
Position fermée = fermeture complète du passage = 80 cm

Terminé pour la partie électronique.
Maintenant, j’attaque la partie mécanique.

Remarques bienvenues :grin: