Arduino Forum

International => Français => Topic started by: Uzuma on Mar 31, 2014, 07:36 pm

Title: [Résolu] Mettre mon ds1307 à l'heure
Post by: Uzuma on Mar 31, 2014, 07:36 pm
Bonsoir,

comme dit dans le titre j'aimerais pouvoir mettre mon ds1307 à l'heure. Oui bien sûr un tutoriel (http://forum.arduino.cc/index.php?topic=77849.0) existe déjà sur le forum mais l'ennui c'est que j'ai déjà testé le code mais il ne donne pas les résultats escomptés. J'ai cherché ailleurs sur le net sans rien trouver bon. Tout ce qui m'importe c'est que mon horloge récupère l'heure courante de l'ordinateur. Le but est de pouvoir me servir de l'heure pour d'autres applications.

Dans l'espoir de trouver quelques choses de concluant, je vous dit merci d'avance.
Title: Re: Mettre mon ds1307 à l'heure
Post by: Artouste on Mar 31, 2014, 07:57 pm

Bonsoir,

comme dit dans le titre j'aimerais pouvoir mettre mon ds1307 à l'heure. Oui bien sûr un tutoriel (http://forum.arduino.cc/index.php?topic=77849.0) existe déjà sur le forum mais l'ennui c'est que j'ai déjà testé le code mais il ne donne pas les résultats escomptés. J'ai cherché ailleurs sur le net sans rien trouver bon. Tout ce qui m'importe c'est que mon horloge récupère l'heure courante de l'ordinateur. Le but est de pouvoir me servir de l'heure pour d'autres applications.

Dans l'espoir de trouver quelques choses de concluant, je vous dit merci d'avance.

J'ai utilisé le tuto de JF , ça fonctionnait "nickel" , c'est quoi exactement ton soucis avec ?
Title: Re: Mettre mon ds1307 à l'heure
Post by: jfs on Mar 31, 2014, 08:28 pm
Oups... un week end un peu mouvementé et du coup j'ai oublié de refaire les tests avec l'IDE 1.xx et Processing 2.xx

Le tout sans lcd  :smiley-sweat:

Est ce que tu as essayé avec un lcd ?
Title: Re: Mettre mon ds1307 à l'heure
Post by: Artouste on Mar 31, 2014, 08:39 pm

Oups... un week end un peu mouvementé et du coup j'ai oublié de refaire les tests avec l'IDE 1.xx et Processing 2.xx

Le tout sans lcd  :smiley-sweat:

Est ce que tu as essayé avec un lcd ?

Salut JF
coté arduino depuis la 1.00 les fonctions lecture/ecriture  I²C ont changées

Code: [Select]
/*
Permet de mettre une horloge ds1307 en synchronisation avec l'heure NTP
Par le biais d'une application Arduino-Processing
*/

/*

Comporte des parties de code écrites par :
- Maurice Ribble
  4-17-2008
  http://www.glacialwanderer.com/hobbyrobotics
  Pour le ds1307

- X. HINAULT
   01/2010
   http://www.mon-club-elec.fr
   Pour le LCD

*/

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// Stops the DS1307, but it has the side effect of setting seconds to 0
// Probably only want to use this for testing
/*void stopDs1307()
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.write(0x80);
Wire.endTransmission();
}*/

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second,        // 0-59
byte minute,        // 0-59
byte hour,          // 1-23
byte dayOfWeek,     // 1-7
byte dayOfMonth,    // 1-28/29/30/31
byte month,         // 1-12
byte year)          // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));    // 0 to bit 7 starts the clock
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));      // If you want 12 hour am/pm you need to set
  // bit 6 (also need to change readDateDs1307)
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(
byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}


#include <LiquidCrystal.h>

const int RS=2; //declaration constante de broche
const int E=3; //declaration constante de broche
const int D4=4; //declaration constante de broche
const int D5=5; //declaration constante de broche
const int D6=6; //declaration constante de broche
const int D7=7; //declaration constante de broche
LiquidCrystal lcd(RS, E, D4, D5, D6, D7);

int octetReception=0; // variable de stockage des valeurs reçues sur le port Série (ASCII)
char caractereRecu=0; // variable pour stockage caractère recu
int compt=0; // variable comptage caractères reçus

String chaineReception=""; // déclare un objet String vide pour reception chaine
int oldSecond;

void setup() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin(); // initialise 1wire

  Serial.begin(115200); // Initialise la communication série

  // lit les valeurs de l'horloge pour les replacer si elle est déjà à l'heure
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  if ((year)== NULL){ // si l'année = NULL
  // preinitialise l'horloge mets les valeurs lue précédement (à 0 si premier allumage)
  setDateDs1307(int(second), int(minute), int(hour), int(dayOfWeek), int(dayOfMonth), int(month), int(year));
  }

  //***** LCD *****//
  lcd.begin(20,4); // Initialise le LCD avec 20 colonnes x 4 lignes
  delay(10); // pause rapide pour laisser temps initialisation
  lcd.print("initialisation") ; // affiche la chaîne texte - message de test
  lcd.setCursor(0, 1) ;
  lcd.print("de l'horloge") ;
  delay(2000); // pause de 2 secondes
  lcd.clear(); // // efface écran et met le curseur en haut à gauche
  delay(100); // pour laisser temps effacer écran

  //**** liaison pour l'heure NTP ****//
  Serial.println('A'); // envoi un "top" à Processing
  while (millis()<5000) {  // attente pendant 5 secondes d'une liaison série (ne fonctionne pas en dessous)
    while (Serial.available()>0) { // tant qu'un octet est dans la liaison série

      octetReception=Serial.read(); // Lit le 1er octet reçu et le met dans la variable     

      if (octetReception==13) { // si l'octet reçu est le retour chariot (CR ou 13)

        // converti la chaine en entier pour les valeurs de temps
        second = int((chaineReception.charAt(0)-48)*10)+int(chaineReception.charAt(1)-48) ;
        minute = int((chaineReception.charAt(2)-48)*10)+int(chaineReception.charAt(3)-48);
        hour = int((chaineReception.charAt(4)-48)*10)+int(chaineReception.charAt(5)-48);
        dayOfWeek = 1;
        dayOfMonth = int((chaineReception.charAt(6)-48)*10)+int(chaineReception.charAt(7)-48);
        month = int((chaineReception.charAt(8)-48)*10)+int(chaineReception.charAt(9)-48);
        year = int((chaineReception.charAt(12)-48)*10)+int(chaineReception.charAt(13)-48); //int((chaineReception.charAt(10)-48)*1000)+int((chaineReception.charAt(11)-48)*100)+

        //mets le DS1307 en syncronisation avec l'horloge de l'ordinateur
        setDateDs1307(int(second), int(minute), int(hour), int(dayOfWeek), int(dayOfMonth), int(month), int(year));

        chaineReception=""; //RAZ de la chaine de réception
        break; // sort de la boucle while
      }
      else { // si le caractère reçu n'est pas un saut de ligne
        caractereRecu=char(octetReception); // convertit l'octet reçu en caractère
        chaineReception=chaineReception+caractereRecu; // ajoute le caratère à la chaine
      }
    }
  }
}

void loop(){

  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

  if(second!=oldSecond){  // change l'affichage uniquement au changement de seconde
    Serial.print(hour, DEC);
    Serial.print(":");
    Serial.print(minute, DEC);
    Serial.print(":");
    Serial.print(second, DEC);
    Serial.print("  ");
    Serial.print(month, DEC);
    Serial.print("/");
    Serial.print(dayOfMonth, DEC);
    Serial.print("/");
    Serial.print(year, DEC);
    Serial.print("  Day_of_week:");
    Serial.println(dayOfWeek, DEC);

    lcd.home();
    if (int(hour)<=9)lcd.print(0);
    lcd.print(int(hour));
    lcd.print (":");
    if (int(minute)<=9)lcd.print(0);
    lcd.print(int(minute));
    lcd.print (":");
    if (int(second)<=9)lcd.print(0);
    lcd.print(int(second));
    lcd.setCursor (0,1);
    if (int(dayOfMonth)<=9)lcd.print(0);
    lcd.print(int(dayOfMonth));
    lcd.print ("/");
    if (int(month)<=9)lcd.print(0);
    lcd.print(int(month));
    lcd.print ("/20");
    lcd.print(int(year));

  }
  oldSecond=second;  // réinitialise oldSecond

}
Title: Re: Mettre mon ds1307 à l'heure
Post by: jfs on Mar 31, 2014, 08:50 pm
Oui, sur la deuxième page du tuto j'avais fait cette correction.
Title: Re: Mettre mon ds1307 à l'heure
Post by: Uzuma on Mar 31, 2014, 10:09 pm
Bonsoir,


J'ai utilisé le tuto de JF , ça fonctionnait "nickel" , c'est quoi exactement ton soucis avec ?



Je ne comprends pas moi-même, je ne devrais pas avoir de soucis  normalement :(


Oups... un week end un peu mouvementé et du coup j'ai oublié de refaire les tests avec l'IDE 1.xx et Processing 2.xx

Le tout sans lcd  :smiley-sweat:

Est ce que tu as essayé avec un lcd ?


Je  n'ai pas essayé avec le lcd car je n'en ai pas à ma disposition (je n'ai que des afficheurs 7 segments). Mais moi je me disais qu'il ne devrait pas y avoir de problème même sans lcd.
Svp aidez-moi à résoudre ce problème.
Title: Re: Mettre mon ds1307 à l'heure
Post by: john_lenfr on Mar 31, 2014, 10:12 pm
Code: [Select]
// libraries
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include "RTClib.h"
#include <EthernetUdp.h>

// Configuration des adresses Ethernet (MAC) et Internet (IP) du serveur TCP/IP de la carte Arduino.
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB5, 0x42 };//Valeur en hexadécimale de l'adresse MAC de la carte Arduino. Valeur unique sur le réseau.
IPAddress ip(192,168,1,12);

// Configuration pour connection à un serveur NTP pour mise à jour de l'heure
unsigned int localPort = 8888;             // local port to listen for UDP packets
IPAddress timeServer(95, 130, 9, 77);      // http://Ntp.crashdump.fr se synchronise sur les serveur de strate 1
//IPAddress timeServer(193, 79, 237, 14);
//IPAddress timeServer(193, 52, 137, 193);   //http://www.pool.ntp.org/fr/
byte pb[48];                  // buffer to hold incoming and outgoing packets // NTP time stamp is in the first 48 bytes of the message

//Déclaration Internet
EthernetServer server(80);//déclaration du serveur internet de la carte Arduino.
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

// for refresh time day
const unsigned long DISPLAY_INTERVAL_day = 86400000; // wait for 1 day
static unsigned long lastTime_day=0;  // in ms
unsigned long time_day=0;      // in ms

// DS 1307 Time declarations
typedef enum clock__members
{   clock__MemberDay,
   clock__MemberMonth,
   clock__MemberYear,
   clock__MemberHour,
   clock__MemberMinute,
   clock__MemberSecond
} clock__member_t;

static void clock__printDatetime();
static RTC_DS1307  clock__rtc;
static DateTime clock__currentTime;


Code: [Select]

///// SETUP /////
void setup() {
      Serial.begin(9600);
      Ethernet.begin(mac, ip);
      server.begin();
      Wire.begin();

      // Initialize RTC.
      clock__rtc.begin();
      delay(10);

      // update RTC time with NTP protocol if connected to network
      ntpUpdate();        
}


Code: [Select]

///// MAIN PROG /////
void loop(){

 clock__currentTime = clock__rtc.now();
 clock__printDatetime();


 // Update time every day by NTP
 time_day=millis();
 if (time_day-lastTime_day>DISPLAY_INTERVAL_day)  // if at least DISPLAY_INTERVAL ms have passed
 {
   ntpUpdate(); // update RTC time with NTP protocol  
   lastTime_day=time_day;  // reset timer
 }

}


Code: [Select]
static void clock__printDatetime(){
   // Build date string
   char date[] = "XX/XX/XXXX";
   snprintf
   (
       date,
       strlen(date) + 1,
       "%02d/%02d/%04d",
       clock__currentTime.day(),
       clock__currentTime.month(),
       clock__currentTime.year()
   );
   
   // Build time string
   char time[] = "00:00:00";
   snprintf
   (
       time,strlen(time) + 1,
       "%02d:%02d:%02d",
       clock__currentTime.hour(),
       clock__currentTime.minute(),
       clock__currentTime.second()
   );
   
   // Print date
   lcd.setCursor(3, 0);
   lcd.print(date);
   
   // Print time
   lcd.setCursor(4, 1);
   lcd.print(time);
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
 // set all bytes in the buffer to 0
 memset(pb, 0, 48);
 // Initialize values needed to form NTP request
 // (see URL above for details on the packets)
 pb[0] = 0b11100011;   // LI, Version, Mode
 pb[1] = 0;     // Stratum, or type of clock
 pb[2] = 6;     // Polling Interval
 pb[3] = 0xEC;  // Peer Clock Precision
 // 8 bytes of zero for Root Delay & Root Dispersion
 pb[12]  = 49;
 pb[13]  = 0x4E;
 pb[14]  = 49;
 pb[15]  = 52;

 // all NTP fields have been given values, now
 // you can send a packet requesting a timestamp:
 // all NTP fields have been given values, now
 // you can send a packet requesting a timestamp:        
 Udp.beginPacket(address, 123); //NTP requests are to port 123
 Udp.write(pb,48);
 Udp.endPacket();
}

void ntpUpdate(void)
{
   lcd.setCursor(0,0);
   lcd.print("NTP Time sync...");
   Udp.begin(localPort);
   delay(250);
   // send an NTP packet to a time server
   sendNTPpacket(timeServer);

   // wait to see if a reply is available
   delay(1000);

   if ( Udp.parsePacket() ) {
         // read the packet into the buffer
     
         Udp.read(pb, 48);
     
         // NTP contains four timestamps with an integer part and a fraction part
         // we only use the integer part here
         unsigned long t1, t2, t3, t4;
         t1 = t2 = t3 = t4 = 0;
         for (int i=0; i< 4; i++)
         {
           t1 = t1 << 8 | pb[16+i];      
           t2 = t2 << 8 | pb[24+i];      
           t3 = t3 << 8 | pb[32+i];      
           t4 = t4 << 8 | pb[40+i];
         }
           
         // part of the fractional part
         // could be 4 bytes but this is more precise than the 1307 RTC
         // which has a precision of ONE second
         // in fact one byte is sufficient for 1307
           float f1,f2,f3,f4;
           f1 = ((long)pb[20] * 256 + pb[21]) / 65536.0;      
           f2 = ((long)pb[28] * 256 + pb[29]) / 65536.0;      
           f3 = ((long)pb[36] * 256 + pb[37]) / 65536.0;      
           f4 = ((long)pb[44] * 256 + pb[45]) / 65536.0;
           //Serial.println(f1);
           //Serial.println(f2);
           //Serial.println(f3);
           //Serial.println(f4);
           const unsigned long seventyYears = 2208988800UL;
           t1 -= seventyYears;
           t2 -= seventyYears;
           t3 -= seventyYears;
           t4 -= seventyYears;
     
           //Serial.println("T1 .. T4 && fractional parts");
           //PrintDateTime(DateTime(t1)); Serial.println(f1,4);
           //PrintDateTime(DateTime(t2)); Serial.println(f2,4);
           //PrintDateTime(DateTime(t3)); Serial.println(f3,4);
           
           //PrintDateTime(DateTime(t4)); Serial.println(f4,4);
           //Serial.println();
           // Adjust timezone and DST... in my case substract 4 hours for Chile Time
           // or work in UTC?
           t4 += adjustDstEurope(t4); // Adjustig Time with DST Europe/France: UTC+1h in winter, UTC+2h in summer
           t4 += 1;                // adjust the delay(1000) lost at begin of loop
           if (f4 > 0.4) t4++;     // adjust fractional part, see above
           clock__rtc.adjust(DateTime(t4)); // update RTC DS 1307 Clock
           lcd.setCursor(0,0);
           lcd.print("NTP sync OK!    ");
           delay(2000);
           lcd.clear();
     }
     else
     {
     lcd.setCursor(0,0);
     lcd.print("NTP sync not OK!");
     delay(2000);
     lcd.clear();
     }
}


int adjustDstEurope(DateTime t)
{
/*You can use the following equations to calculate when DST starts and ends.
The divisions are integer divisions, in which remainders are discarded.
"mod" means the remainder when doing integer division, e.g., 20 mod 7 = 6.
That is, 20 divided by 7 is 2 and 6/7th (where six is the remainder).
With: y = year.
       For the United States:
           Begin DST: Sunday April (2+6*y-y/4) mod 7+1
           End DST: Sunday October (31-(y*5/4+1) mod 7)
          Valid for years 1900 to 2006, though DST wasn't adopted until the 1950s-1960s. 2007 and after:
           Begin DST: Sunday March 14 - (1 + y*5/4) mod 7
           End DST: Sunday November 7 - (1 + y*5/4) mod 7;
       European Economic Community:
           Begin DST: Sunday March (31 - (5*y/4 + 4) mod 7) at 1h U.T.
           End DST: Sunday October (31 - (5*y/4 + 1) mod 7) at 1h U.T.
           Since 1996, valid through 2099
(Equations by Wei-Hwa Huang (US), and Robert H. van Gent (EC))

Adjustig Time with DST Europe/France/Paris: UTC+1h in winter, UTC+2h in summer

*/

 // last sunday of march
 int beginDSTDate=  (31 - (5* t.year() /4 + 4) % 7);
 //Serial.println(beginDSTDate);
 int beginDSTMonth=3;
 //last sunday of october
 int endDSTDate= (31 - (5 * t.year() /4 + 1) % 7);
 //Serial.println(endDSTDate);
 int endDSTMonth=10;
 // DST is valid as:
 if (((t.month() > beginDSTMonth) && (t.month() < endDSTMonth))
     || ((t.month() == beginDSTMonth) && (t.day() >= beginDSTDate))
     || ((t.month() == endDSTMonth) && (t.day() <= endDSTDate)))
 return 7200;      // DST europe = utc +2 hour (summer time)
 else return 3600; // nonDST europe = utc +1 hour (winter time)
}


Avec gestion heure d'été, heure d'hiver
Title: Re: Mettre mon ds1307 à l'heure
Post by: Uzuma on Mar 31, 2014, 11:38 pm

........................................
Avec gestion heure d'été, heure d'hiver


J'aimerais que l'on me rassure : Avec ce code, je n'aurai pas besoin de shield ethernet n'est-ce pas ? L'arduino seul peut faire l'affaire n''est-ce pas ?!

Title: Re: Mettre mon ds1307 à l'heure
Post by: john_lenfr on Apr 01, 2014, 12:10 am
non avec ce code  il faut un shield.

ton arduino sera branché en permanence a ton PC en usb? je n'en voit pas l'interet dans ce cas
Title: Re: Mettre mon ds1307 à l'heure
Post by: Uzuma on Apr 01, 2014, 01:08 am

non avec ce code  il faut un shield.


Ce n'est ce que je cherchais. Il n'y a que ça comme alternative ?


ton arduino sera branché en permanence a ton PC en usb? je n'en voit pas l'interet dans ce cas


Non. Mon système en entier sera autonome. Le branchement au PC ne servira juste qu'à téléverser le programme.
Title: Re: Mettre mon ds1307 à l'heure
Post by: john_lenfr on Apr 01, 2014, 09:01 am
Et tu souhaites mettre à l'heure régulièrement ou juste une fois définitivement?
Sinon si tu veux pas de câble ça doit pouvoir passer avec un shield wifi non?

Title: Re: Mettre mon ds1307 à l'heure
Post by: gunsman76 on Apr 01, 2014, 09:37 am
En fait c'est assez simple de mettre à l'heure, je ne comprends pas pourquoi tout le monde se complique la vie...

Tu déclares ta librairie DS1307

Dans le void setup :

Code: [Select]
Serial.begin(57600);
    Wire.begin();
    RTC.begin();
   



  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(__DATE__, __TIME__));

  }



Dans le void loop :

Code: [Select]

  //RTC.adjust(DateTime(__DATE__, __TIME__));

 
  DateTime now = RTC.now();
  lcd.setCursor(0, 1);
  lcd.print (now.hour(),DEC);
  lcd.print(":");
  lcd.print(now.minute(), DEC);



Il faut juste décommenter le ligne   //RTC.adjust(DateTime(__DATE__, __TIME__));  lorsque tu es connecté à ton ordi, une fois à l'heure, il faut téléverser le programme une seconde fois en recommantant la ligne   //RTC.adjust(DateTime(__DATE__, __TIME__));


voilà
Title: Re: Mettre mon ds1307 à l'heure
Post by: john_lenfr on Apr 01, 2014, 10:09 am
Oui c'est clair que si c'est pour mettre à l'heure une seule fois c'est plus simple.
Ce code est d'ailleurs par défaut dans la lib RTC.
Title: Re: Mettre mon ds1307 à l'heure
Post by: Uzuma on Apr 01, 2014, 05:13 pm

Et tu souhaites mettre à l'heure régulièrement ou juste une fois définitivement?


Une seule fois.



En fait c'est assez simple de mettre à l'heure, je ne comprends pas pourquoi tout le monde se complique la vie...


Effectivement tu as raison ;)

Merci beaucoup pour ton intervention ! Avec le code que tu as laissé, j'ai fait quelques recherches sur google (en tapant les bons mots cette fois) et je suis tombé sur le code d'Adafruit (http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/overview) qui m'a beaucoup aidé d'ailleurs. Faut dire que mon problème est presque résolu, car l'heure y est presque : je veux dire qu'il y a un décalage d'une minute environ. Enfin ...... regardez par vous-même :

(http://img15.hostingpics.net/pics/765776Capture.png)
Title: Re: Mettre mon ds1307 à l'heure
Post by: jfs on Apr 01, 2014, 07:52 pm
Bon... j'ai tout ressorti, enlevé la poussière  :smiley-mr-green:

Mis en configuration sans lcd (tout viré ce qui s'y rapporte), branché mon ds1307 sur les pin A4 et A5 (Duemilanova atmega168).

Je téléverse le sketch pour la version 1.xx (j'utilise la 1.04), lance le sketch Processing (1.5.1),cette fois je suis en position 4 de la liste des ports disponibles, je change la position du port dans le sketch, débranche mon arduino, lance le sketch Processing à nouveau, rebranche l'Arduino.... j'attends, dans la console série Processing une série de chiffres s'affiche signe qu'il s'est passé quelques chose, je sors du sketch Processing en appuyant sur le carré, Je lance la console série sur l'IDE Arduino.... et l'heure de mon ds1307 est au 10ème de seconde près le même que l'horloge de mon ordi.

mon ds1307 n'a pas de pile, donc c'est pas une heure qui reste en mémoire.

Voili voilou
Title: Re: Mettre mon ds1307 à l'heure
Post by: Uzuma on Apr 02, 2014, 12:43 am

Bon... j'ai tout ressorti, enlevé la poussière  :smiley-mr-green:

Mis en configuration sans lcd (tout viré ce qui s'y rapporte), branché mon ds1307 sur les pin A4 et A5 (Duemilanova atmega168).

Je téléverse le sketch pour la version 1.xx (j'utilise la 1.04), lance le sketch Processing (1.5.1),cette fois je suis en position 4 de la liste des ports disponibles, je change la position du port dans le sketch, débranche mon arduino, lance le sketch Processing à nouveau, rebranche l'Arduino.... j'attends, dans la console série Processing une série de chiffres s'affiche signe qu'il s'est passé quelques chose, je sors du sketch Processing en appuyant sur le carré, Je lance la console série sur l'IDE Arduino.... et l'heure de mon ds1307 est au 10ème de seconde près le même que l'horloge de mon ordi.

mon ds1307 n'a pas de pile, donc c'est pas une heure qui reste en mémoire.

Voili voilou



Merci mon modo  XD  (et pardon si je t'ai fait perdre du temps) J'ai refais comme tu l'as si bien décrit mais je n'y arrive toujours pas. Mais comme je l'ai dit, j'ai réussi à le faire avec le code d'Adafruit(faut dire qu'avec les librairies toutes prêtes, c'est encore plus aisé). Le seul truc qui me turlupine encore c'est qu'il y a un décalage assez instable de temps.
Voici le code :

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;

void setup () {
    Serial.begin(57600);
    Wire.begin();
    RTC.begin();

  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(__DATE__, __TIME__));
  }

}

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(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    Serial.print(" since 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.unixtime() + 7 * 86400L + 30);

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



Alors s'il y a moyen d'ajuster cela pour avoir ne serait-ce qu'une différence assez négligeable ...
Title: Re: Mettre mon ds1307 à l'heure
Post by: gunsman76 on Apr 02, 2014, 06:09 am
Quand tu dis décalage de temps, elle avance ou retarde, c'est ça ?
Si c'est le cas, cela provient du quartz qui n'est pas de bonne qualité.  Pas grand chose à faire,  changer de module. Il faut éviter les ds1307 bas de gamme,  prendre un module chez gotronic par exemple, la qualité est nettement meilleur.
Title: Re: Mettre mon ds1307 à l'heure
Post by: jfs on Apr 02, 2014, 07:29 am
Pas de soucis  ;)

Une chose encore, la console série Arduino et le sketch Processing ne doivent pas être lancé en même temps.
Title: Re: Mettre mon ds1307 à l'heure
Post by: haifger on Apr 02, 2014, 01:44 pm

Alors s'il y a moyen d'ajuster cela pour avoir ne serait-ce qu'une différence assez négligeable ...

Ce décalage de quelques dizaines de secondes est normal et il n'y a pas grand chose que tu puisse y faire avec cette méthode.

Pour détailler un peu, cette ligne de code :
Code: [Select]
RTC.adjust(DateTime(__DATE__, __TIME__));
utilise des macros prédéfinies du préprocesseur qui permettent d'enregistrer dans le programme la date et l'heure de la compilation, ou pour être encore plus précis le moment ou le préprocesseur a analysé le code.

Grosso modo l'enchaînement des opérations est le suivant :

Il n'est donc pas très étonnant qu'il y ait au final un décalage de plusieurs (dizaines de) secondes entre l'heure effectivement installée dans la puce et l'heure théorique du PC.

D'un autre côté, comme l'a dit gunsman76, la plupart des cartes « à-pas-cher » contenant des DS1307 ont des dérives journalières de plusieurs dizaines de secondes, voire minutes. Ce décalage initial devrait donc assez rapidement devenir le dernier de tes soucis :)
Title: Re: Mettre mon ds1307 à l'heure
Post by: Artouste on Apr 02, 2014, 02:06 pm

Quand tu dis décalage de temps, elle avance ou retarde, c'est ça ?
Si c'est le cas, cela provient du quartz qui n'est pas de bonne qualité.  Pas grand chose à faire,  changer de module. Il faut éviter les ds1307 bas de gamme,  prendre un module chez gotronic par exemple, la qualité est nettement meilleur.

bonjour
Il n'y a pas de DS1307 "bas de gamme"  :smiley-mr-green: , ce qu'il peut y avoir ce sont des modules de provenance differentes equipés avec du QZ horloger "tout venant" ,  le DS1307 lui ne fait que compter en fonction de la qualité de sa BdT .

un "mauvais" module à l'origine et equipé ensuite d'un QZ "serieux"  deviendra un module bien "meilleur"

pour anecdote :  j'ai un four à micro-ondes dont l'horloge prend allegrement une avance de  5 mn/semaine  :smiley-mr-green:

je pourrais surement changer le QZ , mais quel interet  ?  :

- Pour ce qui est des temps de cuisson , le decalage final est relatif au temps de depart , l'influence est là  ?
- Meme si je fais regulierement une exacte remise à l'heure, je sais que je ne serai jamais en retard  :smiley-mr-green:


Title: Re: Mettre mon ds1307 à l'heure
Post by: Uzuma on Apr 02, 2014, 03:27 pm
Quote

Une chose encore, la console série Arduino et le sketch Processing ne doivent pas être lancé en même temps.


Je n'avais pas fais trop attention à ça.


Grosso modo l'enchaînement des opérations est le suivant :

  • Le préprocesseur remplace __DATE__ et __TIME__ par l'heure actuelle du PC

  • Le compilateur compile

  • Le programme compilé est téléversé dans le microcontrôleur

  • Le programmeur vérifie que le téléversement c'est bien passé

  • Le microcontrôleur redémarre

  • Une fois arrivé à l'instruction citée ci-dessus dans son processus d'initialisation, le microcontrôleur met à jour la puce RTC avec l'heure définie à l'étape 1.

Il n'est donc pas très étonnant qu'il y ait au final un décalage de plusieurs (dizaines de) secondes entre l'heure effectivement installée dans la puce et l'heure théorique du PC.



Merci pour ton explication. Mais je me demandais si, connaissant approximativement le décalage qui survient, il ne serait pas possible dans le code de dire : Après avoir recueilli l'heure, faire (+ 10 secondes) par exemple afin d'ajuster l'heure. Le décalage étant connu.

Aussi tu as dit :
Quote

Ce décalage de quelques dizaines de secondes est normal et il n'y a pas grand chose que tu puisse y faire avec cette méthode.


Mis à part les deux méthodes que j'ai expérimenté, connaîtrais-tu une autre ?
Title: Re: Mettre mon ds1307 à l'heure
Post by: gunsman76 on Apr 02, 2014, 03:42 pm
Après il y a la méthode DCF77. L'heure est synchronisée sur l'horloge atomique.

Seulement chez moi en fonction de la couverture nuageuse et du positionnement du capteur ça ne marche pas. Mais ça marche dans de nombreux cas (je dois être l'exception...).
Title: Re: Mettre mon ds1307 à l'heure
Post by: patg_ on Apr 02, 2014, 04:14 pm

Après il y a la méthode DCF77. L'heure est synchronisée sur l'horloge atomique.

Seulement chez moi en fonction de la couverture nuageuse et du positionnement du capteur ça ne marche pas. Mais ça marche dans de nombreux cas (je dois être l'exception...).


Chez moi ça marche souvent, mais pas tout le temps.
Mon horloge s'est bien mise à l'heure suite au passage à l'heure d'été mais certains jours je la retrouve complètement déréglée. Je n'ai pas implémenté l'algo de décodage DCF77 moi-même, et pas envie de m'y pencher. J'ai une LED à l'intérieur qui clignotte au rythme des impulsions reçue, qui me permet de vérifier la réception du signal (très dépendant de la position de l'horloge, heureusement que mon mur est bien orienté...).

Pour la V2, j'opte pour un DS3234 et un codage manuel de l'algo de changement d'heures. Avec mise à jour manuelle une fois par an pour compenser la dérive d'1 à 2 minutes annuelles de ce type d'horloge RTC.  Je vais aussi utiliser l'EEProm pour mémoriser la date et permettre de changer la pile de l'horloge sans devoir passer par des boutons de réglage de la date. C'est implémenté mais pas encore testé (donc ça ne fonctionne pas encore ;) )

Si l'Arduino est relié par USB au PC il est toujours possible de définir un protocole par lequel l'Arduino demande l'heure au PC lors du démarrage du sketch ou à intervalles réguliers. Y'a un peu de boulot des deux côtés mais ça pourrait être une solution envisageable.
Title: Re: Mettre mon ds1307 à l'heure
Post by: gunsman76 on Apr 02, 2014, 04:16 pm
Je rebondis sur ton changement d'heure été/hiver, je suis super intéressé par l'avancement de ton code.

J'avais commencé à cogiter la dessus, mais par manque de temps je n'ai pas été jusqu'au bout. Bref je pense que je vais m'y remettre rapidement car c'est vraiment super utile.
Title: Re: Mettre mon ds1307 à l'heure
Post by: john_lenfr on Apr 02, 2014, 04:17 pm
Non tu n'es pas l'exception, chez moi je n'ai jamais réussi à capter quoi que ce soit étant orienté Nord en zone urbaine.
Donc j'ai de suite oublié le DCF trop "fragile".

Le NTP fonctionne très bien avec mon DS1307 :)
Title: Re: Mettre mon ds1307 à l'heure
Post by: john_lenfr on Apr 02, 2014, 04:19 pm

Je rebondis sur ton changement d'heure été/hiver, je suis super intéressé par l'avancement de ton code.

J'avais commencé à cogiter la dessus, mais par manque de temps je n'ai pas été jusqu'au bout. Bref je pense que je vais m'y remettre rapidement car c'est vraiment super utile.


Pas la peine de chercher il est déjà ici:
Equations by Wei-Hwa Huang (US), and Robert H. van Gent (EC)
Code: [Select]
int adjustDstEurope(DateTime t)
{
/*You can use the following equations to calculate when DST starts and ends.
The divisions are integer divisions, in which remainders are discarded.
"mod" means the remainder when doing integer division, e.g., 20 mod 7 = 6.
That is, 20 divided by 7 is 2 and 6/7th (where six is the remainder).
With: y = year.
        For the United States:
            Begin DST: Sunday April (2+6*y-y/4) mod 7+1
            End DST: Sunday October (31-(y*5/4+1) mod 7)
           Valid for years 1900 to 2006, though DST wasn't adopted until the 1950s-1960s. 2007 and after:
            Begin DST: Sunday March 14 - (1 + y*5/4) mod 7
            End DST: Sunday November 7 - (1 + y*5/4) mod 7;
        European Economic Community:
            Begin DST: Sunday March (31 - (5*y/4 + 4) mod 7) at 1h U.T.
            End DST: Sunday October (31 - (5*y/4 + 1) mod 7) at 1h U.T.
            Since 1996, valid through 2099
(Equations by Wei-Hwa Huang (US), and Robert H. van Gent (EC))

Adjustig Time with DST Europe/France/Paris: UTC+1h in winter, UTC+2h in summer

*/

  // last sunday of march
  int beginDSTDate=  (31 - (5* t.year() /4 + 4) % 7);
  //Serial.println(beginDSTDate);
  int beginDSTMonth=3;
  //last sunday of october
  int endDSTDate= (31 - (5 * t.year() /4 + 1) % 7);
  //Serial.println(endDSTDate);
  int endDSTMonth=10;
  // DST is valid as:
  if (((t.month() > beginDSTMonth) && (t.month() < endDSTMonth))
      || ((t.month() == beginDSTMonth) && (t.day() >= beginDSTDate))
      || ((t.month() == endDSTMonth) && (t.day() <= endDSTDate)))
  return 7200;      // DST europe = utc +2 hour (summer time)
  else return 3600; // nonDST europe = utc +1 hour (winter time)
}
Title: Re: Mettre mon ds1307 à l'heure
Post by: gunsman76 on Apr 02, 2014, 04:37 pm
Genial !!!

Merci
Title: Re: Mettre mon ds1307 à l'heure
Post by: haifger on Apr 02, 2014, 04:44 pm

Après il y a la méthode DCF77. L'heure est synchronisée sur l'horloge atomique.
Seulement chez moi en fonction de la couverture nuageuse et du positionnement du capteur ça ne marche pas. Mais ça marche dans de nombreux cas (je dois être l'exception...).



Non tu n'es pas l'exception, chez moi je n'ai jamais réussi à capter quoi que ce soit étant orienté Nord en zone urbaine.
Donc j'ai de suite oublié le DCF trop "fragile".


(hors sujet) C'est drôle, j'ai souvent lu sur ce forum des personnes se plaignant de difficultés d'utilisation du signal DCF77, mais personne ne semble avoir essayé d'utiliser le signal émis par Allouis[1] ?
Est-ce parce que la démodulation de phase est plus compliquée que la «simple» modulation d'amplitude ? Et/ou parce qu'il ne semble pas exister de modules tout prêts comme pour le DCF77 ?
J'avoue n'avoir personnellement jamais utilisé ni l'une ni l'autre méthode.

[1] http://fr.wikipedia.org/wiki/%C3%89metteur_d%27Allouis#Signaux_horaires (http://fr.wikipedia.org/wiki/%C3%89metteur_d%27Allouis#Signaux_horaires)
Title: Re: Mettre mon ds1307 à l'heure
Post by: gunsman76 on Apr 02, 2014, 04:48 pm
Je ne connaissais pas du tout.

Si quelqu'un l'utilise, un petit retour serait bien sympa.


Title: Re: Mettre mon ds1307 à l'heure
Post by: john_lenfr on Apr 02, 2014, 05:29 pm
http://forum.arduino.cc/index.php?PHPSESSID=478i4am8h72la6ki460lab7s13&topic=33585.msg245483#msg245483
Title: Re: Mettre mon ds1307 à l'heure
Post by: Uzuma on Apr 07, 2014, 04:50 pm
Bonsoir,

pardon pour mon absence. Je tenais juste à vous dire merci.
Title: Re: Mettre mon ds1307 à l'heure
Post by: patg_ on Jun 15, 2014, 12:36 pm


Je rebondis sur ton changement d'heure été/hiver, je suis super intéressé par l'avancement de ton code.

J'avais commencé à cogiter la dessus, mais par manque de temps je n'ai pas été jusqu'au bout. Bref je pense que je vais m'y remettre rapidement car c'est vraiment super utile.


Pas la peine de chercher il est déjà ici:
Equations by Wei-Hwa Huang (US), and Robert H. van Gent (EC)
Code: [Select]
int adjustDstEurope(DateTime t)
{
/*You can use the following equations to calculate when DST starts and ends.
The divisions are integer divisions, in which remainders are discarded.
"mod" means the remainder when doing integer division, e.g., 20 mod 7 = 6.
That is, 20 divided by 7 is 2 and 6/7th (where six is the remainder).
With: y = year.
        For the United States:
            Begin DST: Sunday April (2+6*y-y/4) mod 7+1
            End DST: Sunday October (31-(y*5/4+1) mod 7)
           Valid for years 1900 to 2006, though DST wasn't adopted until the 1950s-1960s. 2007 and after:
            Begin DST: Sunday March 14 - (1 + y*5/4) mod 7
            End DST: Sunday November 7 - (1 + y*5/4) mod 7;
        European Economic Community:
            Begin DST: Sunday March (31 - (5*y/4 + 4) mod 7) at 1h U.T.
            End DST: Sunday October (31 - (5*y/4 + 1) mod 7) at 1h U.T.
            Since 1996, valid through 2099
(Equations by Wei-Hwa Huang (US), and Robert H. van Gent (EC))

Adjustig Time with DST Europe/France/Paris: UTC+1h in winter, UTC+2h in summer

*/

  // last sunday of march
  int beginDSTDate=  (31 - (5* t.year() /4 + 4) % 7);
  //Serial.println(beginDSTDate);
  int beginDSTMonth=3;
  //last sunday of october
  int endDSTDate= (31 - (5 * t.year() /4 + 1) % 7);
  //Serial.println(endDSTDate);
  int endDSTMonth=10;
  // DST is valid as:
  if (((t.month() > beginDSTMonth) && (t.month() < endDSTMonth))
      || ((t.month() == beginDSTMonth) && (t.day() >= beginDSTDate))
      || ((t.month() == endDSTMonth) && (t.day() <= endDSTDate)))
  return 7200;      // DST europe = utc +2 hour (summer time)
  else return 3600; // nonDST europe = utc +1 hour (winter time)
}



Cette fonction est bugguée: elle ne tient pas compte de l'heure de changement d'heure (l'heure est changée le lendemain).
Voici une implémentation corrigée que je viens juste d'implémenter dans mon horloge chinoise V2. Elle tient compte de l'heure:
Code: [Select]

int adjustDstEurope(DateTime t)
{
/*You can use the following equations to calculate when DST starts and ends.
The divisions are integer divisions, in which remainders are discarded.
"mod" means the remainder when doing integer division, e.g., 20 mod 7 = 6.
That is, 20 divided by 7 is 2 and 6/7th (where six is the remainder).
With: y = year.
        For the United States:
            Begin DST: Sunday April (2+6*y-y/4) mod 7+1
            End DST: Sunday October (31-(y*5/4+1) mod 7)
           Valid for years 1900 to 2006, though DST wasn't adopted until the 1950s-1960s. 2007 and after:
            Begin DST: Sunday March 14 - (1 + y*5/4) mod 7
            End DST: Sunday November 7 - (1 + y*5/4) mod 7;
        European Economic Community:
            Begin DST: Sunday March (31 - (5*y/4 + 4) mod 7) at 1h U.T.
            End DST: Sunday October (31 - (5*y/4 + 1) mod 7) at 1h U.T.
            Since 1996, valid through 2099
(Equations by Wei-Hwa Huang (US), and Robert H. van Gent (EC))

Adjustig Time with DST Europe/France/Paris: UTC+1h in winter, UTC+2h in summer

*/

  // last sunday of march
  int beginDSTDate=  (31 - (5* t.year() /4 + 4) % 7);
  //Serial.println(beginDSTDate);
  int beginDSTMonth=3;
  //last sunday of october
  int endDSTDate= (31 - (5 * t.year() /4 + 1) % 7);
  //Serial.println(endDSTDate);
  int endDSTMonth=10;
  // DST is valid as:
  if (((t.month() > beginDSTMonth) && (t.month() < endDSTMonth))
      || ((t.month() == beginDSTMonth) && (t.day() > beginDSTDate))
  || ((t.month() == beginDSTMonth) && (t.day() == beginDSTDate) && (t.hour() >= 1))
      || ((t.month() == endDSTMonth) && (t.day() < endDSTDate))
  || ((t.month() == endDSTMonth) && (t.day() == endDSTDate) && (t.hour() < 1)))
  return 7200;      // DST europe = utc +2 hour (summer time)
  else return 3600; // nonDST europe = utc +1 hour (winter time)
}

Title: Re: [Résolu] Mettre mon ds1307 à l'heure
Post by: john_lenfr on Jun 15, 2014, 01:00 pm
Je ne m'en suis pas rendu compte quand l'heure a changé.
Et comme je fais une synchro NTP que tout les jour c'est passé inaperçu pour mon application mais merci pour cette correction, je mets de coté ;)