Composants · 15 min de lecture

BME280 Arduino : température, humidité, pression et altitude

Brancher un BME280 ou un BMP280 sur Arduino : adresse I2C 0x76/0x77, bibliothèque Adafruit, calcul d'altitude, alerte 3,3 V, station météo ESP32 et code Pico.

Le BME280 est un capteur environnemental numérique fabriqué par Bosch qui mesure la température, l'humidité relative et la pression atmosphérique dans une seule puce minuscule. Pour l'utiliser avec un Arduino, il te suffit de quatre fils (VCC, GND, SDA, SCL) et de la bibliothèque Adafruit BME280 ; en quelques lignes de code, tu vois les valeurs en °C, % et hPa dans le moniteur série. Comme il mesure la pression, il peut aussi calculer ta hauteur au-dessus du niveau de la mer, autrement dit l'altitude. Son petit frère, le BMP280, lui ressemble presque trait pour trait mais ne mesure pas l'humidité : il ne donne que la température et la pression.

Dans ce guide, tu vas découvrir la différence entre les deux capteurs, pourquoi l'adresse I2C est tantôt 0x76 tantôt 0x77, comment les brancher sur Arduino Uno, ESP32 et Raspberry Pi Pico, comment fonctionne la formule d'altitude et comment choisir la bonne pression au niveau de la mer. Ensuite, tu construiras une mini station météo ESP32 qui s'ouvre sur ton téléphone, tu feras tourner sur la Pico un pilote MicroPython sans bibliothèque et tu verras comment un seul sketch démasque le problème très répandu du "BMP280 vendu comme BME280".

Module capteur BME280 de température, humidité et pression
Module BME280 : la minuscule puce à capot métallique mesure la température, l'humidité et la pression et se branche en I2C ou en SPI.

Qu'est-ce que le BME280 et comment fonctionne-t-il ?

Le BME280 contient trois éléments de mesure. Le capteur de pression mesure, par effet piézorésistif, la déformation d'une fine membrane de silicium sous la poussée de l'air. Le capteur d'humidité est une couche de polymère dont la capacité varie à mesure qu'elle absorbe l'humidité de l'air. Le capteur de température donne la température ambiante et sert aussi à corriger les deux autres mesures. Chaque puce est étalonnée individuellement en usine et ses coefficients sont enregistrés dans sa mémoire interne ; la bibliothèque les lit au démarrage et convertit les valeurs brutes en unités réelles avec les formules de la datasheet. Le petit trou du capot métallique laisse l'air atteindre le capteur : ne le bouche jamais avec du ruban adhésif ou de la colle.

CaractéristiqueBME280BMP280
MesureTempérature, humidité, pressionTempérature, pression
Température-40…+85 °C, ±1 °C (±0,5 °C à 25 °C)-40…+85 °C, ±1 °C (±0,5 °C à 25 °C)
Humidité relative0–100 %, ±3 %Non
Plage de pression300–1100 hPa300–1100 hPa
Précision en pressionAbsolue ±1 hPa, relative ±0,12 hPa (≈ ±1 m)Absolue ±1 hPa, relative ±0,12 hPa (≈ ±1 m)
Tension d'alimentation de la puce1,71–3,6 V1,71–3,6 V
Courant (1 mesure par seconde)3,6 µA (les trois mesures)2,7 µA
Courant en veille0,1 µA0,1 µA
InterfaceI2C (jusqu'à 3,4 MHz) et SPI (jusqu'à 10 MHz)I2C et SPI
Chip ID (registre 0xD0)0x600x58
Taille de la puce2,5 × 2,5 mm (carrée)2,0 × 2,5 mm (rectangulaire)

En bref, le BMP280 est un BME280 un peu moins cher, sans capteur d'humidité ; ses mesures de pression et de température sont tout aussi bonnes. Si tu n'as besoin que de l'altitude ou de la pression atmosphérique, un BMP280 suffit. Pour les projets où l'humidité compte, comme une station météo, une serre ou la surveillance du climat d'une pièce, choisis le BME280. Un cran au-dessus, le BME680/BME688 ajoute un capteur de gaz qui détecte les composés organiques volatils (COV) dans l'air, mais il coûte plusieurs fois plus cher.

BME280 ou DHT11/DHT22 ?

CaractéristiqueDHT11DHT22BME280
Plage et précision en température0–50 °C, ±2 °C-40…+80 °C, ±0,5 °C-40…+85 °C, ±1 °C
Précision en humidité±5 %±2–5 %±3 %
Pression et altitudeNonNonOui
Lecture la plus rapide1 par seconde1 toutes les 2 secondesDes dizaines par seconde
ConnexionUn seul fil de donnéesUn seul fil de donnéesI2C ou SPI
Courant (pendant la mesure)≈ 1 mA≈ 1,5 mAMoins de 1 mA

Les capteurs DHT sont bon marché et simples, mais lents ; ils renvoient parfois des erreurs de lecture et ne mesurent pas la pression. Le BME280 partage le même bus I2C avec d'autres appareils comme un écran, ne consomme presque rien en veille et convient parfaitement aux projets qui tournent des mois sur piles. Pour les détails du DHT11, consulte Capteur de température et d'humidité DHT11, et pour voir toutes les options côte à côte, le comparatif des capteurs de température.

Types de modules et alerte 3,3 V

La puce nue est si petite qu'on l'utilise toujours sur un module, et deux types sont courants. Les modules à 6 broches (souvent violets, vendus sous le nom GY-BME280-3.3 ou GY-BMP280-3.3) ont les broches VCC, GND, SCL, SDA, CSB et SDO ; la plupart n'ont pas de régulateur, et c'est exactement ce que signifie le 3.3 du nom : alimente-les uniquement en 3,3 V. Les modules à 4 broches (VIN, GND, SCL, SDA) embarquent généralement un petit régulateur 3,3 V et souvent des transistors d'adaptation de niveau pour les lignes I2C ; ils peuvent donc aller sur la broche 5V de l'Arduino Uno. Si tu ne sais pas quel type tu as, cherche sur la carte une petite puce de régulateur à trois pattes ; s'il n'y en a pas, utilise le 3,3 V.

Brancher un module 3,3 V sans régulateur sur la broche 5V peut endommager le capteur ; le maximum absolu de la puce est de 4,25 V. Un capteur abîmé ne meurt pas toujours complètement : il donne parfois des températures décalées de quelques degrés ou des pressions incohérentes, ce qui rend la panne plus difficile à repérer.

Branchement du BME280 : Arduino Uno, ESP32 et Pico

Broche du BME280Arduino UnoESP32Raspberry Pi Pico
VCC / VIN3.3V (6 broches) ou 5V (4 broches, avec régulateur)3V33V3(OUT), broche 36
GNDGNDGNDGND, broche 38
SCLA5GPIO 22GP5, broche 7
SDAA4GPIO 21GP4, broche 6
CSB (6 broches)3.3V (sélectionne l'I2C)3V33V3
SDO (6 broches)Libre ou GND : 0x76, 3.3V : 0x77Libre ou GND : 0x76, 3V3 : 0x77Libre ou GND : 0x76, 3V3 : 0x77

C'est sur l'adresse que la plupart des gens bloquent. Si la broche SDO de la puce est à GND, l'adresse est 0x76 ; si elle est à 3,3 V, c'est 0x77. La plupart des modules bon marché tirent SDO à GND par une résistance et utilisent donc 0x76, alors que les cartes Adafruit utilisent 0x77, et la bibliothèque essaie 0x77 par défaut. C'est pourquoi il vaut mieux écrire l'adresse explicitement dans le code. Si la broche CSB est à GND à la mise sous tension, la puce passe en mode SPI et ne répond plus en I2C ; si tu utilises l'I2C, relie CSB au 3,3 V ou vérifie que le module la tire déjà vers le haut. Tu trouveras les broches I2C de ta carte dans l'outil Pinout et le fonctionnement du bus dans Qu'est-ce que l'I2C ?.

Pour mettre deux capteurs sur le même bus, relie la broche SDO de l'un d'eux au 3,3 V afin de passer son adresse à 0x77 ; sur les modules à 4 broches, cela se fait généralement avec un pont de soudure au dos. Au-delà de deux capteurs, le SPI convient mieux : SCL va sur SCK (13 sur l'Uno), SDA sur MOSI (11), SDO sur MISO (12) et la broche CSB de chaque capteur sur sa propre broche numérique ; dans le code, il suffit de déclarer l'objet avec Adafruit_BME280 bme(10);. Comme l'Uno en 5 V pilote directement les lignes SPI, un adaptateur de niveau est indispensable entre lui et un module 3,3 V.

L'Arduino Uno fonctionne en 5 V, et la bibliothèque Wire active les résistances de pull-up internes de A4 et A5 vers 5 V. Un module 6 broches en 3,3 V fonctionne quand même la plupart du temps, car les pull-up du module maintiennent le bus autour de 3,3 V ; mais pour un projet permanent, le plus sûr reste un module 4 broches avec régulateur ou un convertisseur de niveau logique. L'ESP32 et la Pico fonctionnent déjà en 3,3 V, ils n'ont donc pas ce problème.

Installer la bibliothèque Adafruit BME280

  1. Dans l'Arduino IDE, ouvre Outils > Gérer les bibliothèques et cherche Adafruit BME280.
  2. Quand tu cliques sur Installer, choisis Install all dans la fenêtre qui parle des dépendances, pour installer aussi Adafruit Unified Sensor et Adafruit BusIO.
  3. Si ton capteur est un BMP280, installe de la même façon la bibliothèque Adafruit BMP280 ; la bibliothèque du BME280 ne reconnaît pas le BMP280.
  4. Si tu veux, ouvre Fichier > Exemples > Adafruit BME280 Library > bme280test, mais n'oublie pas de mettre l'adresse (0x76) dans la ligne begin().

Premier sketch : lire température, humidité et pression avec le BME280

Arduino (C++)
1#include <Wire.h>
2#include <Adafruit_Sensor.h>
3#include <Adafruit_BME280.h>
4
5#define DENIZ_SEVIYESI_HPA 1013.25   // bugünkü deniz seviyesi basıncı / today's sea-level pressure
6
7Adafruit_BME280 bme;
8
9void setup() {
10  Serial.begin(9600);
11  // Önce 0x76, olmazsa 0x77 dene / try 0x76 first, then 0x77
12  if (!bme.begin(0x76) && !bme.begin(0x77)) {
13    Serial.println(F("BME280 bulunamadi! Kablolari ve adresi kontrol et."));
14    Serial.print(F("Chip ID: 0x"));
15    Serial.println(bme.sensorID(), HEX);       // 0x58 ise bu bir BMP280 / 0x58 means BMP280
16    while (true) delay(10);
17  }
18  Serial.println(F("BME280 hazir"));
19}
20
21void loop() {
22  float sicaklik = bme.readTemperature();          // °C
23  float nem      = bme.readHumidity();             // % bağıl nem / % relative humidity
24  float basinc   = bme.readPressure() / 100.0F;    // Pa -> hPa
25  float irtifa   = bme.readAltitude(DENIZ_SEVIYESI_HPA);   // metre / meters
26
27  Serial.print(F("Sicaklik: ")); Serial.print(sicaklik, 1); Serial.println(F(" C"));
28  Serial.print(F("Nem:      ")); Serial.print(nem, 1);      Serial.println(F(" %"));
29  Serial.print(F("Basinc:   ")); Serial.print(basinc, 1);   Serial.println(F(" hPa"));
30  Serial.print(F("Irtifa:   ")); Serial.print(irtifa, 0);   Serial.println(F(" m"));
31  Serial.println();
32  delay(2000);
33}
FonctionCe qu'elle fait
bme.begin(0x76)Démarre le capteur ; renvoie true si un appareil répond à l'adresse et que son chip ID vaut 0x60
readTemperature()Température, °C
readHumidity()Humidité relative, %
readPressure()Pression, Pa (divisée par 100, elle donne des hPa)
readAltitude(P0)Hauteur par rapport à la pression au niveau de la mer P0 (hPa), en mètres
seaLevelForAltitude(altitude, P)Pression au niveau de la mer à partir d'une altitude connue, hPa
sensorID()Le chip ID lu : 0x60 BME280, 0x58 BMP280
setTemperatureCompensation(x)Ajoute x °C à chaque lecture de température ; l'humidité et la pression sont corrigées en conséquence

Une fois le sketch téléversé et le moniteur série ouvert à 9600 bauds, tu verras dans une pièce des valeurs d'environ 23,4 °C, 45 % d'humidité et 1009,8 hPa. La pression évolue lentement au fil des heures ; souffle sur le capteur et tu verras l'humidité grimper en quelques secondes, touche-le du doigt et la température monte. Par défaut, la bibliothèque mesure en continu en mode normal avec le suréchantillonnage le plus élevé (x16) ; c'est idéal pour un premier essai, mais comme tu le verras plus bas, un autre réglage donne des résultats plus précis pour les mesures météo sur la durée.

Modes de mesure : forced, normal et le bon réglage

Le BME280 a trois modes. En mode sleep, il ne mesure rien et consomme 0,1 µA. En mode forced, il fait une seule mesure puis se rendort ; pour chaque nouvelle valeur, tu appelles takeForcedMeasurement(). En mode normal, il mesure en continu de lui-même avec le temps de veille que tu as réglé. Le suréchantillonnage (oversampling) mesure plusieurs fois la même valeur et en fait la moyenne pour réduire le bruit, et le filtre IIR lisse les sauts de pression brusques (une porte qui claque, une rafale de vent). Dans sa datasheet, Bosch recommande ces réglages selon l'usage :

UsageModeSuréchantillonnage (pression / température / humidité)Filtre IIRCourant moyen
Surveillance météoForced, 1 mesure par minutex1 / x1 / x1Désactivé≈ 0,16 µA
Mesure d'humiditéForced, 1 mesure par secondeIgnorée / x1 / x1Désactivé≈ 2,9 µA
Navigation en intérieur (étages, ascenseur)Normal, veille de 0,5 msx16 / x2 / x116≈ 633 µA
Quand le capteur mesure en continu, la puce et la carte chauffent très légèrement ; c'est ce qu'on appelle l'auto-échauffement. Si tu mesures la température d'une pièce ou de l'extérieur, utilise le mode forced et contente-toi de quelques mesures par minute. Si la valeur reste malgré tout plus haute d'un écart constant qu'un thermomètre de confiance, tu peux ajouter une correction comme bme.setTemperatureCompensation(-1.0);.

Pression au niveau de la mer et calcul de l'altitude

La pression de l'air diminue avec l'altitude, on peut donc calculer l'altitude à partir de la pression mesurée. La bibliothèque utilise cette formule barométrique : h = 44330 × (1 − (P / P0)^0,1903). Ici, P est la pression que tu mesures et P0 la pression actuelle au niveau de la mer (les deux en hPa). L'atmosphère standard prend P0 = 1013,25 hPa et, près du niveau de la mer, un écart de 1 hPa correspond à environ 8,3 mètres.

Le piège, c'est que P0 n'est pas fixe : elle varie en gros entre 990 et 1035 hPa selon la météo. Si la vraie valeur du jour est de 1023 hPa et que tu laisses 1013,25 dans le code, le capteur affichera une altitude inférieure d'environ 80 mètres. Pour des résultats justes, tu dois tenir P0 à jour : utilise la "pression ramenée au niveau de la mer" publiée par les services météo ou la valeur Q du METAR de l'aéroport le plus proche (par exemple Q1018, soit 1018 hPa). Tu peux aussi faire l'inverse : si tu connais l'altitude de ton emplacement, calcule P0 avec seaLevelForAltitude(altitude, pression). Par exemple, si le capteur mesure 905 hPa à Ankara (environ 938 m), la pression ramenée au niveau de la mer vaut environ 1012,6 hPa, exactement le chiffre que tu vois dans les applis météo.

Pour l'altitude absolue, la précision absolue de ±1 hPa représente une incertitude d'environ ±8 mètres. En mesure relative, en revanche, le capteur est bien meilleur : ±0,12 hPa ≈ ±1 m. Un étage d'immeuble fait environ 3 mètres, soit 0,36 hPa, donc le BME280 repère sans peine à quel étage tu te trouves ou si un ascenseur bouge. Le sketch ci-dessous prend comme référence la moyenne de 20 mesures au démarrage, puis affiche la hauteur par rapport à ce point et la pression au niveau de la mer calculée à partir d'une altitude connue :

Arduino (C++)
1#include <Wire.h>
2#include <Adafruit_Sensor.h>
3#include <Adafruit_BME280.h>
4
5#define BILINEN_IRTIFA 938.0   // bulunduğun yerin rakımı (m), örnek Ankara / your altitude (m), e.g. Ankara
6
7Adafruit_BME280 bme;
8float referansHpa;             // açılıştaki basınç / pressure at start-up
9
10void setup() {
11  Serial.begin(9600);
12  if (!bme.begin(0x76)) {
13    Serial.println(F("BME280 bulunamadi!"));
14    while (true) delay(10);
15  }
16  // İç mekan navigasyonu ayarı: düşük gürültü / indoor navigation preset: low noise
17  bme.setSampling(Adafruit_BME280::MODE_NORMAL,
18                  Adafruit_BME280::SAMPLING_X2,    // sıcaklık / temperature
19                  Adafruit_BME280::SAMPLING_X16,   // basınç / pressure
20                  Adafruit_BME280::SAMPLING_X1,    // nem / humidity
21                  Adafruit_BME280::FILTER_X16,     // IIR filtre / IIR filter
22                  Adafruit_BME280::STANDBY_MS_0_5);
23  delay(1000);                                      // filtre otursun / let the filter settle
24
25  float toplam = 0;
26  for (int i = 0; i < 20; i++) {                   // 20 ölçümün ortalaması / average of 20 readings
27    toplam += bme.readPressure() / 100.0F;
28    delay(50);
29  }
30  referansHpa = toplam / 20;
31}
32
33void loop() {
34  float basinc = bme.readPressure() / 100.0F;                               // istasyon basıncı / station pressure
35  float denizSeviyesi = bme.seaLevelForAltitude(BILINEN_IRTIFA, basinc);    // hPa
36  float bagilYukseklik = bme.readAltitude(referansHpa);                     // başlangıca göre / relative to start
37
38  Serial.print(F("Istasyon basinci: "));   Serial.print(basinc, 2);         Serial.println(F(" hPa"));
39  Serial.print(F("Deniz seviyesi (QNH): ")); Serial.print(denizSeviyesi, 1); Serial.println(F(" hPa"));
40  Serial.print(F("Baslangica gore: "));    Serial.print(bagilYukseklik, 2); Serial.println(F(" m"));
41  Serial.println();
42  delay(1000);
43}

Si tu soulèves la carte du sol jusqu'au-dessus de ta tête, tu verras la valeur "Baslangica gore" (par rapport au départ) augmenter d'environ 2 mètres. Comme la pression atmosphérique varie de quelques hPa au cours de la journée, cette mesure relative dérive au bout de quelques heures ; en usage prolongé, il faut donc renouveler la référence de temps en temps. Pour stabiliser encore les valeurs, tu peux ajouter la moyenne glissante de l'article Filtrer les données d'un capteur.

Mini station météo avec ESP32 : une page web à ouvrir sur ton téléphone

Grâce au Wi-Fi de l'ESP32, tu peux consulter les mesures du BME280 sur une page web depuis n'importe quel téléphone ou ordinateur du même réseau. Le sketch ci-dessous utilise la bibliothèque WebServer fournie avec le core ESP32 : aucune bibliothèque supplémentaire n'est nécessaire. La page principale se charge une fois, puis un petit JavaScript va chercher du JSON sur /veri toutes les 5 secondes et met à jour les valeurs sans recharger la page. Le capteur fonctionne en mode forced, il ne mesure donc que lorsque quelqu'un regarde la page, et la pression est affichée ramenée au niveau de la mer pour que tu puisses la comparer aux prévisions météo. Si c'est ta première fois avec l'ESP32, commence par Qu'est-ce que l'ESP32 ?.

  1. Branche le BME280 comme dans le tableau : VCC sur 3V3, SDA sur GPIO 21, SCL sur GPIO 22.
  2. Saisis les informations de ton réseau dans les champs WIFI_ADI (nom du réseau) et WIFI_SIFRE (mot de passe) du code, et l'altitude de ton emplacement dans RAKIM_M.
  3. Choisis la carte ESP32 Dev Module et téléverse le sketch.
  4. Ouvre le moniteur série à 115200 bauds ; une fois connecté, il affiche l'adresse IP.
  5. Tape cette adresse (par exemple 192.168.1.42) dans le navigateur d'un téléphone connecté au même réseau Wi-Fi ; les cartes de température, d'humidité et de pression apparaissent.
Arduino (C++)
1#include <WiFi.h>
2#include <WebServer.h>
3#include <Wire.h>
4#include <Adafruit_Sensor.h>
5#include <Adafruit_BME280.h>
6
7const char* WIFI_ADI   = "WiFiAdin";      // kendi ağ adın / your network name
8const char* WIFI_SIFRE = "WiFiSifren";    // kendi şifren / your password
9const float RAKIM_M    = 938.0;           // bulunduğun yerin rakımı / your local altitude
10
11Adafruit_BME280 bme;
12WebServer server(80);
13
14// Telefonda açılan sayfa, 5 sn'de bir /veri'yi okur / phone page, reads /veri every 5 s
15const char SAYFA[] PROGMEM = R"rawliteral(
16<!DOCTYPE html><html><head><meta charset="utf-8">
17<meta name="viewport" content="width=device-width,initial-scale=1">
18<title>Mini Hava İstasyonu</title>
19<style>
20body{font-family:sans-serif;text-align:center;background:#0f172a;color:#e2e8f0;margin:0;padding:16px}
21.k{display:inline-block;min-width:140px;margin:8px;padding:16px;border-radius:14px;background:#1e293b}
22.d{font-size:2.2em;font-weight:bold;margin:6px 0}
23</style></head><body>
24<h2>Mini Hava İstasyonu</h2>
25<div class="k">Sıcaklık<div class="d" id="t">--</div>°C</div>
26<div class="k">Nem<div class="d" id="h">--</div>%</div>
27<div class="k">Basınç<div class="d" id="p">--</div>hPa</div>
28<script>
29async function guncelle() {
30  const v = await (await fetch('/veri')).json();
31  document.getElementById('t').textContent = v.t.toFixed(1);
32  document.getElementById('h').textContent = v.h.toFixed(0);
33  document.getElementById('p').textContent = v.p.toFixed(1);
34}
35guncelle();
36setInterval(guncelle, 5000);
37</script>
38</body></html>
39)rawliteral";
40
41void anaSayfa() {
42  server.send(200, "text/html", SAYFA);
43}
44
45void veriGonder() {
46  bme.takeForcedMeasurement();                     // tek ölçüm al, sonra uyu / one measurement, then sleep
47  float p = bme.readPressure() / 100.0F;
48  String json = "{\"t\":" + String(bme.readTemperature(), 2) +
49                ",\"h\":" + String(bme.readHumidity(), 1) +
50                ",\"p\":" + String(bme.seaLevelForAltitude(RAKIM_M, p), 1) + "}";
51  server.send(200, "application/json", json);
52}
53
54void setup() {
55  Serial.begin(115200);
56  Wire.begin(21, 22);                              // SDA, SCL
57  if (!bme.begin(0x76)) {
58    Serial.println("BME280 bulunamadi!");
59    while (true) delay(10);
60  }
61  // Hava durumu izleme ayarı: kendi kendini ısıtmayı azaltır / weather monitoring preset: less self-heating
62  bme.setSampling(Adafruit_BME280::MODE_FORCED,
63                  Adafruit_BME280::SAMPLING_X1,    // sıcaklık / temperature
64                  Adafruit_BME280::SAMPLING_X1,    // basınç / pressure
65                  Adafruit_BME280::SAMPLING_X1,    // nem / humidity
66                  Adafruit_BME280::FILTER_OFF);
67
68  WiFi.mode(WIFI_STA);
69  WiFi.begin(WIFI_ADI, WIFI_SIFRE);
70  while (WiFi.status() != WL_CONNECTED) {
71    delay(500);
72    Serial.print(".");
73  }
74  Serial.print("\nTarayicida ac / open in browser: http://");
75  Serial.println(WiFi.localIP());
76
77  server.on("/", anaSayfa);
78  server.on("/veri", veriGonder);
79  server.begin();
80}
81
82void loop() {
83  server.handleClient();
84}
L'ESP32 chauffe de quelques degrés pendant qu'il tourne, et si tu places le capteur juste à côté de la carte, cette chaleur fausse la mesure. Éloigne le BME280 de la carte avec un câble de 10 à 15 cm, place-le près des ouïes d'aération du boîtier et garde-le à l'abri du soleil. Pour un tableau de bord plus complet avec graphiques et boutons, passe à Serveur web ESP32 et WebSocket.

BME280 avec la Raspberry Pi Pico (MicroPython)

MicroPython n'intègre aucun module pour le BME280. Au lieu de télécharger un fichier de pilote, le code ci-dessous embarque un petit pilote : il lit les coefficients d'étalonnage, fait prendre au capteur une seule mesure en mode forced et calcule le résultat avec les formules de la datasheet. Comme il vérifie le chip ID, il fonctionne aussi avec le BMP280 et saute tout seul la ligne d'humidité. Branche le capteur sur GP4 (SDA), GP5 (SCL) et 3V3(OUT), puis enregistre le code sur la Pico depuis Thonny sous le nom main.py. Si la Pico est nouvelle pour toi, Qu'est-ce que la Raspberry Pi Pico ? et Les bases de MicroPython te faciliteront la tâche.

MicroPython
1from machine import Pin, I2C
2import struct, time
3
4i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
5ADR = 0x76                                   # olmazsa 0x77 dene / try 0x77 if it fails
6P0 = 1013.25                                 # deniz seviyesi basıncı (hPa) / sea-level pressure (hPa)
7
8def s8(x):                                   # işaretli 8 bit / signed 8-bit
9    return x - 256 if x > 127 else x
10
11chip = i2c.readfrom_mem(ADR, 0xD0, 1)[0]
12BME = chip == 0x60                           # 0x60 BME280, 0x58 BMP280
13print("Chip ID:", hex(chip), "BME280" if BME else "BMP280 (nem yok / no humidity)")
14
15# Fabrika kalibrasyon katsayıları / factory calibration coefficients
16T1, T2, T3, P1, P2, P3, P4, P5, P6, P7, P8, P9 = struct.unpack("<HhhHhhhhhhhh", i2c.readfrom_mem(ADR, 0x88, 24))
17if BME:
18    H1 = i2c.readfrom_mem(ADR, 0xA1, 1)[0]
19    e = i2c.readfrom_mem(ADR, 0xE1, 7)
20    H2 = struct.unpack("<h", e[0:2])[0]
21    H3 = e[2]
22    H4 = (s8(e[3]) << 4) | (e[4] & 0x0F)
23    H5 = (s8(e[5]) << 4) | (e[4] >> 4)
24    H6 = s8(e[6])
25    i2c.writeto_mem(ADR, 0xF2, b"\x01")      # nem x1 (ctrl_meas'tan önce) / humidity x1 (before ctrl_meas)
26
27def oku():
28    i2c.writeto_mem(ADR, 0xF4, b"\x25")      # sıcaklık x1, basınç x1, forced mod / temp x1, press x1, forced mode
29    time.sleep_ms(15)                        # ölçümün bitmesini bekle / wait for the measurement
30    d = i2c.readfrom_mem(ADR, 0xF7, 8 if BME else 6)
31    adc_p = (d[0] << 12) | (d[1] << 4) | (d[2] >> 4)
32    adc_t = (d[3] << 12) | (d[4] << 4) | (d[5] >> 4)
33
34    # Sıcaklık (datasheet formülü) / temperature (datasheet formula)
35    v1 = (adc_t / 16384 - T1 / 1024) * T2
36    v2 = (adc_t / 131072 - T1 / 8192) ** 2 * T3
37    t_fine = v1 + v2
38    t = t_fine / 5120
39
40    # Basınç, Pa / pressure, Pa
41    v1 = t_fine / 2 - 64000
42    v2 = v1 * v1 * P6 / 32768 + v1 * P5 * 2
43    v2 = v2 / 4 + P4 * 65536
44    v1 = (P3 * v1 * v1 / 524288 + P2 * v1) / 524288
45    v1 = (1 + v1 / 32768) * P1
46    p = 1048576 - adc_p
47    p = (p - v2 / 4096) * 6250 / v1
48    p = p + (P9 * p * p / 2147483648 + p * P8 / 32768 + P7) / 16
49
50    h = None
51    if BME:                                  # nem, % / humidity, %
52        adc_h = (d[6] << 8) | d[7]
53        x = t_fine - 76800
54        x = (adc_h - (H4 * 64 + H5 / 16384 * x)) * (H2 / 65536 * (1 + H6 / 67108864 * x * (1 + H3 / 67108864 * x)))
55        x = x * (1 - H1 * x / 524288)
56        h = min(max(x, 0), 100)
57    return t, p / 100, h                     # °C, hPa, %
58
59while True:
60    t, p, h = oku()
61    irtifa = 44330 * (1 - (p / P0) ** 0.1903)    # metre / meters
62    print("Sicaklik: %.1f C  Basinc: %.1f hPa  Irtifa: %.0f m" % (t, p, irtifa))
63    if h is not None:
64        print("Nem: %.1f %%" % h)
65    time.sleep(2)

Quelques détails du code méritent ton attention. Le réglage d'humidité (registre 0xF2) ne prend effet qu'après une écriture dans 0xF4 ; c'est pourquoi on envoie d'abord le réglage d'humidité, puis l'ordre de mesure. La valeur 0x25 écrite dans 0xF4 signifie "température x1, pression x1, mode forced" ; avec ces réglages, une mesure dure au plus 10 ms environ, donc attendre 15 ms suffit. Testé avec les valeurs d'étalonnage d'exemple de la datasheet du BMP280 de Bosch, le code renvoie 25,08 °C et 1006,5 hPa : ses calculs correspondent exactement aux formules de Bosch.

Le BMP280 vendu comme BME280 : quel capteur as-tu vraiment ?

Comme les deux puces se montent sur le même circuit, certains vendeurs vendent des modules BMP280 comme des BME280 ; parfois, la carte indique seulement "BME/BMP280". Le symptôme est toujours le même : la bibliothèque Adafruit BME280 affiche "Could not find a valid BME280 sensor, check wiring, address, sensor ID!" et juste en dessous SensorID was: 0x58. D'autres bibliothèques n'affichent aucune erreur mais indiquent toujours une humidité de 0 ou nan. Ton câblage n'y est pour rien : ta puce est un BMP280, qui ne mesure pas l'humidité.

BME280
BME280
BMP280
BMP280
  • Regarde la forme de la puce : si le capot métallique est carré (2,5 × 2,5 mm), c'est un BME280 ; s'il est nettement rectangulaire (2,0 × 2,5 mm), c'est un BMP280. Avec le zoom de l'appareil photo du téléphone, la différence se voit facilement.
  • Lis le chip ID : la méthode la plus fiable est le sketch ci-dessous ; il lit l'identifiant dans le registre 0xD0 de la puce et t'indique de quel capteur il s'agit.
  • Méfie-toi du prix : un vrai BME280 coûte nettement plus cher qu'un BMP280 ; sois méfiant face aux modules "BME280" vendus bien en dessous du prix du marché.
Arduino (C++)
1#include <Wire.h>
2
3void setup() {
4  Serial.begin(9600);
5  Wire.begin();
6  bool bulundu = false;
7
8  for (uint8_t adres = 0x76; adres <= 0x77; adres++) {
9    Wire.beginTransmission(adres);
10    if (Wire.endTransmission() != 0) continue;   // bu adreste cihaz yok / no device at this address
11
12    Wire.beginTransmission(adres);
13    Wire.write(0xD0);                             // chip ID register'ı / chip ID register
14    Wire.endTransmission();
15    Wire.requestFrom(adres, (uint8_t)1);
16    uint8_t id = Wire.read();
17    bulundu = true;
18
19    Serial.print(F("Adres 0x"));
20    Serial.print(adres, HEX);
21    Serial.print(F("  Chip ID 0x"));
22    Serial.print(id, HEX);
23    if (id == 0x60)                    Serial.println(F("  -> BME280 (sicaklik + nem + basinc)"));
24    else if (id >= 0x56 && id <= 0x58) Serial.println(F("  -> BMP280 (nem olcmez)"));
25    else if (id == 0x61)               Serial.println(F("  -> BME680 / BME688"));
26    else if (id == 0x55)               Serial.println(F("  -> BMP180"));
27    else                               Serial.println(F("  -> bilinmeyen yonga / unknown chip"));
28  }
29
30  if (!bulundu) Serial.println(F("0x76 ve 0x77'de sensor yok: kablolari kontrol et"));
31}
32
33void loop() {
34}

Si le résultat est 0x58, pas de panique : les mesures de température et de pression du BMP280 sont aussi bonnes que celles du BME280. Installe la bibliothèque Adafruit BMP280 et utilise le sketch ci-dessous ; si tu as besoin de l'humidité, ajoute un DHT22 séparé au projet ou renvoie le produit. Il arrive aussi de tomber sur des échantillons de BMP280 avec l'ID 0x56 ou 0x57 ; pour eux, écris la ligne begin sous la forme bmp.begin(0x76, 0x56).

Arduino (C++)
1#include <Wire.h>
2#include <Adafruit_BMP280.h>
3
4Adafruit_BMP280 bmp;
5
6void setup() {
7  Serial.begin(9600);
8  if (!bmp.begin(0x76) && !bmp.begin(0x77)) {
9    Serial.println(F("BMP280 bulunamadi! Kablolari ve adresi kontrol et."));
10    while (true) delay(10);
11  }
12  // Datasheet'in önerdiği varsayılan ayarlar / default settings from the datasheet
13  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,
14                  Adafruit_BMP280::SAMPLING_X2,     // sıcaklık / temperature
15                  Adafruit_BMP280::SAMPLING_X16,    // basınç / pressure
16                  Adafruit_BMP280::FILTER_X16,      // IIR filtre / IIR filter
17                  Adafruit_BMP280::STANDBY_MS_500); // bekleme süresi / standby time
18}
19
20void loop() {
21  Serial.print(F("Sicaklik: ")); Serial.print(bmp.readTemperature(), 1);       Serial.println(F(" C"));
22  Serial.print(F("Basinc:   ")); Serial.print(bmp.readPressure() / 100.0F, 1); Serial.println(F(" hPa"));
23  Serial.print(F("Irtifa:   ")); Serial.print(bmp.readAltitude(1013.25), 0);   Serial.println(F(" m"));
24  Serial.println();
25  delay(2000);
26}

Idées de projets avec le BME280

  • Station météo de bureau : affiche température, humidité et pression sur un écran OLED ou un écran LCD I2C branché sur le même bus I2C.
  • Prévision météo au baromètre : enregistre la pression toutes les heures ; une baisse de plus de 2 hPa en 3 heures annonce en général une dégradation du temps, alors qu'une hausse régulière annonce un ciel dégagé.
  • Point de rosée et alerte moisissure : calcule le point de rosée avec la formule de Magnus (a = 17,62, b = 243,12 °C) et déclenche une alerte quand la température du mur s'en approche.
  • Serre connectée : commande un ventilateur ou une pompe de brumisation selon l'humidité et la température ; tous les détails dans le projet de serre connectée avec Arduino.
  • Enregistreur de données : écris les mesures sur un module carte SD ou, avec un ESP32, dans Google Sheets et trace une courbe hebdomadaire.
  • Capteur domotique : envoie les valeurs depuis un ESP32 vers Home Assistant via MQTT.
  • Station extérieure sur piles : réveille l'ESP32 de son deep sleep toutes les 10 minutes ; le BME280 ne consomme que 0,1 µA en veille.
  • Compteur d'étages : utilise le sketch d'altitude relative pour afficher l'étage atteint dans l'ascenseur ou dans l'escalier.

Erreurs fréquentes et solutions

SymptômeCause probableSolution
"Could not find a valid BME280 sensor", SensorID 0x0 ou 0xFFMauvaise adresse ou erreur de câblageUtilise begin(0x76), vérifie que SDA et SCL ne sont pas inversés et que GND est relié, lance un scanner I2C
Même erreur, SensorID 0x58La puce est en réalité un BMP280Utilise la bibliothèque Adafruit BMP280 et ajoute un autre capteur pour l'humidité
fatal error: Adafruit_Sensor.h: No such file or directoryUne bibliothèque dépendante n'est pas installéeInstalle la bibliothèque Adafruit Unified Sensor
Les valeurs affichent nanAucune nouvelle mesure demandée en mode forced, ou échec de begin()Appelle takeForcedMeasurement() avant chaque lecture et vérifie le résultat de begin()
Température trop haute de 1 à 3 °CAuto-échauffement dû à la mesure continue, chaleur d'un ESP32 ou d'un régulateur voisinPasse en mode forced, éloigne le capteur de la carte, utilise setTemperatureCompensation() si besoin
Pression d'à peine 900 hPaC'est la pression à la station ; elle baisse quand l'altitude augmenteRamène-la au niveau de la mer avec seaLevelForAltitude() pour la comparer aux prévisions
Altitude fausse de plusieurs dizaines de mètresPression au niveau de la mer laissée à 1013,25Saisis la P0 actuelle (QNH) ou étalonne avec une altitude connue
Blocages aléatoires avec des fils longsLe bus I2C est long et bruitéGarde le câble sous 50 cm, baisse la vitesse I2C ou passe en SPI
Ne mets pas le capteur dans une boîte fermée et étanche ; pour mesurer l'humidité et la pression, l'air doit atteindre la puce. À l'extérieur, un abri à persiennes ouvert par le bas, qui protège de la pluie et du soleil direct (comme les abris des stations météo), donne les résultats les plus justes. Si le capteur est mouillé par de la condensation, il peut afficher 100 % d'humidité pendant un moment ; tout revient à la normale une fois qu'il a séché.

Le BME280 assure sur une seule petite carte toutes les mesures de base d'une station météo : commence par vérifier l'adresse et le chip ID, choisis ensuite le mode de mesure selon ton objectif et, pour l'altitude, garde la pression au niveau de la mer à jour. Dans l'application BlueGrays, tu trouveras des projets à combiner avec ce guide, comme la mesure de température et d'humidité avec le DHT11 et le DHT22, des écrans météo ESP32, un enregistreur de température et un serveur web ESP32, chacun avec schémas de circuit et code pas à pas.

Questions fréquentes

Quelle est la différence entre le BME280 et le BMP280 ?

Le BME280 mesure la température, l'humidité relative et la pression ; le BMP280 ne mesure que la température et la pression et n'a pas de capteur d'humidité. La précision en pression et en température est la même. Les puces diffèrent aussi : le BME280 est carré (2,5 × 2,5 mm), le BMP280 rectangulaire (2,0 × 2,5 mm), et leurs chip ID sont 0x60 et 0x58.

L'adresse I2C du BME280 est-elle 0x76 ou 0x77 ?

Elle vaut 0x76 quand la broche SDO est reliée à GND et 0x77 quand elle est reliée au 3,3 V. La plupart des modules bon marché utilisent 0x76, les cartes Adafruit 0x77. La bibliothèque Adafruit essaie 0x77 par défaut, tu devras donc peut-être écrire bme.begin(0x76) dans ton code ; en cas de doute, lance un scanner I2C.

Le BME280 fonctionne-t-il en 5 V ?

La puce elle-même accepte au maximum 3,6 V. La plupart des modules 4 broches marqués VIN ont un régulateur et peuvent donc être branchés sur le 5V. Les modules 6 broches en 3,3 V sans régulateur doivent être alimentés uniquement en 3,3 V ; le 5 V peut endommager le capteur.

Comment corriger l'erreur "Could not find a valid BME280 sensor" ?

Regarde d'abord la valeur SensorID affichée sous l'erreur. Si c'est 0x58, ton capteur est un BMP280 et tu dois utiliser la bibliothèque Adafruit BMP280. Si c'est 0x0 ou 0xFF, c'est un problème d'adresse ou de câblage : essaie begin(0x76), vérifie que SDA et SCL ne sont pas inversés et que la broche CSB est au 3,3 V.

Quelle est la précision du BME280 pour mesurer l'altitude ?

Il mesure les variations de hauteur relative à environ ±1 m près, ce qui suffit pour détecter un changement d'étage. L'altitude absolue dépend de la pression au niveau de la mer que tu saisis ; une erreur de 1 hPa décale le résultat d'environ 8 m. En saisissant le QNH du moment ou en étalonnant sur une altitude connue, tu peux descendre à quelques mètres près.

Pourquoi mon BME280 indique-t-il une température trop élevée ?

Les causes les plus fréquentes sont l'auto-échauffement dû à la mesure continue et la chaleur des composants voisins comme l'ESP32 ou un régulateur. Passe en mode forced, prends quelques mesures par minute et éloigne le capteur de la carte avec un câble. S'il reste un écart constant, compare avec un thermomètre fiable et corrige-le avec setTemperatureCompensation().

Voir tous les projets
Température et humidité avec DHT11
#55Intermédiaire

Température et humidité avec DHT11

Quelle température fait-il dans ta chambre, et l'air est-il humide ou sec ? Le capteur DHT11 mesure la température et l'humidité, et l'Arduino affiche les valeurs sur un écran LCD à deux lignes, mises

4.7(47)
64
ESP32 DHT22 Température et humidité (avec écran LCD)
#117Intermédiaire

ESP32 DHT22 Température et humidité (avec écran LCD)

Il s'agit d'un projet permettant de mesurer la température ambiante et le taux d'humidité à l'aide d'un capteur DHT22 et d'afficher ces données en temps réel sur un écran LCD I2C 16x2. Les données du capteur sont lues à l'aide du protocole one-wire grâce à la bibliothèque Adafruit DHT. Ce projet constitue la base des stations météo IoT, de la domotique ou des systèmes de surveillance de l'environnement dans les serres.

4.8(38)
54
Horloge matricielle, calendrier et station météo (MAX7219, DS1307)
#85Intermédiaire
Premium

Horloge matricielle, calendrier et station météo (MAX7219, DS1307)

Un panneau à texte défilant pour ton bureau ou ton mur, qui affiche tour à tour l'heure, la date et la météo de la pièce. Sur l'écran LED 8x32 apparaissent d'abord la température en Celsius et en Fahr

5.0(50)
66
Enregistreur de Température ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
#144Avancé
Premium

Enregistreur de Température ESP32 (DHT22 + DS1307 RTC + microSD + OLED)

Construis un enregistreur de température horodaté avec ESP32 ! Lis la température/humidité du DHT22 chaque minute, obtiens l'heure réelle du DS1307 RTC et enregistre sur carte microSD au format CSV. L'OLED affiche en direct la température (grande police), le pourcentage d'humidité, l'horodatage et le compteur. Le fichier `/temp_log.csv` sur la carte SD s'ouvre dans Excel, Google Sheets ou Python pandas pour analyse — parfait pour surveillance de serre, suivi de température à domicile, c

4.7(7)
12
ESP32 HTTPClient + API météo (avec écran OLED SSD1306)
#134Avancé
Premium

ESP32 HTTPClient + API météo (avec écran OLED SSD1306)

Dans ce projet, nous effectuons un appel à l'API REST de la météo (wttr.in) via Internet à l'aide de l'ESP32 et de la bibliothèque `HTTPClient.h`. Contrairement à la version précédente avec écran LCD I2C, nous utilisons ici un écran OLED SSD1306 (128×64) — ce qui permet d’afficher une police de grande taille, des icônes vectorielles et une présentation visuelle riche sur un seul écran. Sept icônes vectorielles différentes représentant les conditions météorologiques (ensoleillé, partiellement nua

4.3(10)
18
Serveur Web asynchrone ESP32 (avec affichage de l'adresse IP sur l'écran LCD)
#129Avancé
Premium

Serveur Web asynchrone ESP32 (avec affichage de l'adresse IP sur l'écran LCD)

Dans ce projet, nous transformons l'ESP32 en un **serveur web asynchrone** que vous pouvez contrôler depuis votre téléphone ou votre ordinateur connecté au même réseau Wi-Fi. Grâce à la bibliothèque ESPAsyncWebServer, le serveur peut traiter plusieurs requêtes simultanément (contrairement au classique `WebServer.h` qui se bloque sur une seule requête). Depuis votre navigateur, vous pourrez vous connecter à l'adresse IP de l'ESP32, puis allumer et éteindre la LED co

4.8(16)
26
ESP32 HTTPClient + API météo (avec écran LCD)
#133Avancé
Premium

ESP32 HTTPClient + API météo (avec écran LCD)

Dans ce projet, nous effectuons un appel REST à l'API météo (wttr.in) via Internet à l'aide de l'ESP32 et de la bibliothèque `HTTPClient.h`. À l’aide d’ArduinoJson v7, nous analysons la réponse JSON renvoyée et affichons les informations relatives à la ville, à la température, à l’humidité, à la météo et au vent sur un écran LCD I2C, en turc et en anglais. wttr.in est gratuit et ne nécessite pas de clé API : il suffit de saisir le nom d’une ville pour obtenir les conditions météo en temps réel d

4.7(13)
20
Écran LCD I2C ESP32 (16x2)
#119Intermédiaire
Premium

Écran LCD I2C ESP32 (16x2)

Dans ce projet, nous affichons du texte en connectant un écran LCD 16x2 à l'ESP32 via le protocole I2C. Grâce à l'I2C, nous pouvons contrôler l'écran avec seulement 2 broches de données (SDA et SCL) ; cela évite le gaspillage de 6 broches ou plus inhérent à la connexion parallèle classique. Le code affiche un message fixe sur la première ligne et un compteur qui augmente chaque seconde sur la deuxième ligne. De plus, au démarrage, nous lançons un scanner I2C pour afficher l'adresse de l'écran su

4.9(23)
40