lundi 22 décembre 2014

Porte de poulailler Part - 2 : Arduino avec une photo-résistance

Retour Part-1

 Version arduino avec photo-résistance


La première solution qui m'est venue à l'esprit est d'utiliser une photorésistance de type LDR03 comme capteur crépusculaire et une carte de commande de moteur Courant Continue et un arduino nano alimenté par un accu Li-ion 6000mAh.

Petit rappel du matériel :

  • Un arduino nano
  • une carte de commande moteur CC. J'ai utilisé 2 types, une à base du L9110 H-bridge (plus fragile), et l'autre à base d'un  DRV8835 de marque pololu qui a l'avantage d'avoir une alimentation séparé pour le moteur.
  • une photorésistance LDR03 et une résistance de 47k.
  • 2 batteries, une pour le moteur et une autre pour le micro-contrôleur. 

Oui j'ai bien mis 2 batteries, le moteur a besoin de puissance et d'une tension plus importante.

voici le montage simplifié :



Ne sont pas présents le régulateur de tension +5V pour pouvoir utiliser l'accu et le potentiomètre au niveau de la photo-résistance pour affiner le seuil de détection. 
Le potentiomètre n'est pas très utile car la plage de longueur d'onde de la photo-résistance n'est pas terrible, je l'ai remplacé par une résistance de 47k. 

Le code fonctionne comme une bascule, la photo-résistance est branchée sur la pin 'D2' de l'arduino qui est une entrée TTL.  lorsqu'il fait jour la résistance est petite et laisse passer le courant ce qui déclenche le niveau Haut au borne de la pin 'D2' de l'arduino, la porte peut s'ouvrir. A contrario lorsque la nuit est présente, la résistance est alors infinie et bloque le courant, l'entrée de la pin 'D2' passe en niveau bas, la porte peut se fermer.

La commande du moteur est très simple si on envoie un signal Haut sur D9 et bas sur D10, le moteur tourne et le sens s'inverse si D9=bas et D10=Haut. Pour l’arrêt D9=D10=bas. Pour tester votre porte  voici un petit sketch de réglage.


Pour gagner de l'énergie, il est nécessaire de mettre en veille l'arduino, oui mais qui dit mise en veille dit réveille ! Heureusement l'arduino dispose d'une interruption sur la pin D2 et en plus le réveille peut se faire par changement d’état c'est à dire un passage d'un niveau bas vers haut par exemple.
     
Reste un problème à régler, celui de  l'initialisation de la bascule. Dans mon cas la mise en route de l'arduino doit se faire le jour et porte fermée.

voici le code utilisé :
 /*  
 Electronic 77   
  Version 1.0 du 01/12/2013  
  L9110 motor driver controlling   
  - 1 small DC motors  
  - 2 small DC motors   
  - 1 PWM 4 wires  
  */  
 #include <avr/interrupt.h>  
 #include <avr/power.h>  
 #include <avr/sleep.h>  
 #include <avr/io.h>   
  /*  
 SCHEMA Utilisation d'un moteur CC  
 pin IA1 || LOW   || High  
 pin IB1 || HIGH  || Low  
 Motor  || backward || forward  
 PWM: 3, 5, 6, 9, 10, and 11. Provide 8-bit PWM output with the analogWrite() function.   
  */   
 const int IA1 = 9; // DIGITAL PIN 8 Bits   
 const int IB1 = 10; // DIGITAL PIN 8 Bits  
  /*  
  SCHEMA Cellule photosensible  
  reçoit digital un 0 ou 1  
  */  
 const int IP1=2; // DIGITAL INPUT + Interruption  
 const int TpsMontee=2000; // réglage du temps de montée  
 const int TpsDescente=1700; // réglage du temps de descente  
 int IsJourLast=HIGH; //Mise en route il fait jour  
 int flag=0; // sécurité interruption  
 void setup()   
 {  
  DDRD &= B00000011;    // set Arduino pins 2 to 7 as inputs, leaves 0 & 1 (RX & TX) as is  
  DDRB = B00000000;    // set pins 8 to 13 as inputs  
  PORTD |= B11111100;   // enable pullups on pins 2 to 7  
  PORTB |= B11111111;   // enable pullups on pins 8 to 13  
  //Commande du moteur cc via le L9110H  
  pinMode(IA1, OUTPUT); // set pin to output  
  pinMode(IB1, OUTPUT); // set pin to output  
  //Lecture cellule photosensible  
  pinMode(IP1,INPUT); // set pin in INPUT  
 // au branchement lance l'ouverture  
 // COndition initiales :   
 // - faire jour  
 //- Porte poulailler fermée  
  stop();  
 }  
 void loop() {  
  // détection du changement d'etat  
  int IsJour=digitalRead(IP1);  
  if (IsJourLast != IsJour)  
  {  
   // vérifie que la valeur a bien changé n sec plus tard    
   delay(30000); // attends 30 secondes  
   IsJour=digitalRead(IP1);  
  }  
  if (IsJourLast != IsJour)  
  {  
   if (IsJour==LOW)  
   {  
    // Ouvre  
    forward();   
    delay(TpsMontee);  
   }  
   else  
   {  
    // Ferme  
    delay(5500000); // attendre 40 minutes et demi  
    backward();  
    delay(TpsDescente);     
   }   
   stop();  
   IsJourLast=IsJour;  
  }  
  // Met en veille l'arduino  
  sleepNow();  
 }  
 void stop(){  
  digitalWrite(IA1, LOW);  
  digitalWrite(IB1, LOW);  
  delay(1000);  
 }  
 void backward()  
 {  
  digitalWrite(IA1, LOW);  
  digitalWrite(IB1, HIGH);  
 }  
 void forward()  
 {  
  digitalWrite(IA1, HIGH);  
  digitalWrite(IB1, LOW);  
 }  
 // PARTIE MISE EN VEILLE DU proccesseur  
 void sleepNow(void)  
 {  
   flag=0;  
   attachInterrupt(0, pinInterrupt, CHANGE);  
   delay(1000); // important laisse le temps de mettre en place l'interruption  
   //  
   // Choose our preferred sleep mode:  
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);  
   //  
   // Set sleep enable (SE) bit:  
   sleep_enable();  
   //  
   // Put the device to sleep:  
   sleep_mode();  
   //  
   // Upon waking up, sketch continues from this point.  
   sleep_disable();  
   // SORTI DE LA VEILLE    
   flag=1;  
 }  
         //  
 void pinInterrupt(void)  
 {  
  if (flag>0)  
   detachInterrupt(0);  
 }  


Réglage du moteur:

 const int TpsMontee=2000; // réglage du temps de montée  
 const int TpsDescente=1700; // réglage du temps de descente  

le temps est en milliseconde, ajuster ces 2 variables à votre projet.

En conclusion, le système en lui même fonctionne parfaitement, pour palier au problème de justesse de détection du crépuscule, j'ai mis en place une minuterie pour retarder  l'ouverture / fermeture de la porte. 
On verra par la suite qu'il existe d'autres capteurs avec de meilleurs performance. 
Un autre problème apparaît rapidement, celui de l'autonomie. He oui l'arduino même en mode veille consomme trop et le montage ne tient pas la semaine. Il existe des pistes, utiliser un arduino pro en  3V en 8 mHz, ou de changer de micro-controleur par un MSP430.

Nous allons voir dans la partie 3, un montage utilisant une horloge RTC à la place de la photo-résistance.  

3 commentaires:

  1. salut a tous,

    Je suis a la recherche de développeur pour un projet opensource similaire, Nous somme déjà 3 sur ce projet.
    Ce projet consiste a rendre accessible aux plus novices les fonctionnalités du rapberry pi et arduino combinés dans le but de gérer des systêmes domotiques annexes tel qu'une ruche, un jardin, un aquarium, une cave a vin, une champignonnière, un terrarium, une serre, enfin presque tout enfaite.

    Une interface graphique seras accessible depuis partout. Un systême de scénarios configurable permettra la régulation ainsi que l'alerte mail et sms du systême.

    Le But étant de pouvoir partager depuis un site communautaire des données créer par la communauté dans un esprit de DRY (don't repeat yourself), pour éviter que chacun écrive sont petit morceau de code dans sont coin alors qu'il pourrais le rendre accessible a toute une communauté. Quel gains de temps pour toute une communauté!!!.

    n’hésitez pas à nous rejoindre, on ne mort pas lol!!! les projets open sources ont besoin de vous!!

    https://ardui-farm.sonetin.com/

    RépondreSupprimer
  2. bonjour,
    le système est vraiment bien expliqué, le script pour le réglage des moteurs au top
    cependant j'ai un problème liée a la photorésistance la valeur est inversé donc la porte se ferme le jour et s'ouvre la nuit
    ce qui n'est pas le but recherché :) et je n'arrive pas a comprendre la partie du script de la photorésistance,il faut juste changer l'entrée de 0 a 1 mais je ne trouve pas
    merci d'avance pour votre aide

    RépondreSupprimer