Capteur AHT20 température et humidité sans librairie et sans utilisation du type float
Bonjour,
Voici mon code pour lire l'humidité et la température d'un capteur AHT20 sans libraire et sans utiliser de float
Compilé tout seul, il prend 6256 octets de flash et 404 octets de RAM
Mais quand je retire les fonctions Serial.XXX() et que j'intègre ce code à un projet existant qui utilise déjà <Wire.h> et sprintf_P(), alors cela ne me coûte que 690 octets de flash et 4 octets de RAM en plus.
A peine plus que ce que j'ai économisé en optimisant le code pour piloter la RTC I2C 8-)
Autre avantage : on utilise pas le type float (consommateur de ressources et compliqué à gérer avec Arduino)
Le capteur renvoi les données sur 20 bits mais c'est beaucoup trop étant donné sa précision :
+/- 2% pour l'hygrométrie relative (sur une échelle de valeurs allant de 0% à 100%)
+/- 0,3°C pour la température (sur une échelle de valeurs allant de -50°C à 150°C)
Etant donné la précision du capteur d'humidité un seul octet non signé suffit pour stocker une valeur de 0 à 100
La température en dixièmes de degrés (multipliée par dix) est stockée dans un entier signé (il suffit d'en tenir compte dans les calculs et pour l'affichage)
Le capteur est théoriquement capable de renvoyer des températures de -50°C à 150°C mais les composants électroniques cesseront de fonctionner avant que ces températures soient atteintes :aie: :mouarf:
Ce capteur est plutôt précis et il est assez réactif, sauf quand on passe d'une atmosphère humide à une atmosphère sèche, dans ce sens là, le temps de réponse est plus long (il faut attendre 30 secondes mais c'est déjà assez court)
On peut l'alimenter en 5V ou en 3.3V, je l'ai alimenté en 3.3V car il partage le bus I2C avec une RTC alimentée en 3.3V
J'ai laissé en commentaires la fonction qui retourne les valeurs en float.
A bientôt
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| #include <Wire.h>
#define AHT20_ADDRESS 0x38
void setup() {
Serial.begin(115200);
Serial.println(F("ATH20 TEST"));
ATH20_begin();
delay(40); // Needed, if no, first humidity values are bad
}
void loop() {
//float humi, temp;
//if(ATH20_getSensor(&humi, &temp)) {
byte humi;
int temp;
int temp10;
char Buff[50];
if(ATH20_getSensor_B(&humi, &temp)) {
temp10 = temp/10;
sprintf_P(Buff, PSTR("Humidity: %d Temperature %d.%d"),humi,temp10,(temp-temp10*10));
Serial.println(Buff);
} else {
Serial.println(F("ERROR"));
}
delay(100);
}
void ATH20_begin() {
Wire.begin();
Wire.beginTransmission(AHT20_ADDRESS); // transmit to device #8
Wire.write(0xBE);
Wire.endTransmission(); // stop transmitting
}
bool ATH20_startSensor() {
Wire.beginTransmission(AHT20_ADDRESS); // transmit to device #8
Wire.write(0xac);
Wire.write(0x33);
Wire.write(0x00);
Wire.endTransmission(); // stop transmitting
unsigned long timer_s = millis();
while(1) {
if(millis()-timer_s > 200) return false; // time out
Wire.requestFrom(AHT20_ADDRESS, 1);
while(Wire.available()) {
unsigned char c = Wire.read();
if(c&0x80 != 0)return true; // busy
}
delay(20);
}
}
bool ATH20_getSensor_B(byte *h, int *t) {
ATH20_startSensor();
Wire.requestFrom(AHT20_ADDRESS, 6);
unsigned char str[6];
int index = 0;
while (Wire.available()) {
str[index++] = Wire.read(); // receive a byte as character
}
if(str[0] & 0x80)return false;
int __humi; // According to humidity sensor accurate, one byte for humidity is OK
__humi = 100 * str[1] / 255;
*h = (byte) __humi;
long __temp; // According to temperature sensor accurate, 14 bits is OK
__temp = str[3]&0x0f;
__temp <<=8;
__temp += str[4];
__temp <<=2;
__temp += str[5] >> 6;
// temperature = __temp / 16384.0 * 200.0 - 50.0;
// = __temp / 81.92 - 50.0;
// temperature * 10 = 10 * __temp / 81.92 - 500; // According to sensor accurate, we return temp*10 as int (0.1°C step)
__temp = 1000 * __temp / 8192 - 500;
*t = (int) __temp;
return true;
}
/*
bool ATH20_getSensor(float *h, float *t) {
ATH20_startSensor();
Wire.requestFrom(AHT20_ADDRESS, 6);
unsigned char str[6];
int index = 0;
while (Wire.available()) {
str[index++] = Wire.read(); // receive a byte as character
}
if(str[0] & 0x80)return false;
unsigned long __humi = 0;
unsigned long __temp = 0;
__humi = str[1];
__humi <<= 8;
__humi += str[2];
__humi <<= 4;
__humi += str[3] >> 4;
// str[1] str[2] str[3]
// __humi = 76543210 76543210 7654 (20 bits)
// 100% = 11111111 11111111 1111
// 0% = 00000000 00000000 0000
*h = (float)__humi/1048576.0;
__temp = str[3]&0x0f;
__temp <<=8;
__temp += str[4];
__temp <<=8;
__temp += str[5];
// str[3] str[4] str[5]
// __temp = 3210 76543210 76543210 (20 bits)
// 150°C = 1111 11111111 11111111
// -50°C = 0000 00000000 00000000
*t = (float)__temp/1048576.0*200.0-50.0;
return true;
}
*/ |