DS1307 RTC

Bonjour,

Voila il y a quelque temps j'ai installé un système de porte automatique sur mon poulailler.
Au début après quelque erreur tout fonctionnais bien.

Détail du système :

Un panneau solaire avec régulateur et batterie.
Arduino Uno, RTC DS1307 et moteur PAP.

Après quelque temps j'ai vu que la batterie ne tenais pas asse longtemps quand il n'y avais pas asse de soleil pendant 3-4 j.
Alors j'ai cherché une autre solution et j'ai équipé tout le système d'un programmateur 12V, qui du coup alimente la carte Arduino 2x5 min tous les jours afin d'ouvrir et fermé la porte.

Tout fonctionne bien et la batterie tiens asse longtemps maintenant.
Sauf qu'un jour je me suis aperçu que la porte n'avais pas été fermé et qu'en la fermant manuellement elle ne s'ouvrai plus le matin.
En regardant l'heure de la RTC, elle indiqué 165h00m du coup je l'ai reprogrammé et 2j après c'était pareil
La RTC est-elle HS ou le fait d'allumé 10 min par jour la carte sa la perturbe ?

Si je met une autre RTC (DS1307 ou DS3231) sa va faire pareil dans quelque temps ? quoi faire ?

Merci

hello
et la pile de sauvegarde de la 1307, elle dit quoi ?

Bonjour

Elle dit qu'elle ai a 3,11V donc correct

bonjour,

la pile ne peut pas être en cause, sinon la RTC se réveillerait toujours à zéro (à la remise sous tension).

DS1307 / registre 02 (heures) : bit 7 toujours lu à zéro, quelle que soit la valeur qu'on y écrit (voir doc Dallas/Maxim) donc lecture "165" impossible
==> vérifier l'intégrité de la conversion BCD vers décimal, si tant est qu'il y ait besoin de "convertir", il suffit d'afficher les chiffres "de 4 bits" !
(ou vérifier l'origine du soft : perso, à l'exception de ce que fournissent "de base" les IDE/outils de compilation, je n'utilise jamais de soft écrit par un autre que moi-même, donc si ça couille je sais que ça vient de moi ... et je corrige)

165=15x10+15
Typique d'un 255 pris comme un dcb et "converti" en binaire

Le ds1307 ne répond pas ET le programme ne vérifie pas le code retour sur la lecture I2C

Bonjour,
Tu soulèves en fait deux problèmes distincts, l'un avéré, la faiblesse de ton capteur solaire (ou la capacité insuffisante de ta batterie) et un éventuel problème avec ton RTC.

Je commencerais par régler le problème énergétique. Les prix des capteurs ont bien baissé et travailler avec une batterie bien chargée, c'est toujours mieux surtout en hiver. En fait, une installation photovoltaïque doit être strictement autonome. Si ta batterie doit subir régulièrement une mise en charge, ce n'est pas le bon plan. Ce n'est bien sûr qu'un avis.

J'ajoute que j'ignore si ta région est une zone à fouine, mais un seul oubli de fermeture peut avoir des conséquences terribles pour les volailles. Ce n'est pas comme un simple relevé de température ou d'autre paramètre.

Expérience vécue...

Cordialement

Bonjour

Merci pour vos réponse.

Pour le soucis de batterie maintenant c'est bon j'ai plus de soucis.
Effectivement les fouines sont un soucis (pour l'instant rien mais j'en vois de temps en temps). C'est pour sa que pour le moment on ouvre et ferme manuellement mais l'été va être fini et c'est mieux quand il pleut de ne pas sortir mdr.

Le code de manière général je l'écrit complètement, je m'inspire de code d'autres personnes en essayant de comprendre comment y fonctionne et ensuite je le crée à ma façon (peut être pas toujours optimisé mais au moins je le comprend mdr).

Si vous voulez je vous partage mon code défois qu'il y ai un soucis dedans.

#include <Wire.h>    // Bibliothèque pour l'I2C
#include "RTClib.h"  // Bibliothèque pour le module RTC
#include <LiquidCrystal.h> // Bibliothèque pour l'écran
#include <Stepper.h>  // Bibliothèque moteur
#include <EEPROM.h>		// Bibliothèque pour la mémoire EEPROM


RTC_DS1307 RTC;      // Instance du module RTC de type DS1307
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


static long timer;
int tempo = (15*1000); //tempo allumage ecran 15s 
int pHeure = 0;
int pMinute = 0;

int heure = 0;
int minute_ = 0;

  // Bouton

const int boutonPlus = 2;
const int boutonValider = 3;
const int fcUp = 15;    // fin de course montée
const int fcDown = 16;    // fin de course descente

int etatBouton = 0;
int coupureUp = 0;
int coupureDown = 0;

int retroLcd = 17;
int etatEcran = 0;

	// EEPROM
int memP = 0;	// Adresse pour le programme EEPROM
byte MemPrg ;

//int programme_default = 5;
int programme = 1;
int programme_choisi = 1;
int programmeMax = 9; // Nombre de programme maximum
int valide = 0;
String horaire = ("");

  // Moteur
const int stepsPerRevolution = 32*64;  
  // (step,1N2,1N4,1N3,1N1)
Stepper moteur(stepsPerRevolution, 11, 13, 12, 10);
int motorSpeed = 10; // vitesse du moteur (rotation / minute)


void setup(void) {
  //Initialisation de l'éran
  Serial.begin(9600);
  
  // Initialise la liaison I2C  
  Wire.begin();
  
  lcd.begin(16,2);
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.setCursor(0, 1);

  // Initialise le module RTC
  RTC.begin();
  timer=0;

  pinMode (boutonPlus, INPUT_PULLUP);
  pinMode (boutonValider, INPUT_PULLUP);

  pinMode (fcUp, INPUT_PULLUP);
  pinMode (fcDown, INPUT_PULLUP);
  
  pinMode (retroLcd, OUTPUT);
  //programme_choisi = programme_default;
  
  //EEPROM.write(memP, programme);		// Ecriture de la valeur dans la mémoire 

  //bootMoteur();
  //Initialise la date et le jour au moment de la compilation 
  // /!\ /!\ Les lignes qui suivent sert à définir la date et l'heure afin de régler le module, 
  // pour les montages suivant il ne faut surtout PAS la mettre, sans à chaque démarrage 
  // le module se réinitialisera à la date et heure de compilation
  
  //DateTime dt = DateTime(__DATE__, __TIME__);
  //RTC.adjust(dt);
  
  // /!\
  ////////////////////////////////////////////////////////////////////////////////////////////
}

void loop(){
  
  MemPrg = EEPROM.read(memP);  // Lecture de l'EEPROM
  
  DateTime now=RTC.now(); //Récupère l'heure et la date courante
  /*Serial.print(heure);
  Serial.print(" : ");
  Serial.println(minute_);*/
  affiche_date_heure(now);  //Converti la date en langue humaine
  affiche_programme();  // Afiche le programme choisi
  autre_programme(); // Pour modifié le programmme voulu
  
  etatBouton = digitalRead(boutonPlus); // bouton vert
  if (etatBouton == LOW)
  {
    ecran();
    programme++;
    
  }

  etatBouton = digitalRead(boutonValider); // bouton rouge
  if (etatBouton == LOW)
  {
    ecran();
    valider_programme();
  }
  
  switch (programme)
  {
    case 1: //6h 22h

      lcd.clear();
      affiche_programme();
      autre_programme();
      lcd.setCursor (3, 1);
      horaire = "6h - 22h";
    break;

    case 2: //6h30 21h
    
      lcd.clear();
      affiche_programme();
      autre_programme();
      lcd.setCursor (3, 1);
      horaire = "6h30 - 21h";
    break;
    
    case 3:  //7h 20h30

      lcd.clear();
      affiche_programme();
      autre_programme();
      lcd.setCursor (3, 1);
      horaire = "7h - 20h30";
    break;

    case 4: //7h30 19h

      lcd.clear();
      affiche_programme();
      autre_programme();
      lcd.setCursor (3, 1);
      horaire = "7h30 - 19h";
    break;

    case 5: //8h 18h

      lcd.clear();
      affiche_programme();
      autre_programme();
      lcd.setCursor (3, 1);
      horaire = "8h - 18h";
    break;

   case 6: //Manuel montée
    lcd.clear();
    lcd.setCursor(1, 1);
    lcd.print("Manuel montee");
    affiche_programme();

   break;

   case 7:  //Manuel descente
    lcd.clear();
    lcd.setCursor(1, 1);
    lcd.print("Manuel descente");
    affiche_programme();

    break;

   case 8:  //affichage heure
    lcd.clear();
    lcd.setCursor(1, 1);
    lcd.print("Heure : ");
    lcd.print(heure);
    lcd.print(" : ");
    lcd.print(minute_);

    break;

   case 9: //test

      lcd.clear();
      affiche_programme();
      autre_programme();
      lcd.setCursor (3, 1);
      horaire = "test";
    break;
    
  }

  if(programme > programmeMax)
  {
    programme = 1;
  }

  if (millis()>=timer + tempo)
  {
    lcd.noDisplay(); // Coupure de l'ecran
    digitalWrite(retroLcd, LOW); // Coupure du retro de l'ecran
  }

  if (programme_choisi == 6)
  {
    mode_manuel_monte();
  }
  
  if (programme_choisi == 7)
  {
    mode_manuel_descente();
  }

  programme_execution();
  
  delay(200); // delais de 1 seconde
}

// affiche la date et l'heure sur l'écran
void affiche_date_heure(DateTime datetime){
  
  heure = datetime.hour();
  minute_ = datetime.minute();
}

void bootMoteur()
{
  Serial.println("boot moteur");
  moteur.setSpeed(motorSpeed);
  moteur.step(10);
  moteur.step(-10);
  Serial.println("Moteur pret");
}

void affiche_programme()
{
  lcd.setCursor(0, 0);
  lcd.print("Programme ");
  lcd.print(MemPrg);
}

void autre_programme()
{
  lcd.setCursor(0, 1);
  lcd.print(programme);
  lcd.print(" : ");
  lcd.print(horaire);  
}

void valider_programme()
{
    etatBouton = digitalRead(boutonValider);
  if (etatBouton == LOW)
  {	
	Serial.println("bouton OK");
    valide++;
      if  (valide == 8)
      {
        programme_choisi = programme;
		EEPROM.write(memP, programme_choisi);

        valide = 0;
      }
  }
}

void ecran()

{
    lcd.display(); // Allume l'ecran
    digitalWrite (retroLcd, HIGH); // Allume le reto de l'ecran
    timer=millis();

}

void programme_execution()
{

    if(MemPrg==1)
  { 
      if((heure==6) && (minute_==0))
        {
          fc1();
        }
      if((heure==22) && (minute_==0))
        {
          fc2();
        }
  }

    if(MemPrg==2)
  {
     if((heure==6) && (minute_==30))
      {
        fc1();
      }

      if((heure==21) && (minute_==0))
      {
        fc2();
      }    
  }

    if(MemPrg==3)
  {
      if((heure==7) && (minute_==0))
      {
        fc1();
      }

      if((heure==20) && (minute_==30))
      {
        fc2();
      }
  }

    if(MemPrg==4)
  {
      if((heure==7) && (minute_==30))
      {
        fc1();
      }

      if((heure==19) && (minute_==0))
      {
        fc2();
      }    
  }

    if(MemPrg==5)
  {
      if((heure==8) && (minute_==0))
      {
        fc1();
      }

      if((heure==18) && (minute_==0))
      {
        fc2();
      }    
  }
}

void mode_manuel_monte()
{
  fc1();
  programme_choisi = MemPrg;
}

void mode_manuel_descente()
{
  fc2();
  programme_choisi = MemPrg;
}

void fc1()
{
    
  Serial.println("Controle fcUp");  
    coupureUp = digitalRead(fcUp);
  if (coupureUp == 1)
  {
    Serial.println("Appel moteurUp");
    moteurUp();
    Serial.println("moteur en haut retour menu");
  }
}

void fc2()
{
     Serial.println("Controle fcDown");
    coupureDown = digitalRead(fcDown);
  if (coupureDown == 1)
  {
    Serial.println("Appel moteurDown");
    moteurDown();
    Serial.println("moteur en bas retour menu");
  }
}
void moteurUp()
{
  Serial.println("moteur up");
  moteur.setSpeed(motorSpeed);
  moteur.step(100);
  Serial.println("Appel controle fc1");
  fc1();
}

void moteurDown()
{
  Serial.println("moteur down");
  moteur.setSpeed(motorSpeed);
  moteur.step(-100);
  Serial.println("Appel controle fc2");
  fc2();
}

Après quelque temps j'ai vu que la batterie ne tenais pas asse longtemps quand il n'y avais pas asse de soleil pendant 3-4 j.

Utiliser le mode veille diviserait la consommation de la UNO par deux (20mA au lieu de 38). C'est déjà mieux que rien.

Ensuite il est clair qu'avec une UNO l'autonomie ne sera pas fabuleuse.
Une PRO MINI consomme beaucoup moins (en mode veille) :
1.5µA pour une 8MHz
3µA pour une 16MHz

Il faut simplement retirer la LED POWER et dessouder la sortie du régulateur.
Sans dessouder la sortie du régulateur elle consommera 70µA de plus, ce qui reste tout de même honorable, sans commune mesure avec la consommation d'une UNO (le rapport est > 500 fois).

Tu parles de moteur PAP. Comment est-il piloté ? Le driver n'engendre t-il pas une consommation supplémentaire ?

Inconvénient de ta solution : tu confies la fiabilité de ton système à un programmateur horaire, élément qui ajoute un taux de panne non négligeable. Quelle sera sa fiabilité en hiver, ou par forte chaleur ou humidité élevée ?

Enfin, en utilisant une RTC DS3231 la dérive serait beaucoup moins importante, surtout que tu n'as prévu aucune fonction de remise à l'heure.

#EDIT : Dernier inconvénient : la RTC n'est alimentée que par sa pile la majeure partie du temps. Elle va donc durer assez longtemps.

Merci pour la réponse

hbachetti:
Utiliser le mode veille diviserait la consommation de la UNO par deux (20mA au lieu de 38). C'est déjà mieux que rien.

J'avais essayé de programmer le mode veille mais je n'y suis pas arrivé faudrait que je restest à l'occas, j'ai vu un topic la dessus.

Tu parles de moteur PAP. Comment est-il piloté ? Le driver n'engendre t-il pas une consommation supplémentaire ?

Le moteur PAP c'est ceux fourni avec les kit de basse pour commencé.

Inconvénient de ta solution : tu confies la fiabilité de ton système à un programmateur horaire, élément qui ajoute un taux de panne non négligeable. Quelle sera sa fiabilité en hiver, ou par forte chaleur ou humidité élevée ?

Je sais bien mais c'est la seule solution que j'avais pour le moment à voir cette hiver effectivement.

Enfin, en utilisant une RTC DS3231 la dérive serait beaucoup moins importante, surtout que tu n'as prévu aucune fonction de remise à l'heure.

#EDIT : Dernier inconvénient : la RTC n'est alimentée que par sa pile la majeure partie du temps. Elle va donc durer assez longtemps.

Pour la remise à l'heure j'ai vu qu'il y avais une dérive alors de temps en temps je la remet à jour avec l'ordi et le code ....
Ok je vais voir pour changé y doit me resté une 3231 dans mon stock.
Et si j'alimente la RTC en permanence avec la batterie sa peut évité que la pile se décharge trop vite ?

C'est mon 1er vrai projet "fini" en Arduino alors on ai encore loin de la perfection mais on va y arrivé.

Le moteur PAP c'est ceux fourni avec les kit de basse pour commencé.

Je parle du driver. Quel circuit pilote le moteur ? L293D ou autre ?

Et si j'alimente la RTC en permanence avec la batterie sa peut évité que la pile se décharge trop vite ?

Bien entendu, sans dépasser se tension d'alimentation maxi.

hbachetti:
Je parle du driver. Quel circuit pilote le moteur ? L293D ou autre ?

C'est le ULN2003.

Normalement un ULN2003 ne consomme rien en l'absence de commande.

Ok du coup c'est vraiment la UNO qui me pompe la batterie quand il fais pas beau.
Je vais allé étudié de plus prêt le mode veille (qui pourrai servir dans d'autre projet).

Merci bien des conseils.

Un bon lien pour en savoir plus sur le mode sleep de l'arduino

La UNO est un solution inadaptée.

La connectique.
La UNO impose l'utilisation de fils DUPONT, source de faux contacts. Cette connectique ne résistera pas aux conditions extérieures, température, humidité, à moins de placer la carte dans un environnement protégé.
Je suppose que si tu utilises une batterie, c'est que la carte n'est pas dans l'habitation, à température et hygrométrie à peu près maîtrisée.
La soudure sur un PCB ou une plaquette à pastilles est la seule solution pour obtenir une réalisation fiable.

La consommation.
Une PRO MINI consommerait 500 fois moins, rien qu'en supprimant sa LED POWER.

lesept:
Un bon lien pour en savoir plus sur le mode sleep de l'arduino

Ok merci je vais regardé sa

hbachetti:
La UNO est un solution inadaptée.

La connectique.
La UNO impose l'utilisation de fils DUPONT, source de faux contacts. Cette connectique ne résistera pas aux conditions extérieures, température, humidité, à moins de placer la carte dans un environnement protégé.
Je suppose que si tu utilises une batterie, c'est que la carte n'est pas dans l'habitation, à température et hygrométrie à peu près maîtrisée.
La soudure sur un PCB ou une plaquette à pastilles est la seule solution pour obtenir une réalisation fiable.

La consommation.
Une PRO MINI consommerait 500 fois moins, rien qu'en supprimant sa LED POWER.

Oui c'est pour sa que j'ai tout soudé sur un shield que je met sur ma UNO comme sa je peut prendre la carte pour modifié le programme ou autre tranquillement à la maison sans tout débranché.

Dans le poulailler la carte est dans une boite étanche c'est surement pas le top mais c'est mieux que rien.

J'ai changé ma RTC (et mon code...). L'horloge à l'air de fonctionné pour le moment mais en remettant le moteur en fonctionnement et en vérifiant que les FDC fonctionnais toujours, j'ai vu de la fumé s'échappé de la UNO du coup j'ai tout coupé.
En regardant bien c'est le régulateur de tension qui à flambé (je comprend pas j'ai toujours la même tension d'alimentation). Alors j'ai pris une autre UNO que j'avais téléversé le code et remis à la place mais rien ne s'affiche sur mon petit LCD et sa a pas l'air de fonctionné. Le régulateur en grillant aurait pu endommagé le sheild ?

Merci pour votre aide en tout cas