samedi 4 novembre 2017

Porte de poulailler Part - 5 : Arduino avec moteur pas à pas unipolaire

Version Arduino Avec DS3231 et ULN2003


Je suis de retour pour vous proposer une nouvelle variante. Cette fois-ci il s'agit d'un montage à base de la RTC DS3231 (horloge) et d'un moteur unipolaire que j'ai récupéré d'une veille imprimante jet d'encre.
Pour cette réalisation électronique, vous aurez besoin :
  • d'une batterie moto 12 V
  • d'une RTC DS3231
  • d'un moteur unipolaire
  • d'un arduino nano

Code source :
 /*  
 Philippe XXXXXXX
  Version 1.0 du 26/08/2017  
 Driver ULN2003 et moteur unipolaire  
  - 1 PWM 4 wires  
  */  
 #include <Wire.h>  
 #include <RTClibExtended.h>  
 #include <avr/interrupt.h>  
 #include <avr/power.h>  
 #include <avr/sleep.h>  
 #include <avr/io.h>   
 #include <Stepper.h>  
 #define STEPS 100  
  /*  
 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.   
  reçoit digital un 0 ou 1  
  */  
 const int IP1=2; // DIGITAL INPUT + Interruption  
 const int IP4=4; // sensor door closed  
 const int NbToursMontee=400; // réglage du temps de montée  
 const int NbToursDescente=-400; // réglage du temps de descente  
 int flagInit=0;  
 int flag=0; // sécurité interruption  
 //Heure été  
 ////////////////////////// JANV  FEV   Mars  Avr  Mai  Jun  Juil  Aout  Sept  Oct   Nov  Dec  
 int LeveSoleilHeure[24]=  { 8,8,  8,7,  7,7,  7,7,  6,6,  6,6,  6,6,  6,7,  7,7,   8,8,  7,8, 8,8  };  
 int LeveSoleilMinute[24]= {30,20, 10,50, 25,00, 28,02, 40,23, 13,13, 21,33, 51,8, 27,44,  03,21, 43,03, 20,31  };  
 int CoucheSoleilHeure[24]= {18,18, 18,19, 19,19, 21,21, 21,21, 22,22, 22,22, 21,21, 20,20,  19,19, 18,17, 17,18  };  
 int CoucheSoleilMinute[24]={00,20, 45,04, 26,42, 03,20, 39,56, 10,26, 30,15, 45,23, 53,27,  57,33, 05,54, 48,01  };  
 //7 27 / 20 53  
 // original  
  //int CoucheSoleilHeure[24]= {17,17, 18,18, 18,19, 20,20, 21,21, 21,21, 21,21, 21,20, 20,19,  19,19, 17,17, 17,17  };  
  //int CoucheSoleilMinute[24]={35,52, 15,34, 54,12, 33,50, 09,26, 40,46, 44,35, 15,53, 23,57,  27,03, 39,24, 18,21  };  
 Stepper small_stepper(STEPS, 11, 9, 10, 8);  
 RTC_DS3231 RTC;   //we are using the DS3231 RTC  
 void setup()   
 {  
  //------------------------------  
  //RTC init  
  //------------------------------  
  //Set SQW pin to OFF (in my case it was set by default to 1Hz)  
  //The output of the DS3231 INT pin is connected to this pin  
  //It must be connected to arduino D2 pin for wake-up  
  RTC.writeSqwPinMode(DS3231_OFF);  
  //Lecture cellule photosensible  
  pinMode(IP1,INPUT_PULLUP); // set pin in INPUT  
  pinMode(IP4,INPUT_PULLUP);   
 }  
 void loop() {  
   //When exiting the sleep mode we clear the alarm  
   //Initialize communication with the clock  
   Wire.begin();  
   RTC.begin();   
   //clear any pending alarms  
   RTC.armAlarm(1, false);  
   RTC.clearAlarm(1);  
   RTC.alarmInterrupt(1, false);  
   RTC.armAlarm(2, false);  
   RTC.clearAlarm(2);  
   RTC.alarmInterrupt(2, false);  
   DateTime t=RTC.now();  
   int Index=(t.month()-1)*2;     
   if( t.day()>15)  
    Index++;  
   if(canOpen(t,Index))  
   {  
    forward();  
    RTC.setAlarm(ALM1_MATCH_HOURS,CoucheSoleilMinute[Index], CoucheSoleilHeure[Index],0);   
   }  
   else  
   {  
     backward();  
    RTC.setAlarm(ALM1_MATCH_HOURS,LeveSoleilMinute[Index], LeveSoleilHeure[Index],0);   
   }  
   flagInit=1;  
   //Set alarm1 every day at 18:33  
   //RTC.setAlarm(ALM1_MATCH_HOURS, 33, 18, 0);  //set your wake-up time here  
   RTC.alarmInterrupt(1, true);   
  // Met en veille l'arduino  
  sleepNow();  
 }  
 // functional algo  
 boolean canOpen(DateTime t,int index)  
 {  
   if (  
   ((t.hour()== LeveSoleilHeure[index] && t.minute()>= LeveSoleilMinute[index]) || t.hour()> LeveSoleilHeure[index])  
   &&   
   (t.hour()< CoucheSoleilHeure[index] || (t.hour()== CoucheSoleilHeure[index] && t.minute()< CoucheSoleilMinute[index]))  
   )  
   return true;  
   else   
   return false;  
 }  
 void MotorStop()  
 {  
   delay(1000);  
   digitalWrite(8, LOW);  
   digitalWrite(9, LOW);  
   digitalWrite(10, LOW);  
   digitalWrite(11, LOW);    
 }  
 void backward()  
 {  
  small_stepper.setSpeed(10);   
  small_stepper.step(NbToursMontee); //Ca tourne  
 /*  
  // sensor detect   
  int Closed=digitalRead(IP4);  
  if (Closed>0) // sensor not detect the door  
  {  
   //need to reset the position (10 step max)  
   int tr=5;  
   while (tr>0)  
   {  
    tr--;  
    small_stepper.step(1); //Ca tourne  
    if (digitalRead(IP4)==0) tr=0; // door closed  
   }  
  }  
  */  
  MotorStop();  
 }  
 void forward()  
 {  
  small_stepper.setSpeed(20);   
  small_stepper.step(NbToursDescente); //Ca tourne   
  MotorStop();  
 }  
 // PARTIE MISE EN VEILLE DU proccesseur  
 void sleepNow(void)  
 {  
   flag=0;  
   attachInterrupt(0, pinInterrupt,FALLING);// CHANGE); FALLING  
   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);  
 }  

samedi 17 janvier 2015

Porte de poulailler Part - 4 : MSP430G2452 RTC alarme

Version MSP430G2452 avec DS3231

Retour partie 3
Avant de commencer cet article, juste un petit mot pour vous dire que c'est la configuration que j'ai choisie et qui tourne depuis des mois. Avant d'aller plus loin  voici une photo du montage dans sa boite.



DS3231


Nous allons améliorer notre montage précédent en changeant de RTC, le composant DS3231 dispose de 2 alarmes et d'une sortie (pin3) INT/SQW. L'adressage du bus i2C est le même que pour le DS1307 (0x68). Avec l'arduino on peut utiliser la même librairie pour jouer avec. Utile pour mettre à l'heure l'horloge par exemple.


Pourquoi utiliser le MSP430G2452 ?

La nouvelle génération d'arduino devient intéressante avec la version 3.3 volts et la possibilité de mettre en veille le port série. Mais j'ai consulté des articles, des forums au sujet de la consommation d'énergie et dans ce domaine les MSP430 s'en sortent plutôt pas mal annonçant des modes veilles de quelques nano-ampères et en plus un réveil rapide. Sur le marché Texas instrument propose des LaunchPad pour débuter, par défaut dans la boite vous trouverez 2 micros-contrôleurs :
  • MSP430G2553
  • MSP430G2452
J'ai retenu le second car il y avait plus d'infos sur les forums et je trouve qu'il est plus facile à prendre en main. on va pouvoir utiliser son 'Timer' interne et les interruptions pour endormir et réveiller notre processeur. 

Remarques: Attention à la manipulation du processeur, les pattes sont fragiles au moment de la mise en place et du retrait. Aidez vous d'une pince à épiler à passer dessous le boitier pour le lever uniformément.


Les changements induits ?

L'alimentation du MSP430G2452 est de 3.3v, par conséquent le bus I2C doit fonctionner en 3.3v, heureusement pour nous, le DS3231 s'en sort bien il fonctionne correctement à cette tension nous ne serons pas obligé de mettre des pull-up. Idem pour la commande moteur si vous utilisez le 'DRV8885 de chez pololu' aucun changement à faire. Plutôt des bonnes nouvelles de ce côté là.

Du côté de la programmation, il existe le logiciel Energia qui est le clône d'arduino avec ces sketchs. Mais là il y a un soucis quand on s’intéresse comme moi à la consommation, on se rend compte qu'avec Energia on ne peut pas utiliser le mode veille comme on le voudrait, peut-être que cela a été changé depuis.... Alors j'ai décidé de télécharger le logiciel proposé par TI sous licence mais gratuit à condition d'avoir des projets de petites tailles ce qui est mon cas. Après avoir rempli un formulaire assez précis de l'utilisation que l'on veut en faire, on arrive enfin à télécharger "Code-composer studio 5-5'.

Les premiers pas !

Il existe des tutos divers et très bien fait sur le sujet donc je ne m'attarderai pas sur la configuration du logiciel et de la compilation du code du MSP430.



Le schéma :
Remarques : l'alimentation du DS3231 est permanente, le micro-contrôleur pourrait commander l'alim, via un 4N55 et il faudrait brancher une résistance de tirage (pull-up) sur l'alarme pour fonctionner sans alimentation extérieure ce qui permettrait de gagner encore...

Le montage du prototype :


Partie code :

J'ai transposé le code arduino, on retrouve
les temps de descente et de montée


 
static const unsigned long Timeropen=15;  
static const unsigned long Timerclose=12;  

 le tableau de réglage mois par mois.


 

 ////////////////////////////////////// JANV  FEV  Mars  Avr  Mai  Jun  
 unsigned char LeveSoleilHeure[12]=  { 7, 6, 6, 6, 5, 5, 4, 4, 4, 4, 4, 4  };  
 unsigned char LeveSoleilMinute[12]= { 0,50, 40,20, 40, 0, 30, 5, 5, 0, 0, 0  };  
 unsigned char CoucheSoleilHeure[12]= {18,18, 18,19, 19,20, 20,20, 20,20, 21,21  };  
 unsigned char CoucheSoleilMinute[12]={10,15, 30,00, 45,35, 0,25, 45,55, 15,35  }; 


Le principe est presque identique à la version Arduino.
Au démarrage la porte du poulailler doit être fermée. Lors de la mise sous tension, la porte s'ouvre (cela permet de vérifier que tout est correctement branché), puis une fois que l'alarme est programmée je mets en veille le MSP430G2452 il est réveillé par interruption sur la pin 1.4 lorsque l'alarme se déclenche. Le micro-contrôleur procède alors à l'ouverture ou fermeture selon l'heure et programme la prochaine alarme sur le DS3231 et se rendort gentiment...

La fonction arduino "delay()" est remplacée par l'utilisation du TimerA avec interruption.

J'ai utilisé et adapté la librairie I2C développé par 
* Kerr D. Wong  
  * http://www.kerrywong.com  

extrait du fichier principal "main.c"

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 // Commande d'un moteur pour l'ouverture et la fermeture d'un poulailler  
 // ELECTRONIC77  
 // 26/03/2014  
 // Matériel :  
 // - MSP430G2452  
 // - RTC DS3232 I2C  
 // - Carte de commande bidirectionnelle d'un moteur CC  
 // - 4N35 optocoupleur  
 // - Transistor de puissance BD233  
 // - Résistance 220 Ohms  
 // - 1 Moteur CC  
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 /* Branchement  
  * 2 alimentation VCC 3.3 et VCC2 5V  
  *  
  *      Clock   MSP430G2452  
  *      SQW               P1.4  
  *      SQL      P1.6  
  *      SDA      P1.7  
  *                 VCC      3.3V  
  *                 GND      GND  
  *  
  *                4N35        MSP430G2452  
  *                1   220 Ohms  P1.0  
  *                2   GND  
  *                3  
  *                4   BD233 patte 3  
  *                5   VCC2  
  *                6  
  *  
  *                BD233  
  *                1 Carte de commande VCC  
  *                2 VCC2  
  *                3 4N35 4  
  *  
  *                Carte de commande  
  *                VCC BD233 1  
  *                GND GND2  
  *                IB1 MSP430G2452 P1.1  
  *                IA1 MSP430G2452 P1.2  
  *  
  *               MSP430G2452  
  *               RST résistance de 47kOmhs Vcc + condo de 100nano vers GND  
  *  
  */  
 #include <msp430.h>  
 #include "DS3231.h"  
 ///////////////////////////////////////////////////  
 //Header  
 unsigned char getIndex(Date t);  
 void initCommandeMoteur();  
 void ouvre();  
 void fermeture();  
 void SetAlarm();  
 void stop();  
 //////////////////////////////////////////////////  
 static const unsigned long Timeropen=15;  
 static const unsigned long Timerclose=12;  
 //////////////////////////////////////////////////  
 //Heure Hiver  
 //http://ecole.onsevoitdemainalors.org/IMG/pdf/41_Tableau_02.pdf  
 //matin retire 1h45  
 // soir ajoute 1h30  
 ////////////////////////////////////// JANV  FEV  Mars  Avr  Mai  Jun  
 unsigned char LeveSoleilHeure[12]=  { 7, 6, 6, 6, 5, 5, 4, 4, 4, 4, 4, 4  };  
 unsigned char LeveSoleilMinute[12]= { 0,50, 40,20, 40, 0, 30, 5, 5, 0, 0, 0  };  
 unsigned char CoucheSoleilHeure[12]= {18,18, 18,19, 19,20, 20,20, 20,20, 21,21  };  
 unsigned char CoucheSoleilMinute[12]={10,15, 30,00, 45,35, 0,25, 45,55, 15,35  };  
 /**  
  * Kerr D. Wong  
  * http://www.kerrywong.com  
  *  
  * D3231 RTC Example Using MSP430G2452  
  * sans pull up p1.6=SCL p1.7=sda  
  */  
 volatile unsigned long iCompteur=0;  
 unsigned char isAlarmSet;  
 Date dt;  
 Date dtAlarm;  
 Date dtSetAlarm;  
 /**  
  * Stop the Watch Dog Timer  
  */  
 void inline stopWatchDogTimer() {  
   WDTCTL = WDTPW + WDTHOLD;  
 }  
 void init()  
 {  
      stopWatchDogTimer();  
 /*  
      P1DIR = 0xFF;               // All P1.x outputs  
      P1OUT = 0;                // All P1.x reset  
      P2DIR = 0xFF;               // All P2.x outputs  
      P2OUT = 0;  
 */  
 }  
 void StartInterruptClock(){  
       P1DIR = 0x01;               // P1.0 output, else input  
       P1OUT = 0x10;              // P1.4 set, else reset  
       P1REN |= 0x10;              // P1.4 pullup  
       P1IE |= 0x10;               // P1.4 interrupt enabled  
       P1IES |= 0x10;              // P1.4  High to Low Edge  
       P1IFG &= ~0x10;              // P1.4 IFG cleared  
       _BIS_SR(LPM4_bits+GIE); // Enter low power mode 4 le plus bas)  
 }  
 // Port 1 interrupt service routine  
 #pragma vector=PORT1_VECTOR  
 __interrupt void Port_1(void){  
      turnOffAlarm(0x01);  
      //P1OUT ^=0x01; // P1.0 =toggle ^ XOR // POUR DEBUG  
      P1IFG &=~0x10; //P1.4 IFG Cleared (flag)  
      //Ouvre ou ferme la porte du poulailler  
      initCommandeMoteur();  
      //Tempo  
      unsigned char i=0;  
      for (i=0;i<255;i++);  
      if (dtAlarm.hour<12)  
      {  
           //lever  
           ouvre();  
      }  
      else  
      {  
           //Coucher  
           fermeture();  
      }  
      stop();  
      //Programmer la prochaine alarme  
      SetAlarm();  
 }  
 void SetAlarm(){  
      setupRTC3232();  
      ///////////////////////////////////  
      turnOffAlarm(0x01);  
      checkIfAlarm(0x01);  
      //////////////////////////////////  
      //setDate3232(); // ToDO A virer c'est pour le reglage de l'heure  
      //Lecture de l'heure  
      dt=getDateDS3232();  
      /*unsigned char c=dt.second;  
                c=dt.minute;  
                c=dt.hour ;  
                c=dt.dayOfWeek;  
                c=dt.dayOfMonth;  
                c=dt.month ;  
                c=dt.year ;*/  
      //recherche l'index de la date d'alarme dans la matrice  
      unsigned char index=getIndex(dt);  
      signed char Lever=CompareTimeHM(dt,LeveSoleilHeure[index],LeveSoleilMinute[index]);  
      signed char Coucher=CompareTimeHM(dt,CoucheSoleilHeure[index],CoucheSoleilMinute[index]);  
      if (Lever==0){  
           // Si l'heure correspond à l'alarme du lever alors on programme l'alarme du couche  
           dtAlarm.dayOfWeek=dt.dayOfWeek;  
           dtAlarm.minute=CoucheSoleilMinute[index];  
           dtAlarm.hour=CoucheSoleilHeure[index];  
           dtAlarm.second=0;  
      }  
      else if(Coucher==0 || Coucher>0){  
           // Si l'heure correspond à l'alarme du coucher alors on programme l'alarme du lever le lendemain  
           // Si L'heure est superieur alarme du coucher on programme l'alarme du lever  
           dtAlarm.dayOfWeek=dt.dayOfWeek+1;  
           if (dtAlarm.dayOfWeek>6) dtAlarm.dayOfWeek=0;  
           dtAlarm.minute=LeveSoleilMinute[index];  
           dtAlarm.hour=LeveSoleilHeure[index];  
           dtAlarm.second=0;  
      }  
      else if (Lever>0 && Coucher<0)  
      {  
           //On entre le lever et le coucher (par exemple 7h00 vers 19h00) On programme le coucher  
           dtAlarm.dayOfWeek=dt.dayOfWeek;  
           dtAlarm.minute=CoucheSoleilMinute[index];  
           dtAlarm.hour=CoucheSoleilHeure[index];  
           dtAlarm.second=0;  
      }  
      else if (Lever<0){  
           //L'heure est plus petite que le lever on programme le lever  
           dtAlarm.dayOfWeek=dt.dayOfWeek;  
           dtAlarm.minute=LeveSoleilMinute[index];  
           dtAlarm.hour=LeveSoleilHeure[index];  
           dtAlarm.second=0;  
      }  
      //RAPPEL ERRROR ATTENTION DIFFERENT unsigned char A1MH=0x52;//t.minute;  
      turnOnAlarm(1);  
      isAlarmSet=checkAlarmEnabled(1);  
      setA1Time(dtAlarm.dayOfWeek,dtAlarm.hour,dtAlarm.minute,dtAlarm.second,0x08,0x01,0x00,0x00); //une fois par seconde  
      dtSetAlarm=getA1Time();  
      //repete la transmission de l'alarme en cas de pbl  
      unsigned char i=0;  
      for (i=0;i<5;i++)  
      {  
           if (CompareTimeHM(dtSetAlarm,dtAlarm.hour,dtAlarm.minute)!=0)  
           {  
                setA1Time(dtAlarm.dayOfWeek,dtAlarm.hour,dtAlarm.minute,dtAlarm.second,0x08,0x01,0x00,0x00); //une fois par seconde  
                dtSetAlarm=getA1Time();  
           }  
      }  
 }  
 void main(void) {  
      init();  
      // La premiere fois ouvre  
      // refermer à la main si nécessaire  
      initCommandeMoteur();  
      ouvre();  
      stop();  
      SetAlarm();  
      StartInterruptClock(); // Enter low power mode 4 le plus bas)  
 }  
 ////////////////////////////////////////////////////:  
 ///////////////DELAY  /////////////////////////////:  
 ////////////////////////////////////////////////////:  
 void StartInterruptTimerA(){  
        CCTL0 = CCIE;               // CCR0 interrupt enabled  
       CCR0 = 50000;                                    // 50000 SMCLK cycles  
       TACTL = TASSEL_2 + MC_2;         // SMCLK, contmode  
       //_BIS_SR(LPM0_bits + GIE);         // Enter LPM0 w/ interrupt  
       _BIS_SR( GIE);         // Enter LPM0 w/ interrupt  
 }  
 // Timer A0 interrupt service routine  
 #pragma vector=TIMER0_A0_VECTOR  
 __interrupt void Timer_A (void)  
 {  
  //P1OUT ^= 0x01;              // Toggle P1.0  
  //CCR0 += 50000;              // Add Offset to CCR0  
      //Arrete le timer et on averti que c'est bon  
      TACTL = TASSEL_2 + MC_0; // Stop Le timer  
      CCTL0 &= ~ CCIE; // disable interrupt  
 }  
 void delay(unsigned long aDelay){  
      iCompteur=0;  
      for (iCompteur=0;iCompteur<aDelay;iCompteur++){  
           StartInterruptTimerA();  
           while(CCTL0 & CCIE)//FlagTimerA==0)  
           {  
                //P1OUT ^=0x01; // P1.0 =toggle ^ XOR // POUR DEBUG  
           }  
      }  
 }  
 ///////////////////////////////////////////////////////////////////////  
 //////: GESTION POULAILLER  
 ///////////////////////////////////////////////////////////////////////  
 unsigned char getIndex(Date t){  
  unsigned char Index=t.month;  
   if (t.month>6)  
        {  
        // on redescend dans le tableau Juillet -> decembre  
        Index=13-t.month;  
        Index=(Index-1)*2;  
          if( t.dayOfMonth<15)  
               Index++;  
        }  
   else  
   {  
        // Janvier vers Juin  
        Index=(Index-1)*2;  
        if( t.dayOfMonth>15)  
             Index++;  
   }  
   return Index;  
 }  
 void initCommandeMoteur()  
 {  
      // ALIMENTATION  
      P1DIR |= 0x01;          //P1.0 output (alimentation Carte moteur)  
      // Commande Moteur 1  
      P1DIR |= 0x02;          //P1.1 output  
      // Commande Moteur 2  
      P1DIR |= 0x04;           //P1.2 Output  
      // Active l'alimentation  
      P1OUT |= 0x01;           //set High Alimentation du moteur  
 }  
 void ouvre(){  
      P1OUT |= 0x02;  
      P1OUT &=~0x04;  
      delay(Timeropen);  
 }  
 void fermeture(){  
      P1OUT |= 0x04;  
      P1OUT &=~0x02;  
      delay(Timerclose);  
 }  
 void stop(){  
      //Arrete tout  
      P1OUT &=~0x04;  
      P1OUT &=~0x02;  
      P1OUT &=~0x01; // coupe l'alimentation du DS3231  
 }  

Lien vers le code source complet : Commande de portillon avec MSP430 G 2452


Cette version est plus économe en énergie, environ 3mA. Si on regarde en détail on perd  1mA par le régulateur, si on dispose d'un accu 3v alors on peut le supprimer. Autre piste  la carte DS3231 qui consomme 1mA avec une petite led sur la carte qui reste allumée que l'on pourrait supprimer. Pour ma part je me contente de cette version suffisamment optimisée.
Il ne reste plus qu'à l'alimenter avec un petit kit solaire (l'autonomie est alors largement suffisante > 1 mois ). 

Je vais écrire un nouvel article sur la détection crépusculaire, j'ai trouvé une led crépusculaire intéressante proche de la sensibilité de l'oeil humain et des poules.




Part 5

jeudi 25 décembre 2014

Réglage du moteur

Cette article va vous aider à régler rapidement votre ouverture/fermeture  de porte de votre poulailler


Une étape essentielle lors de la mise en service de la porte du poulailler est celle du réglage du temps de descente et de montée.



c'est le rôle du sketch ci-dessous il vous aidera à trouver vos propres valeurs en fonction de votre installation. (Rappel, les valeurs sont en millisecondes.)


 /*  
 ELECTRONIC 77   
  Version 1.0 du 01/12/2013  
  L9110 motor driver controlling   
  - 1 small DC motors  
  */  
  /*  
 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  
 const int IALIM=2;   
  /*  
  SCHEMA Cellule photosensible  
  reçoit digital un 0 ou 1  
  */  
 //const int IP1=3; // DIGITAL INPUT   
 int IsJourLast=HIGH; //Mise en route il fait jour  
 void setup()   
 {  
  //Commande du moteur cc via le L9110H  
  pinMode(IA1, OUTPUT); // set pin to output  
  pinMode(IB1, OUTPUT); // set pin to output  
  pinMode(IALIM,OUTPUT); // set pin output  
  // au branchement lance l'ouverture  
  //forward();   
  //delay(10000);  
  //stop();  
 }  
 void loop() {  
  digitalWrite(IALIM, HIGH);  
    forward();   
    delay(1100);  
    stop();  
    digitalWrite(IALIM, LOW);   
    delay(10000);  
    digitalWrite(IALIM, HIGH);  
    backward();  
    delay(880);  
    stop();  
    delay(10000);  
 }  
 void stop(){  
  digitalWrite(IA1, LOW);  
  digitalWrite(IB1, LOW);  
 }  
 void backward()  
 {  
  digitalWrite(IA1, LOW);  
  digitalWrite(IB1, HIGH);  
  }  
 void forward()  
 {  
  digitalWrite(IA1, HIGH);  
  digitalWrite(IB1, LOW);  
  }  

la porte s'ouvre et se ferme toutes les 10 secondes "delay(10000)",  il vous faut régler le temps de montée actuellement fixé à "1100":
    
forward();   
delay(1100);  // temps de montée  
stop(); 

Temps de descente :
 
backward();  
delay(880);  
stop();

Bon réglage !

mercredi 24 décembre 2014

Porte de poulailler Part - 3 : Arduino avec RTC (horloge)

 Retour Part-2

Version arduino avec horloge RTC

Dans cette article nous allons voir comment utiliser une horloge RTC. L'idée est de fermer et d'ouvrir la porte du poulailler selon un horaire défini par le microcontrôleur. On a besoin d'une horloge (Real Time Clock) DS1307 sur batterie interne, d'une carte de commande de moteur CC avec un bridge type DRV8835 par exemple et de 2 alimentations : une pour le microcontrôleur et l'autre pour le moteur. 

La mise en oeuvre d'une horloge RTC sur bus I2C se fait en connectant  la sortie 'sda' sur le pin 4  et 'sdl' sur le pin 5 de l'arduino. Pour le branchement des autres éléments je vous invite à consulter la partie 2.

 Schéma de câblage :

Réglage de l'heure :

Lors de l'achat de votre RTC, vous voudrez certainement régler l'heure, inutile de faire un article de plus vous trouverez toutes les infos ici ! Voici le lien vers la librairie RTCLib nécessaire pour utiliser l'horloge.
Dans mon cas j'ai opté pour conserver l'heure d'hiver. 

L'étape suivante est de paramétrer les tableaux d'ouverture et de fermeture dans le code du microcontrôleur (ces tableaux seront utilisés dans le sketch de l'arduino un peu plus loin) :

Après une petite recherche sur internet, vous trouverez certainement les horaires de lever et de coucher du soleil de votre région.
http://ecole.onsevoitdemainalors.org/IMG/pdf/41_Tableau_02.pdf

Voici les tableaux que nous allons utiliser :
 
 ////////////////////////// JANV    FEV    Mars    Avr   Mai    Jun  
 int LeveSoleilHeure[12]=  {07,06, 06,06, 05,05, 04,04, 03,03, 03,03  };  
 int LeveSoleilMinute[12]= {00,50, 40,20, 40,00, 30,00, 45,15, 05,05  };  
 int CoucheSoleilHeure[12]= {18,18, 19,19, 19,20, 21,21, 21,22, 22,22  };  
 int CoucheSoleilMinute[12]={15,45, 00,30, 45,35, 00,25, 45,05, 20,25  };  



Observons les 2 tableaux suivants: LeveSoleilHeure[12] ,LeveSoleilMinute[12].

Ils représentent une demi année,  pour faire l'année complète on reprends le tableau à l'envers, ainsi juillet=juin, aout=mai etc... il y a un tableau pour les heures et un autre pour les minutes. Il y a 2 heures de défini par mois par exemple pour le mois de janvier, du [1-14] l'ouverture est programmé à 07h00 et du [15-31] janvier l'ouverture se fait à 06h50 heure d'hiver. 

Remarques : Pour économiser de l’énergie, je coupe l'alimentation de la carte de commande du moteur (pin D3), idem pour l'horloge  (pin D2, elle passera automatiquement sur pile de sauvegarde).

Les conditions initiales :
l'arduino doit-être branché de jour et la porte du poulailler est fermée.

Voici le code complet:
 /*   
  Electronic 77  
  Version 3.0 du 09/01/2014   
  L9110 or DRV8835 motor driver controlling    
  - 1 small DC motors      
  - RTC DS1307   
  */   
  #include <Wire.h>   
  #include "RTClib.h"   
  #include <avr/sleep.h>   
  // This library contains functions to set various low-power    
  // states for the ATmega328   
  // This variable is made volatile because it is changed inside   
  // an interrupt function   
  volatile int sleep_count = 0; // Keep track of how many sleep   
  // cycles have been completed.   
  const int interval = 5; // Interval in minutes between waking   
  // and doing tasks.   
  const int sleep_total = (interval*60)/8; // Approximate number    
  // of sleep cycles needed before the interval defined above    
  // elapses. Not that this does integer math.   
  /*   
  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   
  const int TpsMontee=1200; // réglage du temps de montée   
  const int TpsDescente=880; // réglage du temps de descente   
  /*MODULE RTC SPARK FUN BOB 099   
  DS 1307 Communication I2C   
  Récupération de l'heure via I2C sur les ports 4 et 5 analogique de l'arduino NANO   
  */   
  // RTC   
  RTC_DS1307 RTC;   
  int AlimentationRTC=3;   
  //Carte Brighe Commande   
  int ALimentationCMD=2;   
  //POULAILLER    
  boolean FlagOpen=false; //porte   
  //Heure Hiver   
  //http://ecole.onsevoitdemainalors.org/IMG/pdf/41_Tableau_02.pdf   
  //matin retire 1h45    
  // soir ajoute 1h30   
  ////////////////////////// JANV FEV Mars Avr Mai Jun   
  int LeveSoleilHeure[12]= {07,06, 06,06, 05,05, 04,04, 03,03, 03,03 };   
  int LeveSoleilMinute[12]= {00,50, 40,20, 40,00, 30,00, 45,15, 05,05 };   
  int CoucheSoleilHeure[12]= {18,18, 19,19, 19,20, 21,21, 21,22, 22,22 };   
  int CoucheSoleilMinute[12]={15,45, 00,30, 45,35, 00,25, 45,05, 20,25 };   
  void setup(void) {   
   //Commande du moteur cc via le L9110H   
  pinMode(IA1, OUTPUT); // set pin to output   
  pinMode(IB1, OUTPUT); // set pin to output   
  // au branchement lance l'ouverture   
  // COndition initiales :    
  // - faire jour   
  //- Porte poulailler fermée   
  stop();   
   // Carte de commande des moteurs switch alim pour economie d'nrj   
   pinMode(ALimentationCMD, OUTPUT);    
   digitalWrite(ALimentationCMD, LOW);    
   pinMode(AlimentationRTC, OUTPUT);     
   digitalWrite(AlimentationRTC, LOW);    
   Wire.begin();   
   RTC.begin();;   
   //Serial.begin(57600);   
  watchdogOn(); // Turn on the watch dog timer.   
  // The following saves some extra power by disabling some    
  // peripherals I am not using.   
  // Disable the ADC by setting the ADEN bit (bit 7) to zero.   
  ADCSRA = ADCSRA & B01111111;   
  // Disable the analog comparator by setting the ACD bit   
  // (bit 7) to one.   
  ACSR = B10000000;   
  // Disable digital input buffers on all analog input pins   
  // by setting bits 0-5 to one.   
  DIDR0 = DIDR0 | B00111111;   
  //Serial.print("FIN init");   
  //Serial.println();   
  }   
  void loop(void) {   
  goToSleep(); // ATmega328 goes to sleep for about 8 seconds   
  // and continues to execute code when it wakes up   
  if (sleep_count == sleep_total) {   
  // CODE TO BE EXECUTED PERIODICALLY   
   digitalWrite(AlimentationRTC, HIGH);    
   delay(500);   
   DateTime now = RTC.now();   
   digitalWrite(AlimentationRTC, LOW);    
   //Les poules sont -elles levées   
   int index= getIndex(now);   
   if (FlagOpen==false && canOpen(now,index))   
   {   
   //Ouvre   
   OpenPorte();   
   FlagOpen=true;   
   }   
   if (FlagOpen && canClose(now,index))   
   {   
   //Ferme   
   ClosePorte();   
   FlagOpen=false;   
   }   
   //Serial.print(now.year(), DEC);   
   //Serial.print('/');   
   //Serial.print(now.month(), DEC);   
   //Serial.print('/');   
   //Serial.print(now.day(), DEC);   
   //Serial.print(' ');   
   //Serial.print(now.hour(), DEC);   
   //Serial.print(':');   
   //Serial.print(now.minute(), DEC);   
   //Serial.print(':');   
   //Serial.print(now.second(), DEC);   
   //Serial.println();   
   delay(5000);   
   sleep_count = 0;    
  }   
  }   
  void goToSleep()    
  {   
  // The ATmega328 has five different sleep states.   
  // See the ATmega 328 datasheet for more information.   
  // SLEEP_MODE_IDLE -the least power savings    
  // SLEEP_MODE_ADC   
  // SLEEP_MODE_PWR_SAVE   
  // SLEEP_MODE_STANDBY   
  // SLEEP_MODE_PWR_DOWN -the most power savings   
  // I am using the deepest sleep mode from which a   
  // watchdog timer interrupt can wake the ATMega328   
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode.   
  sleep_enable(); // Enable sleep mode.   
  sleep_mode(); // Enter sleep mode.   
  // After waking from watchdog interrupt the code continues   
  // to execute from this point.   
  sleep_disable(); // Disable sleep mode after waking.   
  }   
  void watchdogOn() {   
  // Clear the reset flag, the WDRF bit (bit 3) of MCUSR.   
  MCUSR = MCUSR & B11110111;   
  // Set the WDCE bit (bit 4) and the WDE bit (bit 3)    
  // of WDTCSR. The WDCE bit must be set in order to    
  // change WDE or the watchdog prescalers. Setting the    
  // WDCE bit will allow updtaes to the prescalers and    
  // WDE for 4 clock cycles then it will be reset by    
  // hardware.   
  WDTCSR = WDTCSR | B00011000;    
  // Set the watchdog timeout prescaler value to 1024 K    
  // which will yeild a time-out interval of about 8.0 s.   
  WDTCSR = B00100001;   
  // Enable the watchdog timer interupt.   
  WDTCSR = WDTCSR | B01000000;   
  MCUSR = MCUSR & B11110111;   
  }   
  ISR(WDT_vect)   
  {   
  sleep_count ++; // keep track of how many sleep cycles   
  // have been completed.   
  }   
  ///////////////////////////////////////////////////////////////////////   
  //////: GESTION POULIAILER   
  ///////////////////////////////////////////////////////////////////////   
  int getIndex(DateTime t){   
  int Index=t.month();   
   if (t.month()>6)   
 {  
   Index=13-t.month();    
   Index=(Index-1)*2;     
   if( t.day()<15)   
   Index++;   
 }  
 else   
 {  
   Index=(Index-1)*2;     
   if( t.day()>15)   
   Index++;   
 }  
   //Serial.print("Index ");   
   //Serial.print(Index, DEC);   
   //Serial.println();   
   return Index;   
  }   
  boolean canOpen(DateTime t,int index)   
  {   
   if (t.hour()<=13 && (t.hour()== LeveSoleilHeure[index] && t.minute()>= LeveSoleilMinute[index] || t.hour()> LeveSoleilHeure[index]))   
   return true;   
   else    
   return false;   
  }   
  boolean canClose(DateTime t,int index){   
   if (t.hour()<=23 && (t.hour()== CoucheSoleilHeure[index] && t.minute()>= CoucheSoleilMinute[index] || t.hour()> CoucheSoleilHeure[index]))   
   return true;   
   else    
   return false;   
  }   
  void SetALimentationCMD(boolean isAlimente)   
  {    
  if (isAlimente)   
  {   
   digitalWrite(ALimentationCMD, HIGH);     
   delay(1000);   
  }   
  else   
   digitalWrite(ALimentationCMD, LOW);     
  }   
  void ClosePorte()   
  {   
  SetALimentationCMD(true);   
  //Serial.print("Fermeture de la porte\n");   
   backward();   
   delay(TpsDescente);     
   stop();   
  SetALimentationCMD(false);    
  }   
  void OpenPorte()   
  {   
   SetALimentationCMD(true);   
   //Serial.print("Ouverture de la porte\n");   
   forward();    
   delay(TpsMontee);   
   stop();   
   SetALimentationCMD(false);    
  }   
  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);   
  }   
  ////////////////////////////////////////////////////////////////////////  


 Quel est l'avantage d'utiliser une horloge par rapport à  un capteur crépusculaire ?  

L'horloge est un système plus robuste, il ne souffre pas d'une mauvaise détection du capteur (feuille sur le capteur, etc... ), pas de rebond de détection.
Cependant la consommation comme le montage précédent ne permet pas de tenir la semaine. Malgré une mise en veille de l'arduino toute les 8 secondes.
C'est pourquoi dans la  4ème partie nous allons utiliser une horloge RTC DS3231 qui à l'avantage d'avoir un mode alarme pour mettre en veille prolongée le microcontrôleur et en plus, on va changer de microcontrôleur par un moins gourmand en énergie. J'ai choisi d'acheter un kit 'launchpad' de la famille MSP430 de chez Texas Instrument.

Lien vers la partie 4

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.  

dimanche 21 décembre 2014

Porte de poulailler Part - 1 : Partie mécanique


  Construire une porte de poulailler automatique fonctionnant sur batterie

 

Voilà 1 an maintenant que ma porte est opérationnelle, ma porte a évolué durant quelques mois et finalement je dispose désormais d'une version stable ou plus exactement je dispose d'un panel de solutions ! 
J'ai fait l' acquisition de 2 poules ainsi que d'un joli poulailler en bois et enfin j'ai aménagé un enclos pour leur donner plus d'espace au fond de mon jardin. J'avais pris l'habitude d'ouvrir et de fermer  leur porte  pour leur sécurité (fouine renard etc..). C'est là que m'est venu l'idée de réaliser une porte automatique pour sécuriser le poulailler et pour leur permettre de se balader dans l'enclos même si nous sommes en déplacement. Avec cet article, j'ai voulu partager mon expérience.

Objectif


il m'a fallu du temps pour arriver à mes fins... A première vue le principe est simple: ouvrir la porte le matin, fermer le soir. Il suffit de répondre à cette question, à quelle heure se couche et se lève une poule ? Réponse: en fonction de la luminosité oui mais .... la sensibilité des animaux n'est pas toujours équivalente à celle de l'homme, il se trouve que j'ai une poule qui est une vraie trainarde et une lève tôt. A la limite de l'obscurité elle n'est pas décidée à rentrer....
Bon voilà les bases du problème ! Assez parlé voyons d'abord en détails la partie la plus simple du projet  la partie mécanique.

La partie mécanique


 La contrainte est d'avoir un mécanisme peu couteux en énergie, j'ai retenu le principe de la porte à guillotine pour sa facilité de mise en œuvre. La porte coulisse entre 2 rails de bas en haut et inversement. Le tout commandé par un petit moteur électrique récupéré d'un vieux jouet. Il nous faudra donc une poulie sur l'axe du moteur pour débobiner ou rembobiner un câble fixé à la porte. Petite astuce, j'ai attaché le fil comme dans le schéma ci-dessous. 

Ce schéma présente 2 avantages, la force de traction du moteur est divisée par 2 et il n'est plus nécessaire de mettre en place un frein moteur pour maintenir la porte en position ouverte simplifiant ainsi la mise en œuvre.


Matériaux utilisés

  • 2 glissières en alu qui servaient au store de velux pour réaliser les rails.
  •  Du fil de pêche pour le câble.
  •  Un vieux moteur électrique de jouet.
  • Un plaque de plastic de 3 mm d'épaisseur assez légère et sans entretien qui fera office de porte. 
  • une poulie en bois réalisé avec une perceuse et une scie cloche.
  • Une boite en plastique pour recevoir le moteur et l’électronique. 

Montage 


Porte et glissières :

  • Couper les glissières avec une scie à métaux d'une longueur de 50 cm.

  • Découper un morceau de plastique pour obtenir un rectangle de 28 (largeur) X 20 (hauteur) cm. Biseauter les coins pour faciliter la descente et la montée de la porte.

  • puis à l'aide d'un niveau positionner les glissières sans les fixer de part et d'autre de la porte avec un écartement de 30 cm, introduire la porte et vérifier qu'elle navigue aisément de haut en bas entre les glissières.  Ajuster si nécessaire l'écartement des glissières.

  • Il ne vous reste plus qu'à percer et visser les glissières. 

Remarques : Les glissières sont fixées directement sur la porte attention a ce que les vis n'entravent pas le passage de la porte.

Poulie, moteur :



j'ai réalisé la poulie à l'aide de morceaux de bois coupé à la scie à cloche et d'une douille  que j'ai récupéré  le tout collé avec de l'araldite. Passons au moteur, il faut s'assurer d'avoir une bonne longueur de fil d'alimentation du moteur sinon placer une rallonge (cosses ou des dominos sur les fils du moteurs) pour pouvoir relier le moteur à notre platine de test à l'intérieur de la boite.

Moteur,boite  et câble :


Percer un trou à la scie cloche sur une extrémité de la boite (côté opposé à l'ouverture) pour permettre de faire sortir le moteur électrique de quelques mm . coller ensuite le moteur au pistolet à colle soyer généreux en colle pour bien maintenir l'ensemble et réaliser une bonne étanchéité. 

Remarques : réaliser des petits trous dans le fond de la boite pour évacuer l'eau qui aurait réussi à rentrer.
Il ne reste plus qu'à fixer la boite et de mettre en place le câble, comme le montre la photo suivante(sur la photo la porte est en position haute). Pour cela percer un trou au milieu supérieur de la porte pour permettre le passage du fil de pêche. Placer la porte en position basse et faire un nœud côté crochet  et relier la porte puis la poulie en laissant une surplus de 2 cm qui nous servira de marge d'erreur pour la temporisation d'ouverture de la porte.


Et voilà la partie mécanique est terminée, nous allons nous intéresser à l'électronique dans les prochains articles.

Part - 2