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

Dans le programme, le bouton est intimement lié au buzzer, le bouton est en “inputpullup” il envoie du GND et fait fonctionner la résistance interne de la carte. Le problème ne peut-il pas venir de là ?

Pouvez vous faire un petit schéma à main levée, je ne vois pas bien dans la vidéo si le transistor joue un rôle dans ce que vous mesurez?

Et reposter le code exact de ce que vous faites tourner

Bonjour,

Comme l'écrivent +/- les autres intervenants, c’est assez difficile sur une vidéo de décoder le réel schéma de câblage.

Je vois que sur votre plaque à trou vous avez un petit module alim +5V et +3.3V je présume, qui sert au transistor je présume encore.

Son GND est’il bien relié au GND breadbord et Arduino?

Dans animation, si une sur température est détectée, il y a buzzer on.

Puis dans la scrutation suivante pour la sonde suivante, si pas de surchauffe, il y a buzzer off.

La sortie doit passer son temps à baguotter

bon point

J’ai dessiné le montage du transistor ici Login - Tinkercad . Il me semble que s’il y avait un problème de montage, le buzzer ne sonnerait pas normalement lorsque je le place sur la broche 10 (led HP) qui clignote au dépassement du seuil.

J’ai re-re-re vérifié tous mes branchements, j’ai branché sur une autre UNO, j’ai retiré toutes les sorties led, ainsi que le LCD, il n’y a plus que 4 broches occupées sur ma carte, le +, le-, l’entrée 7 qui entre le 5V. des sondes, et la sortie 9 (buzzer) qui a toujours les mêmes symptômes. Ayant épuré au maximum les branchements, je ne pense pas que le problème vienne de là.

/* programme élaboré le 22.01 /JML sur le forum arduino.
  - j'ai modifié la résolution sur la ligne 29 pour avoir la T° au dixième
  - j'ai modifié les lignes 96 a 106 sur les derniers conseils de JML en plaçant HIFH et LOW afin d'essayer de faire sonner le buzzer.
*/

#include <Wire.h>
#include <hd44780.h>                        // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h>  // i2c expander i/o class header
#include <Toggle.h>                         // https://github.com/Dlloydev/Toggle

#include <OneWire.h>
#include <DallasTemperature.h>

const uint8_t nbCols = 20;
const uint8_t nbRows = 4;
hd44780_I2Cexp lcd;

const byte pinLedHP = 11;
const byte pinLedPC = 12;
const byte pinLedECS = 13;
const byte pinBuzzer = 9;
const byte pinBoutonSilence = 3;
const byte pinLedSilence = 2;

Toggle boutonSilence(pinBoutonSilence);

const byte pinBus = 7;
OneWire busOneWire(pinBus);
DallasTemperature capteurs(&busOneWire);
const uint8_t resolution = 12; // 9, 10, 11 ou 12 bits
uint32_t derniereLecture = 0;


struct Capteur {
  const char * nom;
  DeviceAddress adresse;
  float derniereTemperature;
  bool besoinAffichage;
};


Capteur lesCapteurs[] = {
  {"EHP", {0x28, 0x74, 0xC9, 0x50, 0x00, 0x00, 0x00, 0x53}, 0.0, true}, // 0 - Eau Haut Poêle
  {"EBP", {0x28, 0xE1, 0x33, 0xBB, 0x00, 0x00, 0x00, 0xCF}, 0.0, true}, // 1 - Eau Bas Poêle
  {"HCP", {0x28, 0x93, 0xE6, 0x83, 0x00, 0x00, 0x00, 0xE1}, 0.0, true}, // 2 - Haut Cuve Poêle
  {"BCP", {0x28, 0x2B, 0x0D, 0x88, 0x00, 0x00, 0x00, 0x79}, 0.0, true}, // 3 - Bas Cuve Poêle
  {"PC ",  {0x28, 0xFC, 0x00, 0x34, 0x00, 0x00, 0x00, 0x57}, 0.0, true}, // 4 - PC
  {"ECS", {0x28, 0x4F, 0x78, 0x38, 0x00, 0x00, 0x00, 0x48}, 0.0, true}, // 5 - ECS
};

constexpr byte nbCapteursTemperature = sizeof lesCapteurs / sizeof * lesCapteurs;

const uint32_t demiPeriodeClignotement = 250;

const float seuilHP = 24.0;
//const byte indiceHP = 0;
//const unsigned int frequenceBuzzHP = 800; // Hz

const float seuilPC = 24.0;
const byte indicePC = 4;
const unsigned int frequenceBuzzPC = 1000; // Hz

const float seuilECS = 24.0;
const uint8_t indiceECS = 5;
const unsigned int frequenceBuzzECS = 1200; // Hz

void animations() {
  static bool modeSilence = false;
  static uint32_t debutModeSilence = 0;
  static const uint32_t dureeModeSilence = 10000ul; // 10 secondes en ms

  boutonSilence.poll();
  if (boutonSilence.onPress()) {
    modeSilence = not modeSilence;
    digitalWrite(pinLedSilence, modeSilence ? HIGH : LOW);
    if (modeSilence) debutModeSilence = millis();
  }

  if (modeSilence && millis() - debutModeSilence >= dureeModeSilence) {
    modeSilence = false;
    digitalWrite(pinLedSilence, LOW);
  }

  /*if (lesCapteurs[indiceHP].derniereTemperature >= seuilHP) {                         // si la T° de la sonde HP dépasse le seuil fixé,
    static uint32_t lastBlink;                                                        //  dernier clignottement ??????????????????????????????
    if (millis() - lastBlink >= demiPeriodeClignotement) {                            // ?????????????????????????????????????????
      digitalWrite(pinLedHP, digitalRead(pinLedHP) == HIGH ? LOW : HIGH);             // à priori, on fait clignoter la led ?????????????????????????
      if (not modeSilence) digitalWrite(pinBuzzer, HIGH);                   //tone(pinBuzzer, frequenceBuzzHP, demiPeriodeClignotement / 4);     // si le mode silence n'est pas actif, le buzzer s'allume dans sa fréquence et par intermittence.
      lastBlink = millis();
    }
    } else {                                                                            // sinon
    digitalWrite(pinLedHP, LOW);                                                      // la led est éteinte
    digitalWrite(pinBuzzer, LOW);                                            // noTone(pinBuzzer);                      // le buzzer est innactif
    }
  */
  if (lesCapteurs[0].derniereTemperature >= seuilHP) {             // si la T° de la sonde HP dépasse le seuil fixé,
    if (not modeSilence) digitalWrite(pinBuzzer, HIGH);                   // si l'on est pas en mode silence, on active le buzzer
    static uint32_t lastBlink;                                            // variable pour mémoriser le moment du dernier changement d'état de la LED
    if (millis() - lastBlink >= demiPeriodeClignotement) {                // si on a attendu assez longtemps dans l'état précédent
      digitalWrite(pinLedHP, digitalRead(pinLedHP) == HIGH ? LOW : HIGH); // on inverse l'état de la LED
      lastBlink = millis();                                               // et on mémorise le moment de changement d'état
    }
  } else {                                                                // sinon la sonde n'est pas au dessus du seuil
    digitalWrite(pinLedHP, LOW);                                          // donc la led doit être éteinte
    digitalWrite(pinBuzzer, LOW);                                         // et le buzzer ne doit pas sonner
  }

  if (lesCapteurs[indicePC].derniereTemperature >= seuilPC) {
    static uint32_t lastBlink;
    if (millis() - lastBlink >= demiPeriodeClignotement) {
      digitalWrite(pinLedPC, digitalRead(pinLedPC) == HIGH ? LOW : HIGH);
      if (not modeSilence) tone(pinBuzzer, frequenceBuzzPC, demiPeriodeClignotement / 4);
      lastBlink = millis();
    }
  } else {
    digitalWrite(pinLedPC, LOW);
    noTone(pinBuzzer);
  }

  if (lesCapteurs[indiceECS].derniereTemperature >= seuilECS) {
    static uint32_t lastBlink;
    if (millis() - lastBlink >= demiPeriodeClignotement) {
      digitalWrite(pinLedECS, digitalRead(pinLedECS) == HIGH ? LOW : HIGH);
      if (not modeSilence) tone(pinBuzzer, frequenceBuzzECS, demiPeriodeClignotement / 4);
      lastBlink = millis();
    }
  } else {
    digitalWrite(pinLedECS, LOW);
    noTone(pinBuzzer);
  }
}

void rechercheCapteurs() {
  DeviceAddress adresse;
  busOneWire.reset_search();
  byte idx = 0;
  while (busOneWire.search(adresse)) {
    Serial.print("Capteur ");
    Serial.print(idx);
    Serial.print(" adresse = {");
    for (byte j = 0; j < sizeof adresse; j++) {
      Serial.print("0x");
      if (adresse[j] < 16) Serial.print("0");
      Serial.print(adresse[j], HEX);
      if (j < (sizeof adresse) - 1) Serial.print(", ");
    }
    Serial.println("}");
    idx++;
  }
}


bool mettreAJourTemperatures() {
  if (millis() - derniereLecture <= capteurs.millisToWaitForConversion(resolution)) return false; // conversion non terminée, on sort
  bool modif = false;
  for (byte i = 0; i < nbCapteursTemperature; i++) {
    float t = capteurs.getTempC(lesCapteurs[i].adresse);
    if (!isnan(t) && (isnan(lesCapteurs[i].derniereTemperature) || abs(t - lesCapteurs[i].derniereTemperature) >= 0.1)) {
      lesCapteurs[i].derniereTemperature = t;
      lesCapteurs[i].besoinAffichage = true;
      modif = true;
    }
  }
  capteurs.requestTemperatures(); // relance la prochaine conversion
  derniereLecture = millis();
  return modif;
}



void setup() {
  pinMode (pinLedHP, OUTPUT);       digitalWrite(pinLedHP, LOW);
  pinMode (pinLedPC, OUTPUT);       digitalWrite(pinLedPC, LOW);
  pinMode (pinLedECS, OUTPUT);      digitalWrite(pinLedECS, LOW);
  pinMode (pinBuzzer, OUTPUT);      digitalWrite(pinBuzzer, LOW);
  pinMode (pinLedSilence, OUTPUT);  digitalWrite(pinLedSilence, LOW);
  boutonSilence.begin(pinBoutonSilence);

  Serial.begin(115200);

  int result = lcd.begin(nbCols, nbRows);
  if (result) {
    Serial.print("LCD initialization failed: ");
    Serial.println(result);
    hd44780::fatalError(result);
  }

  lcd.setCursor(0, 0);
  lcd.print("GESTION TEMPERATURE");

  for (uint8_t n = 0; n < nbCapteursTemperature; n++) {
    lcd.setCursor((n < nbRows - 1) ? 0 : nbCols / 2, n % (nbRows - 1) + 1);
    lcd.print(lesCapteurs[n].nom);
    lcd.write(':');
  }

  capteurs.begin();
  // rechercheCapteurs();

  capteurs.setResolution(resolution);
  capteurs.setWaitForConversion(false);
  capteurs.requestTemperatures();
  derniereLecture = millis();

  Serial.println("PRET");
}

void loop() {
  if (mettreAJourTemperatures()) { // retourne vrai si au moins une t° a été mise à jour

    for (byte n = 0; n < nbCapteursTemperature; n++) {
      if (lesCapteurs[n].besoinAffichage) {
        uint8_t col = (n < nbRows - 1) ? 4 : nbCols / 2 + 4;
        uint8_t ligne = n % (nbRows - 1) + 1;
        lcd.setCursor(col, ligne );
        lcd.print("      "); // on efface l'ancienne valeur
        lcd.setCursor(col, ligne );
        lcd.print(lesCapteurs[n].derniereTemperature, 1);
        lesCapteurs[n].besoinAffichage = false;
      }
    }
  }
  animations();
}

Oui, l’alim externe est pour le transistor, je ne sais pas si c’est mieux de faire comme cela ou de placer l’alim externe sur la UNO. Oui, les GND sont bien reliés. Pour vérifier les câblages, j’ai enlevé la plaquette que l’on voit sur la vidéo et pris la tension en branchant le minimum de matériel sur la carte comme je l’ai expliqué plus haut.

Je pense qu’il faut creuser la question … comment faire ?

(j’étais à vérifier mes branchements pendant que vos commentaires ont été mis en ligne, veuillez m’excuser si je suis décalé).

faire monter un flag lorsqu’une demande de buzzer est activée et en fin de boucle tester tous les flags et ne stopper le buzzer que si tous les flags sont false

Bonjour,

A priori vous avez un probléme de code si j’ai bien suivi.

Mais pour répondre à cela

Ce serait bien de pouvoir connaître votre schéma, votre lien vers Tinkercad n'est pas public je crois!

A mon avis vous devriez pouvoir n’avoir qu’une seule alimentation pour le tout.

Je ne connais pas ce terme, je vais creuser la question.

Désolé pour le lien qui n’a pas fonctionné, voici le schéma.

C’est pour le montage final que je me pose cette question. Est-ce que, sur le long terme, je peux faire tourner le programme en branchant directement la carte sur le secteur via un abaisseur de tension ou est-il préférable de placer une autre alimentation comme je l’ai réalisée sur la vidéo ?

Je ne comprends pas ce qu’est le mode parasite, comment on peut l’éviter, je n’ai pas trouvé de discussion là dessus.

En français on parle de lever un drapeau.
Un ”drapeau” est un booléen qui est soit vrai (true) soit faux (false).

A ce que j’ai compris l’emploi du terme ”parasite” n’est pas péjoratif.

C’est un mode d’alimentation qui permet d’éviter le fil d’alimentation, le Ds18B20 s’alimentant à partir du fil signal, les sondes DS18B20 se câblant en série.

Bien évidemment tout n’est pas idyllique, il n’y a pas que des avantage a cette solution, il y a aussi des inconvénients.

Désolé, je n’en connais pas plus.

en fait il faut 3 drapeaux, un pour chaque alarme. on peut faire cela avec un masque ➜ dans un octet chaque bit peut correspondre à l'état d'alarme d'un capteur, c'est ce que je fais ici avec la variable alarmesEnCours qui est ce "drapeau" et donc les bits disent quelles sont les alarmes actives.

j'ai viré le buzzer de wokwi qui n'est pas actif, je l'ai remplacé par une LED. (avec une petite tempo intégrée au if qui allume le buzzer actif, on pourrait faire beep beep à intervalles réguliers au lieu d'une alim constante du buzzer).

Bonjour,

Cf. la datasheet du DS18B20 (Page 7/20 - § Powering the DS18B20)

L'intérêt du mode parasite est de pouvoir cabler le capteur avec seulement 2 fils (et non pas 3). Le principe est d'utiliser le bus pour charger un condensateur à l'intérieur du capteur qui suffit à le faire fonctionner.

Quant aux inconvénients, effectivement cela nécessite que la commutation du bus doit être inférieur à 10 µS, d'où l'utilisation d'un MOSFET pour satisfaire ces conditions ... ce qui complique un peu la mise en œuvre

A suivre...

Merci JML pour cette deuxième proposition qui fonctionne bien dans ma configuration réelle.

Je n’ai pas tout compris mais j’ai effectivement remarqué que dans ce nouveau programme, vous avez intégré l’énumération que vous expliquer dans l’un de vos tuto. Je suis loin de comprendre toutes les subtilités de ce programme mais j’ai l’impression qu’avec le temps, il sera plus facile à appréhender que le précédent ???

J’aimerais retrouver le clignotement des LED et l’intermittence du buzzer… comment y parvenir ?

Bonjour,

Sur la Gate du MOS, vous avez mis 2 résistances de même valeurs, est-ce une erreur de schéma?

2 R de mêmes valeurs représente un pont diviseur par 2.

Il vaut mieux mettre 100 à 300 Ohms entre sortie Arduino et Gate et 4,7k à 10k Ohms entre Gate et 0V.

Pour l'alimentation en définitif, je pense que vous pouvez aisément opté pour un petit boîtier entrée 230V ac sortie 5V DC type chargeur de tél et tout alimenter avec.

regardez comment je faisais clignoter les leds auparavant et intégrez cela

une fois que vous avez compris comment on fait cela avec millis(), vous rajoutez quelque chose d'équivalent pour le buzzer

vous essayez ?

PS : bon comme j'avais écrasé l'ancienne version vous n'allez plus avoir le code avec millis.

J'ai remis le clignotement pour les LEDs, essayez de comprendre comment ça marche et faites pareil pour le buzzer

J’ai cherché en vain dans différentes directions.

Je me dis maintenant que la solution se trouve

dans la séquence :

 if (not modeSilence && alarmesEnCours != AUCUNE_ALARME) {
    // une alarme au moins est en cours et on n'est pas en mode silence
    digitalWrite(pinBuzzer, HIGH);
  } else {
    digitalWrite(pinBuzzer, LOW);
  }
}

J’essaye de la réécrire en

 if (not modeSilence && alarmesEnCours != AUCUNE_ALARME) {
    // une alarme au moins est en cours et on n'est pas en mode silence
    //digitalWrite(pinBuzzer, HIGH);
  static uint32_t chrono = 0;
if (millis() - chrono >= 1000) { 
digitalWrite(pinBuzzer, digitalRead(pinBuzzer) == HIGH ? LOW : HIGH); 
chrono = millis(); 
  } else {
    digitalWrite(pinBuzzer, LOW);
  }
}

Mais lorsque je lance la simulation sur wokwy, on m’écrit :

sketch.ino: In function 'void animations()':
sketch.ino:154:26: error: a function-definition is not allowed here before '{' token
 void rechercheCapteurs() {
                          ^
sketch.ino:174:32: error: a function-definition is not allowed here before '{' token
 bool mettreAJourTemperatures() {
                                ^
sketch.ino:192:14: error: a function-definition is not allowed here before '{' token
 void setup() {
              ^
sketch.ino:229:13: error: a function-definition is not allowed here before '{' token
 void loop() {
             ^
sketch.ino:245:1: error: expected '}' at end of input
 }
 ^
Error during build: exit status 1

Il doit sans doute manquer une accolade fermante un peu plus haut.
Faire CTRL+t dans l'IDE pour réindenter le code correctement et voir où il y a un décalage inattendu.

L’idée est bonne!