Problème pour brancher 7 sondes DS18B20 sur le même bus

Seul l'utilisateur peut déterminer la résolution en fonction de ses besoins. La résolution est sans aucun rapport avec la précision qui reste toujours de 0.5°C.

Si vous faites une moyenne de dix températures 2.5 avec la résolution 0.5 le résultat a toutes les chances d'être 2.5 donc entre 2 et 3°C et rester dans votre consigne, avec la résolution 0,125 le résultat peut devenir 2.35 donc entre 1.85 et 2.85 et sortir de votre consigne.

Si on veut augmenter la précision il faut augmenter le nombre de sondes faire un lot de mesures puis un moyennage global.

on est d'accord, c'est ce que j'ai dit aussi.

Faire la moyenne sur 10 mesures peut améliorer la précision statistique, mais seulement si le bruit est aléatoire et non systématique. Dans ce cas, une résolution de 0,0625 °C à 12 bits devient pertinente, car la moyenne permet de distinguer des variations plus fines que la précision d’une seule mesure.

Si l’erreur du capteur est systématique ou si la dérive est rapide, la moyenne n’améliore pas la précision effective.

Quelle est l’utilité d’augmenter la résolution si le capteur n’a pas la précision requise?

@mjb parle de faire des tendances il est clairement impossible de faire des tendances sans décimales.
Sur mon aquarium je n'ai pas utilisé les tendances car j'ai vu que l'inertie était suffisamment importante pour ne pas nécessiter une réaction très rapide, par contre j'affiche la température avec deux décimales ce qui me permet de voir avec quelle rapidité la température remonte après une coupure de courant sans avoir à attendre 1 h pour voir qu'elle remonte effectivement. De même pour le thermostat ainsi que pour les alarmes tous les calculs sont faits sur 12 bits et la température de l'aquarium reste très stable, le tout avec une fiabilité sans rapport avec les thermostats mécaniques.

@J-M-L j'avais fait des relevés sur la bonne dizaine de DS18B20 que j'ai et les sondes qui mesurent plus ou moins affichent toujours la même erreur par contre elles présentent presque toujours un défaut de linéarité (-0.1 dans la plage 20° +0.1 dans la plage 30°). Ceci n'est pas fait en labo avec des références de précision. Le principe étant de plonger les sondes dans un même récipient d'eau et de voir comment elle se comportent

Pour mémoire Pi à 3.1 ou à 3.14 c'est Paris Strasbourg

Donc vous ne voyez pas une variation de ±0,1 à ±0,2 °C sur la précision mais plutôt proche de 0, c'est cela ?

Pour ma part, j’ai plongé mes six sondes dans un seau d’eau, leur température varie moins qu’à l’air libre. Elles affiche entre 12° et 12,6°.

Je souhaite revenir sur le programme élaboré par JLM pour mes 6 sondes.

Une question est restée sans réponse : pourquoi “long-temps” n'a pas été déclaré comme préconisé dans le tuto d'eskimon ? Est-ce que c’est la ligne “uint32_t derniereLecture = 0;” qui fait cet office ?

dans la ligne

DallasTemperature capteurs(&busOneWire);

ces annotations sont-elles correctes ? // création d'une variable nommée capteurs, du type Dallas Temperature, qui est initialisée en utilisant busOneWire (voir ligne précédente)

mais pourquoi le signe "&" devant bus OneWire ?

uint32_t c'est un type comme unsigned long

qu'est-ce qu'ils proposent dans le tuto d'eskimon ? ce doit être a peu près similaire au nom de la variable près.

Oui la variation est proche du zéro, en tous cas inférieure à 0.1°. C'est confirmé par ma consigne qui est de ±0.25°C et l'aquarium reste bien dans cette zone de température.

@mjb DallasTemperature capteurs(&busOneWire);
capteurs est un objet sur la classe DallasTemperature qui prend en paramètre une référence (le &) sur l'objet busOneWire de la classe OneWIre

OK vous avez tiré un lot sympathique alors !

j'imagine que beaucoup vont une fois de plus penser (et écrire) que je fous la merde, mais un lot de fabrication se doit d'avoir des caractéristiques équivalentes d'un exemplaire à l'autre !

Effectivement un lot industriel est souvent cohérent.
Ce n’est pas le se s que j’avais en tête bien sûr - si on achète chez Ali ou eBay rien ne garantit que les éléments soient tous d’un même lot.

Bonjour,

La distance Paris/Strasbourg, c’est beaucoup ou c’est peu?

3,1 au lieu de Pi, c’est 1,323% et des poussiéres d’erreurs.

Selon les besoins, c’est peu, voir beaucoup.

Comme quoi les petites erreurs du début font des résultats totalement erronés!

On peut avoir de grandes chances d'avoir un lot cohérent en achetant sur Ali, ou autres, à condition de faire ce qu'il faut.

Les composants sont assemblés en bobines comme les bobines de films cinématographiques.
C'est nécessaire pour les machines de placement automatique.

Si les composants achetés sur Ali ou autres sont en vrac, il n'y aucune confiance possible sur l'unité du lot.

Mais si on fait attention aux photos et qu'on achète uniquement des tronçons de bandes, il y a 99 % de chance que les composants, au moins pour un seul tronçon, proviennent du même lot de fabrication.

Les 1% qui restent, c'est si on a la malchance de tomber sur un remplissage de la bassine.

A premiére vue, en ce qui concerne ces sondes DS18B20 sur Aliexpress, je n’ai pas vu de lot ci dessous:

Ça semble trés difficile d’acheter des sondes du même lot.

Pour le particulier qui achéte sur des site comme AliE, et qui ne s'intéresse qu'à des trés petites séries (à l’inverse de la plus part des industriels qui achétent par 100énes ou milliers de composants), la démarche industrielle d’achats de lots est trés difficile voir impossible.

Ça me semble plus cohérent qu’il choisisse de développer son équipement de sorte qu’il soit (par soft ou hard) étalonnalable pour pouvoir compenser les éventuelles erreurs compensables des sondes.

Mais qui a dit l'un empêchait l'autre ?

Il n'y a pas des astuces pour tout, mais quand il y en a, autant les faire connaître, cela ne va pas plus loin.

Exemple : pont pour obtenir une référence précise de 3 V à partir de Vcc = 5V


Si on utilise des résistances à 5 %, un calcul d'erreur tel ceux que l'on me faisait faire quand j'étudiais en BTS me donne :
un 3 V ± 10 % avec le pont de gauche.

Le pont de droite n'utilise qu'une seule valeur de résistance 2k, achetées en bande, qui sont peut-être à +5 % ou peut-être à - 5 %, en fait, on s'en fiche.
Ce qui compte, c'est le différentiel de dispersion entre les valeurs et si elles proviennent d'un même lot, elles peuvent être à moins de 0,5% entre elles et donc le 3 V est précis à ± 1 %.

Et c'est bien pour cela que dans un circuit intégré où les résistances sont à ± 30 % entre lots cela fonctionne très bien car sur un exemplaire particulier les résistances sont fabriquées en même temps et ont peu de dispersion différentielle.
Bien évidement les vrais schémas internes, ceux qui ne sont jamais publiés, sont conçus pour.

Bonjour, les explications données par JLM sur la première partie du programme m’ont permis de progresser mais pas suffisamment pour comprendre totalement la suite de ce code. J’aimerais que vous m’aidiez à comprendre cette deuxième partie que j’ai annotée en fonction de mon niveau de compréhension actuel.

constexpr byte nbCapteursTemperature = sizeof lesCapteurs / sizeof * lesCapteurs;    // que veut dire "constexpr byte" ??? que veut dire "sizeof lesCapteurs / sizeof * lesCapteurs" ?

const uint32_t demiPeriodeClignotement = 250;       // pourquoi const uint32_t??? et pourquoi fixer une demi période de clignotement ? pourquoi 250 ?

const float seuilHP = 50.0;     // le seuil de déclenchement de l'alarme led et buzzer est fixé ici  à 50° On peut changer cette valeur.
const byte indiceHP = 0;      // la sonde HP comme précisé plus haut dans capteur lescapteurs prend la valeur 0, c'est une constante.

const float seuilPC = 50.0;   "   "   "   "   "
const byte indicePC = 4;    "   "   "   "   prend la valeur 4,

const float seuilECS = 50.0;    "   "   "   " prend la valeur 5,
const uint8_t indiceECS = 5;    "   "   "   "   "

enum : uint8_t {AUCUNE_ALARME = 0, ALARME_HP = 1, ALARME_PC = 2, ALARME_ECS = 4};   // ici, il y a une énumération d'état semble t-il pourquoi ???
uint8_t alarmesEnCours = AUCUNE_ALARME;   // Pourquoi ??? est-ce que l'on inverse l'état  // les bits définissent les alarmes actives je ne comprends pas de quelle manière ???

void animations() {             // j'ai l'impression que l'on introduit ici trois fonctions : "modeSilence" ; débtModeSilence ; "duréeModeSilence"
  static bool modeSilence = false;            // on regarde régulièrement l'état du mode silence s'il est vrais faux  pourquoi static ?
  static uint32_t debutModeSilence = 0;         // déclaration de la fonction "débutModeSilence" on met le compteur à 0 est-ce cela ???
  static const uint32_t dureeModeSilence = 10000ul; // 10 secondes en ms    // déclaration de la fonction "duréeModeSilence" le mode silence dure 10 seconde (après que le bouton soit appuyé.)

  boutonSilence.poll();              // Ici, on va gérer le fonctionnement du bouton silence
  if (boutonSilence.onPress()) {            // si le bouton est appuyé :
    modeSilence = not modeSilence;            // on active le mode silence ou on le désactive = inverse le mode à chaque appuie sur le bouton!
    digitalWrite(pinLedSilence, modeSilence ? HIGH : LOW);      // on interroge  l'état du mode silence, s'il est "true"  la pinledSilence devient HIGH sinon elle devient LOW ???
    if (modeSilence) debutModeSilence = millis();       // si le mode silence est activé, on enclenche la fonction débutModeSilence et on enclenche le compteur
  }

  if (modeSilence && millis() - debutModeSilence >= dureeModeSilence) { // si le relevé du compteur au moment de l'appuie sur le bouton moins la durée du chrono est supérieur ou égal à 10 secondes  (dureeModeSilence)

    modeSilence = false;              // le mode silence devient faux (n'est pas activé)
    digitalWrite(pinLedSilence, LOW);         // et la led silence s'éteint
  }

  if (lesCapteurs[indiceHP].derniereTemperature >= seuilHP) {     // si la dernière température du capteur HP est supérieure à son seuil
    static uint32_t chrono = 0;           // le chrono est démarre
    if (millis() - chrono >= 100) {           // si le temps dépasse 0,1 seconde

      digitalWrite(pinLedHP, digitalRead(pinLedHP) == HIGH ? LOW : HIGH);   // la led HP clignote… l'écriture de cette fonction s'appelle l'opérateur ternaire elle Inverse l'état en sortie pinLedHP… si pinLedHP est HIGH alors retourne LOW sinon retourne HIGH …on pourrait l'écrire digitalWrite(pinLedHP, !(digitalRead(pinLedHP))); mais comment contrôle le temps des clignotements

      chrono = millis();             // et le chrono est enchenché
    }
    alarmesEnCours |= ALARME_HP;            // que veut dire le trait vertical devant = ?...l'alarme en cours devient l'alarme HP ?
  } else {                // sinon
    digitalWrite(pinLedHP, LOW);            // la led HP n'est pas alimentée
    alarmesEnCours &= ~ALARME_HP;           // l'alarme en cours n'est plus l'alarme HP mais je ne comprends pas l'écriture.???
  }

  if (lesCapteurs[indicePC].derniereTemperature >= seuilPC) {
    static uint32_t chrono = 0;
    if (millis() - chrono >= 100) {
      digitalWrite(pinLedPC, digitalRead(pinLedPC) == HIGH ? LOW : HIGH);

bonjour Michel

tu déclares un tableau dans lequel tu as 6 lignes qui contiennent les adresses de tes 6 sondes.

si tu veux rajouter ou enlever une sonde, tu devras modifier dans tout le programme les indices des tableaux. sinon, ce serait la cata car supposons que tu aies enlevé une sonde sans changer le nombre de sondes, ton programme ira lire une adresse de sonde qui n’existe pas.

donc pour te faciliter les choses, jml a mis une ligne qui calcule le nombre de sondes.

tu pourras ajouter ou enlever une sonde, ou 2 ou x. le prog le saura.

pour t’en convaincre, rajoute ces ligne en fin du set up

 Serial.println("PRET");
  Serial.print("sizeof lesCapteurs ");Serial.println(sizeof lesCapteurs);
  Serial.print("sizeof * lesCapteurs ");Serial.println(sizeof * lesCapteurs);
  Serial.print("nbCapteursTemperature ");Serial.println(nbCapteursTemperature);

exécutes le prg et regardes ton moniteur

puis rajoutes par exemple 2 sondes, uniquement dans le tableau comme ceci

Capteur lesCapteurs[] = {
  {"EHP", {0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x7E}, 0.0, true}, // 0 - Eau Haut Poêle
  {"EBP", {0x28, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xDE}, 0.0, true}, // 1 - Eau Bas Poêle
  {"HCP", {0x28, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xBE}, 0.0, true}, // 2 - Haut Cuve Poêle
  {"BCP", {0x28, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x87}, 0.0, true}, // 3 - Bas Cuve Poêle
  {"PC ",  {0x28, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xE7}, 0.0, true}, // 4 - PC
  {"ECS", {0x28, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x47}, 0.0, true}, // 5 - ECS
{"ECL", {0x28, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x47}, 0.0, true}, // 5 - ECS
{"ECP", {0x28, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x47}, 0.0, true}, // 5 - ECS
};

et exécutes à nouveau le prog

tu verras que c’est la place totale occupée par le tableau dans la mémoire / par la place occupée par 1 ligne

tu obtiens le nombre de lignes, donc le nombre de sondes.

partout ou dans le programme tu utilises “nbCapteursTemperature” cette constante sera à jour du nombre de sondes.

nota: tu peux aussi voir ici un des intérets de Serial.print :smiley:

enum : uint8_t {AUCUNE_ALARME = 0, ALARME_HP = 1, ALARME_PC = 2, ALARME_ECS = 4};

tu enumères (listes) les différents états que va prendre ton programme.
tu donnes des valeurs à ces différents états
puis tu initialises l'état en cours:

uint8_t alarmesEnCours = AUCUNE_ALARME; // les bits définissent les alarmes actives

il faut lire : alarme en cours = AUCUNE_ALARME ( qui est = à 0)

si alarme en cours est = à ALARME_HP (qui est = à 1)

si alarme en cours est = à ALARME_PC (qui est = à 2)

si alarme en cours est = à ALARME_ECS (qui est = à 4)

au passage, remarques que si pas d’alarme alors alarme en cours est à 0

et que s’il y a une alarme en cours, alarme en cours vaudra 1,2,4 ( tiens du binaire )