Programme ralenti par la lecture d'une température

Bonjour,
J’utilise un petit programme simple qui tourne très vite et utilise 2 interruptions.
Je veux le modifier en ajoutant une valeur de température a partir d’un capeur DS18B20.
En suivant les différent exemples j’ai inséré un bout de code pour lire la température dans mon programme mais ça le ralenti de façon considérable puisque la lecture se fait environ toutes les 1 sec.
Etant débutant sur ce langage je coince

Voici le bout de code classique que j’ai inséré

#include <OneWire.h> // Inclusion de la librairie OneWire
 
#define DS18B20 0x28     // Adresse 1-Wire du DS18B20
#define BROCHE_ONEWIRE 10 // Broche utilisée pour le bus 1-Wire
 
OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds
 
// Fonction récupérant la température depuis le DS18B20
// Retourne true si tout va bien, ou false en cas d'erreur
boolean getTemperature(float *temp){
  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 false;         // Retourne une erreur
  }
   
  if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue
    return false;                        // Si le message est corrompu on retourne une erreur
 
  if (addr[0] != DS18B20) // Vérifie qu'il s'agit bien d'un DS18B20
    return false;         // 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(800);             // 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
   
  // Calcul de la température en degré Celsius
  *temp = ((data[1] << 8) | data[0]) * 0.0625 -2;
   
  // Pas d'erreur
  return true;
}
 
// setup()
void setup() {
  Serial.begin(9600); // Initialisation du port série
}
 
// loop()
void loop() {
  float temp;
   
  // Lit la température ambiante à ~1Hz
  if(getTemperature(&temp)) {
     
    // Affiche la température
    Serial.print("essai : ");
     Serial.print(getTemperature);
    Serial.print("Temperature : ");
    Serial.print(temp);
    Serial.write(176); // caractère °
    Serial.write('C');
    Serial.println();
  }
}

Comment l’insérer sans qu’il ne retarde le programme “rapide” ?
Merci

Urbann:
Bonjour,
J'utilise un petit programme simple qui tourne très vite et utilise 2 interruptions.
Je veux le modifier en ajoutant une valeur de température a partir d'un capeur DS18B20.
En suivant les différent exemples j'ai inséré un bout de code pour lire la température dans mon programme mais ça le ralenti de façon considérable puisque la lecture se fait environ toutes les 1 sec.
Etant débutant sur ce langage je coince

...

Comment l'insérer sans qu'il ne retarde le programme "rapide" ?
Merci

Bonsoir
La lib Onewire est truffée de "delay" :grin:
le Onewire doit respecter des timings tres contraignants

une solution (mais qui n'influera pas sur les "delay") consiste avec les DS18B20 de lancer l'acquisition et de lire le scratchpad
"quand on peut" , ça peut aider , mais il faut quand meme bien avoir à l'esprit que le bus Onewire est un bus lent 8)

C'est exactement ce qu'il me faut :stuck_out_tongue:
Lire la valeur de température toutes les secondes par exemple c'est largement suffisant
Mais j'ai cru comprendre que pendant cette lecture de température , le processeur ne pouvait pas faire autre chose. Exact ou Faux ?
Si c'est possible, traduit en code ça donne quoi ?

En OneWire effectivement ça monopolise le µC

Urbann:
C’est exactement ce qu’il me faut :stuck_out_tongue:
Lire la valeur de température toutes les secondes par exemple c’est largement suffisant
Mais j’ai cru comprendre que pendant cette lecture de température , le processeur ne pouvait pas faire autre chose. Exact ou Faux ?
Si c’est possible, traduit en code ça donne quoi ?

bonjour
ce qui est excessivement penalisant c’est ça

delay(800); // Et on attend la fin de la mesure
et pour limiter cette penalisation il faut proceder à l’envers et avec millis :grin:

principe :

si millis() > temps_ancien+1000 , 1000=lecture toutes les 1000 millisecondes
alors
lire le scratchpad = ds.write(0xBE);
temps_ancien=millis()
lancer une demande d’acquisition =ds.write(0x44, 1);

NB : la premiere lecture du scratchpad sera evidemment foireuse puisque la 1ere demande d’acquisition de T° viendra seulement apres la 1ere lecture.

B@tto:
En OneWire effectivement ça monopolise le µC

bonjour B@tto
la ce qui est vraiment penalisant c'est le delay 800
ce n'est pas un vrai delay de bus onewire , mais le delai necessaire pour effectuer en interne la conversion (d'ailleurs ce delai varie selon la resolution souhaitée entre +4 ms pour 9bits jusqu'à 750 ms pour 12 bits)

Bonjour,

Il existe une façon simple de transformer cette fonction en une fonction non bloquante.
Mais si tu es débutant tu risques de galérer un peu à faire fonctionner une version non bloquante.
Regarde l'exemple "BlinkWithoutDelay", voir si tu comprends.

Tu fais quoi de la température mesurée ? En quoi le délai est gênant dans ton application ?
Si ça ce trouve un capteur plus classique style LM35 pourrait remplacer avantageusement ton DS18B20 :wink:

NB : si tu n'as qu'un seul DS18B20, la fonction te retournera une erreur une fois sur deux. C'est précisé dans les commentaires de mon article d'où le code est tiré :wink:

Artouste:
(d'ailleurs ce delai varie selon la resolution souhaitée entre +4 ms pour 9bits jusqu'à 750 ms pour 12 bits)

Pour ceux que ça intéresse, voici un code (théorique) qui permet de changer la résolution de la conversion :