Go Down

Topic: Shield DS 3231 RTC, gestire ora legale (Read 3011 times) previous topic - next topic

ziopippo

Ho acquistato un RTC DS 3231 e dilibrerie per utilizzarlo ne ho trovato diverse.
Il mio dubbio però è:
Dovendo chiudere tutto in un box poco accessibile, come gestire in modo automatico la sincronizzazione automatica per l'aggiornamento all'ora legale/solare senza utilizzare internet o pc?

Karellen

La butto li: se hai spazio almeno per un piccolo pulsante (magari anche un foro nel case in cui infilare uno stecchino) lo potresti usare per l'ora legale/solare.

Ad ogni tocco inverti una bool o cambi 0/1 in una byte, a seconda del valore assunto o/false o 1/true togli o aggiungi un'ora all'ora corrente, ricalcoli tutto (che se lo fai intorno a mezzanotte potrebbe sbarellare tutto) e riscrivi l'RTC.

My 10b cents :)

uwefed

Puoi calcolare il cambio orario.
Ci sono esempi in rete.
Ciao Uwe



ziopippo

La butto li: se hai spazio almeno per un piccolo pulsante (magari anche un foro nel case in cui infilare uno stecchino) lo potresti usare per l'ora legale/solare.

Ad ogni tocco inverti una bool o cambi 0/1 in una byte, a seconda del valore assunto o/false o 1/true togli o aggiungi un'ora all'ora corrente, ricalcoli tutto (che se lo fai intorno a mezzanotte potrebbe sbarellare tutto) e riscrivi l'RTC.

My 10b cents :)
sto aspettando che mi arrivi la centralina

ma credo di riuscire a trovare spazio per un lcd ed ovviamente 3 tastini per settare alcune impostazioni orarie utili al mio progetto.
Ovviamente potrei prevedere una voce di menù per settare l'ora legale o solare però preferirei che lo facesse autonomamente.

SukkoPera

Sbaglio o usa il collegamento ad un pc per la sincronizzazione?
Sbagli ;D.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

ziopippo


ziopippo

#8
Apr 07, 2018, 05:12 pm Last Edit: Apr 09, 2018, 11:38 am by ziopippo
HO provato
Sbagli ;D.
Sto provando il codice che mi hai consigliato :

Code: [Select]
// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h" // https://github.com/adafruit/RTClib

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"};

void setup () {

#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif

  Serial.begin(9600);

  delay(3000); // wait for console opening

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

byte dstOffset (byte d, byte m, unsigned int y, byte h) {
  /* This function returns the DST offset for the current UTC time.
    This is valid for the EU, for other places see
    http://www.webexhibits.org/daylightsaving/i.html

    Results have been checked for 2012-2030 (but should work since
    1996 to 2099) against the following references:
    - http://www.uniquevisitor.it/magazine/ora-legale-italia.php
    - http://www.calendario-365.it/ora-legale-orario-invernale.html
  */

  // Day in March that DST starts on, at 1 am
  byte dstOn = (31 - (5 * y / 4 + 4) % 7);

  // Day in October that DST ends  on, at 2 am
  byte dstOff = (31 - (5 * y / 4 + 1) % 7);

  if ((m > 3 && m < 10) ||
      (m == 3 && (d > dstOn || (d == dstOn && h >= 1))) ||
      (m == 10 && (d < dstOff || (d == dstOff && h <= 1))))
    return 1;
  else
    return 0;
}

const int utcOffset = 1;

DateTime getLocalTime() {
  DateTime now = rtc.now();
  int32_t deltaSecs = (utcOffset + dstOffset (now.day(), now.month(), now.year(), now.hour()) * 3600UL);
  // int32_t deltaSecs = (utcOffset + dstOffset (now.day(), now.month(), now.year(), now.hour())) * SECS_PER_HOUR
  const unsigned long SECS_PER_HOUR = 3600;
  DateTime correctedNow (now + TimeSpan(deltaSecs));
  return correctedNow;
}

void loop () {
  DateTime now = getLocalTime();

  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();

  Serial.print(" since midnight 1/1/1970 = ");
  Serial.print(now.unixtime());
  Serial.print("s = ");
  Serial.print(now.unixtime() / 86400L);
  Serial.println("d");

  // calculate a date which is 7 days and 30 seconds into the future
  DateTime future (now + TimeSpan(7, 12, 30, 6));

  Serial.print(" now + 7d + 30s: ");
  Serial.print(future.year(), DEC);
  Serial.print('/');
  Serial.print(future.month(), DEC);
  Serial.print('/');
  Serial.print(future.day(), DEC);
  Serial.print(' ');
  Serial.print(future.hour(), DEC);
  Serial.print(':');
  Serial.print(future.minute(), DEC);
  Serial.print(':');
  Serial.print(future.second(), DEC);
  Serial.println();

  Serial.println();
  delay(3000);
}


però sulla seriale mi riporta:
Code: [Select]
2018/4/7 (Sabato) 18:11:40
 since midnight 1/1/1970 = 1523124700s = 17628d
 now + 7d + 30s: 2018/4/15 6:41:46

ovvero un'ora esatta in più; Come mai secondo voi?

SukkoPera

Stampa anche l'ora reale dell'RTC (rtc.now()) e poi vediamo. Ricorda che quella deve rimanere impostata su GMT/UTC.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

ziopippo

#10
Apr 09, 2018, 06:14 pm Last Edit: Apr 09, 2018, 06:41 pm by ziopippo
Stampa anche l'ora reale dell'RTC (rtc.now()) e poi vediamo. Ricorda che quella deve rimanere impostata su GMT/UTC.
Code: [Select]
2018/4/9 (Luned⸮) 18:12:26
 since midnight 1/1/1970 = 1523297546s = 17630d
 now + 7d + 30s: 2018/4/17 6:42:32


ovvero l'ora esatta


Se invece modifico in questo modo:
Code: [Select]
DateTime getLocalTime() {
  DateTime now = rtc.now();
  //int32_t deltaSecs = (utcOffset + dstOffset (now.day(), now.month(), now.year(), now.hour()) * 3600UL);
  const unsigned long SECS_PER_HOUR = 3600;
  int32_t deltaSecs = (utcOffset + dstOffset (now.day(), now.month(), now.year(), now.hour())) * SECS_PER_HOUR;
 
  DateTime correctedNow (now + TimeSpan(deltaSecs));
  return correctedNow;
}

void loop () {
 DateTime now = getLocalTime();
  //DateTime now = rtc.now();
...
...


addirittura mi aumenta di due ore :(

SukkoPera

Allora non ci capiamo: l'RTC deve rimanere impostato sull'ora di Greenwich. Insomma, rtc.now() in questo momento deve essere indietro di due ore.

Inizia a sistemare questo e poi andiamo avanti.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

ziopippo

Allora non ci capiamo: l'RTC deve rimanere impostato sull'ora di Greenwich. Insomma, rtc.now() in questo momento deve essere indietro di due ore.

Inizia a sistemare questo e poi andiamo avanti.
Ipostando
Code: [Select]
DateTime now = rtc.now();  ti avevo già scritto che mi dava l'ora atuale ;)

Code: [Select]
2018/4/9 (Luned⸮) 18:12:26
 since midnight 1/1/1970 = 1523297546s = 17630d
 now + 7d + 30s: 2018/4/17 6:42:32


ovvero l'ora esatta

...

gpb01

#13
Apr 09, 2018, 07:54 pm Last Edit: Apr 09, 2018, 07:54 pm by gpb01
ti avevo già scritto che mi dava l'ora attuale ;)
... ti ha appena ribadito che è SBAGLIATO ... deve darti due ore prima della nostra ora attuale (... ovvero l'ora GMT), quindi rimetti l'orario nel RTC.

Guglielmo
Search is Your friend ... or I am Your enemy !

ziopippo

#14
Apr 09, 2018, 08:13 pm Last Edit: Apr 09, 2018, 08:14 pm by ziopippo
... ti ha appena ribadito che è SBAGLIATO ... deve darti due ore prima della nostra ora attuale (... ovvero l'ora GMT), quindi rimetti l'orario nel RTC.

Guglielmo
Scusa ma non avevo copreso bene.

Domanda: Per impostare l'ora non si usa:
Code: [Select]
rtc.adjust(DateTime(2018, 4, 9, 18, 10, 0));
 
Se si, perchè ignora questo comando lasciando l'ora attuale alle 20 invece che alle 18? (Da me sono ovviamente le 20).

ho provato con un codice "pulito" come questo:
Code: [Select]
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup () {
  while (!Serial); // for Leonardo/Micro/Zero

  Serial.begin(57600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
     rtc.adjust(DateTime(2018, 4, 9, 18, 10, 0));
  }
}

void loop () {
    DateTime now = rtc.now();
    
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
    
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now + TimeSpan(7,12,30,6));
    
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
    
    Serial.println();
    delay(3000);
}

Go Up