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