La cause des mauvaises performances est l'utilisation de valeurs à virgule flottante.
Je vais montrer comment m'en débarrasser.
D'abord nous parler de précision:
- Le TMP36 a une portée de 500 ° C (de -50 ° C à + 450 ° C).
- La lecture analogique fonctionne sur 10 bits de 0 à 1023 (1024 valeurs possibles).
La précision est donc de 500/1024. Environ 0,5 ° C.
Donc, si nous voulons coder la température sur un int
, le bit moins significatif de ce int
doit coder pour 0,5 ° C au lieu de 1 ° C.
Exemple:
int celciusTemperatureByHalfDegree = +40; // +20.0°C
int celciusTemperatureByHalfDegree = +41; // +20.5°C
int celciusTemperatureByHalfDegree = -10; // -5.0°C
int celciusTemperatureByHalfDegree = -15; // -5.5°C
On voit que:
celciusTemperatureByHalfDegree = celciusTemperature * 2
Environ aura:
int reading = analogRead(PIN);
int voltage = (reading * 500)/1024;
int celciusTemperature = voltage - 50;
int celciusTemperatureByHalfDegree = celciusTemperature * 2;
A ce stade, un trop-plein et les problèmes d'arrondi font que ce code soit inutile.
Simplifions il:
int reading = (analogRead(PIN) * 500)/1024;
int celciusTemperatureByHalfDegree = (reading - 50) * 2;
Et encore:
int reading = (analogRead(PIN) * 500)/512;
int celciusTemperatureByHalfDegree = reading - 100;
Et encore:
int reading = (analogRead(PIN) * 125)/128;
int celciusTemperatureByHalfDegree = reading - 100;
A ce stade, il n'y a pas de problème plus arrondi. Mais analogRead()
donne une sortie entre 0 et 1023.
Et 1023 * 125
est plus grand que max int16
(32767), si le dépassement est possible.
Ici, nous allons utiliser 125 = 5 * 25 et 128 = 4 * 32.
int reading = (analogRead(PIN) * 5 * 25)/(4 * 32);
int celciusTemperatureByHalfDegree = reading - 100;
deuiendront:
int reading = analogRead(PIN); // 0 to 1023
reading *= 5; // 0 to 5115 (no overflow)
reading /= 4; // 0 to 1278 (no overflow)
reading *= 25; // 0 to 31950 (no overflow)
reading /= 32; // 0 to 998
int celciusTemperatureByHalfDegree = reading - 100;
Enfin, pour l'imprimer nous utiliserons ce code:
// print the integer value of the temperature
Serial.print(celciusTemperatureByHalfDegree/2);
Serial.print(".");
// less significant bit code for "__.0" of "__.5"
Serial.print(celciusTemperatureByHalfDegree % 2 ? '5' : '0');
Serial.print("°C");
Je pense qu'il serait plus utile de remplacer la balise [précision] avec une langue marque. –