Brancher plusieurs ds1820

Bonjour,

Est-il possible de brancher plusieurs capteurs de températures DS1820 sur le même pin ?

Si cela est possible, comment peut-on savoir duquel vient l'information ?

De quelle façon faut-il les brancher, j'ai vu plusieurs façon dont une dites "parasite" ?

selon moi, tu peux brancher plusieurs DS1820 sur une meme fil, ils sont meme faits pour ca...

d'apres la datasheet MAXIM - Dallas Semiconductor DS1820-DS1820S datasheet pdf, c'est du 1-Wire donc il te faut implementer ce protocole par l'arduino.

Pour les differencier, chaque DS1820 possede un identifiant unique sur 64 bits.

Au demarrage, l'arduino doit decouvrir tous les codes des devices presents sur le bus 1-Wire

extrait de la datasheet :

SEARCH ROM [F0h]
When a system is initially powered up, the master must identify the ROM codes of all slave devices on
the bus, which allows the master to determine the number of slaves and their device types. The master
learns the ROM codes through a process of elimination that requires the master to perform a Search ROM
cycle (i.e., Search ROM command followed by data exchange) as many times as necessary to identify all
of the slave devices. If there is only one slave on the bus, the simpler Read ROM command (see below)
can be used in place of the Search ROM process. For a detailed explanation of the Search ROM
procedure, refer to the iButton Book of Standards at iButton Products | Analog Devices. After every
Search ROM cycle, the bus master must return to Step 1 (Initialization) in the transaction sequence.

le protocole 1-Wire a surement deja été implementé pour l'arduino par qqun...

Ce que j'ai trouvé sur la datasheet pour les branchement :

Donc ça devrait permettre de faire ça ?

La façon dont les flux d'informations passent :

Traduit par Google, voici le protocole pour la recherche du "ROM", je supose que c'est le code d'identification de chaque capteur ?

[edit]Exemple d'une ROM de recherche
Le ROM processus de recherche est la répétition d'une simple
3-pas de routine: lire un peu, lire le complément du
bit, puis écrire la valeur désirée que de peu. Le bus maître
s'acquitte de cette simple, 3 étapes de routine sur chaque bit de
la ROM. Après une passe complète, le bus maître
connaît le contenu de la ROM en un seul dispositif. Le
restants nombre de dispositifs et de leurs codes mai ROM
être identifiés par des laissez-passer.
L'exemple suivant de la mémoire morte processus de recherche
suppose quatre différents périphériques sont connectés à la
même 1-Wire bus. Le ROM de données des quatre dispositifs
comme le montre:
Rom1 00110101 ...
ROM2 10101010 ...
ROM3 11110101 ...
ROM4 00010001 ...
Le processus de recherche est la suivante:

  1. Le bus maître commence la séquence d'initialisation par
    une émission d'impulsions de réinitialisation. L'esclave dispositifs de répondre par
    la délivrance de présence simultanée des impulsions.

  2. Le bus master va alors délivrer la recherche ROM
    commande le 1-Wire bus.

  3. Le bus maître lit un peu à partir du 1-Wire bus.
    Chaque appareil répondre en mettant la valeur du
    premier bit de leur ROM de données sur le 1-Wire
    bus. Rom1 et ROM4 mettra un 0 sur la
    1-Wire bus, c'est-à-dire, tirez-le vers le bas. ROM2 et sera ROM3
    1 un lieu sur le 1-Wire bus en permettant à la ligne
    restent élevés. Le résultat est la conséquence logique et de tous les dispositifs
    sur la ligne, donc le bus maître voit un 0. Le
    Bus Master peu un autre lit. Depuis la Recherche
    ROM de données de commande est en cours d'exécution, tous les
    dispositifs sur le 1-Wire bus répondre à cette deuxième
    lire en plaçant le complément de la première peu de leur
    ROM de données respectives sur le 1-Wire bus. Rom1
    ROM4 et mettra un 1 sur le 1-Wire, ce qui permet
    la ligne à rester élevés. ROM2 et ROM3 mettra un
    0 sur le 1-Wire, ainsi il sera tiré faible. Le bus
    capitaine observe à nouveau un 0 pour le complément de la
    ROM premier bit de données. Le bus capitaine a déterminé
    qu'il existe des dispositifs sur le 1-Wire bus qui
    ont un 0 dans la première position et d'autres qui ont un 1.
    DS1820
    021497 11/27
    Les données obtenues de ces deux lectures de l'étape 3 -
    de routine sont les suivantes interprétations:
    00 Il ya encore des dispositifs qui ont
    conflit bits dans cette position.
    01 Tous les dispositifs à couplage ont encore un 0-bit dans ce
    bit.
    10 Tous les dispositifs à couplage ont encore un 1-bit en ce
    bit.
    11 Il n'existe pas de dispositifs pour le 1-Wire
    bus.

  4. Le bus maître écrit un 0. Cette désactive ROM2
    ROM3 et pour le reste de cette recherche passe,
    ne laissant que Rom1 et ROM4 liés à la
    1-Wire bus.

  5. Le bus maître effectue deux autres lectures et
    reçoit un 0-bit suivi par un 1-bit. Cela indique
    que tous les appareils encore couplé à l'autobus ont aussi 0
    leur deuxième ROM bits de données.

  6. Le bus capitaine a ensuite écrit un 0 à conserver les deux Rom1
    ROM4 et couplés.

  7. Le bus maître exécute deux lit et reçoit
    0-deux bits. Cela indique que les deux 1-bits et 0-bits
    exister en tant que troisième bit de la mémoire morte de données ci-joint
    dispositifs.

  8. Le bus maître écrit un 0-bit. Cette désactive Rom1
    ROM4 laissant que le seul appareil toujours branché.

  9. Le bus maître lit le reste de la ROM bits
    pour ROM4 et continue à accéder à la partie si
    désirée. Ceci termine la première passe et unique
    identifie une partie de la 1-Wire bus.

10.Le bus maître débute une nouvelle séquence de recherche ROM
en répétant les étapes 1 à 7.

  1. Le bus maître écrit un 1-bit. Cette dissocie
    ROM4, ne laissant que Rom1 toujours de pair.

12.Le bus maître lit le reste de la ROM bits
pour Rom1 et communique à la logique sous-jacente
si vous le souhaitez. Ceci termine la deuxième ROM de recherche
passer, dans lequel un autre de la ROM a été trouvé.

13.The bus maître débute une nouvelle ROM de recherche en répétant
les étapes 1 à 3.

14.The Bus Master écrit un 1-bit. Cette désélectionne
Rom1 et ROM4 pour le reste de cette recherche
passer, ne laissant que ROM2 et ROM3 attelé à la
système.

15.Le Bus Master lire exécute deux créneaux horaires et
reçoit deux zéros.

16.The Bus Master écrit un 0-bit. Cette dissocie
ROM3, et ne laissant que ROM2.

17.The Bus Master lit le reste de la ROM bits
pour ROM2 et communique à la logique sous-jacente
si vous le souhaitez. Ceci termine la troisième ROM de recherche
passer, dans lequel un autre de la ROM a été trouvé.

18.The bus maître débute une nouvelle ROM de recherche en répétant
les étapes 13 à 15.

19.The Bus Master écrit un 1-bit. Cette dissocie
ROM2, ne laissant que ROM3.

20.The Bus Master lit le reste de la ROM bits
pour ROM3 et communique à la logique sous-jacente
si vous le souhaitez. Ceci termine la quatrième ROM de recherche
passer, dans lequel un autre de la ROM a été trouvé.
Notez les aspects suivants:
Le bus maître apprend le numéro d'identification unique (ROM de données
modèle) d'un 1-Wire sur chaque appareil ROM Recherche
. Le temps requis pour tirer partie de l'unique
Code de la ROM est:
960 ms + (8 + 3 x 64) 61 ms = 13,16 ms
Le bus master est donc en mesure d'identifier 75 différents
1-Wire dispositifs par seconde.[/edit]

Apparement en suivant l'adresse mentionnée, le fichier sample.c serait celui à mettre dans l'arduino :

All packaged in C++ form. Well, not the keywords.txt file. I'm not sure what that is, though I guess it has something to do with the color coding of the build in editor.

http://www.federated.com/~jim/onewire/ contains the library and a sample program. Feel free to vacuum it up into anything you like.

This library is general 1-wire. It might be nice to derive a DS18S20 class from this that knows about temperature to handle the conversions, or that might start making too much object code. Maybe I'm being too sensitive to code bloat, but it seems that higher level libraries will end up containing a lot of unused functions for any given application. e.g. I won't use the alarm threshold registers in my application but I'd end up with functions for them linked into my code. I had enough worry about that in just the generic functions that I ended up with a couple nasty preprocessor symbols to omit some of the larger functions that people might not need.

Pour suivre ce fil de discussion:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1161557194/30

J'ai branché deux ds18B20 sur mon arduino comme indiqué plus haut, et j'ai mis le sketch"sample.c".

la console série me sort ceci :

Le problème est que le capteur n'est pas reconnu comme un DS1820 :

does any one know if this works with the DS18B20...

I have it hooked up per everything I have found here, in parasite mode, and all get is this

R=28 92 F1 7D 1 0 0 34 Device is not a DS18S20 family device

any ideas?

Solutions :

Yes I ran into that too, as I reported elsewhere - the family code for the 18B20 is different from that for the 18S20. (There's a note one the Arduino OneWire page that mentions this.) Just replace the family code in the test (0x28) with the one for the 18B20 (0x10). For the record, the DS1822 thermometer has yet another family code (0x22).

J'ai donc changé le 0x10 par 0x28 et maintenant j'ai ça :

Ce sketch semble servir à determiner les N° ROM des capteurs.

Je ne sais pas à quoi correspondent "P" et "CRC".

"P" serait le Scratchpad du DS1820 et "CRC" un contrôle pour voir si la mesure renvoyée est correcte (?)...

Le Scratchpad pour le DS18B20 est composé comme cela :

Donc dans la console série ce serait ça :

Je peux retirer ces deux Bytes de la chaine en utilisant data[0] et data[1].

Actuellement je n'arrive pas à convertir ces deux Bytes en °C , il me semblait qu'en additionnant LSB à MSB et en les affichant en décimal j'aurais un affichage correct de la température, mais je me retrouve avec "120" pour 23,3 °Celcius.

J'ai trouvé un code qui semble afficher des °C et °F :

http://www.netfluvia.org/code/ds18B20_test.pde

Voici l'extrait qui m'intéresse :

 /* compute the degrees in celcius / integer part */
  temp_c_int = 0;
  
  /* The measured temp is spread across two bytes of the returned data.
   *  The integer part of the temp value is spread across the least 3 significant
   *  bits of the most significant byte (MSB) and the most significant 4 of 
   *  the LSB.  Here we shift those 7 bits into their proper place in our
   *  result byte. 
   *
   * note: could do this with 2 bit-shift / mask operations, alternatively
   */
  set_bit = 6;
  for (test_bit = 2; test_bit >= 0; test_bit--) {
    temp_c_int |= ( ((data[TEMP_MSB] & (1 << test_bit)) >> test_bit) << set_bit );
    set_bit--;
  }
  for (test_bit = 7; test_bit >= 4; test_bit--) {
    temp_c_int |= ( ((data[TEMP_LSB] & (1 << test_bit)) >> test_bit) << set_bit );
    set_bit--;
  }

#ifdef DEBUG
  Serial.print(temp_c_int,DEC);
#endif

  /* compute the fractional part */

  /*  first figure out what resolution we're measuring in - varies between 1 and 4 bits
   *    after the decimal (based on the contents of the CONFIG_REG byte):
   *        bit 6 == 0 && bit 5 == 0 --> 9-bit resolution (ignore 3 least sig bits)
   *        bit 6 == 0 && bit 5 == 1 --> 10-bit resolution (ignore 2 least sig bits)
   *        bit 6 == 1 && bit 5 == 0 --> 11-bit resolution (ignore 1 least sig bits)
   *        bit 6 == 1 && bit 5 == 1 --> 12-bit resolution   
   */
  if ((data[CONFIG_REG] & (1 << 5)) > 0) {        
    if ((data[CONFIG_REG] & (1 << 4)) > 0) {      // bits 6 and 5 are set
      resolution_floor = 3;
    } else {                                      // bit 6 is set, 5 is clear
      resolution_floor = 2;
    }
  } else {
    if ((data[CONFIG_REG] & (1 << 4)) > 0) {      // bits 6 is clear, 5 is set
      resolution_floor = 1;
    } else {                                      // bit 6 and 5 are clear
      resolution_floor = 0;
    }
  }    

  temp_c_frac = 0;
  for (test_bit = 3; test_bit >= resolution_floor; test_bit--) {
    if ((data[TEMP_LSB] & (1 << test_bit)) > 0) {
      expon = test_bit - 4; // will be negative
      temp_c_frac += pow(2,expon);
    }
  }
#ifdef DEBUG
  Serial.print(" ");
  Serial.print(temp_c_frac * 10000,DEC);
#endif

  /* put it all together */
  temp_c = (float)temp_c_int + temp_c_frac;  

  if ((data[TEMP_MSB] & (1 << 7)) > 0) {   // the temp is negative
    temp_c *= -1;
  }

  temp_f = c2f(temp_c);
  
  Serial.print(" Cx10k=");
  Serial.print(temp_c * 10000,DEC); // Serial.print truncates after the decimal pt
  Serial.print(" Fx10k=");
  Serial.print(temp_f * 10000,DEC);
  
  Serial.print("\n");  
}

J'ai rajouté ça dans Sample.c en enlevant les parties qui ne m'intéressaient pas :

#include <OneWire.h>

/* DS18S20 Celcius degrees */


#define TEMP_LSB 0
#define TEMP_MSB 1
#define CONFIG_REG 4

OneWire  ds(10);  // on pin 10

void setup(void) {

  Serial.begin(9600);
}

void loop(void) {
  
  byte i;
  byte data[12];
  byte addr[8];
  byte present = 0;
  
  int set_bit;
  int resolution_floor;
  int msb,lsb,T;
  int temp_c_int;
  int test_bit;
  
  float expon;
  float temp_c_frac;
  float temp_c;
  float temp_f;
  
  if ( !ds.search(addr)) {
      Serial.print("No more addresses.\n");
      ds.reset_search();
      return;
  }
  
  Serial.print("R=");
  for( i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX);
    Serial.print(" ");
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.print("CRC is not valid!\n");
      return;
  }
  
  if ( addr[0] != 0x28) {
      Serial.print("Device is not a DS18B20 family device.\n");
      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
}

   /* compute the degrees in celcius / integer part */
  
  /* The measured temp is spread across two bytes of the returned data.
   *  The integer part of the temp value is spread across the least 3 significant
   *  bits of the most significant byte (MSB) and the most significant 4 of 
   *  the LSB.  Here we shift those 7 bits into their proper place in our
   *  result byte. 
   *
   * note: could do this with 2 bit-shift / mask operations, alternatively
   */
    temp_c_int = 0;
    set_bit = 6;
for (test_bit = 2; test_bit >= 0; test_bit--) {
    temp_c_int |= ( ((data[TEMP_MSB] & (1 << test_bit)) >> test_bit) << set_bit );
    set_bit--;
}
for (test_bit = 7; test_bit >= 4; test_bit--) {
    temp_c_int |= ( ((data[TEMP_LSB] & (1 << test_bit)) >> test_bit) << set_bit );
    set_bit--;
}

  /* compute the fractional part */

  /*  first figure out what resolution we're measuring in - varies between 1 and 4 bits
   *    after the decimal (based on the contents of the CONFIG_REG byte):
   *        bit 6 == 0 && bit 5 == 0 --> 9-bit resolution (ignore 3 least sig bits)
   *        bit 6 == 0 && bit 5 == 1 --> 10-bit resolution (ignore 2 least sig bits)
   *        bit 6 == 1 && bit 5 == 0 --> 11-bit resolution (ignore 1 least sig bits)
   *        bit 6 == 1 && bit 5 == 1 --> 12-bit resolution   
   */
if ((data[CONFIG_REG] & (1 << 5)) > 0) {        
  if ((data[CONFIG_REG] & (1 << 4)) > 0) {      // bits 6 and 5 are set
      resolution_floor = 3;
    } else {                                      // bit 6 is set, 5 is clear
      resolution_floor = 2;
    }
    } else {
    if ((data[CONFIG_REG] & (1 << 4)) > 0) {      // bits 6 is clear, 5 is set
      resolution_floor = 1;
    } else {                                      // bit 6 and 5 are clear
      resolution_floor = 0;
    }
}    

  temp_c_frac = 0;
for (test_bit = 3; test_bit >= resolution_floor; test_bit--) {
    if ((data[TEMP_LSB] & (1 << test_bit)) > 0) {
      expon = test_bit - 4; // will be negative
      temp_c_frac += pow(2,expon);
    }
}

  /* put it all together */
  temp_c = (float)temp_c_int + temp_c_frac;  

if ((data[TEMP_MSB] & (1 << 7)) > 0) {   // the temp is negative
    temp_c *= -1;
}
  
  
  Serial.print("   Temp en C= ");
  Serial.print(temp_c_int,DEC);
  Serial.print(".");
  Serial.print(temp_c_frac * 100,DEC);
  Serial.println();  
}

A la console série :

La mesure est au demi degrés près.

Cette partie de code sert à déterminer la résolution des capteurs, je l'ai supprimée :

  /* compute the fractional part */

  /*  first figure out what resolution we're measuring in - varies between 1 and 4 bits
   *    after the decimal (based on the contents of the CONFIG_REG byte):
   *        bit 6 == 0 && bit 5 == 0 --> 9-bit resolution (ignore 3 least sig bits)
   *        bit 6 == 0 && bit 5 == 1 --> 10-bit resolution (ignore 2 least sig bits)
   *        bit 6 == 1 && bit 5 == 0 --> 11-bit resolution (ignore 1 least sig bits)
   *        bit 6 == 1 && bit 5 == 1 --> 12-bit resolution   
   
if ((data[CONFIG_REG] & (1 << 5)) > 0) {        
  if ((data[CONFIG_REG] & (1 << 4)) > 0) {      // bits 6 and 5 are set
      resolution_floor = 3;
    } else {                                      // bit 6 is set, 5 is clear
      resolution_floor = 2;
    }
    } else {
    if ((data[CONFIG_REG] & (1 << 4)) > 0) {      // bits 6 is clear, 5 is set
      resolution_floor = 1;
    } else {                                      // bit 6 and 5 are clear
      resolution_floor = 0;
    }
}

J'ai modifié ça :

  int resolution_floor = 1;   //for setting resolution 0 = High-resolution , 3 = Low resolution

Si "resolution_floor" est mis à 3, la résolution est basse, si il est mis à 0 elle devient élevée (permet l'utilisation des chiffres après la virgule, ici 3 chiffres) .

Et j'ai enlevé également ça qui ne sert plus :

#define CONFIG_REG 4

Il faut encore multiplier la fraction pour le nombre de chiffres à afficher après la virgule :

Serial.print(temp_c_frac * 1000,DEC);

A la console série :

Bonjour,

peux-tu nous fournir le contenu du fichier Sample.c que tu as après modification/amelioration ?

je vais démarrer des tests avec mes capteurs très bientot.

merci...

Gromain

Voici le code Sample.c :

#include <OneWire.h>

/* DS18S20 Temperature chip i/o
 
 */

OneWire  ds(10);  // on pin 10

void setup(void) {
  // initialize inputs/outputs
  // start serial port
  Serial.begin(9600);
}



void loop(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  
  if ( !ds.search(addr)) {
      Serial.print("No more addresses.\n");
      ds.reset_search();
      return;
  }
  
  Serial.print("R=");
  for( i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX);
    Serial.print(" ");
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.print("CRC is not valid!\n");
      return;
  }
  
  if ( addr[0] != 0x10) {
      Serial.print("Device is not a DS18S20 family device.\n");
      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("P=");
  Serial.print(present,HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print( OneWire::crc8( data, 8), HEX);
  Serial.println();
}

et le code Celsius_18b20.pde :

#include <OneWire.h>

/* DS18S20 Celcius degrees */


#define TEMP_LSB 0
#define TEMP_MSB 1
//#define CONFIG_REG 4

OneWire  ds(10);  // on pin 10

void setup(void) {

  Serial.begin(9600);
}

void loop(void) {
  
  byte i;
  byte data[12];
  byte addr[8];
  byte present = 0;
  
  int set_bit;
  int resolution_floor = 1;   //for setting resolution 0 = High-resolution , 3 = Low resolution
  int msb,lsb,T;
  int temp_c_int;
  int test_bit;
  
  float expon;
  float temp_c_frac;
  float temp_c;
  float temp_f;
  
  if ( !ds.search(addr)) {
      Serial.print("No more addresses.\n");
      ds.reset_search();
      return;
  }
  
  Serial.print("R=");
  for( i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX);
    Serial.print(" ");
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.print("CRC is not valid!\n");
      return;
  }
  
  if ( addr[0] != 0x28) {
      Serial.print("Device is not a DS18B20 family device.\n");
      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

for ( i = 0; i < 12; i++) {           // we need 9 bytes
    data[i] = ds.read();
}

   /* compute the degrees in celcius / integer part */
  
  /* The measured temp is spread across two bytes of the returned data.
   *  The integer part of the temp value is spread across the least 3 significant
   *  bits of the most significant byte (MSB) and the most significant 4 of 
   *  the LSB.  Here we shift those 7 bits into their proper place in our
   *  result byte. 
   *
   * note: could do this with 2 bit-shift / mask operations, alternatively
   */
    temp_c_int = 0;
    set_bit = 6;
for (test_bit = 2; test_bit >= 0; test_bit--) {
    temp_c_int |= ( ((data[TEMP_MSB] & (1 << test_bit)) >> test_bit) << set_bit );
    set_bit--;
}
for (test_bit = 7; test_bit >= 4; test_bit--) {
    temp_c_int |= ( ((data[TEMP_LSB] & (1 << test_bit)) >> test_bit) << set_bit );
    set_bit--;
}

  /* compute the fractional part */

  /*  first figure out what resolution we're measuring in - varies between 1 and 4 bits
   *    after the decimal (based on the contents of the CONFIG_REG byte):
   *        bit 6 == 0 && bit 5 == 0 --> 9-bit resolution (ignore 3 least sig bits)
   *        bit 6 == 0 && bit 5 == 1 --> 10-bit resolution (ignore 2 least sig bits)
   *        bit 6 == 1 && bit 5 == 0 --> 11-bit resolution (ignore 1 least sig bits)
   *        bit 6 == 1 && bit 5 == 1 --> 12-bit resolution   
   
if ((data[CONFIG_REG] & (1 << 5)) > 0) {        
  if ((data[CONFIG_REG] & (1 << 4)) > 0) {      // bits 6 and 5 are set
      resolution_floor = 3;
    } else {                                      // bit 6 is set, 5 is clear
      resolution_floor = 2;
    }
    } else {
    if ((data[CONFIG_REG] & (1 << 4)) > 0) {      // bits 6 is clear, 5 is set
      resolution_floor = 1;
    } else {                                      // bit 6 and 5 are clear
      resolution_floor = 0;
    }
}    */

  temp_c_frac = 0;
for (test_bit = 3; test_bit >= resolution_floor; test_bit--) {
    if ((data[TEMP_LSB] & (1 << test_bit)) > 0) {
      expon = test_bit - 4; // will be negative
      temp_c_frac += pow(2,expon);
    }
}

  /* put it all together */
  temp_c = (float)temp_c_int + temp_c_frac;  

if ((data[TEMP_MSB] & (1 << 7)) > 0) {   // the temp is negative
    temp_c *= -1;
}
  
  
  Serial.print("   Temp en C= ");
  Serial.print(temp_c_int,DEC);
  Serial.print(".");
  Serial.print(temp_c_frac * 10000,DEC);
  Serial.println();  
}

Bonjour, je rencontre quelques problèmes pour faire fonctionner ce bus 1-Wire.

Je le programme par un pic 16F84A qui lui-même est programmé en assembleur, voici la séquence de programmation que j'utilise, puis le programme. Le but est de lui donner deux seuils de température, puis de le mettre en mode thermostat.

Séquence de programmation :

1 RESET puis attente de réponse (800µs)
2 SKIP ROM (on passe la rom car un seul bus)
3 ENVOIE de la commande 4Eh pour écrire dans le scratchpad
4 ENVOIE du premier byte TH, puis envoie du deuxième byte TL
5 RESET puis attente de réponse (800µs)
6 SKIP ROM
7 ENVOIE de la commande 48h pour copier le scratchpad dans l'EEPROM
8 RESET puis attente de réponse (800µs)
9 SKIP ROM
10 ENVOIE de la commande ECh pour le mettre en mode thermostat
FIN

Voilà, cela ne fonctionne pas et je ne comprends pas pourquoi, j'ai utiliser un temps de 1µs entre chaque bit lorsque j'envoie un byte.

Pour info, voici le programme complet, si quelqu'un peut m'aider, cela serait génial car je suis pris avec le temps pour un TFE.

Bonjour,

je déterre un peu ce post.
J'ai chez moi 3 DS18B20:

  • 2 sont connectés à l'extrémité d'une branche d'une vingtaine de mètre
  • le 3eme est connecté sur une autre branche de 10 mètres env.
  • ces 2 branches sont connectées entre-elles juste avant d'attaquer l'interface (=> réseau en "étoile")
  • Chaque capteur est connecté à Vdd, Gnd et Data (=> pas en mode parasite)

Le tout fonctionne bien avec le convertisseur PC USB-1Wire, je vois les 3 capteurs.
Par contre, connectés à l'arduino je ne sais détecter que les branches séparément. Si je connecte les 2 branches ensembles, j'ai plein d'erreur de CRC (CRC is not valid!) et je suis incapable de récupérer les données: les données reçues changent sans arrêt. J'utilise le code de Jean-François ci-dessus pour mes tests.

c'est idem lorsque je les branche en mode parasite (Vdd et Gnd reliées)

Je ne comprend pas trop pourquoi ca fonctionne avec le convertisseur USB et pas avec l'arduino...

Est-ce que quelqu'un a un réseau 1-Wire fonctionnel avec Arduino ?
Le fait que le réseau soit en étoile pose-t-il problème ?

merci d'avance si vous avez des pistes...

Bon, j'ai trouvé une parade en affectant chaque branche à une pin différente.
Au lieu de créer une fois l'objet "ds" OneWire en début de sketch comme dans le code exemple, je crée l'objet ds à chaque appel de la fonction de lecture en changeant le n° de pin.
J'en ai profité pour créer une table contenant les noms des capteurs à interroger, ça m'évite d'utiliser la fonction search.

Salut,
Gromain, peux-tu uploader ton code stp. malgré mes effort pour detecter mon DS18S20 j'ai du mal a récupérer le CRC. Merci d'avance

Salut,

Mon code oblige de connaitre les adresses auparavant donc il ne te sera pas utile pour ton problème de CRC (j'ai supprimé la fonction search).
J'utilise le code exemple fournit avec la librairie OneWire pour faire mes tests et récupérer les adresses des capteurs.
Si tu as un problème avec les CRC (message "CRC is not valid!"), vérifies d'abord ton câblage (mode parasite ou non, présence de la résistance entre la pin DQ et +5v).
Si tu as un circuit en étoile avec des branches assez longues, alors c'est probablement la cause de tes problèmes. Mais je crois comprendre que tu n'as qu'un DS18S20.
Si tu es en mode parasite (pin GND et Vdd ensemble), vérifies que le second paramètre dans la méthode write est bien à 1

ds.write(0x44,1);         // start conversion, with parasite power on at the end

Je te déconseille d'utiliser le mode parasite si tu as besoin de récupérer très fréquemment les données, surtout si tu as plusieurs capteurs.

pour rappel:

Je ne peux pas te fournir mon code dans l'immédiat, je ne l'ai pas avec moi et suis en déplacement. Tiens nous au courant de l'avancé de tes problèmes.

Qqun interessé pour avoir un code qui remprésente 2 températures de 2 sondes sur un écran LCD?

Postes toujours :wink:

Salut
Je suis intéresse par ton code

Merci