Difficultés d'un débutant avec un DS1683 en I2C pour lire les données.

Bonjour,

J’essaie d’utiliser un composant DS1683 en I2C mais sans succès.

Je souhaite l’utiliser pour compter le nombre d’heures de fonctionnement d’une lampe UV qui doit être remplacée toute les 9600h.
Malheureusement je nage complètement pour lire les données de la puce.
C’est la première fois que j’utilise ce type de composant et avec mes connaissances basiques je n’arrive à rien.
J’ai essayé d’utiliser les exemples inclus avec Wire mais il y a quelque chose que je ne saisis pas.
Les adresses sont définies dans la doc comme 00h …30h-FFh et j’ai beau chercher sur internet comment les adapter pour les utiliser, je ne dois pas chercher la bonne chose.

Voici la doc du composant

Si il serait possible de m’indiquer un tuto assez clair pour que j’arrive à y comprendre quelque chose.
J’ai regardé ceux sur la lecture d’EEPROM en i2c mais il y a toujours quelque chose que je ne saisis pas avec les adresses.
(le problème se situe probablement entre la chaise et le clavier)

J’avais trouvé le code ci-dessous sur le forum qui semble t’il était une ébauche, en le lançant certaines infos remontent mais le souci c’est que je n’ai pas les infos qui m’intéressent, en particulier le temps de fonctionnement que je voudrais utiliser pour faire remonter une info de remplacement de la lampe au bout du délais et surtout il fonctionne sans que je n’arrive à le comprendre comment on gère ces adresses pour pouvoir utiliser toutes les fonctions de la puce.

Merci

[color=#000000][/color]
[color=#000000]#include <Wire.h>
const int16_t DS1683 = 0x6B;
byte STAT = 0;
void setup() {
  // put your setup code here, to run once:
  //Start the I2C bus
  Wire.begin();
  Serial.begin(9600);
 
}//Setup
void loop() {
  GetStatusData();
  delay(1000);
}
void GetStatusData(){      //Read the value of the Status Register
    //Begin Reading Values
  byte RegData = 0x5A;
  Wire.beginTransmission(DS1683);
  Wire.requestFrom(DS1683,1);
  RegData = Wire.read();
    Wire.endTransmission();
  
  //Show Raw Data
  Serial.print("Status Register = ");
  Serial.println(RegData,HEX);
 
  //Show alarms
  Serial.print("Event = ");
  if ((RegData && 0x04) == 1){
    Serial.println("On");
  }
  else{
    Serial.println("Off");
    }
  Serial.print("Event Alarm = ");
  if ((RegData && 0x02) == 1){
    Serial.println("On");
  }
  else{
    Serial.println("Off");
    }
  Serial.print("ETC Alarm = ");
  if ((RegData && 0x01) == 1){
    Serial.println("On");
  }
  else{
    Serial.println("Off");
    }
}      //GetStatusData[/color]

Si il serait possible de m'indiquer un tuto assez clair pour que j'arrive à y comprendre quelque chose.

Assez clair difficile à dire mais si tout simplement tu tapais DS1683 dans la zone de recherche en haut à droite de cette page écran, je pense que tu trouverais ce que tu cherches et avec les premiers résultats en français.

Re-bonjour,

J’arrive enfin à lire les registres mais après quelques heures d’essais en tout genre j’ai toujours des difficultés.

Avec mon code le registre correspondant au status me retourne une valeur qui ne semble pas correspondre.
Le registre Status devrait retourner des 0 ou des 1 pour les 3 derniers bits, hors si je le lis je me retrouve soit avec 1 soit avec 5 en résultat.
Je suppose que c’est une histoire de format car je me retrouve avec les données suivantes qui remontent, j’ai essayé différentes choses mais à force de chercher je me perds:
Si le Pin Event est Low
Status 1
Time 238 216 172 255

Si le pin Event est high Status passe à 5
Status 5
Time 242 216 172 255

J’ai aussi tenté de remettre à zéro les compteurs de temps mais je n’arrive pas à remettre des zeros comme valeur.
Je ne sais pas si c’est ma façon d’écrire la remise à zéro qui pose problème ou si c’est le mot de passe bloquant ces fonctions, j’ai essayé sans la partie mot de passe sans rien obtenir de plus.
Le mot de passe serait des 1 de partout si j’ai bien compris la documentation (the PWE bits are set to 1 to match the factory default Password Value of all 1s.)

Merci

Voici mon code pour l’instant le plus basique :

#include <Wire.h>
const int16_t slave_address = 0x6B; //ADDRESSE DU DS1683
int16_t register_address_ST = 0x1; //REGISTRE DU STATUS
int16_t register_address_ET = 0xA; //REGISTRE DU TEMPS
int16_t pass1_address = 0x2;
int16_t pass2_address = 0x3;
int16_t pass3_address = 0x4;
int16_t pass4_address = 0x5;
int16_t password_digit = 11111111;
void setup() {
  //Start the I2C bus
  Wire.begin();
  Serial.begin(9600);

  //déblocage des fonctions avec MDP

  // Chiffre 1 du Mot de Passe
  Wire.beginTransmission(slave_address);
  Wire.write(pass1_address);
  Wire.write(password_digit);
  Wire.endTransmission();
  // Chiffre 2 du Mot de Passe
  Wire.beginTransmission(slave_address);
  Wire.write(pass2_address);
  Wire.write(password_digit);
  Wire.endTransmission();
  // Chiffre 3 du Mot de Passe
  Wire.beginTransmission(slave_address);
  Wire.write(pass3_address);
  Wire.write(password_digit);
  Wire.endTransmission();
  // Chiffre 4 du Mot de Passe
  Wire.beginTransmission(slave_address);
  Wire.write(pass4_address);
  Wire.write(password_digit);
  Wire.endTransmission();

  // RAZ du Registre 1 du capteur
  Wire.beginTransmission(slave_address);
  Wire.write(register_address_ET);
  Wire.write(00000000);
  Wire.endTransmission();
}

void loop() {
  GetStatusData();
  GetElapsedTimeData();
  delay(1000);
}

void GetStatusData() {
  Wire.beginTransmission(slave_address);
  Wire.write(register_address_ST);
  Wire.endTransmission();
  if (Wire.requestFrom(slave_address, 1) > 0 ) {
    byte data1 = Wire.read();//Status
    Serial.print("Status ");
    Serial.print(data1);
    Serial.println(" ");

  }
}      //Lecture des Status


void GetElapsedTimeData() {
  Wire.beginTransmission(slave_address);
  Wire.write(register_address_ET);
  Wire.endTransmission();
  if (Wire.requestFrom(slave_address, 4) > 0 ) {
    byte data1 = Wire.read();//Byte 1
    byte data2 = Wire.read(); //Byte 2
    byte data3 = Wire.read(); //Byte 3
    byte data4 = Wire.read(); //Byte 4

    Serial.print("Time ");
    Serial.print(data1);
    Serial.print(" ");
    Serial.print(data2);
    Serial.print(" ");
    Serial.print(data3);
    Serial.print(" ");
    Serial.print(data4);
    Serial.println(" ");

  }
}      //Lecture du Temps écoulé

Quand vous lisez un registre et que les trois derniers bits sont significatifs, vous récupérez un code binaire sur trois bits qui correspond à une valeur entre 0 et 7, en décimal. Lorsque vous faites un "print" de cette valeur, sans autre formatage explicite, c'est la valeur décimale qui est visible. Soit vous faites la conversion de tête, pour savoir par exemple que "5" correspond à "101", soit vous utilisez un formatage d'impression en binaire avec un printf, soit vous récupérez la valeur à "0" ou "1" du bit qui vous intéresse en faisant un ET logique avec un masque, par exemple :

if (status & 0x04) faireUnTruc () ; // on fait un truc si le bit 2 est à 1

Ça ne fonctionne pas comme ça,

 //déblocage des fonctions avec MDP

  // Chiffre 1 du Mot de Passe
  Wire.beginTransmission(slave_address);
  Wire.write(pass1_address);
  Wire.write(password_digit);
  Wire.endTransmission();
  // Chiffre 2 du Mot de Passe
  Wire.beginTransmission(slave_address);
  Wire.write(pass2_address);
  Wire.write(password_digit);
  Wire.endTransmission();
  // Chiffre 3 du Mot de Passe
  Wire.beginTransmission(slave_address);
  Wire.write(pass3_address);
  Wire.write(password_digit);
  Wire.endTransmission();
  // Chiffre 4 du Mot de Passe
  Wire.beginTransmission(slave_address);
  Wire.write(pass4_address);
  Wire.write(password_digit);
  Wire.endTransmission();

La transmission du mot de passe doit se faire en un seul transfert

 //déblocage des fonctions avec MDP

  // ouverture commande entree mot de passe
  Wire.beginTransmission(slave_address);
  Wire.write(pass1_address);
  // Chiffre 1 du Mot de Passe
  Wire.write(password_digit);
  // Chiffre 2 du Mot de Passe
  Wire.write(password_digit);
  // Chiffre 3 du Mot de Passe
  Wire.write(password_digit);
  // Chiffre 4 du Mot de Passe
  Wire.write(password_digit);
  Wire.endTransmission();

A noter que par défaut la protection par mot de passe n’est pas activée sur un composant neuf, donc si tu ne l’as pas activé toi même, il est inutile de le rentrer.

From the factory, the DS1683 powers up without password protection enabled.

jr2fl:
Re-bonjour,

J’ai aussi tenté de remettre à zéro les compteurs de temps mais je n’arrive pas à remettre des zeros comme valeur.

Tu parles des compteurs de temps. Il n’y a qu’un seul compteur de temps dont la valeur est mémorisé dans 4 octets. Pour le remettre à zéro il faut donc écrire dans les 4 adresses consécutives (0xA - 0xD)
Selon la doc, l’écriture est possible lorsque la pin EVENT est à l’état bas.

When the EVENT pin is low, the ETC register can be written by the I2C bus.

Avec vos explications le fonctionnement est tout de suite beaucoup plus clair, ça éclaire tout ce que je n’avais pas saisi. Malheureusement je n’y arrive toujours pas.

Avec le pin event sur low la console série sort:
Status 1
Event = On
Event Alarm = On
ETC Alarm = On
Time 209 231 172 255

Et quand le pin Event est activé
Status 101
Event = On
Event Alarm = On
ETC Alarm = On
Time 209 231 172 255

Le changement d’état de event est bien répercuté à la lecture mais il y a quelque chose qui ne fonctionne pas pour la lecture de chaque bit.

Pour la remise à zéro du compteur, je n’ai pas activé le mot de passe, j’ai quand même essayé avec et sans, toujours avec le pin event sur low et en appliquant la même méthode que pour mot de passe pour les 4 bytes du compteur de temps mais ça n’a aucun effet.
Merci

[color=#000000]#include <Wire.h>

//Time Elapsed DS1683
const int16_t slave_address = 0x6B; //ADDRESSE DU DS1683
const int16_t register_address_ST = 0x01; //REGISTRE DU STATUS
const int16_t register_address_ET = 0x0A; //REGISTRE DU TEMPS
const int16_t pass1_address = 0x2;
byte password_digit = 0x01;
byte reset_etc = 0x00;

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




  //déblocage des fonctions avec MDP
  //Wire.beginTransmission(slave_address);
  // Wire.write(pass1_address);
  // Chiffre 1 du Mot de Passe
  // Wire.write(password_digit);
  // Chiffre 2 du Mot de Passe
  // Wire.write(password_digit);
  // Chiffre 3 du Mot de Passe
  // Wire.write(password_digit);
  // Chiffre 4 du Mot de Passe
  // Wire.write(password_digit);
  // Wire.endTransmission();



  // RAZ du Registre 1 du capteur
  Wire.beginTransmission(slave_address);
  Wire.write(register_address_ET);
  Wire.write(reset_etc);
  Wire.write(reset_etc);
  Wire.write(reset_etc);
  Wire.write(reset_etc);
  Wire.endTransmission();

}

void loop() {
  GetStatusData();
  GetElapsedTimeData();
  delay(1000);

}


void GetStatusData() {

  Wire.beginTransmission(slave_address);
  Wire.write(register_address_ST);
  Wire.endTransmission();
  Wire.requestFrom(slave_address, 1);
  byte Statusdata = Wire.read();//Status
  Serial.print("Status ");
  Serial.print(Statusdata, BIN); //format BIN
  Serial.println(" ");

  //Show alarms
  Serial.print("Event = ");
  if ((Statusdata && 0x04) == 1) {
    Serial.println("On");
    Serial.println(Statusdata && 0x04);
  }
  else {
    Serial.println("Off");
  }
  Serial.print("Event Alarm = ");
  if ((Statusdata && 0x02) == 1) {
    Serial.println("On");
    Serial.println(Statusdata && 0x02);
  }
  else {
    Serial.println("Off");
  }
  Serial.print("ETC Alarm = ");
  if ((Statusdata && 0x01) == 1) {
    Serial.println("On");
    Serial.println(Statusdata && 0x01);
  }
  else {
    Serial.println("Off");
  }
}//Lecture des Status


void GetElapsedTimeData() {
  Wire.beginTransmission(slave_address);
  Wire.write(register_address_ET);
  Wire.endTransmission();
  Wire.requestFrom(slave_address, 4);
  byte data1 = Wire.read();//Byte 1
  byte data2 = Wire.read(); //Byte 2
  byte data3 = Wire.read(); //Byte 3
  byte data4 = Wire.read(); //Byte 4

  Serial.print("Time ");
  Serial.print(data1);
  Serial.print(" ");
  Serial.print(data2);
  Serial.print(" ");
  Serial.print(data3);
  Serial.print(" ");
  Serial.print(data4);
  Serial.println(" ");

}[/color]

Il y a un petit problème ici (et sur les autres tests aussi)

 if ((Statusdata && 0x04) == 1) {

le && fait une opération logique entre 2 booléns.
Toi tu veux faire un masque sur un byte.
Il faut l'écrire comme ça

 if ((Statusdata & 0x04) != 0) {

ou plus simplement

 if (Statusdata & 0x04) {

Merci pour le correctif, en effet ça fonctionne.
Il semble par contre qu'une alarme soit enregistrée vu qu'il y a un 1 qui ressort même quand le Event est low.(ou alors j'ai toujours rien compris à la doc :grinning: )

Il me reste le souci d'écriture que je n'arrive pas à solutionner, le pin Event est bien sur low mais rien ne s'écrit.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.