Je cherche a suivre la temperature de l'eau de ma piscine et de mon systeme de chauffage au moyens de 2 sondes DS18B20.
Tout fonctionnait bien sur la breadboard mais depuis que je suis passé au réel en installant tout mon projet en dur, j ´ai les 2 sondes de temperature qui me donnent des valeurs bizarres.
La temperature relevé n'est pas en phase avec la réalité. La valeurs fluctue en fonction de la journée.
D'ou peut venir le probleme car tout le reste fonctionne.
J'ai cablé les 2 sondes avec du fil telephone 4 paires avec de petits dominos et les sondes sont situés á 18 m de mon arduino uno.
18m c'est quand même beaucoup.
L'I²C n'a pas été conçu pour de telle distance à la base.
Il faut prendre quelques précautions:
abaisser la valeur des pullups sur SDC et SCL. Afin de rendre la ligne moins susceptible aux perturbations et aussi améliorer le temps de monté des signaux
ralentir l'horloge. Parce que sur les grandes longueurs de fils le temps de monté peut devenir trop grand au regard de la fréquence de l'horloge
Il me semble que le problème a déjà été évoqué sur le forum et quelqu'un avait proposé une référence de buffer I²C qui permettait d'attaquer de longues lignes.
fdufnews:
18m c'est quand même beaucoup.
L'I²C n'a pas été conçu pour de telle distance à la base.
heu non ... c'est un bus 1wire
Il me semble que le problème a déjà été évoqué sur le forum et quelqu'un avait proposé une référence de buffer I²C qui permettait d'attaquer de longues lignes.
Les trames d'informations échangées avec les DS18B20 intègrent un CRC.
Donc déjà, si tu as un code propre qui vérifie la validité des CRC avant exploitation des informations remontées par la sonde, tu peux facilement déterminer s'il s'agit d'un problème de ligne ou pas.
biss:
La valeurs fluctue en fonction de la journée.
Cette description des symptômes me semble très insuffisante pour pouvoir poser un diagnostic.
En fait pour les symptomes, lorsque la sonde me donne 32°, la temperature de l'eau est en fait a 26,6° avec un thermometre digital classique.
Ce matin, la sonde me donnait 19,8° alors qu'en realité l'eau etait a 26°. Puis dans la journée la temperature via la sonde est de 23°.
Sur la breadboard tout fonctionnait bien mais la sonde avait que 50 cm de fil.
Faut il que je mette un delai entre les 2 prises de mesures de mes 2 sondes pour laisser le temps du calcul.
Normalement en bus onewire la distance de cable dans mon cas est largement bonne.
Je ne comprends pas pourquoi ca ne marche plus ou plutot mal.
C'est quoi le CRC => une petite recherche sur internet te renseignera
Le problème des exemples et bibliothèques DS18B20 pour arduino que l'on trouve couramment sur le net, c'est que la gestion complète du CRC n'est pas toujours intégrée, ce qui constitue une faiblesse face au risque de mauvaise transmission d'infos entre la sonde et l'arduino.
Si je simplifie : c'est un code qui permet de vérifier l'intégrité d'une série d'octets reçus.
Quand tu lis la température, la sonde envoie à l'arduino un tableau d'octets (scratchpad), dont l'un d'entre eux est en réalité le résultat d'un calcul fait à partir de tous les autres.
Au niveau de l'arduino, il faut refaire le même calcul et vérifier que le résultat est bien le même que celui reçu de la sonde.
Si différent, c'est qu'au moins un bit de la trame a été altéré, et dans ce cas il faut poubelliser le message reçu sans le traiter.
Peux-tu montrer la partie de ton source qui effectue la lecture de la température ?
Comme convenu mon code qui permet de lire la température :
// Fonction récupérant la température depuis le DS18B20
int getTemperature(OneWire *ds, float *temp) // Retourne true si tout va bien, ou false en cas d'erreur
{
byte data[9], addr[8];
// data : Données lues depuis le scratchpad
// addr : adresse du module 1-Wire détecté
if (!ds->search(addr)) // Recherche un module 1-Wire
{
ds->reset_search(); // Réinitialise la recherche de module
return 0; // Retourne une erreur
}
if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue
return 0; // Si le message est corrompu on retourne une erreur
if (addr[0] != DS18B20) // Vérifie qu'il s'agit bien d'un DS18B20
return 0; // Si ce n'est pas le cas on retourne une erreur
ds->reset(); // On reset le bus 1-Wire
ds->select(addr); // On sélectionne le DS18B20
ds->write(0x44, 1); // On lance une prise de mesure de température
delay(850); // Et on attend la fin de la mesure
ds->reset(); // On reset le bus 1-Wire
ds->select(addr); // On sélectionne le DS18B20
ds->write(0xBE); // On envoie une demande de lecture du scratchpad
for (byte i = 0; i < 9; i++) // On lit le scratchpad
data[i] = ds->read(); // Et on stock les octets reçus
*temp = ((data[1] << 8) | data[0]) * 0.0625; // Calcul de la température en degré Celsius
return 1; // Pas d'erreur
}
dans ton code il y a une verif du CRC sur l'adresse mais pas sur la mesure
dans le code en lien avec mon précédent message le CRC est fait sur les deux
Si je comprend tout il faut que je rajoute un test sur le 9° octet dans mon code pour verifier que tout ce passe bien sur le plan adresse = data 7 et sur le plan mesure = data 8.
If (capteur.crc8(data,8)==data[8]) alors ok sinon probleme.
Si je n' ai pas la bonne valeur que dois je faire et quelle est l'explication.
Et si tout est ok quelle va etre la prochaine etape dans la resolution de mon probleme.
En comparant mon code et celui mis en lien j'ai constater que le data est sur 12 bit et l'adresse sur 8 bit alors que dans mon code le data est sur 9 bit et l'adresse sur 8 bit.
Est ce que mon probleme ne viendrait pas de cela et que le calcul ne serait alors pas complet ?