// Programme écrit pas Matthieu MONCEAUX. avril 2018 // Ouvre et ferme automatiquement la porte du poulailler en fonction de la lumière // Et donne à manger juste avant d'ouvrir la porte // Coupe le goutte à goutte si manque de lumière (commande d'un relais branché en série avec des horloges de programmation) // // Schéma cablage (voir http://mmonceaux.free.fr/): // D4 = capteur magnétique position haute, entre masse, D4 et résistance de 10k au +5V (et cond 10nF pour éviter effet rebond) // D5 arduino ---> IN1 step // D6 arduino ---> IN2 step // D7 arduino ---> IN3 step // D8 arduino ---> IN4 step // Pour arduino Nano : alim sur pin27-"5v" = 5v (et pas sur "Vin"-pin30,7v à 12v pour éviter de chauffer le régulateur de la carte nano) // Capteur LDR sur A0 avec : +5V <-> Potar 1K <-> Résist 6,8K <-> LDR <-> masse (et condensateur 220µF en parallele à LDR) #include // charger en mémoire la routine de gestion du moteur pas à pas ///////// DECLARATION CONSTANTES VARIABLES const int nombre_demi_tour = 16; //14 <---------- nombre de demi-tours nécessaires pour descendre suffisamment la trappe 14t=25cm int ldr; // lit la valeur du capteur LDR int capteur_porte_haut; // = 0 si la porte est ouverte, et que le contact entre aimant et capteur magnétique est bon int essai_montee = 0; // nombre d'essai pour arriver au capteur porte haut ; afin d'arrêter le moteur s'il n'est pas possible d'arriver au niveau du capteur int porte_fermee; // variable pour mémoriser l'état de la porte : si fermee = 1 const int pin_ldr = A0; const int pin_temperature = A1; const int pin_bouton = A2; const int pin_buzzer = 4; const int pin_capteur_porte_haut = A4; // fil blanc unsigned int i; unsigned int bouton_mangeoire; unsigned int demi_tour_mangeoire = 1; // par défaut, un demi tour suffit const int StepsPerRevolution = 1024; // Pour moteur 28BYJ-48 2048=1 tour, 1024=1/2 tour. Stepper myStepper_porte(StepsPerRevolution, 5, 7, 6, 8); Stepper myStepper_mangeoire(StepsPerRevolution, 10, 12, 11, 13); //// FONCTION TOUR_MANGEOIRE : fixe le nombre de tour du moteur mangeoire /// une pression du bouton incrémente le nombre de tour (et bip du buzzer pour confirmer) // une pression > 4s entraine la rotation du moteur correspondant au nombre de tour (avec bips de confirmation) void nombre_tour_mangeoire() { bouton_mangeoire = analogRead(pin_bouton); Serial.print("bouton_mangeoire="); Serial.print(bouton_mangeoire); Serial.println(""); if (bouton_mangeoire > 500) // bouton simple (avec condensateur pour éviter les doubles pressions involontaires) { demi_tour_mangeoire = demi_tour_mangeoire + 1; if (demi_tour_mangeoire > 15) { demi_tour_mangeoire = 2; } for (i = 0; i < demi_tour_mangeoire ; i++) // on emet un bip correspondant au nombre de tour mangeoire { tone(pin_buzzer, 1300, 230); //(pin, frequency, duration) delay(270); noTone(pin_buzzer); digitalWrite(pin_buzzer, LOW); } bouton_mangeoire = analogRead(pin_bouton); if (bouton_mangeoire > 500) { Serial.print(" le moteur tourne sur "); Serial.print(demi_tour_mangeoire); Serial.print(" demi-tours"); myStepper_mangeoire.step(-StepsPerRevolution * demi_tour_mangeoire); delay(200); myStepper_mangeoire.step(-StepsPerRevolution * demi_tour_mangeoire); delay(200); myStepper_mangeoire.step(-StepsPerRevolution * demi_tour_mangeoire); delay(200); myStepper_mangeoire.step(-StepsPerRevolution * demi_tour_mangeoire); delay(200); myStepper_mangeoire.step(-StepsPerRevolution * demi_tour_mangeoire); eteindre_moteurs(); } } Serial.print("bouton_mangeoire= "); Serial.print(bouton_mangeoire); Serial.print(" demi_tour_mangeoire= "); Serial.print(demi_tour_mangeoire); Serial.println(""); } //// FONCTION ETEINDRE : eteind réellement le moteur ; la fonction "mystepper" ne l'eteingnait pas bien et il continuait à chauffer sans tourner... void eteindre_moteurs() { digitalWrite(5, LOW); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(8, LOW); digitalWrite(10, LOW); digitalWrite(12, LOW); digitalWrite(11, LOW); digitalWrite(13, LOW); } ///////// SETUP : DEMARRE SEULEMENT APRES RESET OU NOUVELLE MISE EN ALIMENTATION void setup() // Fonction setup qui s'enclenche seulement 1 fois après un reset (ou OFF/ON) de la carte Arduino { // Définition des entrées : pinMode(pin_buzzer, OUTPUT); // d4 , fil blanc pinMode(pin_ldr, INPUT); //a0 , pinMode(pin_temperature, INPUT); //a1 pinMode(pin_bouton, INPUT); //a2 , fil noir pinMode(pin_capteur_porte_haut, INPUT); //a4 , fil blanc // pinMode(pin_capteur_porte_bas, INPUT); //a5 , fil gris // moteur porte automatique pinMode(5, OUTPUT); // moteur pas à pas pinMode(7, OUTPUT); // moteur pas à pas pinMode(6, OUTPUT); // moteur pas à pas pinMode(8, OUTPUT); // moteur pas à pas // moteur mangeoire pinMode(10, OUTPUT); // moteur pas à pas pinMode(11, OUTPUT); // moteur pas à pas pinMode(12, OUTPUT); // moteur pas à pas pinMode(13, OUTPUT); // moteur pas à pas pinMode(pin_ldr, INPUT); pinMode(pin_temperature, INPUT); pinMode(pin_bouton, INPUT); pinMode(pin_ldr, INPUT); myStepper_porte.setSpeed(28); // reglage de la vitesse du moteur pas à pas (28BYJ-48) : 4 à 14 ou 28 en mode demi-tour myStepper_mangeoire.setSpeed(28); // reglage de la vitesse du moteur pas à pas (28BYJ-48) : 4 à 14 ou 28 en mode demi-tour Serial.begin(9600); // Ouverture du "moniteur série" pour affichage dans le logiciel Arduino sur PC // Affichage des états dans le moniteur série capteur_porte_haut = analogRead(pin_capteur_porte_haut); // lit la valeur du capteur magnétique de fin de course porte en haut Serial.print("Capteur Porte Haut (0=contact)= "); Serial.print(capteur_porte_haut); Serial.print(" "); Serial.print("Porte Fermee= "); Serial.print(porte_fermee); Serial.print(" "); Serial.print("Nombre Essai montee= "); Serial.print(essai_montee); Serial.print(" "); ldr = analogRead(pin_ldr); // lit la valeur du capteur LDR, moins il y a de la lumière, plus la valeur de LDR est grande Serial.print("LDR="); Serial.print(ldr); // affiche la valeur de ldr dans le moniteur série Serial.println(); delay(10); // stabilisation affichage // préparation de la porte : monter jusqu'au capteur haut : while (capteur_porte_haut != 0 and essai_montee < 40) // Tant que la porte n'est pas en haut (haut=0) ou essai de montée <40 { myStepper_porte.step(-StepsPerRevolution * 1); essai_montee = essai_montee + 1; // pour éviter au moteur de fonctionner sans arrêt si la corde est cassée // Affichage des états dans le moniteur série capteur_porte_haut = digitalRead(pin_capteur_porte_haut); // lit la valeur du capteur magnétique de fin de course porte en haut Serial.print("Capteur Porte Haut (0=contact)= "); Serial.print(capteur_porte_haut); Serial.print(" "); Serial.print("Porte Fermee= "); Serial.print(porte_fermee); Serial.print(" "); Serial.print("Nombre Essai montee= "); Serial.print(essai_montee); Serial.print(" "); ldr = analogRead(pin_ldr); // lit la valeur du capteur LDR, moins il y a de la lumière, plus la valeur de LDR est grande Serial.print("LDR="); Serial.print(ldr); // affiche la valeur de ldr dans le moniteur série Serial.println(); delay(10); // stabilisation affichage porte_fermee = 0; } eteindre_moteurs(); } ///////////////////////////////////////////// void loop() // Fonction loop = programme principal du Arduino, boucle qui tourne sans arrêt { nombre_tour_mangeoire(); // fonction qui definie le nombre de tours à faire par la mangeoire // Affichage des états dans le moniteur série capteur_porte_haut = digitalRead(pin_capteur_porte_haut); // lit la valeur du capteur magnétique de fin de course porte en haut Serial.print("Capteur Porte Haut (0=contact)= "); Serial.print(capteur_porte_haut); Serial.print(" "); Serial.print("Porte Fermee= "); Serial.print(porte_fermee); Serial.print(" "); Serial.print("Nombre Essai montee= "); Serial.print(essai_montee); Serial.print(" "); ldr = analogRead(pin_ldr); // lit la valeur du capteur LDR, moins il y a de la lumière, plus la valeur de LDR est grande Serial.print("LDR="); Serial.print(ldr); // affiche la valeur de ldr dans le moniteur série Serial.println(); delay(10); // stabilisation affichage //////////////// alors c'est la nuit --> fermer porte if ((ldr > 950) && (porte_fermee == 0)) // alors c'est la nuit --> fermer porte { // Affichage des états dans le moniteur série capteur_porte_haut = digitalRead(pin_capteur_porte_haut); // lit la valeur du capteur magnétique de fin de course porte en haut Serial.print("Capteur Porte Haut (0=contact)= "); Serial.print(capteur_porte_haut); Serial.print(" "); Serial.print("Porte Fermee= "); Serial.print(porte_fermee); Serial.print(" "); Serial.print("Nombre Essai montee= "); Serial.print(essai_montee); Serial.print(" "); ldr = analogRead(pin_ldr); // lit la valeur du capteur LDR, moins il y a de la lumière, plus la valeur de LDR est grande Serial.print("LDR="); Serial.print(ldr); // affiche la valeur de ldr dans le moniteur série Serial.println(); delay(10); // stabilisation affichage porte_fermee = 1; //porte fermée myStepper_porte.step(StepsPerRevolution * nombre_demi_tour); // myStepper.step(-StepsPerRevolution*nombre_demi_tour); eteindre_moteurs(); // éteindre réellement le moteur pas à pas delay(2000); } //////////////// alors c'est le jour --> ouvrir la porte if ((ldr < 700) && (porte_fermee == 1)) // alors c'est le jour --> ouvrir la porte { porte_fermee = 0; essai_montee = 0; // Je démarre la mangeoire Serial.print(" le moteur tourne sur "); Serial.print(demi_tour_mangeoire); Serial.print(" demi-tours"); myStepper_mangeoire.step(-StepsPerRevolution * demi_tour_mangeoire); delay(200); myStepper_mangeoire.step(-StepsPerRevolution * demi_tour_mangeoire); delay(200); myStepper_mangeoire.step(-StepsPerRevolution * demi_tour_mangeoire); delay(200); myStepper_mangeoire.step(-StepsPerRevolution * demi_tour_mangeoire); delay(200); myStepper_mangeoire.step(-StepsPerRevolution * demi_tour_mangeoire); eteindre_moteurs(); // éteindre réellement le moteur pas à pas //delay (180000); // attendre 3mn, le temps que les poules mangent un peu while ((capteur_porte_haut == 1) && (essai_montee < 30)) // Tant que la porte n'est pas en haut (haut=0) ou essai de montée <30 { myStepper_porte.step(-StepsPerRevolution * 1); essai_montee = essai_montee + 1; // pour éviter au moteur de fonctionner sans arrêt si la corde est cassée // Affichage des états dans le moniteur série capteur_porte_haut = digitalRead(pin_capteur_porte_haut); // lit la valeur du capteur magnétique de fin de course porte en haut Serial.print("Capteur Porte Haut (0=contact)= "); Serial.print(capteur_porte_haut); Serial.print(" "); Serial.print("Porte Fermee= "); Serial.print(porte_fermee); Serial.print(" "); Serial.print("Nombre Essai montee= "); Serial.print(essai_montee); Serial.print(" "); ldr = analogRead(pin_ldr); // lit la valeur du capteur LDR, moins il y a de la lumière, plus la valeur de LDR est grande Serial.print("LDR="); Serial.print(ldr); // affiche la valeur de ldr dans le moniteur série Serial.println(); delay(10); // stabilisation affichage } delay(2000); eteindre_moteurs(); // eteindre reelement le moteur ; une partie des bobines étaient encore alimentées et le moteur chauffait sans tourner } //// TEMPERATURE int sensorVal = analogRead(pin_temperature); //lecture de la broche A0 float voltage = (sensorVal / 1024.0) * 5.0; // convert the ADC reading to voltage Serial.print("Temperature = "); float celsius = voltage * 100; // convert the voltage to temperature in degrees C Serial.println(celsius); Serial.print("°C"); delay(500); // stabilise l'affichage dans le moniteur série } // fin du programme général