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"
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
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 ?
Urbann:
C’est exactement ce qu’il me faut
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
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)
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
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é
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 :