Controler un mini ascenseur

Le projet :
Installer un ascenseur à la maison de poupée de ma petite fille.
L’ascenseur doit s’arrêté au premier étage ou au second et redescendre à la demande. Il est contrôlé par une télécommande filaire.
La télécommande comporte 4 boutons (1er étage, 2eme étage, descente, lumière)
« Lumière » allume l’éclairage de la maison (Ca c’est ok dans mon programme)
Le bouton 1er étage fait monter l’ascenseur au 1er quel que soit sa position
Le bouton 2er étage fait monter l’ascenseur au second quel que soit sa position
S’il est au premier et que j’appuie sur le bouton 2eme étage. il doit pouvoir monter au second sans redescendre au RdC et vice versa.
Concernant le moteur et c’est là que j’ai besoin de vous, j’ai réussi à le faire tourner et à l’arrêter avec le bouton « buttonPin1 » qui sera affecté au 1er étage.
Je cherche dans un premier temps à l’arréter apres un parcours denonné.
J’ai penser à un compteur que arreterais le moteur, du genre :

//Gestion du moteur 1er etage
 boolean buttonIsUp = digitalRead(4);
  if (buttonWasUp && !buttonIsUp) {
    delay(10); }  
  for (int compteur = 1; compteur <10; compteur ++) 
      {
      digitalWrite(MotorPin, HIGH); }
   if (!buttonIsUp && compteur > 10){
       compteur  = 0;
       digitalWrite(MotorPin, LOW);  
       delay(50);
    }
    buttonWasUp = buttonIsUp;
}

Mais ca ne fonctionne pas … et là s’arrete mes minces connaissances ...

int ledPin = 8; 
int buttonPin1 = 3;
int buttonPin2 = 4;
int buttonPin3 = 6;
int buttonPin4 = 7;
int MotorPin = 12;

boolean buttonWasUp = true;
boolean MotorEnabled = false;



 


void setup() 
{
   pinMode(ledPin, OUTPUT);
   pinMode(buttonPin1, INPUT);
   pinMode(buttonPin2, INPUT_PULLUP);
   pinMode(buttonPin3, INPUT);
   pinMode(buttonPin4, INPUT);
   pinMode(MotorPin, OUTPUT);
   
   
}   
void loop() 
{
 //  gertion de la led
   if (digitalRead(buttonPin1) == HIGH)
  {
    digitalWrite(ledPin, HIGH);
  }
  if (digitalRead(buttonPin1) == LOW)
  {
    digitalWrite(ledPin, LOW);  
  }
  
  //___________________________________
//Gestion du moteur 1er etage
   
   boolean buttonIsUp = digitalRead(4);
   if (buttonWasUp && !buttonIsUp) {
      delay(10);
    buttonIsUp = digitalRead(2);
      if (!buttonIsUp) {
         MotorEnabled = !MotorEnabled;
         digitalWrite(12, MotorEnabled);
      }
   }
   buttonWasUp = buttonIsUp;

} 

Que se passe-t-il si on appuie sur Rdc, 1er et 2nd à la suite ? y-a-t-il mémorisation ?

le mieux serait de mettre un petit détecteur de fin de course à chaque étage. ça vous permettrait de contrôler plus finement l'ascenseur.

Sinon c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)

Bonjour à tous,
Le projet a évolué. Voici le dernier schéma de câblage et le code. Merci de me faire part de vos observations :

#define borneENA        10      // On associe la borne "ENA" du L298N à la pin D10 de l'arduino
#define borneIN1        9       // On associe la borne "IN1" du L298N à la pin D9 de l'arduino
#define borneIN2        8       // On associe la borne "IN2" du L298N à la pin D8 de l'arduino
#define borneIN3        7       // On associe la borne "IN3" du L298N à la pin D7 de l'arduino
#define borneIN4        6       // On associe la borne "IN4" du L298N à la pin D6 de l'arduino
#define borneENB        5       // On associe la borne "ENB" du L298N à la pin D5 de l'arduino

int buttonPin2 = 4; //1er etage
int buttonPin3 = 12;//2eme etage
int buttonPin4 = 13;// descente
int position =0;
int i;
int speed1; //vitesse
int led=11; //la led est branchée avec le pin 11
int iB=0;    //i une variable d'entrée qui s'incrémente au niveau du programme
int bpm = 0;

void setup() {
  
  // Configuration de toutes les pins de l'Arduino en "sortie" (car elles attaquent les entrées du module L298N)
  pinMode(borneENA, OUTPUT);
  pinMode(borneIN1, OUTPUT);
  pinMode(borneIN2, OUTPUT);
  pinMode(borneIN3, OUTPUT);
  pinMode(borneIN4, OUTPUT);
  pinMode(borneENB, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(3, INPUT_PULLUP);
  pinMode(led,OUTPUT);   //déclaration de la LED comme sortie
  pinMode(3, INPUT_PULLUP);   
}

void loop() {
  //_______________________________
  // GESTION DE LA LUMIERE
  //_______________________________

  //  gestion des leds
int pusshed = digitalRead(3); //lire l'état du bouton
  if(pusshed == LOW){      // si le bouton est appuyé
        if(iB%2==0){        //on mesure son modulo s'il est egal à 0 on execute les autres taches
        digitalWrite(11, HIGH); //allumer la led
          }
      else{
        digitalWrite(11, LOW); //sinon éteindre la led
        }
      if(bpm==0){   //si une variable de mémoire d'entréé est mise 0
      iB++;  //incrémenter le i
      bpm=1; //une variable de mémoire d'entréé est mise à 1
       }
      }
  else{
     bpm=0; //sinon on remet la variable à 0 pour commencer l'action à nouveau
  }
  
//_________________________________



//_________________________________
 // GESTION DES ETAGES
//_________________________________
// action Bouton Etage 1
//________________________________

// Etage 1 ascenseur au RDC vers etage 1 (montée) CYCLE 11
position = 0;
i = 10;
 if (digitalRead(buttonPin2) == LOW && position == 0) // si le bouton etage 1 est appuyé et que l'ascenseur est au RDC
 {
 
   for (; i < 10; i++) // 10  valeur test remplacer par durée de montée
   delay(500);
  //  "marche avant" l'ascenseur monte
  digitalWrite(borneIN1, HIGH);                
  digitalWrite(borneIN2, LOW);                  
  
// Et on lance le moteur (branché sur le pont A du L298N)
  lancerRotationMoteurPontA();

  if (i == 9)
     
     digitalWrite(borneENA, LOW);  // Désactive l'alimentation du moteur     
     
  }
     delay(500);
     i=0;
  //________________________________
// Etage 1 ascenseur a l'étage 2 vers etage 1 (descente) CYCLE 12
position = 20;
i = 10; 
   if (digitalRead(buttonPin2) == LOW && position == 20) // si le bouton est appuyé et que l'ascenseur est au RDC
 {
   for (; i > 10; i--) // 10  valeur test remplacer par durée de descente
   delay(500);
  //  "marche arriere" l'ascenseur descend
  digitalWrite(borneIN1, LOW);                  
  digitalWrite(borneIN2, HIGH);                 
  
// Et on lance le moteur (branché sur le pont A du L298N)
  lancerRotationMoteurPontA();

  if (i == 10)
     
     digitalWrite(borneENA, LOW);  // Désactive l'alimentation du moteur     
     
  }
     delay(500);
     i=0;

  //________________________________
// Etage 1 ascenseur déja a l'Etage 1 CYCLE 13
position = 10;

   if (digitalRead(buttonPin2) == LOW && position == 10) // si le bouton est appuyé et que l'ascenseur est a etage 1
 {
 }
// action Bouton Etage 2
//________________________________
// Etage 2 ascenseur au RDC vers etage 2 (montée) CYCLE 21
position = 0;
i = 20; 
 if (digitalRead(buttonPin2) == LOW && position == 0) // si le bouton etage 1 est appuyé et que l'ascenseur est au RDC
 {
  i= 0;
   for (; i < 20; i++) // 10  valeur test remplacer par durée de montée
   delay(500);
  //  "marche avant" l'ascenseur monte
  digitalWrite(borneIN1, HIGH);                
  digitalWrite(borneIN2, LOW);                  
  
// Et on lance le moteur (branché sur le pont A du L298N)
  lancerRotationMoteurPontA();

  if (i == 19)
     
     digitalWrite(borneENA, LOW);  // Désactive l'alimentation du moteur     
     
  }
     delay(500);
     i=0;

//________________________________
// Etage 2 ascenseur au RDC vers etage 2 (montée) CYCLE 22
position = 10;
i = 20; 
 if (digitalRead(buttonPin2) == LOW && position == 10) // si le bouton etage 1 est appuyé et que l'ascenseur est au RDC
 {
 
   for (; i < 20; i++) // 10  valeur test remplacer par durée de montée
   delay(500);
  //  "marche avant" l'ascenseur monte
  digitalWrite(borneIN1, HIGH);                
  digitalWrite(borneIN2, LOW);                  
  
// Et on lance le moteur (branché sur le pont A du L298N)
  lancerRotationMoteurPontA();

  if (i == 19)
     
     digitalWrite(borneENA, LOW);  // Désactive l'alimentation du moteur     
     
  }
     delay(500);
     i=10;
  //________________________________
// Etage 2 ascenseur déja a l'Etage 2 CYCLE 23
position = 20;

   if (digitalRead(buttonPin2) == LOW && position == 20) // si le bouton est appuyé et que l'ascenseur est a etage 2
 {
 }


// action Bouton Etage RDC
//________________________________

// RDC ascenseur a l'étage 2 vers RDC (descente) CYCLE 1
position = 20;
i = 20; 
   if (digitalRead(buttonPin2) == LOW && position == 20) // si le bouton est appuyé et que l'ascenseur est au RDC
 {
   for (; i > 0; i--) // 10  valeur test remplacer par durée de descente
   delay(500);
  //  "marche arriere" l'ascenseur descend
  digitalWrite(borneIN1, LOW);                  
  digitalWrite(borneIN2, HIGH);                 
  
// Et on lance le moteur (branché sur le pont A du L298N)
  lancerRotationMoteurPontA();

  if (i == 0)
     
     digitalWrite(borneENA, LOW);  // Désactive l'alimentation du moteur     
     
  }
     delay(500);
     i=20;
  //________________________________
// RDC ascenseur a l'Etage 1 vers RDC (descente) CYCLE 2
position = 10;
i = 10; 
   if (digitalRead(buttonPin2) == LOW && position == 10) // si le bouton est appuyé et que l'ascenseur est a etage 1
 {
   for (; i > 0; i--) // 10  valeur test remplacer par durée de descente
   delay(500);
  //  "marche arriere" l'ascenseur descend
  digitalWrite(borneIN1, LOW);                  
  digitalWrite(borneIN2, HIGH);                 
  
// Et on lance le moteur (branché sur le pont A du L298N)
   
  lancerRotationMoteurPontA();

  if (i == 0)
     
     digitalWrite(borneENA, LOW);  // Désactive l'alimentation du moteur     
     
  }
     delay(500);
     i=10;

  //________________________________
// RDC ascenseur déja a RDC CYCLE 0
position = 0;

   if (digitalRead(buttonPin2) == LOW && position == 0) // si le bouton est appuyé et que l'ascenseur est a etage 1
 {
 }

}


// Fontion faisant tourner le moteur
//__________________________________
void lancerRotationMoteurPontA() {    
 
  digitalWrite(borneENA, HIGH);       // Active l'alimentation du moteur 
  delay(2000);                        // et attend 2 secondes

  digitalWrite(borneENA, LOW);        // Désactive l'alimentation du moteur 
  delay(1000);                        // et attend 1 seconde

  speed1 = analogRead(A0); //Lire la valeur du potentiomètre
  speed1 = speed1*0.2492668622; //Calibrage
  
  analogWrite(borneENA,speed1);//Etablir la vitesse
}

on est bien d'accord que vous n'utilisez pas ces piles "en vrai"

Et c’est une étourderie d’avoir mis des dels en parallèle !
Chaque diode doit avoir SA résistance de limitation de courant.
Aucune diode n’est identique aux autres, seule celle qui aura le plus faible Vd s’allumera.

Avec les boutons poussoirs il va y avoir des rebonds.
Les rebonds peuvent se gérer par moyen logiciel.
Si tu préfères éviter de surcharger inutilement le code, un simple condensateur de 100 nF en parallèle sur le contact fonctionne parfaitement bien. C’est seulement un choix à faire.

Ok merci JLM ... le circuit doit etre allimenté comment ?

68tjs merci. je vais isoler les leds. Vous avez jeté un coup d'oeil sur le code? vous en pensé quoi? je suis en apprentissage :sweat_smile: .. merci pour votre indulgence ! :blush:

Comme le suggère @J-M-L , un système basé sur le temps de parcourt ne sera pas fiable dans le temps. Il va se décaler petit à petit.
Il faut placer un détecteur à chaque étage (inter, barrière lumineuse, ...) pour détecter le passage de la cabine de l'ascenseur.

Merci fdufnews. Je refleuris a cette modification.

Bonjour,

D'un point de vue câblage, en plus des autres remarques, il faut relier les - piles au GND Arduino pour que les LEDS marchent.

Et alimenter le potentiométre entre GND et +5V et non +Vin pour que son point milieu ne dépasse pas 5V

Bonjour plaf33140

Je plussoie aux détecteurs à chaque étage, j'utiliserai des détecteurs à effet de hall comme ceci:
image

un à chaque étage, un petit aimant dans la cabine suffit.

Pour ce qui est de ton programme, je ne l'ai pas détaillé, mais il y a une chose à éviter c'est ce genre de chose:

pinMode(11, OUTPUT);
pinMode(3, INPUT_PULLUP);

3 et 11 ne disent pas grand chose, il faut absolument créer des variables comme tu l'a déjà fait et utiliser leur nom, c'est plus parlant quand l'on lit ton programme.

Cordialement
jpbbricole

fdufnews

le detecteur doit s'activer au passage du bas de la cabine et non le haut . Quel detecteur utiliser ?

OK jpbbricole

Peu importe, du moment que tu en tiens compte dans le code.

Oh là, pas de confusion, cela fonctionne parfaitement avec les numéros de pins, même si on ne cré pas des variables.

Je pense que ce que @jpbbricole a voulu dire, c'est que, pour la lisibilité du code, surtout quand on le reprend après quelques semaines ou quelque mois, il est préférable d'utiliser des noms de variable qui "parlent".

Le code est beaucoup plus compréhensible à la relecture.
Tu as parfaitement le droit de faire comme tu veux, mais c'est mieux comme le conseille @jpbbricole :grinning:.

1 Like

Concernant les capteurs, je n'ai plus de pins disponibles en analogique. Une solution ?? Merci

Bonjour plaf33140

Pour les barrières lumineuses ou capteurs magnétiques, c'est lu sur une entrée digitale, il te reste A1, A2, A3 et A4 et A5 pour autant que tu ne veuille pas utiliser le bus i2C.
Si tu n'as qu'un moteur, tu peux prendre les entrées 8, 9, 10 qui ne sont pas utilisées par ton pont en H.

Cordialement
jpbbricole

Bonsoir,

Il te reste A1, A2, A3, A4, A5 que tu peux définir en entrées digitales ou analogique selon le type de capteurs détecteurs choisis (détecteurs digitales ou analogiques).

Oui surtout qu’il l’a déjà fait

Il faudrait aussi homogénéiser les définitions des pins, idéalement avec un type plutôt qu’un define et un nom parlant et si nécessaire un commentaire pertinent

const byte brocheLed = 11; // broche pour la led qui sert à xxxx

Methodes d’enseignement d’avant 1968 !
Faites comme je vous dis c’est un ordre, je n’ai pas a me justifier.

Depuis je vous rappele que la soupape a explosé avec fracas.