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);  
 }