[Résolu] horloge RTCds1307 et port serie.

Bonjour à tous,
je débute avec une carte arduino duemilanove et une horloge RTC avec un DS1307. J'ai réalisé une carte et j'ai utilisé tout ce qu'il faut avec le quartz, les résistances de pull-up sur la carte de 10K, le condo de lissage, etc. J'ai testé la carte et tout semble fonctionner correctement.
J'ai essayé un code pour voir, pompé sur le site http://www.ladyada.net/.
J'ai téléchargé la librairie et le code pour mettre à l'heure la ds1307. j'ai mis le code RTC_DS dans le répertoire de la librairie. J'ai bien réussi à la mettre à l'heure et à la bonne date et j'ai eu l'heure et la date sur l'interface arduino du port com sur mon PC.
Lors d'un nouvel allumage de la carte un peu plus tard, plus rien ou alors des données incohérentes sur l'écran.
De plus, je n'arrive pas à l'utiliser pour lire l'heure de façon simple, par exemple en tapant une commande à partir de mon PC et en l'envoyant sur le port série. J'ai essayé d'autres bouts de code trouvés un peu partout sur internet, mais rien n'y fait.

J'avoue ne pas très bien comprendre d'une part l'anglais (et la traduction google n'aide pas vraiment!) et le coup des bibliothèques qu'il faut rajouter.
J'ai à peu près compris le système "open source", mais j'ai quand même un peu de mal à tout comprendre, même avec les différents tutoriaux que j'ai pu lire à droite ou à gauche sur la toile.
Quelqu'un, sur ce forum, aurait-il un bout de code ou une explication pour m'aider à lire l'heure sur le port com de mon PC à partir d'une commande écrite et envoyée à partir de l'interface arduino ou d'hyperterminal.
Merci par avance et à très bientôt. 8)

Bonjour Picho,

Le DS1307 communique via I2C, si tu souhaites de l'aide il faudrait nous joindre le code incriminé.
les programmes traitant l'exploitation des DS1307 sont légion sur la toile. Pour ton cas particulier, il faut voir en fonction de ce que a fait.
Icare

tien voila un exemple que j'ai utilisé et qui fonctionne, je ne sais pas si il va sur ton RTC mais je pense que oui ! moi aussi j'ai eu des problème de mauvaise lecture soudaine avec des valeurs erroné, c'était du à un faut contact.
tien:

#include <SPI.h>
const int  cs=8; //chip select

void setup() {
Serial.begin(9600);
RTC_init();
//day(1-31), month(1-12), year(0-99), hour(0-23), minute(0-59), second(0-59)
SetTimeDate(16,4,12,15,40,16);
}
 
void loop() {
  Serial.println(ReadTimeDate());
  delay(1000);
}
//=====================================
int RTC_init(){
      pinMode(cs,OUTPUT); // chip select
      // start the SPI library:
      SPI.begin();
      SPI.setBitOrder(MSBFIRST);
      SPI.setDataMode(SPI_MODE3); // both mode 1 & 3 should work
      //set control register
      digitalWrite(cs, LOW); 
      SPI.transfer(0x8E);
      SPI.transfer(0x60); //60= disable Osciallator and Battery SQ wave @1hz, temp compensation, Alarms disabled
      digitalWrite(cs, HIGH);
      delay(10);
}
//=====================================
int SetTimeDate(int d, int mo, int y, int h, int mi, int s){
    int TimeDate [7]={s,mi,h,0,d,mo,y};
    for(int i=0; i<=6;i++){
        if(i==3)
            i++;
        int b= TimeDate[i]/10;
        int a= TimeDate[i]-b*10;
        if(i==2){
            if (b==2)
                b=B00000010;
            else if (b==1)
                b=B00000001;
        }  
        TimeDate[i]= a+(b<<4);
        digitalWrite(cs, LOW);
        SPI.transfer(i+0x80);
        SPI.transfer(TimeDate[i]);       
        digitalWrite(cs, HIGH);
  }
}
//=====================================

String ReadTimeDate(){
    String temp;

    int TimeDate [7]; //second,minute,hour,null,day,month,year     
    for(int i=0; i<=6;i++){
        if(i==3)
            i++;
        digitalWrite(cs, LOW);
        SPI.transfer(i+0x00);
        unsigned int n = SPI.transfer(0x00);       
        digitalWrite(cs, HIGH);
        int a=n & B00001111;   
        if(i==2){  
            int b=(n & B00110000)>>4; //24 hour mode
            if(b==B00000010)
                b=20;       
            else if(b==B00000001)
                b=10;
            TimeDate[i]=a+b;
        }
        else if(i==4){
            int b=(n & B00110000)>>4;
            TimeDate[i]=a+b*10;
        }
        else if(i==5){
            int b=(n & B00010000)>>4;
            TimeDate[i]=a+b*10;
        }
        else if(i==6){
            int b=(n & B11110000)>>4;
            TimeDate[i]=a+b*10;
        }
        else{  
            int b=(n & B01110000)>>4;
            TimeDate[i]=a+b*10;
            }
    }
    temp.concat(TimeDate[4]);
    temp.concat("/") ;
    temp.concat(TimeDate[5]);
    temp.concat("/") ;
    temp.concat(TimeDate[6]);
    temp.concat("     ") ;
    temp.concat(TimeDate[2]);
    temp.concat(":") ;
    temp.concat(TimeDate[1]);
    temp.concat(":") ;
    temp.concat(TimeDate[0]);
  return(temp);
}

Je crois que tu n'a pas besoin d'une lib particulière, GL !

Skizo !

Salut,

Skizoh, ton code ne va pas fonctionner car il semble prévu pour une RTC SPI. Alors que le montage de Picho utilise un DS1307 en I2C :cold_sweat: La bibliothèque RTClib d'Adafruit est parfaitement fonctionnelle et utilisée par beaucoup de monde. Autant déboguer avec une bibliothèque validée...

Concernant la perte de l'heure, as-tu bien mis une pile de sauvegarde ? Si oui, je plussoie Icare, on va avoir besoin de voir ton code...

++

autant pour moi pas fait gaff :slight_smile:

Comme tu débutes, je suppose que si tu un code tel quel, tu n'as pas fait attention que le setup() il y a la mise à l'heure de l'horloge, qui se fait donc ... à chaque redémarrage.

Bonjour,

Je ne sait pas si cela te sera d'une grande aide mais je peut te proposer ce lien :

Qui se base sur la librairie RTClib de ladyada.

Ou encore ce lien :

Qui n'utilise aucune librairie (tout est géré en bas niveau) mais que j'ai documenté au maximum.

Bonjour et merci à vous tous.
Je précise qu'effectivement j'utilise un protocole i2c pour communiquer avec ma carte RTC avec la sortie SDA branchée sur l'entrée analog4 et la sortie SCL sur l'entrée nommée analog5 de ma Duemilanove. le plus de ma RTC sur le +5V et les grnd sont raccordés.

J'avais pris exactement le même code que celui fournit sur le site internet (celui que vient de me donner skywodd a savoir [Test] Module RTC DS1307 | Skyduino - Le DIY à la française). J'ai ensuite mis la librairie RTClib dans c:~~~\arduino\librairy.

j'obtiens sur le port com8 :
45/25/165 18:85:85
45/25/165 18:85:85
45/25/165 18:85:85
45/25/165 18:85:85
45/25/165 18:85:85
45/25/165 18:85:85
45/25/165 18:85:85
0/0/0 0:0:0
0/0/0 0:0:0
0/0/0 0:0:0
0/0/0 0:0:0
0/0/0 0:0:0
0/0/0 0:0:0
0/0/0 0:0:0
et 0/0/0 0:0:0 tout le temps après.

J'ai testé le code une deuxième fois et, à la compilation j'ai encore le message suivant:

Dans la barre orange : no matching functionfor call to'DS1307::get(uint8_t*,4fois et à la fin ,uint16_t*)'
En dessous:
sketch_jun25a.cpp: In function 'void loop()':
sketch_jun25a:17: error: no matching function for call to 'DS1307::get(uint8_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*, uint16_t*)'
C:\Users\Famille\Desktop\arduino-1.0.1-windows\arduino-1.0.1\libraries\DS1307/DS1307.h:77: note: candidates are: void DS1307::get(int*, boolean)
C:\Users\Famille\Desktop\arduino-1.0.1-windows\arduino-1.0.1\libraries\DS1307/DS1307.h:78: note: int DS1307::get(int, boolean)

Il est vrai que dans le dossier RTC_lib du site ladyada ( GitHub - adafruit/RTClib: A fork of Jeelab's fantastic RTC Arduino library ) il y a un dossier "example" qui contient un autre dossier nommé "DS1307". Est-ce celui ci qui est la librairie dont j'ai besoin?

Sinon j'ai testé un autre code (enfin plusieurs) sans utiliser de librairie ds1307 et il(s) ne fonctionne(ent) pas. Je pense qu'il va falloir que je revois tout cela depuis le début.
Merci de bien continuer à m'aider dans mes recherches.
Bonne journée et à bientôt. :slight_smile:

picho:
J'avais pris exactement le même code que celui fournit sur le site internet (celui que vient de me donner skywodd a savoir [Test] Module RTC DS1307 | Skyduino - Le DIY à la française). J'ai ensuite mis la librairie RTClib dans c:~~~\arduino\librairy.
(...)
Il est vrai que dans le dossier RTC_lib du site ladyada ( GitHub - adafruit/RTClib: A fork of Jeelab's fantastic RTC Arduino library ) il y a un dossier "example" qui contient un autre dossier nommé "DS1307". Est-ce celui ci qui est la librairie dont j'ai besoin?

Oui mais je viens juste de me rendre compte que la librairie a été lourdement modifié depuis le moment ou j'ai fait mon article.
J'ai modifier le code pour qu'il compile avec le derniére version de la libRTC de ladyada.

picho:
Sinon j'ai testé un autre code (enfin plusieurs) sans utiliser de librairie ds1307 et il(s) ne fonctionne(ent) pas. Je pense qu'il va falloir que je revois tout cela depuis le début.

Tu est sur de ton montage (résistances de pull-up, etc ...) ?
C'est trés étrange que tout les codes pour DS1307 ne marchent pas.

skywodd:

picho:
Tu est sur de ton montage (résistances de pull-up, etc ...) ?
C'est trés étrange que tout les codes pour DS1307 ne marchent pas.

Attention aussi à avoir toujours une "bonne alim sauvegarde 3V"
en cas de défaut sur elle, ça renvoi ce que "ça veux"

testé à l'instant en 022, pas de soucis
ça coince en 1.0x

//
// Maurice Ribble
// 4-17-2008
// http://www.glacialwanderer.com/hobbyrobotics

// This code tests the DS1307 Real Time clock on the Arduino board.
// The ds1307 works in binary coded decimal or BCD.  You can look up
// bcd in google if you aren't familior with it.  There can output
// a square wave, but I don't expose that in this code.  See the
// ds1307 for it's full capabilities.

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

void setup()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  Serial.begin(9600);

  // Change these values to what you want to set your clock to.
  // You probably only want to set your clock once and then remove
  // the setDateDs1307 call.
  second = 15;
  minute = 34;
  hour = 18;
  dayOfWeek = 1;
  dayOfMonth = 7;
  month = 12;
  year = 11;
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}

void loop()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  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);

  delay(1000);
}

re ... bonjour,
Bon voilà, je suis vraiment confus!!!! :blush: :blush:
Effectivement, j'avais bien un problème sur ma carte : une soudure mal faite...... désolé! en fait la panne était intermittente et j'ai eu du mal à trouver d'où venait le problème.
Mais il est vrai que j'ai quand même du mal avec ces histoires de librairies - Je commence déjà tout juste à comprendre un peu le langage C....
Avant, j'étais plutôt sur Picaxe avec le Basic, plus simple, mais moins puissant.

Enfin en tout cas, j'ai ressayé le code donnée par skynodd avec la librairie RTC_lib du site ladyada.
Et ça marche !!!!!! Encore merci.
Vraiment désolé pour tous ces tracas et merci beaucoup pour m'avoir consacré du temps sur mon problème.
J'espère pouvoir dépanner quelqu'un sur ce forum à un autre moment, lorsque je serai un peu plus calé en C-arduino et .... en matière de soudure!

picho:
Effectivement, j'avais bien un problème sur ma carte : une soudure mal faite...... désolé! en fait la panne était intermittente et j'ai eu du mal à trouver d'où venait le problème.

Problème résolu donc ?
Si oui edit ton 1er post et ajoute [Résolu] devant le titre :wink:

picho:
Mais il est vrai que j'ai quand même du mal avec ces histoires de librairies - Je commence déjà tout juste à comprendre un peu le langage C....
Avant, j'étais plutôt sur Picaxe avec le Basic, plus simple, mais moins puissant.

Les Picaxe c'est un autre monde, le C/C++ une fois maitrisé a une puissance bien supérieur.
D'ici quelque temps tu verras les librairies ne seront plus un probléme :wink:
C'est parfois plus simple de faire son propre code que d'utiliser une librairie (le DS1307 est un exemple typique).