La température monte…

Pour pouvoir faire le suivi d’une cave à vin, j’avais besoin de plusieurs capteurs de température et d’humidité, pas le top mais tout de même assez précis.

Voici un petit tour des différents capteurs pas trop cher (moins de 6 euros) et facilement accessible que j’ai testé. Ils sont tous utilisable avec une carte Arduino et accepte du 5v (sauf le BME280 qui est en 3v3 mais le breakout permet l’alimentation en 5v). A la fin de l’article, vous trouverez le programme pour les contrôler tous AHAHAH…hum… les faire fonctionner tous.

Le DS18B20 de Maxim (ex Dallas)

Voici un capteur de température, plus petit (boitier TO92), simple mais efficace, précis et avec une résolution à 2 décimales. Il ne fait que la température mais m’a servi à avoir une première référence. Communication en 1-wire.

Le DHT11 de Aosong

Le capteur de base pour les arduinistes avec mesure de la température et l’humidité. Petit capteur pas cher … et pas très précis surtout pour l’humidité relative. Il ne peut pas mesurer de température négative et est limité sur la plage pour l’humidité relative. Il n’a pas de décimale pour les valeurs. Communication en 1-wire spécifique.

Le DHT22 (AM2302) de Aosong

Le grand frère du DHT11, plus gros, plus précis, plus cher. Il peut mesurer des températures négatives et utilise la plage 0 à 100% pour l’humidité relative. Il propose également une résolution à une décimale. Communication en 1-wire spécifique.

Le DHT12 de Aosong

Le petit frère de la famille DHT. Il est plus petit que les deux mais précis et d’un cout moindre que le DHT22. Il a une résolution à une décimale. Communication en I²C ou en single-bus.

Le AM2320 de Aosong

Disons un cousin des DHT, légèrement inférieur en taille que le DHT11, il est noir, à 4 pin comme le DHT12. Communication en I²C ou en single-bus.

Le BME280 de Bosch

Ce capteur permet de mesurer la température, l’humidité et la pression atmosphérique. Il est vraiment tout petit (4mm² à vue d’oeil) et ne consomme quasiment rien, parfait pour être intégré dans un smartphone par exemple. En prenant en compte la pression atmosphérique au niveau de la mer, il permet de calculer l’altitude. Plus cher que les autres, plus de fonctions. Communication en I²C ou SPI.

 

Le montage

Il y a des résistances (ici de 4,7kOhm ou 10kOhm) sur tous les cables Data (DATA, SCL, SDA).

 

Alimentation et branchement en fonction des datasheet.

La librairie softwareWire permet de faire de l’I²C avec d’autres pins de la carte Arduino que les pins réservées (à savoir A4 et A5), vous pouvez choisir celles que vous voulez et surtout vous pouvez donc gérer plusieurs devices I²C qui ont la même adresse en créant plusieurs bus I²C (un par device avec la même adresse). Ici le DHT12 et l’AM2320 sont sur 2 bus différents car ils ont la même adresse.

 

 

Les tests

La sortie de la console de l’IDE Arduino (DHT11 sans DHT22) :

DS18B20 : Temperature : 22.37 *C
DHT11 : Temperature : 21.00 *C , Humidite : 20.00 %
DHT12 : Temperature : 22.00 *C , Humidite : 49.20%
BME280 : Temperature : 25.01 *C , Humidite : 47.20 % , Pressure : 1008.75 hPa , Approx. Altitude : 86.84 m
AM2320 : Temperature : 23.20 *C , Humidite : 51.40%

La sortie de la console de l’IDE Arduino (DHT22 sans DHT11) :

DS18B20 : Temperature : 22.37 *C
DHT22 : Temperature : 23.40 *C , Humidite : 1.00 %
DHT12 : Temperature : 21.90 *C , Humidite : 49.50%
BME280 : Temperature : 24.97 *C , Humidite : 47.22 % , Pressure : 1008.70 hPa , Approx. Altitude : 87.30 m
AM2320 : Temperature : 23.20 *C , Humidite : 51.20%

En effet je n’ai pas réussi a faire fonctionner en même temps les DHT11 et DHT22 ni à récupérer l’humidité avec le DHT22 (à moins que le capteur ne soit cuit).

Analyse

N’ayant pas de d’outil pour faire la calibration, c’est la moyenne et les valeurs les plus proche du thermomètre qui me semble les plus fiables. Le thermomètre affiche 23°C.

Les DS18B20, DHT22 et AM2320 affichent une température très proche de celle du thermomètre. Le DHT12 a 1 degré d’écart et les BME280 et DHT11 2 degrés d’écart. Cependant entre 20 et 30 degrés, les écarts semblent rester constant. Il suffit donc de gérer un offset pour récupérer la bonne température.

concernant l’humidité relative, à part le problème avec le DHT22 et le DHT11 qui est à son minima, les autres capteurs sont aux alentours des 50% en intérieur (les sites météo donne une humidité relative d’environ 70% en extérieur). En soufflant doucement sur les capteurs, l’humidité relative s’envole (+ de 90%), sauf pour le DHT22 qui ne bouge pas et le DHT11 qui mont péniblement à 70% (en soufflant longtemps… dessus). Très bon point pour le BME280 qui est le premier à revenir à un niveau proche de 50% suivi par l’AM2320 un peu plus lent et en dernier les DHT12 et surtout le DHT11.

Conclusion

Malgré la bonne réactivité du BME280 (et juste l’offset sur la température) et le fonctionnement très correct de DHT12 (également avec un offset), le capteur que je vais utiliser sera l’AM2320 qui est plus calibré un peu moins réactif mais un peu moins cher et surtout avec un format plus adapté que le breakout.

 

Des liens qui peuvent être utiles et qui m’ont (fortement) inspirés :

Les différents codes :

Les exemples fournis dans les librairies et

DHT11DHT22 – carnet du maker

DS18B20 – carnet du maker

Playground Arduino

Les librairies pour Arduino :

les librairies disponibles sur Arduino (voir en tête du code)

Adafruit_Sensor
Adafruit_BME280

DHTxx

BME280 – library Adafruit

I²C softwareWire

AM2320_SOFTWIRE // modification de la librairie AM2320 https://github.com/lazyscheduler/AM2320 (à venir sur le github des Fabriqueurs)

Les datasheet :

DS18B20 – Datasheet

DHT11 – Datasheet

DHT22 (AM2302) – Datasheet

DHT12 – Datasheet

AM2320 – Datasheet

BME280 – Datasheet

Petit bonus : voici comment calculer la température en Fahrenheit

Fahrenheit = Celsius x 1.8 + 32.0

et bien sur l’inverse Celsius  = (Fahrenheit – 32) / 1.8

Petit bonus 2 : le BME280 est également un bon capteur de pression. La pression atmosphérique varie en fonction de l’altitude. Si on connait la pression au niveau de la mer, on peut en déduire l’altitude à laquelle se trouve le capteur. Il faut récupérer la pression au niveau de la mer de l’endroit ou se trouve le capteur. Vous trouverez l’information sur des site tel que pression niveau de la mer. La pression atmosphérique est donné en hPa (hectopascal). Puis il suffit d’utiliser la commande de la bibliothèque Adafruit.

readAltitude(xxxx.x); //avec xxxx.x étant la pression en hPa avec une décimale

Le code

Le DHT11 est en commentaire pour faire fonctionner le DHT22.

[pastacode lang=”c” manual=”%23include%20%3COneWire.h%3E%20%2F%2F%20pour%20le%20protocole%201-wire%20avec%20le%20DSB1820%20%2F%2F%20dispo%20sur%20les%20librairies%20Arduino%0A%23include%20%3CWire.h%3E%20%2F%2F%20pour%20le%20bus%20I%C2%B2C%0A%23include%20%3CSPI.h%3E%0A%23include%20%3CAdafruit_Sensor.h%3E%0A%23include%20%3CAdafruit_BME280.h%3E%0A%23include%20%3Cdht.h%3E%2F%2F%20DHT12%0A%23include%20%3CSoftwareWire.h%3E%20%2F%2F%20g%C3%A9rer%20plusieurs%20devices%20I2C%20avec%20la%20m%C3%AAme%20adresse%20sur%20plusieurs%20couple%20pins%20SDA%20SCL%20(autre%20que%20les%20pins%20standard)%20https%3A%2F%2Fgithub.com%2FTestato%2FSoftwareWire%0A%23include%20%3CAM2320_SOFTWIRE.h%3E%20%2F%2F%20modification%20de%20la%20librairie%20AM2320%20https%3A%2F%2Fgithub.com%2Flazyscheduler%2FAM2320%20%2F%2F%20original%20AM2320%20https%3A%2F%2Fgithub.com%2Fhibikiledo%2FAM2320%20%2F%2F%20http%3A%2F%2Fwww.instructables.com%2Fid%2FConnecting-AM2320-With-Arduino%2F%20%0A%2F%2F%20cela%20permet%20d’avoir%20%C3%A9galement%20la%20librairie%20AM2320%20hardwire%0A%0A%2F%2F%20infos%20pour%20le%20DS18B20%0A%2F%2F%20OneWire%20DS18S20%2C%20DS18B20%2C%20DS1822%20Temperature%20Example%0A%2F%2F%20http%3A%2F%2Fwww.pjrc.com%2Fteensy%2Ftd_libs_OneWire.html%0A%2F%2F%20The%20DallasTemperature%20library%20can%20do%20all%20this%20work%20for%20you!%0A%2F%2F%20http%3A%2F%2Fmilesburton.com%2FDallas_Temperature_Control_Library%0AOneWire%20%20ds(9)%3B%20%20%2F%2F%20on%20pin%209%20(a%204.7K%20resistor%20is%20necessary)%0A%2F%2Fadresse%20du%20capteur%20%3A28%20FF%20A2%2041%2020%2016%2004%2024%20%0A%0A%2F%2F%20infos%20pour%20le%20BME280%20temperature%20humidit%C3%A9%20pression%0A%23define%20BME_SCK%2013%20%20%2F%2F%20SCL%0A%23define%20BME_MISO%2012%20%2F%2F%20SDO%0A%23define%20BME_MOSI%2011%20%2F%2F%20SDA%0A%23define%20BME_CS%2010%20%20%20%2F%2F%20CSB%20ou%20SS%0A%23define%20SEALEVELPRESSURE_HPA%20(1019.2)%20%2F%2F%20pression%20au%20niveau%20de%20la%20mer%20http%3A%2F%2Fwww.infoclimat.fr%2Fcartes%2Fobservations-meteo%2Ftemps-reel%2Fpression-au-niveau-de-la-mer%2Ffrance.html%0A%2F%2FAdafruit_BME280%20bme%3B%20%2F%2F%20I2C%0AAdafruit_BME280%20bme(BME_CS)%3B%20%2F%2F%20hardware%20SPI%0A%2F%2FAdafruit_BME280%20bme(BME_CS%2C%20BME_MOSI%2C%20BME_MISO%2C%20BME_SCK)%3B%20%2F%2F%20software%20SPI%0Aunsigned%20long%20delayTime%3B%0A%0A%2F%2F%20infos%20pour%20le%20DHT11%0A%2F%2F%20de%20face%20%3A%20Pin%20Definition%201.VDD%202.DATA%203.non%20connect%C3%A9%204.GND%0Aconst%20byte%20BROCHE_CAPTEUR_DHT11%20%3D%208%3B%2F%2F%20pin%20DATA%20du%20capteur%20%2F%20Resistance%20de%20pullup%20broche%20data-Vcc%2010k%20%2B%20condensateur%20100nf%20Vcc–%7C%7C–gnd%0A%2F%2F%20infos%20pour%20le%20DHT22%0A%2F%2F%20de%20face%20%3A%20Pin%20Definition%201.VDD%202.DATA%203.non%20connect%C3%A9%204.GND%0Aconst%20byte%20BROCHE_CAPTEUR_DHT22%20%3D%207%3B%2F%2F%20pin%20DATA%20du%20capteur%20%2F%20Resistance%20de%20pullup%20broche%20data-Vcc%2010k%20%2B%20condensateur%20100nf%20Vcc–%7C%7C–gnd%0A%2F*%20Code%20d’erreur%20de%20la%20fonction%20readDHT11()%20et%20readDHT22()%20*%2F%0Aconst%20byte%20DHT_SUCCESS%20%3D%200%3B%20%20%20%20%20%20%20%20%2F%2F%20Pas%20d’erreur%0Aconst%20byte%20DHT_TIMEOUT_ERROR%20%3D%201%3B%20%20%2F%2F%20Temps%20d’attente%20d%C3%A9pass%C3%A9%0Aconst%20byte%20DHT_CHECKSUM_ERROR%20%3D%202%3B%20%2F%2F%20Donn%C3%A9es%20re%C3%A7ues%20erron%C3%A9es%0A%2F%2F%20infos%20pour%20le%20DHT12%0A%2F%2F%20de%20face%20%3A%20%20%20Pin%20Definition%201.VDD%202.SDA%203.GND%204.SCL%0Adht12%20DHT(0x5c)%3B%0A%0A%2F%2F%20Pou%20l’AM2320%20Pin%20Definition%201.VDD%202.SDA%203.GND%204.SCL%0AAM2320_SOFTWIRE%20sensor(6%2C5)%3B%20%2F%2Fpin%205%20et%206%20de%20la%20carte%20arduinio%0A%0A%0A%0Avoid%20setup(void)%20%7B%0A%20%20Serial.begin(115200)%3B%0A%20%20%20%20Serial.println(F(%22Test%20BME280%20%2F%20DS18B20%20%2F%20DHT11%20%2F%20DHT22%20%2F%20DHT12%20%2F%20AM2320%22))%3B%0A%0A%20%20%20%20bool%20status%3B%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20default%20settings%0A%20%20%20%20status%20%3D%20bme.begin()%3B%0A%20%20%20%20if%20(!status)%20%7B%0A%20%20%20%20%20%20%20%20Serial.println(%22Could%20not%20find%20a%20valid%20BME280%20sensor%2C%20check%20wiring!%22)%3B%0A%20%20%20%20%20%20%20%20while%20(1)%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0A%20%20%20%20delayTime%20%3D%202000%3B%0A%0A%20%20%20%20%2F*%20Place%20la%20broche%20du%20capteur%20en%20entr%C3%A9e%20avec%20pull-up%20*%2F%0A%20%20%20%20pinMode(BROCHE_CAPTEUR_DHT11%2C%20INPUT_PULLUP)%3B%0A%20%20%20%20pinMode(BROCHE_CAPTEUR_DHT22%2C%20INPUT_PULLUP)%3B%0A%0A%20%20%20%20delay(1000)%3B%20%2F%2F%20let%20sensor%20boot%20up%0A%20%20%20%20Serial.println(%22end%20setup%22)%3B%0A%7D%0A%0Avoid%20loop(void)%20%7B%0A%20%20%2F%2F—%20DS18B20%20end%0A%20%20byte%20i%3B%0A%20%20byte%20present%20%3D%200%3B%0A%20%20byte%20type_s%3B%0A%20%20byte%20data%5B12%5D%3B%0A%20%20byte%20addr%5B8%5D%3B%0A%20%20%0A%20%20float%20celsius%2C%20fahrenheit%3B%0A%20%20%0A%20%20if%20(%20!ds.search(addr))%20%7B%0A%20%20%20%20%2F%2FSerial.println(%22No%20more%20addresses.%22)%3B%0A%20%20%20%20%2F%2FSerial.println()%3B%0A%20%20%20%20ds.reset_search()%3B%0A%20%20%20%20delay(250)%3B%0A%20%20%20%20return%3B%0A%20%20%7D%0A%20%20%0A%20%20%2F%2FSerial.print(%22ROM%20%3D%22)%3B%0A%20%20for(%20i%20%3D%200%3B%20i%20%3C%208%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%2F%2FSerial.write(‘%20’)%3B%0A%20%20%20%20%2F%2FSerial.print(addr%5Bi%5D%2C%20HEX)%3B%0A%20%20%7D%0A%0A%20%20if%20(OneWire%3A%3Acrc8(addr%2C%207)%20!%3D%20addr%5B7%5D)%20%7B%0A%20%20%20%20%20%20Serial.println(%22CRC%20is%20not%20valid!%22)%3B%0A%20%20%20%20%20%20return%3B%0A%20%20%7D%0A%20%20%2F%2FSerial.println()%3B%0A%20%0A%20%20%2F%2F%20the%20first%20ROM%20byte%20indicates%20which%20chip%0A%20%20switch%20(addr%5B0%5D)%20%7B%0A%20%20%20%20case%200×10%3A%0A%20%20%20%20%20%20Serial.println(%22%20%20Chip%20%3D%20DS18S20%22)%3B%20%20%2F%2F%20or%20old%20DS1820%0A%20%20%20%20%20%20type_s%20%3D%201%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%20case%200×28%3A%0A%20%20%20%20%20%20%2F%2FSerial.println(%22%20%20Chip%20%3D%20DS18B20%22)%3B%0A%20%20%20%20%20%20type_s%20%3D%200%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%20case%200×22%3A%0A%20%20%20%20%20%20Serial.println(%22%20%20Chip%20%3D%20DS1822%22)%3B%0A%20%20%20%20%20%20type_s%20%3D%200%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%20default%3A%0A%20%20%20%20%20%20Serial.println(%22Device%20is%20not%20a%20DS18x20%20family%20device.%22)%3B%0A%20%20%20%20%20%20return%3B%0A%20%20%7D%20%0A%0A%20%20ds.reset()%3B%0A%20%20ds.select(addr)%3B%0A%20%20ds.write(0x44%2C%201)%3B%20%20%20%20%20%20%20%20%2F%2F%20start%20conversion%2C%20with%20parasite%20power%20on%20at%20the%20end%0A%20%20%0A%20%20delay(2000)%3B%20%20%20%20%20%2F%2F%20maybe%20750ms%20is%20enough%2C%20maybe%20not%0A%20%20%2F%2F%20we%20might%20do%20a%20ds.depower()%20here%2C%20but%20the%20reset%20will%20take%20care%20of%20it.%0A%20%20%0A%20%20present%20%3D%20ds.reset()%3B%0A%20%20ds.select(addr)%3B%20%20%20%20%0A%20%20ds.write(0xBE)%3B%20%20%20%20%20%20%20%20%20%2F%2F%20Read%20Scratchpad%0A%0A%20%20%2F%2FSerial.print(%22%20%20Data%20%3D%20%22)%3B%0A%20%20%2F%2FSerial.print(present%2C%20HEX)%3B%0A%20%20%2F%2FSerial.print(%22%20%22)%3B%0A%20%20for%20(%20i%20%3D%200%3B%20i%20%3C%209%3B%20i%2B%2B)%20%7B%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20we%20need%209%20bytes%0A%20%20%20%20data%5Bi%5D%20%3D%20ds.read()%3B%0A%20%20%20%20%2F%2FSerial.print(data%5Bi%5D%2C%20HEX)%3B%0A%20%20%20%20%2F%2FSerial.print(%22%20%22)%3B%0A%20%20%7D%0A%20%20%2F%2FSerial.print(%22%20CRC%3D%22)%3B%0A%20%20%2F%2FSerial.print(OneWire%3A%3Acrc8(data%2C%208)%2C%20HEX)%3B%0A%20%20%2F%2FSerial.println()%3B%0A%0A%20%20%2F%2F%20Convert%20the%20data%20to%20actual%20temperature%0A%20%20%2F%2F%20because%20the%20result%20is%20a%2016%20bit%20signed%20integer%2C%20it%20should%0A%20%20%2F%2F%20be%20stored%20to%20an%20%22int16_t%22%20type%2C%20which%20is%20always%2016%20bits%0A%20%20%2F%2F%20even%20when%20compiled%20on%20a%2032%20bit%20processor.%0A%20%20int16_t%20raw%20%3D%20(data%5B1%5D%20%3C%3C%208)%20%7C%20data%5B0%5D%3B%0A%20%20if%20(type_s)%20%7B%0A%20%20%20%20raw%20%3D%20raw%20%3C%3C%203%3B%20%2F%2F%209%20bit%20resolution%20default%0A%20%20%20%20if%20(data%5B7%5D%20%3D%3D%200×10)%20%7B%0A%20%20%20%20%20%20%2F%2F%20%22count%20remain%22%20gives%20full%2012%20bit%20resolution%0A%20%20%20%20%20%20raw%20%3D%20(raw%20%26%200xFFF0)%20%2B%2012%20-%20data%5B6%5D%3B%0A%20%20%20%20%7D%0A%20%20%7D%20else%20%7B%0A%20%20%20%20byte%20cfg%20%3D%20(data%5B4%5D%20%26%200×60)%3B%0A%20%20%20%20%2F%2F%20at%20lower%20res%2C%20the%20low%20bits%20are%20undefined%2C%20so%20let’s%20zero%20them%0A%20%20%20%20if%20(cfg%20%3D%3D%200×00)%20raw%20%3D%20raw%20%26%20~7%3B%20%20%2F%2F%209%20bit%20resolution%2C%2093.75%20ms%0A%20%20%20%20else%20if%20(cfg%20%3D%3D%200×20)%20raw%20%3D%20raw%20%26%20~3%3B%20%2F%2F%2010%20bit%20res%2C%20187.5%20ms%0A%20%20%20%20else%20if%20(cfg%20%3D%3D%200×40)%20raw%20%3D%20raw%20%26%20~1%3B%20%2F%2F%2011%20bit%20res%2C%20375%20ms%0A%20%20%20%20%2F%2F%2F%2F%20default%20is%2012%20bit%20resolution%2C%20750%20ms%20conversion%20time%0A%20%20%7D%0A%20%20celsius%20%3D%20(float)raw%20%2F%2016.0%3B%0A%20%20Serial.print(%22DS18B20%20%3A%20%22)%3B%0A%20%20Serial.print(%22Temperature%20%3A%20%22)%3B%0A%20%20Serial.print(celsius)%3B%0A%20%20Serial.println(%22%20*C%22)%3B%0A%20%20%2F%2F—%20DS18B20%20end%0A%20%20%0A%20%20%2F%2F—%20DHT11%20start%0A%20%20float%20temperature%2C%20humidity%3B%0A%20%20%2F*%20Lecture%20de%20la%20temp%C3%A9rature%20et%20de%20l’humidit%C3%A9%2C%20avec%20gestion%20des%20erreurs%20*%2F%0A%20%20%2F%2F%20N.B.%20Remplacer%20readDHT11%20par%20readDHT22%20en%20fonction%20du%20capteur%20utilis%C3%A9%20!%0A%20%20byte%20retourDHT11%3D%20%20readDHT11(BROCHE_CAPTEUR_DHT11%2C%20%26temperature%2C%20%26humidity)%3B%0A%0A%20%20switch%20(retourDHT11)%20%7B%0A%20%20%20%20case%20DHT_SUCCESS%3A%20%0A%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%2F*%20Affichage%20de%20la%20temp%C3%A9rature%20et%20du%20taux%20d’humidit%C3%A9%20*%2F%0A%20%20%20%20%20%20Serial.print(%22DHT11%20%20%20%3A%20%22)%3B%0A%20%20%20%20%20%20Serial.print(F(%22Temperature%20%3A%20%22))%3B%0A%20%20%20%20%20%20Serial.print(temperature%2C%202)%3B%0A%20%20%20%20%20%20Serial.print(%22%20*C%20%2C%20%22)%3B%0A%20%20%20%20%20%20Serial.print(F(%22Humidite%20%3A%20%22))%3B%0A%20%20%20%20%20%20Serial.print(humidity%2C%202)%3B%0A%20%20%20%20%20%20Serial.println(%22%20%25%22)%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%0A%20%20%20%20case%20DHT_TIMEOUT_ERROR%3A%20%0A%20%20%20%20%20%20Serial.println(F(%22Pas%20de%20reponse%20!%22))%3B%20%0A%20%20%20%20%20%20break%3B%0A%20%20%20%0A%20%20%20%20case%20DHT_CHECKSUM_ERROR%3A%20%0A%20%20%20%20%20%20Serial.println(F(%22Pb%20de%20communication%20!%22))%3B%20%0A%20%20%20%20%20%20break%3B%0A%20%20%7D%0A%20%20%0A%20%20%2F*%20Pas%20plus%20d’une%20mesure%20par%20seconde%20*%2F%0A%20%20%2F%2F%20N.B.%20Avec%20le%20DHT22%20il%20est%20possible%20de%20r%C3%A9aliser%20deux%20mesures%20par%20seconde%0A%20%20%2F%2Fdelay(1000)%3B%0A%20%0A%20%20%2F%2F—%20DHT11%20end%0A%0A%20%20%2F%2F—%20DHT22%20start%0A%20%20%2F%2Ffloat%20temperature%2C%20humidity%3B%0A%20%20%2F*%20Lecture%20de%20la%20temp%C3%A9rature%20et%20de%20l’humidit%C3%A9%2C%20avec%20gestion%20des%20erreurs%20*%2F%0A%20%20%2F%2F%20N.B.%20Remplacer%20readDHT11%20par%20readDHT22%20en%20fonction%20du%20capteur%20utilis%C3%A9%20!%0A%2F*%20%20byte%20retourDHT22%3D%20%20readDHT22(BROCHE_CAPTEUR_DHT22%2C%20%26temperature%2C%20%26humidity)%3B%0A%0A%20%20switch%20(retourDHT22)%20%7B%0A%20%20%20%20case%20DHT_SUCCESS%3A%20%0A%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%2F*%20Affichage%20de%20la%20temp%C3%A9rature%20et%20du%20taux%20d’humidit%C3%A9%20*%2F%0A%2F*%20%20%20%20%20%20Serial.print(%22DHT22%20%20%20%3A%20%22)%3B%0A%20%20%20%20%20%20Serial.print(F(%22Temperature%20%3A%20%22))%3B%0A%20%20%20%20%20%20Serial.print(temperature%2C%202)%3B%0A%20%20%20%20%20%20Serial.print(%22%20*C%20%2C%20%22)%3B%0A%20%20%20%20%20%20Serial.print(F(%22Humidite%20%3A%20%22))%3B%0A%20%20%20%20%20%20Serial.print(humidity%2C%202)%3B%0A%20%20%20%20%20%20Serial.println(%22%20%25%22)%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%0A%20%20%20%20case%20DHT_TIMEOUT_ERROR%3A%20%0A%20%20%20%20%20%20Serial.println(F(%22Pas%20de%20reponse%20!%22))%3B%20%0A%20%20%20%20%20%20break%3B%0A%20%20%20%0A%20%20%20%20case%20DHT_CHECKSUM_ERROR%3A%20%0A%20%20%20%20%20%20Serial.println(F(%22Pb%20de%20communication%20!%22))%3B%20%0A%20%20%20%20%20%20break%3B%0A%20%20%7D%0A%20%20%0A%20%20%2F*%20Pas%20plus%20d’une%20mesure%20par%20seconde%20*%2F%0A%20%20%2F%2F%20N.B.%20Avec%20le%20DHT22%20il%20est%20possible%20de%20r%C3%A9aliser%20deux%20mesures%20par%20seconde%0A%20%20%2F%2Fdelay(1000)%3B%0A%20%20%2F%2F—%20DHT22%20end%0A%0A%20%20%2F%2F—%20DHT12%20start%0A%20%20unsigned%20long%20b%20%3D%20micros()%3B%0A%20%20dht%3A%3AReadStatus%20chk%20%3D%20DHT.read()%3B%0A%20%20unsigned%20long%20e%20%3D%20micros()%3B%0A%0A%20%20%2F%2FSerial.print(F(%22Read%20sensor%3A%20%22))%3B%0A%0A%20%20switch%20(chk)%0A%20%20%7B%0A%20%20%20%20case%20dht%3A%3AOK%3A%0A%20%20%20%20%20%20%2F%2FSerial.print(F(%22OK%2C%20took%20%22))%3B%0A%20%20%20%20%20%20%2F%2FSerial.print%20(e%20-%20b)%3B%20Serial.print(F(%22%20usec%2C%20%22))%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%20case%20dht%3A%3AERROR_CHECKSUM%3A%0A%20%20%20%20%20%20Serial.println(F(%22Checksum%20error%22))%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%20case%20dht%3A%3AERROR_TIMEOUT%3A%0A%20%20%20%20%20%20Serial.println(F(%22Timeout%20error%22))%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%20case%20dht%3A%3AERROR_CONNECT%3A%0A%20%20%20%20%20%20Serial.println(F(%22Connect%20error%22))%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%20case%20dht%3A%3AERROR_ACK_L%3A%0A%20%20%20%20%20%20Serial.println(F(%22AckL%20error%22))%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%20case%20dht%3A%3AERROR_ACK_H%3A%0A%20%20%20%20%20%20Serial.println(F(%22AckH%20error%22))%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%20default%3A%0A%20%20%20%20%20%20Serial.println(F(%22Unknown%20error%22))%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%7D%0A%0A%20%20Serial.print(%22DHT12%20%20%20%3A%20%22)%3B%0A%20%20Serial.print(F(%22Temperature%20%3A%20%22))%3B%0A%20%20Serial.print((float)DHT.getTemperature()%2F(float)10)%3B%0A%20%20Serial.print(%22%20*C%20%2C%20%22)%3B%0A%20%20Serial.print(F(%22Humidite%20%3A%20%22))%3B%0A%20%20Serial.print((float)DHT.getHumidity()%2F(float)10)%3B%0A%20%20Serial.println(F(%22%25%22))%3B%0A%0A%0A%20%20%2F%2FSerial.print(F(%22%2C%20Dew%20Point%20(degrees%20C)%3A%20%22))%3B%0A%20%20%2F%2FSerial.println(DHT.dewPoint())%3B%0A%20%20%2F%2F—%20DHT12%20end%0A%0A%20%20%2F%2F—%20BME280%20start%0A%20%20printValues()%3B%0A%20%20%2F%2F—%20BME280%20end%0A%0A%20%20%2F%2F—%20AM2320%20start%0A%20%20%2F%2F%20reveil%20du%20device%0A%20%20switch(sensor.Read())%20%7B%0A%20%20%20%20case%202%3A%0A%20%20%20%20%20%20Serial.println(%22CRC%20failed%22)%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%20case%201%3A%0A%20%20%20%20%20%20Serial.println(%22Sensor%20offline%22)%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%20%20case%200%3A%0A%20%20%20%20%20%20Serial.print(%22AM2320%20%20%3A%20%22)%3B%0A%20%20%20%20%20%20Serial.print(F(%22Temperature%20%3A%20%22))%3B%0A%20%20%20%20%20%20Serial.print(sensor.t)%3B%0A%20%20%20%20%20%20Serial.print(%22%20*C%20%2C%20%22)%3B%0A%20%20%20%20%20%20Serial.print(F(%22Humidite%20%3A%20%22))%3B%0A%20%20%20%20%20%20Serial.print(sensor.h)%3B%0A%20%20%20%20%20%20Serial.println(F(%22%25%22))%3B%0A%20%20%20%20%20%20break%3B%0A%20%20%7D%0A%0A%20%20%2F%2F—%20AM2320%20end%0A%0A%20%20Serial.println(%22%22)%3B%0A%0A%20%20delay(delayTime)%3B%0A%0A%7D%0A%2F%2F————-%0Avoid%20printValues()%20%7B%0A%20%20%20%20Serial.print(%22BME280%20%20%3A%20%22)%3B%0A%20%20%20%20Serial.print(%22Temperature%20%3A%20%22)%3B%0A%20%20%20%20Serial.print(bme.readTemperature())%3B%0A%20%20%20%20Serial.print(%22%20*C%20%2C%20%22)%3B%0A%20%20%20%20Serial.print(%22Humidite%20%3A%20%22)%3B%0A%20%20%20%20Serial.print(bme.readHumidity())%3B%0A%20%20%20%20Serial.print(%22%20%25%20%2C%20%22)%3B%0A%0A%20%20%20%20Serial.print(%22Pressure%20%3A%20%22)%3B%0A%20%20%20%20Serial.print(bme.readPressure()%20%2F%20100.0F)%3B%0A%20%20%20%20Serial.print(%22%20hPa%20%2C%20%22)%3B%0A%20%20%20%20Serial.print(%22Approx.%20Altitude%20%3A%20%22)%3B%0A%20%20%20%20Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA))%3B%0A%20%20%20%20Serial.println(%22%20m%22)%3B%0A%7D%0A%2F%2F————-%0Abyte%20readDHT11(byte%20pin%2C%20float*%20temperature%2C%20float*%20humidity)%20%7B%0A%20%20%0A%20%20%2F*%20Lit%20le%20capteur%20*%2F%0A%20%20byte%20data%5B5%5D%3B%0A%20%20byte%20ret%20%3D%20readDHTxx(pin%2C%20data%2C%2018%2C%201000)%3B%0A%20%20%0A%20%20%2F*%20D%C3%A9tecte%20et%20retourne%20les%20erreurs%20de%20communication%20*%2F%0A%20%20if%20(ret%20!%3D%20DHT_SUCCESS)%20%0A%20%20%20%20return%20ret%3B%0A%20%20%20%20%0A%20%20%2F*%20Calcul%20la%20vraie%20valeur%20de%20la%20temp%C3%A9rature%20et%20de%20l’humidit%C3%A9%20*%2F%0A%20%20*humidity%20%3D%20data%5B0%5D%3B%0A%20%20*temperature%20%3D%20data%5B2%5D%3B%0A%0A%20%20%2F*%20Ok%20*%2F%0A%20%20return%20DHT_SUCCESS%3B%0A%7D%0A%2F%2F————-%0Abyte%20readDHT22(byte%20pin%2C%20float*%20temperature%2C%20float*%20humidity)%20%7B%0A%20%20%0A%20%20%2F*%20Lit%20le%20capteur%20*%2F%0A%20%20byte%20data%5B5%5D%3B%0A%20%20byte%20ret%20%3D%20readDHTxx(pin%2C%20data%2C%201%2C%201000)%3B%0A%20%20%0A%20%20%2F*%20D%C3%A9tecte%20et%20retourne%20les%20erreurs%20de%20communication%20*%2F%0A%20%20if%20(ret%20!%3D%20DHT_SUCCESS)%20%0A%20%20%20%20return%20ret%3B%0A%20%20%20%20%0A%20%20%2F*%20Calcul%20la%20vraie%20valeur%20de%20la%20temp%C3%A9rature%20et%20de%20l’humidit%C3%A9%20*%2F%0A%20%20float%20fh%20%3D%20data%5B0%5D%3B%0A%20%20fh%20*%3D%20256%3B%0A%20%20fh%20%2B%3D%20data%5B1%5D%3B%0A%20%20fh%20*%3D%200.1%3B%0A%20%20*humidity%20%3D%20fh%3B%0A%20%0A%20%20float%20ft%20%3D%20data%5B2%5D%20%26%200x7f%3B%0A%20%20ft%20*%3D%20256%3B%0A%20%20ft%20%2B%3D%20data%5B3%5D%3B%0A%20%20ft%20*%3D%200.1%3B%0A%20%20if%20(data%5B2%5D%20%26%200×80)%20%7B%0A%20%20%20%20ft%20*%3D%20-1%3B%0A%20%20%7D%0A%20%20*temperature%20%3D%20ft%3B%0A%0A%20%20%2F*%20Ok%20*%2F%0A%20%20return%20DHT_SUCCESS%3B%0A%7D%0A%2F**%0A%20*%20Fonction%20bas%20niveau%20permettant%20de%20lire%20la%20temp%C3%A9rature%20et%20le%20taux%20d’humidit%C3%A9%20(en%20valeurs%20brutes)%20mesur%C3%A9%20par%20un%20capteur%20DHTxx.%0A%20*%2F%0Abyte%20readDHTxx(byte%20pin%2C%20byte*%20data%2C%20unsigned%20long%20start_time%2C%20unsigned%20long%20timeout)%20%7B%0A%20%20data%5B0%5D%20%3D%20data%5B1%5D%20%3D%20data%5B2%5D%20%3D%20data%5B3%5D%20%3D%20data%5B4%5D%20%3D%200%3B%0A%20%20%2F%2F%20start_time%20est%20en%20millisecondes%0A%20%20%2F%2F%20timeout%20est%20en%20microsecondes%0A%20%0A%20%20%2F*%20Conversion%20du%20num%C3%A9ro%20de%20broche%20Arduino%20en%20ports%20%2F%20masque%20binaire%20%22bas%20niveau%22%20*%2F%0A%20%20uint8_t%20bit%20%3D%20digitalPinToBitMask(pin)%3B%0A%20%20uint8_t%20port%20%3D%20digitalPinToPort(pin)%3B%0A%20%20volatile%20uint8_t%20*ddr%20%3D%20portModeRegister(port)%3B%20%20%20%2F%2F%20Registre%20MODE%20(INPUT%20%2F%20OUTPUT)%0A%20%20volatile%20uint8_t%20*out%20%3D%20portOutputRegister(port)%3B%20%2F%2F%20Registre%20OUT%20(%C3%A9criture)%0A%20%20volatile%20uint8_t%20*in%20%3D%20portInputRegister(port)%3B%20%20%20%2F%2F%20Registre%20IN%20(lecture)%0A%20%20%0A%20%20%2F*%20Conversion%20du%20temps%20de%20timeout%20en%20nombre%20de%20cycles%20processeur%20*%2F%0A%20%20unsigned%20long%20max_cycles%20%3D%20microsecondsToClockCycles(timeout)%3B%0A%20%0A%20%20%2F*%20Evite%20les%20probl%C3%A8mes%20de%20pull-up%20*%2F%0A%20%20*out%20%7C%3D%20bit%3B%20%20%2F%2F%20PULLUP%0A%20%20*ddr%20%26%3D%20~bit%3B%20%2F%2F%20INPUT%0A%20%20delay(100)%3B%20%20%20%2F%2F%20Laisse%20le%20temps%20%C3%A0%20la%20r%C3%A9sistance%20de%20pullup%20de%20mettre%20la%20ligne%20de%20donn%C3%A9es%20%C3%A0%20HIGH%0A%20%0A%20%20%2F*%20R%C3%A9veil%20du%20capteur%20*%2F%0A%20%20*ddr%20%7C%3D%20bit%3B%20%20%2F%2F%20OUTPUT%0A%20%20*out%20%26%3D%20~bit%3B%20%2F%2F%20LOW%0A%20%20delay(start_time)%3B%20%2F%2F%20Temps%20d’attente%20%C3%A0%20LOW%20causant%20le%20r%C3%A9veil%20du%20capteur%0A%20%20%2F%2F%20N.B.%20Il%20est%20impossible%20d’utilise%20delayMicroseconds()%20ici%20car%20un%20d%C3%A9lai%0A%20%20%2F%2F%20de%20plus%20de%2016%20millisecondes%20ne%20donne%20pas%20un%20timing%20assez%20pr%C3%A9cis.%0A%20%20%0A%20%20%2F*%20Portion%20de%20code%20critique%20-%20pas%20d’interruptions%20possibles%20*%2F%0A%20%20noInterrupts()%3B%0A%20%20%0A%20%20%2F*%20Passage%20en%20%C3%A9coute%20*%2F%0A%20%20*out%20%7C%3D%20bit%3B%20%20%2F%2F%20PULLUP%0A%20%20delayMicroseconds(40)%3B%0A%20%20*ddr%20%26%3D%20~bit%3B%20%2F%2F%20INPUT%0A%20%0A%20%20%2F*%20Attente%20de%20la%20r%C3%A9ponse%20du%20capteur%20*%2F%0A%20%20timeout%20%3D%200%3B%0A%20%20while(!(*in%20%26%20bit))%20%7B%20%2F*%20Attente%20d’un%20%C3%A9tat%20LOW%20*%2F%0A%20%20%20%20if%20(%2B%2Btimeout%20%3D%3D%20max_cycles)%20%7B%0A%20%20%20%20%20%20%20%20interrupts()%3B%0A%20%20%20%20%20%20%20%20return%20DHT_TIMEOUT_ERROR%3B%0A%20%20%20%20%20%20%7D%0A%20%20%7D%0A%20%20%20%20%0A%20%20timeout%20%3D%200%3B%0A%20%20while(*in%20%26%20bit)%20%7B%20%2F*%20Attente%20d’un%20%C3%A9tat%20HIGH%20*%2F%0A%20%20%20%20if%20(%2B%2Btimeout%20%3D%3D%20max_cycles)%20%7B%0A%20%20%20%20%20%20%20%20interrupts()%3B%0A%20%20%20%20%20%20%20%20return%20DHT_TIMEOUT_ERROR%3B%0A%20%20%20%20%20%20%7D%0A%20%20%7D%0A%0A%20%20%2F*%20Lecture%20des%20donn%C3%A9es%20du%20capteur%20(40%20bits)%20*%2F%0A%20%20for%20(byte%20i%20%3D%200%3B%20i%20%3C%2040%3B%20%2B%2Bi)%20%7B%0A%20%0A%20%20%20%20%2F*%20Attente%20d’un%20%C3%A9tat%20LOW%20*%2F%0A%20%20%20%20unsigned%20long%20cycles_low%20%3D%200%3B%0A%20%20%20%20while(!(*in%20%26%20bit))%20%7B%0A%20%20%20%20%20%20if%20(%2B%2Bcycles_low%20%3D%3D%20max_cycles)%20%7B%0A%20%20%20%20%20%20%20%20interrupts()%3B%0A%20%20%20%20%20%20%20%20return%20DHT_TIMEOUT_ERROR%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F*%20Attente%20d’un%20%C3%A9tat%20HIGH%20*%2F%0A%20%20%20%20unsigned%20long%20cycles_high%20%3D%200%3B%0A%20%20%20%20while(*in%20%26%20bit)%20%7B%0A%20%20%20%20%20%20if%20(%2B%2Bcycles_high%20%3D%3D%20max_cycles)%20%7B%0A%20%20%20%20%20%20%20%20interrupts()%3B%0A%20%20%20%20%20%20%20%20return%20DHT_TIMEOUT_ERROR%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20%0A%20%20%20%20%2F*%20Si%20le%20temps%20haut%20est%20sup%C3%A9rieur%20au%20temps%20bas%20c’est%20un%20%221%22%2C%20sinon%20c’est%20un%20%220%22%20*%2F%0A%20%20%20%20data%5Bi%20%2F%208%5D%20%3C%3C%3D%201%3B%0A%20%20%20%20if%20(cycles_high%20%3E%20cycles_low)%20%7B%0A%20%20%20%20%20%20data%5Bi%20%2F%208%5D%20%7C%3D%201%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20%0A%20%20%2F*%20Fin%20de%20la%20portion%20de%20code%20critique%20*%2F%0A%20%20interrupts()%3B%0A%20%0A%20%20%2F*%0A%20%20%20*%20Format%20des%20donn%C3%A9es%20%3A%0A%20%20%20*%20%5B1%2C%200%5D%20%3D%20humidit%C3%A9%20en%20%25%0A%20%20%20*%20%5B3%2C%202%5D%20%3D%20temp%C3%A9rature%20en%20degr%C3%A9s%20Celsius%0A%20%20%20*%20%5B4%5D%20%3D%20checksum%20(humidit%C3%A9%20%2B%20temp%C3%A9rature)%0A%20%20%20*%2F%0A%20%20%20%0A%20%20%2F*%20V%C3%A9rifie%20la%20checksum%20*%2F%0A%20%20byte%20checksum%20%3D%20(data%5B0%5D%20%2B%20data%5B1%5D%20%2B%20data%5B2%5D%20%2B%20data%5B3%5D)%20%26%200xff%3B%0A%20%20if%20(data%5B4%5D%20!%3D%20checksum)%0A%20%20%20%20return%20DHT_CHECKSUM_ERROR%3B%20%2F*%20Erreur%20de%20checksum%20*%2F%0A%20%20else%0A%20%20%20%20return%20DHT_SUCCESS%3B%20%2F*%20Pas%20d’erreur%20*%2F%0A%7D” message=”Test 6 capteurs” highlight=”” provider=”manual”/]

Posted in arduino, Projet en cours, Technique.

One Comment

  1. Super tutoriel!
    Merci pour ce test et synthèse complète, c’est parfait pour moi qui commence un projet où j’ai besoin de récupérer des variables environnementales.
    Code, lib, spec, tout y est! cool.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.