Nouvelles:

Le Forum est maintenant chiffré (préambule https). Bien sûr, des liens externes insérés dans les sujets vont demeurer inchangés. Mais la composition des pages du Forum est désormais sécurisée. Si des problèmes d'affichage surviennent, veillez à vider votre cache pour ce site.

Menu principal

[Resolve] Derive sur RTC Cravity SD2405

Démarré par TK_Ryuzaki, Octobre 26, 2019, 04:04:07 PM

« précédent - suivant »

TK_Ryuzaki

Bonjour, j'utilise un module RTC gravity SD2405 pour un projet d' horloge avec arduino nano, mon soucis est qu' après plusieurs heure sans alimentation du module se dernier commence à  dérivé de quelques minutes pour plusieurs heure je ne comprend pas vraiment pourquoi .

j'utilise le code arduino suivant(fournit avec la doc SD2405):
#include "GravityRtc.h"
#include "Wire.h"
GravityRtc rtc;     //RTC Initialization

void setup() {
  Serial.begin(9600);

  rtc.setup();

//Set the RTC time automatically: Calibrate RTC time by your computer time
  //rtc.adjustRtc(F(__DATE__), F(__TIME__));

  //Set the RTC time manually
  //rtc.adjustRt(2017,6,19,1,12,7,0);  //Set time: 2017/6/19, Monday, 12:07:00
}

void loop() {
  rtc.read();
  //*************************Time********************************
  Serial.print("   Year = ");//year
  Serial.print(rtc.year);
  Serial.print("   Month = ");//month
  Serial.print(rtc.month);
  Serial.print("   Day = ");//day
  Serial.print(rtc.day);
  Serial.print("   Week = ");//week
  Serial.print(rtc.week);
  Serial.print("   Hour = ");//hour
  Serial.print(rtc.hour);
  Serial.print("   Minute = ");//minute
  Serial.print(rtc.minute);
  Serial.print("   Second = ");//second
  Serial.println(rtc.second);


Auriez vous une idée du problème ou une solution sachant que le module seras amené à  ne pas être alimenté plusieurs jours merci .

Électro-Bidouilleur

À part la source d'alimentation qui est différente, je ne vois pas qu'est-ce qui pourrait causer ce changement dans l'exactitude de l'horloge. Votre module est peut-être défectueux. On garantit une déviation de moins de 2.5 minutes par année...

TK_Ryuzaki

#2
tout d' abord merci pour votre intérêt sur mon post ;)

pour la défectuosité du produit je ne pense pas au départ j' avais un DS1307 mais même problème j'ai pensé au quartz et au variation de température c' est pourquoi j'utilise le SD2405

Si je comprend bien:
si la tension d' alimentation est instable ou variable cela pose problème ? car actuellement l’Arduino nano qui contrôle tout ça est sur du 12V après contact d' une voiture donc grosse variation de tension et de température en vue :(

Si c'est le cas voici une version corrigé avec régulateur quand pensez vous ?



kamill

Bonjour,

Tu devrais plutôt t'orienter vers un DS3231 qui a une compensation de température intégrée.

TK_Ryuzaki

#4
Bonjour je croyais que le module d' adafruit avais un compensation après vérification il s’avère que non,
je vais donc faire l' acquisition d'un DS3231 Amazon link (livraison le 31)et vous tiens informé des évolution merci pour votre aide ;)

j'ai aussi modifier le pcb en ajoutant 2 diode type 1N4007 ce qui ne devrais pas faire de mal.

papyblue

Bonjour,
Avez-vous essayé d'utiliser le registre TTF du SD2405 pour ajuster la fréquence ?

PB

TK_Ryuzaki

Bonjour, j' ai biens trouver le registre TTF dans la doc à  l' adresse 12H, mais j' ignore comment ajusté la fréquence cela se passe dans "GravityRtc.cpp" avec les commandes wire.write() ?

papyblue

Bonjour,

L'auteur de la bibliothèque n'a pas implémenté la fonction, il faut donc écrire directement les commandes sur le bus I2C.
1) il faut d'abord calculer la valeur de correction a introduire en suivant les explications détaillées données dans le §5.4 de la datasheet.
2) L'écriture du registre se fait en suivant le protocole défini dans le §6.
PB

TK_Ryuzaki

Merci à  tous pour votre aide, le projet est terminer j' ai utiliser un module DS3231.

Mon problème de dérive venais de l’ancien module défectueux (suite à  une erreur de manip ?).

je poste mon code si jamais quelqu'un voudrais s'en inspiré ou encore me proposé mieux :p
toutes les fichiers (pcb, schema etc..) son disponible sur mon https://server1.radislabs.com/article.php?Page=RL000005

#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#define ADRESSE_I2C_RTC 0x68

//************Button*****************//
int P1=3; // Button SET MENU'
int P2=4; // Button +
int P3=5; // Button -
int P4=6; // not use

//************Variables**************//
int Copyscreen = 0; // Si ecran de demarage afficher
int pinRetro; // not use
byte seconde, minutes, heure, numJourSemaine, numJourMois, mois, annee;
//numJourSemaine = 0-6 => voir tableau jourDeLaSemaine     numJourMois = 12/20/...
String jourDeLaSemaine[7] = {"Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"};
String NomMois[13] = {"","JANV","FEVR","MARS","AVRI","MAIS","JUIN","JUIE","AOUT","SEPT","OCTO","NOVE","DECE"};
int menu =0; //ini le menu à  0
LiquidCrystal_I2C lcd(0x27, 20, 4);
//LiquidCrystal_I2C lcd(0x3F,20,4);


void setup () {
  lcd.init(); // initialisation de l'afficheur
  lcd.backlight(); // active le retro eclairage lcd
  lcd.clear(); // nettoie l' afficheur

  pinMode(P1,INPUT);
  pinMode(P2,INPUT);
  pinMode(P3,INPUT);
  pinMode(P4,INPUT);

  Serial.begin(9600);
  Wire.begin();
  int menu=0;
}

// Convertir les nombres décimaux normaux en décimaux codés binaires
byte decToBcd(byte val){return( (val/10*16) + (val%10));}
// Convertir les nombres décimaux codés binaires en décimaux normaux
byte bcdToDec(byte val){return( (val/16*10) + (val%16));}

void loop () {
// SERIALprint();
  COPY(); //Screen start
 
  // Si P1 press on active le setmenu
  if(digitalRead(P1))
  {
   menu=menu+1;
  }
// Si Menu = 0 on affiche l heure
  if (menu==0)
    {
     
    SETvar(); //Obtiens heure RTC
     LCDprint(); // Affiche heure sur lcd

    }
  if (menu==1)
    {
    DisplaySetHour(); // Set heure
    }
  if (menu==2)
    {
    DisplaySetminutes(); // Set minutes
    }
  if (menu==3)
    {
    DisplaySetYear(); // Set annee
    }
  if (menu==4)
    {
    DisplaySetMonth(); // Set mois
    }
  if (menu==5)
    {
    DisplaySetDay(); // Set jour dans le mois
    }
  if (menu ==6)
  {
    DisplaySetDayName(); // Set jour de la semaine
  }
  if (menu==7)
    {
    StoreAgg(); // Stock les valeurs dans le RTC
    menu=0;
    }
}


void StoreAgg()
{
// Variable saving
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Sauvegarde");
  lcd.setCursor(0,1);
  lcd.print("En cour ...");
  seconde = 0 ;
// Change l'heure et la date de l'horloge en temps réel
Wire.beginTransmission(ADRESSE_I2C_RTC);
Wire.write(0); // Positionner le pointeur de registre sur 00h
Wire.write(decToBcd(seconde));
Wire.write(decToBcd(minutes));
Wire.write(decToBcd(heure));
Wire.write(decToBcd(numJourSemaine));
Wire.write(decToBcd(numJourMois));
Wire.write(decToBcd(mois));
Wire.write(decToBcd(annee));
Wire.endTransmission();
  lcd.clear();
  menu =0;
  delay(200);
}
void DisplaySetminutes()
{
// Setting the minutess
  lcd.clear();
  if(digitalRead(P2)==HIGH)
  {
    if (minutes==59)
    {
      minutes=0;
    }
    else
    {
      minutes=minutes+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (minutes==0)
    {
      minutes=59;
    }
    else
    {
      minutes=minutes-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set minutes:");
  lcd.setCursor(0,1);
  lcd.print(minutes,DEC);
  delay(200);
}
 
void DisplaySetYear()
{
    lcd.clear();
// setting the year
  if(digitalRead(P2)==HIGH)
  {   
    annee=annee+1;
  }
   if(digitalRead(P3)==HIGH)
  {
    annee=annee-1;
  }
  lcd.setCursor(0,0);
  lcd.print("Set Annee:");
  lcd.setCursor(0,1);
  lcd.print(annee,DEC);
  delay(200);
}

void DisplaySetMonth()
{
    lcd.clear();
// Setting the month
  if(digitalRead(P2)==HIGH)
  {
    if (mois==12)
    {
      mois=1;
    }
    else
    {
      mois=mois+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (mois==1)
    {
      mois=12;
    }
    else
    {
      mois=mois-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set mois:");
  lcd.setCursor(0,1);
  lcd.print(NomMois[mois]);
  delay(200);
}

void DisplaySetDay()
{
    lcd.clear();
// Setting the day
  if(digitalRead(P2)==HIGH)
  {
    if (numJourMois ==31)
    {
      numJourMois =1;
    }
    else
    {
      numJourMois =numJourMois +1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (numJourMois ==1)
    {
      numJourMois =31;
    }
    else
    {
      numJourMois =numJourMois -1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Jour du mois :");
  lcd.setCursor(0,1);
  lcd.print(numJourMois ,DEC);
  delay(200);
}
void DisplaySetDayName()
{
    lcd.clear();
// Setting the DayName
  if(digitalRead(P2)==HIGH)
  {
    if (numJourSemaine==6)
    {
      numJourSemaine=0;
    }
    else
    {
      numJourSemaine=numJourSemaine+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (numJourSemaine==0)
    {
      numJourSemaine=0;
    }
    else
    {
      numJourSemaine=numJourSemaine-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Nom du jour :");
  lcd.setCursor(0,1);
  lcd.print(jourDeLaSemaine[numJourSemaine]);
  delay(200);
}
void DisplaySetHour()
{
    lcd.clear();
// time setting

  if(digitalRead(P2)==HIGH)
  {
    if(heure==23)
    {
      heure=0;
    }
    else
    {
      heure=heure+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if(heure==0)
    {
      heure=23;
    }
    else
    {
      heure=heure-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Heure:");
  lcd.setCursor(0,1);
  lcd.print(heure,DEC);
  delay(200);
}
void COPY(){
  if (Copyscreen == 0) {
   lcd.setCursor(0,0);
  lcd.print("Anthony.A");
  lcd.setCursor(0,1);
  lcd.print("RADISlabs.com");
  delay(1200);
  lcd.clear();
  Copyscreen = 1;
  }
}
void SETvar(){
// Réception de l'heure et de la date
Wire.beginTransmission(ADRESSE_I2C_RTC);
Wire.write(0); // Positionner le pointeur de registre sur 00h
Wire.endTransmission();
Wire.requestFrom(ADRESSE_I2C_RTC, 7);
// Accède aux données de l'horloge (à  partir du registre 00h)
seconde = bcdToDec(Wire.read() & 0x7f);
minutes = bcdToDec(Wire.read());
heure = bcdToDec(Wire.read() & 0x3f);
numJourSemaine = bcdToDec(Wire.read());
numJourMois = bcdToDec(Wire.read());
mois = bcdToDec(Wire.read());
annee = bcdToDec(Wire.read());
delay(200);
}
void SERIALprint(){
// Affichage de l'heure (moniteur série)
if (heure<10){Serial.print("0");}
Serial.print(heure, DEC);
Serial.print(":");
if (minutes<10){Serial.print("0");}
Serial.print(minutes, DEC);
Serial.print(":");
if (seconde<10){Serial.print("0");}
Serial.println(seconde, DEC);
// Affichage de la date (moniteur série)
Serial.print(jourDeLaSemaine[numJourSemaine]);
Serial.print(" ");
if (numJourMois<10){Serial.print("0");}
Serial.print(numJourMois, DEC);
Serial.print("/");
if (mois<10){Serial.print("0");}
Serial.print(mois, DEC);
Serial.print("/");
Serial.println(annee, DEC);
}
void LCDprint(){
  //envois date sur lcd
  lcd.setCursor(0, 0);
lcd.print(jourDeLaSemaine[numJourSemaine]);
  lcd.setCursor(3, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(numJourMois, DEC);
  lcd.setCursor(6, 0);
  lcd.write(165);
  lcd.setCursor(7, 0);
  lcd.print(NomMois[mois]);
  lcd.setCursor(11, 0);
  lcd.write(165);
  lcd.setCursor(12, 0); // 2000 years
  lcd.print("20"); // 2000 years
  lcd.setCursor(14, 0);
  lcd.print(annee, DEC);
  //envois heure sur ecran i2c
  lcd.setCursor(0, 1);
  if (heure < 10)
  {
    lcd.setCursor(0, 1);
    lcd.print("0");
    lcd.setCursor(1, 1);
    lcd.print(heure, DEC);
  }
  else {
    lcd.setCursor(0, 1);
    lcd.print(heure, DEC);
  }
  lcd.setCursor(2, 1);
  lcd.print(':');
  if (minutes < 10)
  {
    lcd.setCursor(3, 1);
    lcd.print("0");
    lcd.setCursor(4, 1);
    lcd.print(minutes, DEC);   
  }
  else {
    lcd.setCursor(3, 1);
    lcd.print(minutes, DEC);
  }
  lcd.setCursor(5, 1);
  lcd.print(':');
  if (seconde < 10)
  {
    lcd.setCursor(6, 1);
    lcd.print("0");
    lcd.setCursor(7, 1);
    lcd.print(seconde, DEC);
  }
  else
  {
  lcd.setCursor(6, 1);
  lcd.print(seconde, DEC);
  } 
  delay(200);
}