DS1307 [RESOLU]

On est bien d'accord : tu as un quartz de 32.768KHz (quartz de montre) sur les broches X1/X2 ?
Parce que sinon, sans quartz c'est un peu normal que rien ne bouge smiley-wink

Lol oui de ce coté la j'ai bien un 32.768Khz et non pas un 32...Mhz et il est bien sur les deux premier pin de la chip.

J'ai vue plusieurs topic ou il parlait d'utilisé la ram du ds1307 je pense que celui que j'ai peut me servir à ça. Je peut écrire deçus mais l'oscillation ne marche pas donc bon c'est à essayer.
(Merci pour le lien je le garde sous le coude :slight_smile: )

Encore faut il que je dompte là bête!(Au vue des lacunes que j'ai avec le bus i2C...) ]:smiley:

pouic13:

On est bien d'accord : tu as un quartz de 32.768KHz (quartz de montre) sur les broches X1/X2 ?
Parce que sinon, sans quartz c'est un peu normal que rien ne bouge smiley-wink

Lol oui de ce coté la j'ai bien un 32.768Khz et non pas un 32...Mhz et il est bien sur les deux premier pin de la chip.

J'ai vue plusieurs topic ou il parlait d'utilisé la ram du ds1307 je pense que celui que j'ai peut me servir à ça. Je peut écrire deçus mais l'oscillation ne marche pas donc bon c'est à essayer.
(Merci pour le lien je le garde sous le coude :slight_smile: )

Encore faut il que je dompte là bête!(Au vue des lacunes que j'ai avec le bus i2C...) ]:smiley:

si tu arrive a ecrire et relire la RAM ce n'est donc pas un probleme d'I2C ni tres surement de DS1307,
reverifie les soudures quartz

juste pour que l'on soit bien d'accord
le Ds1307 necessite 2 phases
une phase de mise à l'heure et démarrage de l'oscillateur
une phase ensuite de lecture
tu procede comment pour les 2 etapes ?

pouic13:
Merci je croyais avoir mal compris mais malheureusement non.

Je viens d'essayer la led reste allumé.

As-tu bien activé la sortie SQW/OUT écrivant 0x10 dans le registre à l'adresse 07? Si c'est bon elle doit être allumée 500mS et éteinte 500mS.
Si tu as un oscillo, tu peux écrire 0x13 dans ce même registre et normalement tu devrais voir le 32kHz.

Si tu relis le registre à l'adresse 0, le bit de poids fort est-il bien à zéro (arrêt de l'oscillateur si le bit est à un)

Peut tu envoyer l'état réel des registres du DS1307.
Pour cela point n'est besoin d'utiliser une bibliothèque particulière autre que Wire :

void lit_ds1307()
{
	uint8_t octet_lu[7];
	uint8_t i ;

	//Lecture des registres
	
	//Positionnement sur l'octet à lire en premier:
		Wire.beginTransmission(0x68);
		Wire.write(0x00);
		Wire.endTransmission(0x68);
	//Lecture de 8 octets a partir de la position précédemment indiquée
		Wire.requestFrom(0x68, 8) ;
		for (i=0 ; i<=7 ; i++)
		{
			octet_lu[i] = Wire.read();
		}
	// Affichage	
		for (i=0 ; i<=7 ; i++)
		{
			Serial.print("Registre n: ")	;	Serial.print(i);
			Serial.print("  ")	;	Serial.println(octet_lu[i], BIN)	;
		}
}

C'est ce que je me suis fait la première fois que j'ai utilisé une DS1307 histoire de savoir où je mettais les pieds.

Nota : les 56 autres registres "utilisateurs" peuvent aussi être lus de la même façon.

Edit : pour vérifier la sortie SQWE c'est possible de le faire au voltmètre.
Avec 1 Hz tu devrais voir un affichage alterner entre d'une part 4et 5 V et d'autre part 0 et 2 volts (vérifié fonctionne avec mon voltmètre).
Avec une fréquence plus élevée je n'ai pas essayé mais le voltmètre devrait intégrer et afficher pas loin de 2,5 V

reverifie les soudures quartz

J'ai aussi essayer avec un autre quartz de même valeur aucun effet.

le Ds1307 necessite 2 phases
une phase de mise à l'heure et démarrage de l'oscillateur
une phase ensuite de lecture
tu procede comment pour les 2 etapes ?

J'ai procédé de la même maniéré que skywodd et jean-françois dans leur tuto.(sans parler des librairies toutes faites)
Personnellement j'écarte définitivement l’hypothèse d'une erreur de codage ou d'écriture car même en utilisant juste une librairie Wire rien ne bouge .
Comme je le dit et le redit la mise à l'heure ainsi que la lecture s’effectue bien mais pas "l'oscillation".

As-tu bien activé la sortie SQW/OUT écrivant 0x10 dans le registre à l'adresse 07?

Oui je l'ai fait et pour vérifier j'ai utilisé un led (avec une résistance) branché sur sur la sortie SQW/OUT. Résultat la led s'allume mais ne s’éteint pas (pas d'oscillation mais l’écriture oui).

Peut tu envoyer l'état réel des registres du DS1307.

Avec le code que tu ma donné il me ressort ça:

Registre n: 1  11111111
Registre n: 2  11111111
Registre n: 3  11111111
Registre n: 4  11111111
Registre n: 5  11111111
Registre n: 6  11111111
Registre n: 7  11111111

J'apprécie beaucoup votre dévouement mais je crois qu'on touche le fond XD
j'ai peut être endommager ma puce sans m'en rendre compte d'une manière ou d'une autre.
J'attend juste de récupérer un autre ds1307 pour confirmer mais la je ne vois que ça.

Faut voir le bon coté Je pourrais toujours m'en servir comme mémoire d’appoint...

EDIT: Je viens d'essayer d'utiliser la RAM et ça fonctionne j'ai mis un petit imp. écr.

A titre d'information sur ma puce DS1307 j'avais :
Registre 0 -> 10000000
Registre 1 à 7 -> 00000000

Ce qui me gêne c'est que des bits qui d'après la datasheet devraient être à 0 parce que non utilisés sont à 1 sur ta puce.
Il s'agit des bits :
Reg2 B7
Reg3 B7 B6 B5 B4 B3
Reg4 B7 B6
Reg5 B7 B6 B5
Reg7 B6 B5 B3 B2

Je viens de me rappeler un truc con : quand j'ai reçu mon module il ne fonctionnait pas parce que la pile ne faisait plus que 1.5V au lieu de 3 Volt.

Retire donc la pile et mesure la en dehors du montage pour voir.

J'ai relancé ton 68tjs une fois en enlevant la pile pour vider la mémoire et une autre fois en la remettant et ça ne change pas.
La pile et neuve j'ai encore vérifier(pour la énième fois... :stuck_out_tongue: ) et elle fait 2.96V.

Tous les bit reste à 1 pas un 0 n'est affiché.

pouic13:
J'ai relancé ton 68tjs une fois en enlevant la pile pour vider la mémoire et une autre fois en la remettant et ça ne change pas.
La pile et neuve j'ai encore vérifier(pour la énième fois... :stuck_out_tongue: ) et elle fait 2.96V.

Tous les bit reste à 1 pas un 0 n'est affiché.

2.96V c'est pas une pile (type CRXXYY) bien en forme
essaye ça ne coute rien pour test avec deux bonnes vieilles (mais en forme :grin: ) A.. en serie
verifie la tension avant connexion et ensuite connecté

Si tu modifie un registre puis que tu relis la valeur de ce même registre est-ce que ça ressort toujours 11111111 ?
Si oui il y a un problème avec le DS1307 lui même (si la RAM marche = I2C ok) ...

J'ai encore testé pour le plaisir des yeux la pile mais... non.
D’après ce que j'ai pu comprendre la pile ne joue qu'un rôle lors d'une coupure de courant donc bon ça n'intervient pas vraiment dans le fonctionnement normale si je puis dire.

Si tu modifie un registre puis que tu relis la valeur de ce même registre est-ce que ça ressort toujours 11111111 ?

XD Je souris bêtement devant mon écran car depuis que j'ai mon problème je cherche désespérément à comprendre le fonctionnement de l'i2C, de la librairie "Wire" et de ce foutu datasheet avec ces beaux schémas.

Ce que tu me dis skywodd je l'ai dans la tête depuis le début mais je ne sais pas me servir des infos dont je dispose.

Je vois toujours pas comment ça fait que l'adresse du DS1307 et 0x68 ou encore 0x1 ou le 12 pourquoi pas.
Et l'histoire des bit je ne mi retrouve pas du tout.
Quand vous écrivez 0x00 ça veut dire quoi?

Enfin bref je suis perdu je n'arrive pas à naviguer correctement deçu je touche des trucs mais sans vraiment comprendre le fond.

Existe-t-il un tuto ou quelqu'un qui ce sente de faire un cour :smiley:

Désoler de le demandé comme ça mais je suis vraiment frustré de pas comprendre.

pouic13:
Je souris bêtement devant mon écran car depuis que j'ai mon problème je cherche désespérément à comprendre le fonctionnement de l'i2C, de la librairie "Wire" et de ce foutu datasheet avec ces beaux schémas.

J'ai fait un tutoriel sur l'I2C et la librairie Wire (voir sur mon blog), si tu peut supporter le son de bip de ma vidéo youtube je t'invite à le regarder :wink:
Sinon pour la lecture des registres les commentaires de mon code ne ton pas mis sur la voie ?

pouic13:
Je vois toujours pas comment ça fait que l'adresse du DS1307 et 0x68 ou encore 0x1 ou le 12 pourquoi pas.

C'est la datasheet qui dit quel adresse utiliser.
On décale juste la valeur de 1 bit vers la droite pour virer le bit de "R/W" I2C que la librairie Wire gère en interne.

pouic13:
Et l'histoire des bit je ne mi retrouve pas du tout.
Quand vous écrivez 0x00 ça veut dire quoi?

0x00 = valeur 0 en hexadécimal :wink:

L'I2C est un bus conçu par Philips pour l'interconnection entre circuits intégrés.
Pour la petite histoire Philips Semi-conducteurs s'appelle maintenant NXP.

L'I2C est une vrai norme elle a ses règles.
Un seul maître peut diriger le bus, les autres composants I2C étant des esclaves.
Chaque esclave I2C possède une adresse propre sur 1 octet (8bits).
L'adresse est composé d'une mnémonique correspond à une "famille" suivi d'une adresse "personnelle". Le total des deux faisant 7 bits, le 8eme bit composant l'adresse est là pour dire si le maître veut écrire dans l'esclave ou lire dans l'esclave.

Les familles sont gérées par NXP maintenant. Par exemple le PCF8574 appartient à la famille "0100" et il possède 3 bits A0,A1,A2 configurables ce qui fait que l'on peut avoir jusqu'à 7 PCF8574 sur le même bus.
Le DS1307 est particulier dans le sens où se serait ridicule d'avoir plusieurs DS1307 sur le même bus : il n'a pas de bits d'adresse configurable.
Donc voilà pour les adresses.

Parlons de Wire !
Pour commencer la bibliothèque Wire n'existe pas c'est un abus de langage.
Ce qui existe c'est la bibliothèque TwoWire. Les auteurs de la bibliothèque TwoWire ont instancié eux même un objet Wire: dans la dernière ligne du fichier Wire.cpp on peut lire la ligne suivante :
TwoWire Wire = TwoWire() ;
qui est bien une instanciation de l'objet Wire. Ceci pour vous simplifier la vie, mais aussi ajouter de la confusion.

La gestion de l'I2C est assez complexe, la bibliothèque "Wire" le fait très bien cela ne vaut pas le coup de réinventer la roue, par contre je n'en dirait pas autant des bibliothèques DS1307 qui a mon avis sont complètement inutile : il est préférable de passer le temps nécessaire à leur compréhension à comprendre le fonctionnement de Wire et de lire la datasheet du composant à piloter. Au moins quand cela ne se passe pas comme prévu tu ne reste pas le bec dans l'eau à ne rien comprendre, enfin c'est ma manière de procéder.
Pour trouver l'adresse du DS1307 tu peut utiliser un scanner de bus I2C (celui de fdunews est le plus ergonomique que j'ai vu, je recommande chaudement) mais c'est entièrement passif et si tu as plusieurs esclaves I2C c'est foutu. Beaucoup plus efficace est la lecture de la datasheet où tu trouvera la "famille", le nombre de bits d'adresse configurables et la signification de tous les registres.

Pour signifier à un esclave que le maître veut lui parler il faut écrire
Wire.beginTransmission(adresse_composant); // (Famille plus adresse configurable), le dernier bit Read/Write c'est Wire qui le gère
Ensuite il faut indiquer à quelle adresse INTERNE de l'esclave le maître veut intervenir
Wire.write(adresse_du_registre_de_l_esclave) ;
Ensuite il faut soit lire
octet_lu = Wire.read();
soit écrire :
Wire.write(donnee) ;

Revenons au DS1307.
Pour écrire dans un registre il suffit de faire , aprés un Wire.begin() dans le setup() bien sûr qui configurera l'ATMega.

void ecrit_ds1307(uint8_t registre, uint8_t donnee)
{
	Wire.beginTransmission(0x68);    // indique au DS1307 d'adresse hexadecimale 0x68 que le maître veut lui parler
		Wire.write(registre);    // Le maître indique à l'esclave qu'il veut intervenir sur le registre indiqué
		Wire.write(donnee);    // Le mâitre écrit l'octet "donnee"
	Wire.endTransmission(0x68);     // le maître libère l'esclave
}

Pour lire un registre

uint8_t lit_ds1307(uint8_t registre)
{
	uint8_t lecture ;
	
	//Positionnement sur l'octet à lire 
		Wire.beginTransmission(0x68); // indique au DS1307 d'adresse hexadecimale 0x68 que le maître veut lui parler
		Wire.write(registre);       // Le maître indique à l'esclave qu'il veut intervenir sur le registre indiqué
		Wire.endTransmission(0x68);  // le maître libère l'esclave
	//lecture
		Wire.requestFrom(0x68, 1) ;  // Le maître réclame à l'esclave 1 octet à partir du registre précédement activé
 		lecture = Wire.read();      // Le maître lit l'octet.
       return lecture;  // la fonction est de type uint8_t elle renvoie un octet.
}

Si tu as des difficultés avec les représentations décimale, hexadécimale ou binaire d'un même nombre : une seule adresse le site du zéro !

Bon courage :grin:

68tjs:
L'I2C est un bus conçu par Philips pour l'interconnection entre circuits intégrés.
Pour la petite histoire Philips Semi-conducteurs s'appelle maintenant NXP.

L'I2C est une vrai norme elle a ses règles................

Un vrai plaisir à lire...

MERCI pour ces réponses!

Bon y reste pas mal de truc à débroussailler encore mais je comprend un peu mieux des petits truc qui me coince.

Une phrase ma interpellé celle-ci:

Le DS1307 est particulier dans le sens où se serait ridicule d'avoir plusieurs DS1307 sur le même bus : il n'a pas de bits d'adresse configurable.

Ca veut dire que si je branche 2 ds1307 l'arduino ne pourra pas identifier qui est qui?
Il n'a aucun moyen pour donné une adresse fictive a un esclave, un peu comme un masque?
(Comme tu la dit brancher 2 ds1307 en temps normale c'est inutile mais la c'est la CRISE! lol...)

Je demande ça car c'était l'occasion pour moi de recyclé celui dont l'horloge ne marche pas.

Merci beaucoup encore pour ton intervention 68tjs.
Je vais de ce pas regarder ton tuto skywodd.

Ca veut dire que si je branche 2 ds1307 l'arduino ne pourra pas identifier qui est qui?

Rappelle moi la carte que tu as exactement et qu'est ce que tu appelle un "ds1307".
Si comme je le pense tu possède la carte habituelle avec deux boîtiers SO8 (cms) ce n'est pas la carte qui a une adresse mais chaque puce possède la sienne :
Le DS1307 = 0b1101000
L'eeprom 24C32 = 0b1010 A2 A1 A0

Sur la carte que je possède l'adresse de l'eeprom est câblée en "dur" avec l'adresse 000 (les pattes A0, A1, A2 sont reliées à la masse. Son adresse est donc 0b1010000 .
Je peux utiliser jusqu'à 6 composants I2C supplémentaires appartenant à " la famille 1010 ", a condition qu'aucun n'ait l'adresse 000.

Quant à "récupérer " le DS1307 défaillant (à condition qu'il le soit vraiment, fais ce que t'a demandé Skywood : écrit dans un registre) le jeu n'en vaut pas la chandelle. Une eeprom 24C32 coûte moins de 1 € , possède 4096 octets (54 pour le ds1307) et à une durée de rétention de 100 ans sans alimentation contre que dalle avec le ds1307 si tu retire la pile.

Dernier conseil : tu as encore des zônes d'ombres sur le bus I2C. Cherche de la documentation sur le bus I2C et rien que sur le bus, n'ajoute pas le mot arduino dans tes critères de recherche.

Je n'ai pas de carte pré-fabriqué, j'utilise une puce DS1307. Sur le datasheet son adresse est marqué: 1101000 (d'ou le 0x68 XD ).

J'ai bidouiller encore un peu à l'aide des infos que tu ma fournies et je peu lire, écrire et modifier puis relire et reécrire tous les registres (secondes 0x00, minutes 0x01... ainsi que la ram 0x08).

Mais l'oscillation toujours rien, en regardant le datasheet apparemment le DS1307 peut fonctionné sans sont étage d'oscillation et la seul maniéré de contrôler si l'oscillateur marche c'est avec la sortie SWQ/OUT comme vous me l'avez déjà fait contrôler.
J'ai aussi essayer d'activé et de désactivé le bit 7 de l'adresse 0 mais ça ne fait toujours rien.

On apprend pas mal chose en étant dans la caca lol.

je peu lire, écrire et modifier puis relire et reécrire tous les registres (secondes 0x00, minutes 0x01... ainsi que la ram 0x08).

Bien on avance.
Il faudrait mettre tout les registres à 0. C'est à faire une seule fois.

Normalement l'oscillateur devrait se mettre en route. Si l'oscillateur est en route les bits des secondes, minutes etc devraient s'incrémenter. Tu devrais pouvoir le vérifier en faisant des opération de lectures à intervalle régulier.

Pour réaliser le programme qui va bien je te déconseille d'utiliser la librairie RTC quand cela ne va pas il faut aller au plus simple.

Je verrais bien l'architecture suivante : (attention c'est du principe ce n'est pas du code !!)

setup()
{
Wire.begin
Serial.begin
Ecrit_dans_les_registres
}

loop()
{
Lit_dans_les_registre ; // les registres 0 et 1 sont suffisants
Affiche_contenu_des__registres ; // Utiliser Serial.print(octet_lu, BIN) qui affiche sous forme binaire
delay(1000) ; // une mesure toutes les secondes
}

En te contentant de surveiller que les registres des secondes et des minutes tu simplifies au maximum.
Inutile de faire une conversion Décimal_codé_ Binaire en décimal la seule chose qui compte a ce stade c'est :
est-ce que les bits changent ou pas quand le temps s'écoule ?

S'ils ne changent pas il faudra arrêter l'acharnement thérapeutique.
S'ils changent ce sera encourageant et il sera possible d'aller plus loin.

S'ils ne changent pas il faudra arrêter l'acharnement thérapeutique.

je crois qu'on en est là XD

Je te mets le code quand même:

#include <Wire.h>


//fonction ecriture 
void ecrit_ds1307(uint8_t registre, uint8_t donnee)
{
    Wire.beginTransmission(0x68);  // indique au DS1307 d'adresse hexadecimale 0x68 que le maître veut lui parler
     Wire.write(registre);    // Le maître indique à l'esclave qu'il veut intervenir sur le registre indiqué
     Wire.write(donnee);    // Le mâitre écrit l'octet "donnee"
  Wire.endTransmission(0x68);     // le maître libère l'esclave
}

//fonction lecture
uint8_t lit_ds1307(uint8_t registre)
{
  uint8_t lecture ;
//Positionnement sur l'octet à lire 
  Wire.beginTransmission(0x68); // indique au DS1307 d'adresse hexadecimale 0x68 que le maître veut lui parler
  Wire.write(registre);       // Le maître indique à l'esclave qu'il veut intervenir sur le registre indiqué
  Wire.endTransmission(0x68);  // le maître libère l'esclave
//lecture
  Wire.requestFrom(0x68, 1) ;  // Le maître réclame à l'esclave 1 octet à partir du registre précédement activé
    lecture = Wire.read();      // Le maître lit l'octet.
  return lecture;  // la fonction est de type uint8_t elle renvoie un octet.
}



void setup()
{
  Serial.begin(9600);
  Wire.begin();
  ecrit_ds1307(0x00, 1);
  ecrit_ds1307(0x01, 2);
}

void loop()
{
  Serial.println( lit_ds1307(0x00), BIN);
  Serial.println( lit_ds1307(0x01), BIN);
  delay(1000);
  
}

Et ça donne quoi dans le serial monitor ?

Avec ce code ça me donne 1 et 10 (y me zap tout les zéro devant le 1 pas trop compris) mais ça ne s'incrémente pas il me renvoie toujours les mêmes valeurs c'est un DS1307 fidèle :stuck_out_tongue:

Par contre c'est normale qu'il accept les valeurs décimales?
Dans les code que vous m'avez donné vous utilisez tous plus ou moins des convertisseurs DEC>BCD.
J'ai essayer de lui envoyer des décimales (comme dans l'exemple) ou du binaire et il prend les deux? j'ai fait une boulette ou c'est normale?