{{tag>dev arduino exemple todo}} ====== Arduino: Passage à niveau ====== ===== Schéma du montage ===== ===== Sketch ===== Ci-dessous le programme complet. /* Fun MOOC, Programmer un objet avec Arduino TP 04: Le passage à niveau Le fonctionnement normal est un feu allumé au rouge (le feu vert est éteint) et une barrière fermée (0°). Le fonctionnement normal est interrompu par l'appui sur un bouton poussoir. Si l'appui du bouton est détecté, alors la barrière (actionnée par le servomoteur) se relève doucement. Lorsque la barrière est à la verticale (90°), le feu vert s'allume pendant 5 secondes pendant lesquelles la barrière reste ouverte (90°) et le feu rouge s'éteint. Après les 5 secondes, le feu repasse au rouge, la barrière redescend doucement et le fonctionnement normal reprend. Nous souhaitons recevoir le message "Bouton appuye" dans le moniteur série lorsque l'appui a été détecté. A propos du montage: - Un servomoteur branché sur les broches 9, +5V et GND) - Un bouton pour demander l'ouverture de la barrière branché sur la broche 2 avec resistance de pull down de 1KΩ - Un feu bicolore qui passera au vert lorsque la barrière sera complètement ouverte - Avec une LED rouge sur la broche 3 en serie avec une resistance de 220Ω - Avec une LED verte sur la broche 4 en serie avec une resistance de 220Ω */ // On inclus la bibliothèque Servo afin de bénéficier des fonctions de pilotage des servomoteurs #include const int GREEN_LED = 4; const int RED_LED = 3; const int PIN_SERVO = 9; const int GATE_MOTOR_STEP=1; //Permet de regler la vitesse d'ouverture/fermeture de la barriere, pas de 1° par défaut. //Valeurs conseillées de 1 à 10. //servo moteur de la barriere Servo gate_motor; // Broche reliée au bouton de demande de levée de barrière (montage PULL DOWN identique au TP 02) const int BUTTON_PIN = 2; //variable d'enregistrement d'une demande de levée de barriere. bool cross_request = false; //NB: C'est le dernier TP, aucune information n'a été donnée au sujet de la déclaration/définition de types et de fonctions. // J'ai fait le choix les utiliser pour augmenter la lisibilité dans la boucle principale et la maintenance du code. // Définition du type enuméré traffic_light pouvant prendre 2 valeurs RED ou GREEN enum traffic_light {RED, GREEN}; /** * Fonction: trafficLightTo() * Role: Controle le feu de signalisation * Parametres: * const traffic_light l: Ne peut prendre que deux valeurs: soit RED, soit GREEN selon le feu à allumer. * Retour: Néant */ void trafficLightTo(const traffic_light l); // Définition d'un type enuméré gate_position pouvant prendre 2 valeurs OPEN ou CLOSE enum gate_position {OPEN, CLOSE}; /** * Fonction: setGate() * Role: Controle l'ouverture et la fermeture le la barrière. * Parametres: * const gate_position p: Ne peut prendre que deux valeurs: soit OPEN, soit CLOSE pour ouvrir ou fermer la barriere. * Retour: Néant */ void setGate(const gate_position p); void setup() { //Initialisation de la connexion série à 9600 bauds Serial.begin(9600); //Les broches reliées aux DELs sont configurées en sorties pinMode(GREEN_LED, OUTPUT); pinMode(RED_LED, OUTPUT); gate_motor.attach(PIN_SERVO); // L'etat du boutton est lu, configuration en entrée pinMode(BUTTON_PIN, INPUT); //Etat initial: on passe le feu au rouge, la barriere doit être baissée trafficLightTo(RED); gate_motor.write(0); } void loop() { if(digitalRead(BUTTON_PIN) == HIGH) { // Le bouton est enfoncé, on enregistre la demande de traversée. cross_request = true; //envoi du message sur port serie Serial.println("Bouton appuye"); } if(cross_request == true) { // Une demande de traversée a été enregistrée. // Ouvrir la barriere et passer le feu au vert setGate(OPEN); trafficLightTo(GREEN); // 5 secondes pour passer delay(5000); //Délai écoulé on condamne le passage. //Passer le feu au rouge et refermer la barriere trafficLightTo(RED); setGate(CLOSE); // La demande de traversée a été prise en compte, on réinitialise la valeur cross_request = false; } } void trafficLightTo(const traffic_light l) { switch (l) { case RED: //eteint le vert digitalWrite(GREEN_LED, LOW); //allume le rouge digitalWrite(RED_LED, HIGH); break; case GREEN: //eteint le rouge digitalWrite(RED_LED, LOW); //allume le vert digitalWrite(GREEN_LED, HIGH); break; } } void setGate(const gate_position p) { volatile int pos; //declarer cette variable volatile permet conserver sa valeur entre les appels de la fonction. switch (p) { case OPEN: //Boucle d'ouverture progressive de 0 à 90° for (pos = 0; pos <= 90; pos += GATE_MOTOR_STEP) { gate_motor.write(pos); // Demande au servo de prendre la position de consigne dans la variable pos delay(15); // Attendre quelques millisecondes pour laisser le servo atteindre la position de consigne pos } break; case CLOSE: //Boucle de fermeture progressive for (pos = 90; pos >= 0; pos -= GATE_MOTOR_STEP) { gate_motor.write(pos); // Demande au servo de prendre la position de consigne dans la variable pos delay(15); // Attendre quelques millisecondes pour laisser le servo atteindre la position de consigne pos } break; } }