Un temporizzatore con il chip RTC DS1307: il codice

Eccomi di nuovo con il temporizzatore.

Come ho spiegato nel post precedente voglio accendere e/o spegnere un utilizzatore a 220 V utilizzando dei relè.

Ad oggi non ho mai avuto esperienza nell’utilizzo dei relè, quindi lo schema comprenderà l’accensione/spegnimento di un led.

Ecco lo schema visto precedentemente con l’aggiunta del led collegato al PIN 13 digitale di Arduino:

persito

 

Ed ecco il codice:

 

#include <Wire.h>
#include <String.h>
#include "RTClib.h"

#define BUFFER_SIZE 20
#define STATE_OFF  0
#define STATE_ON   1

//Giornate di programmazione
const int numeroProgrammazioni = 4;
String lunedi[numeroProgrammazioni] = {
  "21:35", "20:30","20:35","20:40"};
String martedi[numeroProgrammazioni] = {
  "11:00", "11:35","13:10","13:50"};
String mercoledi[numeroProgrammazioni] = {
  "20:55", "19:58","20:00","20:05"};
String giovedi[numeroProgrammazioni] = {
  "10:00", "10:35","17:10","20:00"};
String venerdi[numeroProgrammazioni] = {
  "10:00", "10:35","14:10","15:00"};
String sabato[numeroProgrammazioni] = {
  "18:15", "18:20","18:22","18:25"};
String domenica[numeroProgrammazioni] = {
  "10:00", "10:35","12:10","15:00"};
//Fine giornate di programmazione

RTC_DS1307 rtc;
int fsm_state;
String START_TIME;
String END_TIME;
int nSize = numeroProgrammazioni / 2;
String giornoTemp[numeroProgrammazioni];

void setup () {
  //Serial.println("Inizio Setup");
  fsm_state = STATE_OFF;
  Serial.begin(57600);
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
  rtc.begin();

  if (! rtc.isrunning()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  pinMode(13,OUTPUT);        //Collegamento al LED
}

void loop () {
    // Ricavo il time attuale
    DateTime now = rtc.now();  

    int giorno = now.dayOfWeek();      //0 = lunedi 1 = martedi 2 = mercoledi ....
    //Serial.println( giorno);
    if (giorno == 1){                  //lunedi
      memcpy(giornoTemp,lunedi, sizeof(lunedi));
    }
    else if (giorno == 2){            //martedi
      memcpy(giornoTemp,martedi, sizeof(martedi));
    }
    else if (giorno == 3){            //mercoledi
      memcpy(giornoTemp,mercoledi, sizeof(mercoledi));
    }
    else if (giorno == 4){            //giovedi
      memcpy(giornoTemp,giovedi, sizeof(giovedi));
    }
    else if (giorno == 5){            //venerdi
      memcpy(giornoTemp,venerdi, sizeof(venerdi));
    }
    else if (giorno == 6){            //sabato
      memcpy(giornoTemp,sabato, sizeof(sabato));
    }
    else if (giorno == 7){            //domenica
      memcpy(giornoTemp,domenica, sizeof(domenica));
    }

    //verifico lo stato che dovrà assumere
    int isON = 0;
    for (int i= 0; i< nSize;i++){
      START_TIME = giornoTemp[i*2];
      END_TIME = giornoTemp[(i*2)+1];
      isON = setStatus(now,START_TIME,END_TIME);
      gestisciCarico(isON);
    } //end for

  delay(3000);
}

int setStatus(DateTime timeOra, String START_TIME, String END_TIME)
{
  //recupero l'ora
  DateTime dSTART_TIME = DateTime(timeOra.year(),timeOra.month(),timeOra.day(),START_TIME.substring(0, 2).toInt(),START_TIME.substring(3, 5).toInt(),0);
  DateTime dEND_TIME = DateTime(timeOra.year(),timeOra.month(),timeOra.day(),END_TIME.substring(0, 2).toInt(),END_TIME.substring(3, 5).toInt(),0);
  long lSTART_TIME = dSTART_TIME.unixtime();
  long lEND_TIME = dEND_TIME.unixtime(); 

  switch(fsm_state) {
  case STATE_OFF:
    if(timeOra.unixtime() > lSTART_TIME && timeOra.unixtime() < lEND_TIME) {
      fsm_state = STATE_ON;
      //Serial.println("caso 1");
    }
    break;
  case STATE_ON:
    if(timeOra.unixtime() > lEND_TIME) {
      fsm_state = STATE_OFF;
      //Serial.println("caso 2");
    }
    break;
  }

  return fsm_state;
}

void gestisciCarico(int isON)
{
  if (isON == 1){
    digitalWrite(13,HIGH);
  }
  else
  {
    digitalWrite(13,LOW);
  }
}

Spiegazione del codice:

dalla riga 12 alla riga 25: settaggio delle ore del giorno in cui accendere il led in questo caso
riga 47: viene settato RTC con l’ora e la data di compilazione del codice
riga 50: imposto il collegamento al led su pin 13
Nel loop:
riga 55: ricavo giorno e ora corrente
riga 57: ricavo il giorno corrente (0 = lunedi, 1 = martedi….), questo mi serve per capire in quale stringa di array andare a verificare se accendere il led,se l’array lunedi, martedi e cosi via
riga 86: utilizzo la funzione setStatus per verificare se accendere o meno il led
riga 84: funzione setStatus: per confrontare le date utilizzo la funzione unixtime() che converte la data in formato unix, quindi come long. Il confronto quindi si limita al confronto fra due long. La funzione restituisce un int 0/1 se necessario attivare o meno il led
riga 87: funzione gestisciCarico: la funzione prende in input il valore precedentemente restituito. A questo punto viene acceso o spendo il led.

 

A questo punto il nostro led si accenderà o spegnerà nelle ore da noi stabilite.

I passaggi successivi, che spiegherò prossimamente sono:

1. aggiunta di una funzione random (opzionale): se la funzione random è attiva, allora all’ora di accensione/spegnimento dei giorni settimanali vengono aggiunti dei minuti casuali.

2. modifica del circuito per ospitare il relè e quindi per accendere o spegnere una lampada

Un temporizzatore con il chip RTC DS1307: idea e collegamenti

Ciao di nuovo a tutti, su suggerimento di mio papà, voglio utilizzare Arduino per poter accendere e spegnere una lampada o un qualsiasi utilizzatore a 220 V in determinati orari della settimana.

Quindi ad esempio:
– il lunedì voglio che la mia lampada si accende alle ore 8.15 fino alle 9.40, il pomeriggio invece dalle 17.10 alle 17.45.
– il martedì dalle ore 9.20 alle ore 10.50
– il mercoledì dalle ore 10.00 alle ore 11.00 e nel pomeriggio dalle ore 15.10 alle ore 15.45
e cosi via, fino a domenica

Per fare questo mi sono procurato il chip DS1307: è un RTC (Real-time clock) molto economico che permette di tenere traccia del tempo e della data.
Inoltre è provvisto di una batteria a tampone che garantisce il funzionamento dell’orologio interno anche in assenza di alimentazione esterna.

E’ possibile colloquiare con il chip tramite protocollo I2C, quindi con la libreria Wire.

Il collegamento fra arduino e il chip è molto semplice, come da foto sottostante:

 

Temporizzatore

 

Riepilogando:

 

 

PIN Arduino PIN DS1307
5 V 5 V
GND GND
Pin Analogico 4 SDA
Pin Analogico 5 SCL

 

I collegamenti fra Arduino e il chip variano a seconda del modello di Arduino (uno, leonardo, ecc).
Infatti i PIN SDA (data line) e SCL (clock line) differiscono come da link precedente.

 

Board I2C / TWI pins
Uno, Ethernet A4 (SDA), A5 (SCL)
Mega2560 20 (SDA), 21 (SCL)
Leonardo 2 (SDA), 3 (SCL)
Due 20 (SDA), 21 (SCL), SDA1, SCL1

 

Vedremo nel prossimo post come gestire la date ed ora e come poter utilizzare queste informazioni per poter accendere quando desideriamo un dispositivo.

Alla prossima!!!