Je viens à vous pour savoir si quelqu'un ne possèderait pas un programme arduino pour deux capteurs DS18b20 connectés sur 2 pins différentes. J'ai un programme qui marche pour un seul capteur et j'essaye de le modifier pour avoir les deux capteurs qui s'affichent mais sans succès alors je poste ce message.
#include <OneWire.h>
const int broche_OneWire=10;
const int modeLecture=0xBE;
const int lancerMesure=0x44;
byte data[12];
byte adresse[8];
int tempet=0;
float tempetf=0.0;
OneWire capteur(broche_OneWire);
void setup() {
Serial.begin(9600);
Serial.println("**** Detection du capteur **** ");
while (capteur.search(adresse)== false)
{
Serial.println("Aucun capteur 1-wire present sur la broche ! ");
delay (1000);
}
Serial.print ("1 capteur 1-wire present avec code adresse 64 bits : ");
for(int i = 0; i < 8; i++) {
if (adresse[i]<16) Serial.print('0');
Serial.print(adresse[i], HEX);
Serial.print(" ");
}
Serial.println();
if (adresse[0]==0x28)
{
Serial.println ("Type du capteur present : Capteur temperature DS18B20.");
}
else
{
Serial.println ("Le capteur present n'est pas un capteur de temperature DS18B20.");
}
if (capteur.crc8( adresse, 7) == adresse[7])
{
Serial.println ("Verification du code CRC de l'adresse 64 bits de ce capteur : VALIDE !");
}
else
{
Serial.println ("Verification du code CRC de l'adresse 64 bits de ce capteur : NON VALIDE !");
}
//------- message final détection ----
Serial.println("----- fin de la recherche du capteur ----");
Serial.println("");
}
void loop(){
Serial.println("**** Acquisition d'une mesure de la temperature **** ");
capteur.reset();
capteur.select(adresse);
capteur.write(lancerMesure,1);
delay(1000);
capteur.reset();
capteur.select(adresse);
capteur.write(modeLecture,1);
for ( int i = 0; i < 9; i++) {
data[i] = capteur.read();
}
Serial.println("");
Serial.println("---- lecture de la RAM du capteur ---- ");
Serial.print("Octet 0 (Resultat poids faible)="), Serial.println(data[0],BIN);
Serial.print("Octet 1 (Resultat poids fort)="), Serial.println(data[1],BIN);
Serial.print("Octet 2 (Alarme haute)="), Serial.println(data[2],BIN);
Serial.print("Octet 3 (Alarme basse)="), Serial.println(data[3],BIN);
Serial.print("Octet 4 (Registre de configuration)="), Serial.println(data[4],BIN);
Serial.print("Octet 5 (Reserve)="), Serial.println(data[5],BIN);
Serial.print("Octet 6 (Reserve)="), Serial.println(data[6],BIN);
Serial.print("Octet 7 (Reserve)="), Serial.println(data[7],BIN);
Serial.print("Octet 8 (code CRC mesure)="), Serial.println(data[8],BIN);
//----- test de validité des valeurs reçues par contrôle du code CRC ----
Serial.println("");
Serial.println("---- test de controle de validite des donnees recues ---- ");
// le dernier (9ème) octet de la RAM est un code de contrôle CRC
// à l'aide de la fonction crc8 on peut vérifier si ce code est valide
if (capteur.crc8( data, 8) == data[8]) // vérification validité code CRC des valeurs reçues
{
Serial.println ("Verification du code CRC de ce resultat : VALIDE !");
}
else
{
Serial.println ("Verification du code CRC de ce resultat : NON VALIDE !");
}
//----- caclul de la température mesurée (enfin!) ---------
Serial.println("");
Serial.println("---- calcul de la temperature ---- ");
//---- extraction du résultat de la mesure à partir des registres de la RAM ---
data[1]=data[1] & B10000111; // met à 0 les bits de signes inutiles
tempet=data[1]; // bits de poids fort
tempet=tempet<<8;
tempet=tempet+data[0]; // bits de poids faible
Serial.print ("Mesure brute =");
Serial.println (tempet);
// --- en mode 12 bits, la résolution est de 0.0625°C - cf datasheet DS18B20
tempetf=float(tempet)*6.25;
tempetf=tempetf/100.0;
Serial.print ("Mesure Finale =");
Serial.print (tempetf,2);
Serial.println (" Degres Celsius. ");
//while(1); // stoppe loop
} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
// ********************************************************************************
//*************** Autres Fonctions du programme *************
// --- Fin programme ---
Le problème, si je connecte les deux capteurs sur la même pin, le programme m'en reconnait qu'un seul et ne laisse pas le choix de choisir l'un ou l'autre ! c'est çà que je ne comprends pas dans votre réponse
Voici un exemple bien documenté tiré du site de X. HINAULT qui permet la détection de capteurs 18B20.
// --- Programme Arduino ---
// Copyright X. HINAULT - Créé le 10/04/2010
// www.mon-club-elec.fr
// Code sous licence GNU GPL :
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// --- Que fait ce programme ? ---
/* test simple de la détection des capteurs
de température One-wire de type DS18B20
présents sur une broche de la carte Arduino
*/
// --- Fonctionnalités utilisées ---
// Utilise la connexion série vers le PC
// Utilise un ou plusieurs capteurs One Wire
// --- Circuit à réaliser ---
// Connexion série entre la carte Arduino et le PC (utilise les broches 0 et 1)
// Connecter sur la broche 9 la broche de données du capteur One Wire
//**************** Entête déclarative *******
// A ce niveau sont déclarées les librairies, les constantes, les variables...
// --- Inclusion des librairies utilisées ---
#include <OneWire.h> // librairie pour capteur OneWire
// --- Déclaration des constantes ---
// --- constantes des broches ---
const int broche_OneWire=10; //declaration constante de broche
// --- Déclaration des variables globales ---
byte data[12]; // Tableau de 12 octets pour lecture des 9 registres de RAM et des 3 registres d'EEPROM du capteur One Wire
byte adresse[8]; // Tableau de 8 octets pour stockage du code d'adresse 64 bits du composant One Wire
int compt=0; // variable de comptage du nombre de capteurs sur le bus One Wire
// --- Déclaration des objets utiles pour les fonctionnalités utilisées ---
OneWire capteur(broche_OneWire); // crée un objet One Wire sur la broche voulue
//**************** FONCTION SETUP = Code d'initialisation *****
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme
void setup() { // debut de la fonction setup()
// --- ici instructions à exécuter au démarrage ---
Serial.begin(115200); // initialise connexion série à 115200 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission
//---- détection des capteurs présents sur le bus One Wire
Serial.println("*** Liste des elements presents sur le bus 1-wire *** ");
while (capteur.search(adresse)== true) // tant qu'un nouveau capteur est détecté
{
// la fonction search renvoie la valeur VRAI si un élément 1-wire est trouvé. Stocke son adresse dans le tableau adresse
// adresse correspond à l'adresse de début du tableau adresse[8] déclaré ...
// ce code est exécuté pour chaque capteur détecté
compt=compt+1; // incrémente la variable de comptage du nombre de compteurs
Serial.print ("Numero ");
Serial.print (compt);
Serial.print (": 1 capteur 1-wire present avec code adresse 64 bits : ");
//--- affichage des 64 bits d'adresse au format hexadécimal
for(int i = 0; i < 8; i++) { // l'adresse renvoyée par la fonction search est stockée sur 8 octets
if (adresse[i]<16) Serial.print('0'); // pour affichage des O poids fort au format hexadécimal
Serial.print(adresse[i], HEX); // affiche 1 à 1 les 8 octets du tableau adresse au format hexadécimal
Serial.print(" ");
}
Serial.println();
//---- test du type de capteur ----
// le type du capteur est donné par le 1er octet du code adresse 64 bits
// Valeur 0x28 pour capteur type DS18B20, 0x10 pour type DS18S20, 0x22 pour type DS1820
if (adresse[0]==0x28) Serial.println ("Type : Capteur temperature DS18B20.");
//----- contrôle du code CRC ----
// le dernier octet de l'adresse 64bits est un code de contrôle CRC
// à l'aide de la fonction crc8 on peut vérifier si ce code est valide
if (capteur.crc8( adresse, 7) == adresse[7]) // vérification validité code CRC de l'adresse 64 bits
// le code CRC de l'adresse 64 bits est le 8ème octet de l'adresse (index 7 du tableau)
{
Serial.println ("Verification du code CRC de l'adresse 64 bits de ce capteur : VALIDE !");
}
else
{
Serial.println ("Verification du code CRC de l'adresse 64 bits de ce capteur : NON VALIDE !");
}
Serial.println("------------");
} // fin boucle while test présence capteur
if (compt==0) // si aucun capteur n'a été détecté
{
Serial.println("Aucun capteur present sur le bus 1-wire"); // affiche message + saut de ligne
}
else // si au moins 1 capteur a été détecté
{
Serial.print(compt); // affiche nombre de capteurs détectés
Serial.println (" capteur(s) detecte(s) sur ce bus 1-wire"); // affiche message + saut de ligne
Serial.println ("**** Recherche terminee - fin de liste **** "); // affiche message + saut de ligne
}
} // fin de la fonction setup()
// ********************************************************************************
//*************** FONCTION LOOP = Boucle sans fin = coeur du programme *************
// la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension
void loop(){ // debut de la fonction loop()
// --- ici instructions à exécuter par le programme principal ---
} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
// ********************************************************************************
//*************** Autres Fonctions du programme *************
// --- Fin programme ---
Il ne reste plus qu'à calculer et afficher la température.
D'autres exemples sont fournis sur cet excellent site.
Salutations.
ci-dessous un exemple fonctionnel de gestion de multiple DS18b20 que j'avais déjà publié sur l'ancien forum.
Le code est configuré pour un fonctionnement en mode parasite (2 fils). Si tu utilises le mode normal, les performances seront améliorées (tps de réponse plus court), mais il faudra modifier quelques paramètres (voir dans les commentaires).
Configure NBRE_CAPTEUR en fonction du nombre DS18b20
Configure les instances de temperature[] (adresse du DS18b20, la pin sur lequel il est connecté, et un petit nom)
Tu peux bien sur affecter plusieurs fois la même pin...
#include <stdio.h>
#include <string.h>
#include <OneWire.h>
#define NBRE_CAPTEUR 1 // nombre de capteur sur l'arduino
// *********** declararation des variables gestion des capteurs de temperature *******************
typedef struct Temperature Temperature;
struct Temperature
{
float valeur; // temperature en Celsius, 1 chiffre apres la virgule
byte addr[8]; // identifiant capteur
int pin; // numero de pin a utiliser
char mnemo[32]; // mnemonique de la variable
};
Temperature temperature[NBRE_CAPTEUR]; //creation des instances
// *********** fin declararation des variables gestion des capteurs de temperature *******************
void setup(){
Serial.begin(9600); // initialisation de la liaison serie
// *********** initialisation des variables gestion des capteurs de temperature *******************
temperature[0].addr[0]= 0x10; // identifiant capteur
temperature[0].addr[1]= 0x5;
temperature[0].addr[2]= 0x81;
temperature[0].addr[3]= 0x94;
temperature[0].addr[4]= 0x1;
temperature[0].addr[5]= 0x8;
temperature[0].addr[6]= 0x0;
temperature[0].addr[7]= 0x24;
temperature[0].pin=4;
temperature[0].valeur=0; // temperature en °C, 1 chiffre apres la virgule
strcpy(temperature[0].mnemo,"temp_salon"); // ex: salon
}
void loop(){
gestion_temperature();
delay(5000);
}
void gestion_temperature()
{
/********************************************************************************
Cette fonction permet d'interroger tous les capteurs de temperature OneWire
qui ont ete declare dans "temperature[i]"
********************************************************************************/
byte i=0;
for(i=0; i<NBRE_CAPTEUR; i++){
Serial.print(temperature[i].mnemo);
Serial.print(" => ");
temperature[i].valeur =getStuff(temperature[i].addr,temperature[i].pin);
Serial.print(temperature[i].valeur);
Serial.println(" C ");
delay(100);
}
}
float getStuff(byte addr[8], int pin) // indiquer le n? de pin ? utiliser
{
/********************************************************************************
Cette fonction permet d'interroger le capteur de temperature OneWire
qui a ?t? d?clar? dans "temperature[i]"
********************************************************************************/
OneWire ds(pin); // creation d'un objet OneWire avec le bon n? de pin
byte i;
byte present = 0;
byte data[12];
float real_temp;
float temp_count;
float read_temp;
// Fonction recherche d?sactiv?e car non utilis?e
/*if ( !ds.search(addr)) {
Serial.print("No more addresses.\n");
ds.reset_search();
}
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 998;
}
if ( addr[0] != 0x10) {
Serial.print("Device is not a DS18S20 family device.\n");
return 999;
}
*/
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power off at the end (1=parasite mode)
delay(1000); // delay de 1s si mode parasite. 100ms en mode normal
// 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();
}
read_temp=((data[1]<<8) | data[0]) >> 1 ; // Divide the temperature by 2
temp_count=float(data[7] - data[6])/(float)data[7]; // Convert to real temperature
real_temp = ((float)read_temp-0.25)+temp_count;
// arrondi 1 chiffre apres la virgule
int temp = real_temp*10;
real_temp = (float)temp/10;
// Serial.println();
return real_temp;
}
Si tu ne connais pas l'adresse de tes DS18b20, décommente provisoirement les lignes, ou plus simple, utilises le code sample.c fournis avec la lib OneWire pour déterminer toutes les adresses.
Bonjour, merci beaucoup pour toutes ces infos, par ctre un soucis que je rencontre c'est que je ne possède pas les librairies string et stdio sur arduino et j'ai la version 022. Est ce que ces librairies se trouvent quelque part?
<stdio.h> et <string.h> sont des bibliothèques standard du C, elles sont donc incluent dans l'IDE arduino.
Je ne pense pas que tu auras de problème de compilation à ce niveau là.
Quel est ton problème ? c'est à la compilation ? une fois chargé ?
Si c'est à la compilation, tu peux toujours coller ici un extrait des erreurs que tu as.
A la compilation, je n'ai pas d'erreur, c'est juste à l'affichage que j'ai 0° et -1.20°. J'ai affecté le numéro de pin :
int pin[10]; Est ce que c'est comme cela qu'il faut l'affecter ?
J'ai défini le NBRE_CAPTEUR 2
#include <stdio.h>
#include <string.h>
#include <OneWire.h>
#define NBRE_CAPTEUR 2 // nombre de capteur sur l'arduino
// *********** declararation des variables gestion des capteurs de temperature *******************
typedef struct Temperature Temperature;
struct Temperature
{
float valeur; // temperature en Celsius, 1 chiffre apres la virgule
byte addr[8]; // identifiant capteur
int pin[10]; // numero de pin a utiliser
char mnemo[32]; // mnemonique de la variable
};
Temperature temperature[NBRE_CAPTEUR]; //creation des instances
// *********** fin declararation des variables gestion des capteurs de temperature *******************
void setup(){
Serial.begin(9600); // initialisation de la liaison serie
// *********** initialisation des variables gestion des capteurs de temperature *******************
temperature[0].addr[0]= 0x10; // identifiant capteur
temperature[0].addr[1]= 0x5;
temperature[0].addr[2]= 0x81;
temperature[0].addr[3]= 0x94;
temperature[0].addr[4]= 0x1;
temperature[0].addr[5]= 0x8;
temperature[0].addr[6]= 0x0;
temperature[0].addr[7]= 0x24;
temperature[0].pin;
temperature[0].valeur=0; // temperature en °C, 1 chiffre apres la virgule
strcpy(temperature[0].mnemo,"temp_salon"); // ex: salon
}
void loop(){
gestion_temperature();
delay(5000);
}
void gestion_temperature()
{
/********************************************************************************
Cette fonction permet d'interroger tous les capteurs de temperature OneWire
qui ont ete declare dans "temperature[i]"
********************************************************************************/
byte i=0;
for(i=0; i<NBRE_CAPTEUR; i++){
Serial.print(temperature[i].mnemo);
Serial.print(" => ");
temperature[i].valeur =getStuff(temperature[i].addr,temperature[i].pin[10]);
Serial.print(temperature[i].valeur);
Serial.println(" C ");
delay(100);
}
}
float getStuff(byte addr[8], int pin) // indiquer le n? de pin ? utiliser
{
/********************************************************************************
Cette fonction permet d'interroger le capteur de temperature OneWire
qui a ?t? d?clar? dans "temperature[i]"
********************************************************************************/
OneWire ds(pin); // creation d'un objet OneWire avec le bon n? de pin
byte i;
byte present = 0;
byte data[12];
float real_temp;
float temp_count;
float read_temp;
// Fonction recherche d?sactiv?e car non utilis?e
/*if ( !ds.search(addr)) {
Serial.print("No more addresses.\n");
ds.reset_search();
}
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 998;
}
if ( addr[0] != 0x10) {
Serial.print("Device is not a DS18S20 family device.\n");
return 999;
}
*/
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power off at the end (1=parasite mode)
delay(1000); // delay de 1s si mode parasite. 100ms en mode normal
// 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();
}
read_temp=((data[1]<<8) | data[0]) >> 1 ; // Divide the temperature by 2
temp_count=float(data[7] - data[6])/(float)data[7]; // Convert to real temperature
real_temp = ((float)read_temp-0.25)+temp_count;
// arrondi 1 chiffre apres la virgule
int temp = real_temp*10;
real_temp = (float)temp/10;
// Serial.println();
return real_temp;
}
J'ai récupéré les adresses des capteurs dans Sample.c
#include <stdio.h>
#include <string.h>
#include <OneWire.h>
#define NBRE_CAPTEUR 2 // nombre de capteur sur l'arduino
// *********** declararation des variables gestion des capteurs de temperature *******************
typedef struct Temperature Temperature;
struct Temperature
{
float valeur; // temperature en Celsius, 1 chiffre apres la virgule
byte addr[8]; // identifiant capteur
int pin; // numero de pin a utiliser
char mnemo[32]; // mnemonique de la variable
};
Temperature temperature[NBRE_CAPTEUR]; //creation des instances
// *********** fin declararation des variables gestion des capteurs de temperature *******************
void setup(){
Serial.begin(9600); // initialisation de la liaison serie
// *********** initialisation des variables gestion des capteurs de temperature *******************
temperature[0].addr[0]= 0x28; // capteur rouge
temperature[0].addr[1]= 0x9D;
temperature[0].addr[2]= 0x4C;
temperature[0].addr[3]= 0xDB;
temperature[0].addr[4]= 0x2;
temperature[0].addr[5]= 0x0;
temperature[0].addr[6]= 0x0;
temperature[0].addr[7]= 0xF7;
temperature[0].pin=10;
temperature[0].valeur=0; // temperature en °C, 1 chiffre apres la virgule
strcpy(temperature[0].mnemo,"temp_rouge"); // ex: salon
temperature[1].addr[0]= 0x28; // capteur rouge
temperature[1].addr[1]= 0x37;
temperature[1].addr[2]= 0x54;
temperature[1].addr[3]= 0xDD;
temperature[1].addr[4]= 0x2;
temperature[1].addr[5]= 0x0;
temperature[1].addr[6]= 0x0;
temperature[1].addr[7]= 0x26;
temperature[1].pin=10;
temperature[1].valeur=1; // temperature en °C, 1 chiffre apres la virgule
strcpy(temperature[1].mnemo,"temp_jaune"); // ex: salon
}
void loop(){
gestion_temperature();
delay(1000);
}
void gestion_temperature()
{
/********************************************************************************
Cette fonction permet d'interroger tous les capteurs de temperature OneWire
qui ont ete declare dans "temperature[i]"
********************************************************************************/
byte i=0;
for(i=0; i<NBRE_CAPTEUR; i++){
Serial.print(temperature[i].mnemo);
Serial.print(" => ");
temperature[i].valeur =getStuff(temperature[i].addr,temperature[i].pin);
Serial.print(temperature[i].valeur);
Serial.println(" C ");
delay(100);
}
}
float getStuff(byte addr[8], int pin) // indiquer le n? de pin ? utiliser
{
/********************************************************************************
Cette fonction permet d'interroger le capteur de temperature OneWire
qui a ?t? d?clar? dans "temperature[i]"
********************************************************************************/
OneWire ds(pin); // creation d'un objet OneWire avec le bon n? de pin
byte i;
byte present = 0;
byte data[12];
float real_temp;
float temp_count;
float read_temp;
// Fonction recherche d?sactiv?e car non utilis?e
/*if ( !ds.search(addr)) {
Serial.print("No more addresses.\n");
ds.reset_search();
}
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 998;
}
if ( addr[0] != 0x10) {
Serial.print("Device is not a DS18S20 family device.\n");
return 999;
}
*/
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power off at the end (1=parasite mode)
delay(1000); // delay de 1s si mode parasite. 100ms en mode normal
// 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();
}
read_temp=((data[1]<<8) | data[0]) >> 1 ; // Divide the temperature by 2
temp_count=float(data[7] - data[6])/(float)data[7]; // Convert to real temperature
real_temp = ((float)read_temp-0.25)+temp_count;
// arrondi 1 chiffre apres la virgule
int temp = real_temp*10;
real_temp = (float)temp/100;
// Serial.println();
return real_temp;
}
Il me reconnait le 1er capteur, mais le deuxième il me le met à -0.12°C
merci pour ce code.
mais j'ai l'impression que la température affichée est sous estimé (de 3 ou 4 degrés).
c'est possible ?
alors qu'avec ce code, j'ai la bonne température :
#include <OneWire.h>
/* DS18S20 Celcius degrees */
#define TEMP_LSB 0
#define TEMP_MSB 1
//#define CONFIG_REG 4
OneWire ds(2); // 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();
}
et je n'arrive pas a mettre 1 seul chiffre après la virgule.
merci par avance.
la bibliothèque de X. HINAULT est très sympa, mais des que les températures négatives arrivent elle fonctionne bcp moins bien !
en fait le bug se cache dans ce coin la
data[1]=data[1] & B10000111; // met à 0 les bits de signes inutiles
tempet=data[1]; // bits de poids fort
tempet=tempet<<8;
tempet=tempet+data[0]; // bits de poids faible
En fait le bit de signe n'est pas si inutile que ça !!!
J'utilise une façon plus bourrine pour récupérer la dite température, en une seule ligne.
tempet=(data[1]<<8)|data[0];
Sachant que je fait des courbes sur mon mac a partir des données de mon arduino, j'ai cherché le pourquoi de mes tracés bizarre un certain temps !
J'ai trouvé des tas de trucs passionnants sur son site, mais pas de rubrique "contact"
Je crois qu'il se cache derrière le pseudo d'un des intervenants de ce site (vu la FAQ, la traduction d'une bonne partie de la doc Arduino et pleins de liens),
j'ose espérer qu'il trouvera cette bouteille a la mer.