Go Down

Topic: [Tuto] ds1307 Arduino Processing mise à l'heure NTP (Read 11636 times) previous topic - next topic

Jean-François

Comme indiqué précédemment dans un autre topic, voici un petit tuto pour mettre votre ds1307 à l'heure NTP (network time protocol).
Il subsiste une petite latence de quelques dixièmes de secondes, mais pour du NTP c'est correct  XD.

J'ai utilisé ce schéma pour monter ma puce RTC sur une plaque de prototypage (pas de pcb laser pour cette fois XD).



Ce qui a donné cela :



Un quartz de 32.768kHz doit être monté sur les broches 1 et 2, pas besoins de condensateur (dixit le constructeur).

La pile est de 3V.

Le code Arduino n'utilise pas de librairie ds1307, je trouvais plus intéressant de d'utiliser une partie de ce code ( source).
J'ai ajouté la partie qui demande à Processing d'envoyer une chaine indiquant l'heure de l'ordinateur hôte.
Le code est commenté pour Arduino et Processing.

Une petite vidéo qui explique la procédure :

http://www.youtube.com/watch?v=g4dnDkGnESs


Le code coté Arduino :

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.send(0);
Wire.send(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.send(0);
 Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
 Wire.send(decToBcd(minute));
 Wire.send(decToBcd(hour));      // If you want 12 hour am/pm you need to set
 // bit 6 (also need to change readDateDs1307)
 Wire.send(decToBcd(dayOfWeek));
 Wire.send(decToBcd(dayOfMonth));
 Wire.send(decToBcd(month));
 Wire.send(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.send(0);
 Wire.endTransmission();

 Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

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


#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

}


MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Jean-François

#1
Nov 04, 2011, 04:27 pm Last Edit: Mar 26, 2014, 06:04 pm by Jean-François Reason: 1
Pour installer Processing :

http://www.processing.org

Et le code coté Processing :

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

import processing.serial.*;

Serial myPort; // nom du port série

int oldsecond=second();

void setup() {

 println(Serial.list());// envoi dans le terminal les ports série disponibles

 myPort = new Serial(this, Serial.list()[0], 115200); // ouvre une liaison série sur le port '0'
}
int i=0;
void draw() {
 background(204); // défini la couleur de la fenetre de l'application

 while (myPort.available() > 0) {    
   char inByte = myPort.readChar();  // lit le port série de l'Arduino
   if (inByte == 65) { // si le caractère en entrée = A
     oldsecond=second();
     while(second()==oldsecond) {
     } //laisse continuer la boucle au changement de seconde

     // formate la chaine en mettant un '0' devant les unités
     String joinedTime =nf(second(),2)+nf(minute(),2)+nf(hour(),2)+nf(day(),2)+nf(month(),2)+str(year());
     println (joinedTime); // envoi la chaine dans le terminal
     myPort.write (joinedTime+"\r"); // envoi la chaine suivie d'un retour chariot sur le port série
   }
   break;  // sort de la boucle while
 }
}


Et voualààà.... enjoy  XD

Pour les commentaires.... pas de soucis, mais pas sur la tête, les coups  :smiley-mr-green:
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

arduimat

J'adore la vidéo :) Merci pour ce tuto.

Question : Combien de temps peut tenir le module RTC avec la pile 3V plate ?

Jean-François

#3
Nov 04, 2011, 04:49 pm Last Edit: Nov 05, 2011, 08:26 am by Jean-François Reason: 1
D'après ce que j'ai lu ça pourrait tenir 10 ans  XD, mais la pile n'est sollicitée que si l'alimentation principale est coupée.
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

skywodd

Sympa ce petit tuto et aussi le support pour la pile très "DIY" :smiley-mr-green:

Justement je suis en train de faire un tuto sur l'I2C et le SPI avec une carte arduino ... coïncidence ? je ne crois pas. (/musique de X-files)


PS: Non mais elle est ou la boite de roquefort ! ... ralala il y a même plus d'emballage :smiley-mr-green:
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Jean-François

Bon... à la demande de skywodd, voilà une horloge pour pas rater l'heure du petit déj  XD :

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

skywodd

JF-Clock, l'horloge avec 40% de matière grasse 8)

J'adore ! Faut que je trouve une boite pour mettre mon arduino dedans :P
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Jean-François

C'est tout ce que j'avais sous la main ce matin  :smiley-mr-green:
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Artouste


Comme indiqué précédemment dans un autre topic, voici un petit tuto pour mettre votre ds1307 à l'heure NTP (network time protocol).
Il subsiste une petite latence de quelques dixièmes de secondes, mais pour du NTP c'est correct  XD.

J'ai utilisé ce schéma pour monter ma puce RTC sur une plaque de prototypage (pas de pcb laser pour cette fois XD).





bonjour
sympa, j'ai retrouvé un DS1307 (caché au milieu de DS1337 DS1337C) dans mes "boites à grouilles"  :smiley-mr-green:
et vu la météo, je vais faire chauffer le fer .

perso, j'aime bien le DS1904 en RTC "sauvegardée" , j'aime bien le onewire   :)   pour de la gestion "calme" des evenements.

Jean-François

Un petit soucis... mais je pense que cela vient du choix du quartz.
En trois jours mon horloge accuse un retard de 2-3 secondes.
Je vais faire des essais avec un ds32kHs afin de voir si c'est plus précis  :D
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Artouste

#10
Nov 07, 2011, 08:01 pm Last Edit: Nov 07, 2011, 08:12 pm by Artouste Reason: 1

Un petit soucis... mais je pense que cela vient du choix du quartz.
En trois jours mon horloge accuse un retard de 2-3 secondes.
Je vais faire des essais avec un ds32kHs afin de voir si c'est plus précis  :D

oui c'est le probleme avec les quartz horloger "tout venant ou de recup"
et comme les capas sont integrées dans le ds on ne peut pas "jouer" à voir si une petite capa variable en //
ne pourrait pas quand même être utilisée pour réglage fin (en configurant et en utilisant la sortie SQW vers un fréquencemètre pour calibration.

le mien testé hier.  :smiley-mr-green:




Jean-François

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

skywodd


le mien testé hier.  :smiley-mr-green:



Elle est où la boite de margarine ?  XD


La boite ! La boite ! On veut la boite !

--
SkyWodd, membre du parti pour les emballages réutilisable.

:smiley-mr-green:
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Artouste


Elle est où la boite de margarine ?  XD

OOups  :smiley-mr-green:
désolé de l'oubli !
Et comme je n'ai pas là sous la main de pot de crème double de Gruyère, je vais tenter semaine prochaine et à la
louche d'intégrer ça comme ça pour que cela soit evidemment plus présentable,  parce que cela le "Vaud" bien.   :)



artouste --->[]  déjà loin !  :smiley-red:


Jean-François

A la vache... parce que je le veau bien  XD

Va être bien dans un calandos, l'horloge  :smiley-mr-green:
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Go Up