Il s’agit d’une station météo sans fil avec mesure de la température, de l’humidité et de la pression atmosphérique. Elle utilise un module avec un capteur BME280 et un module nrf24l01 + pour la transmission sans fil. Le cœur est un atmega328p qui peut être programmé avec arduino.

Le BME280
Le BME280 est un capteur environnemental qui permet de mesurer la pression, l’humidité et la température avec une consommation de courant réduite (3,6 μA à 1Hz). En mode sommeil, il atteint une consommation de 0.1 μA. Niveau interface, il dispose de ports I²C et SPI.
Le module utilisé comporte 6 pins :

PIN |
I²C |
SPI |
VCC |
+3.3v |
+3.3v |
GND |
GND |
GND |
SCK |
SCL (avec résistance pull-up vers VCC) |
SCK |
SDI |
SDA (avec résistance pull-up vers VCC) |
MOSI |
CSB |
+3.3v (par défault en mode I²C) |
Slave Select (SS) |
SDO |
- GND : adresse 0x76(par défault)
- +3.3v : adresse 0x77
|
MISO |
Schéma du circuit
Le circuit s’articule autour d’un Atmega328p comme dans la plupart des circuits présentés sur ce blog. C’est le même que celui présent sur l’Arduino Uno. La partie sans fil est assurée par un module Nrf24l01+. Le BME280 est utilisé avec le mode I²C et l’adresse 0x76. Il est alimenté en 3.3V, avec un accu LiFePO4 par exemple, qui, vu la faible consommation, peut tenir plusieurs mois.
C5,C1,C2,C3,C6 |
100nF |
Q1 |
AO3401 |
IC1 |
ATMEGA328P-P + Support |
R1 |
1.2MΩ |
R2 |
470kΩ |
R3 |
100kΩ |
D1 |
LED |
R8 |
560Ω |
U2 |
BME280 + Support 1×6 |
C4 |
470µF |
U1 |
nRF24L01 + Support 2×4 |
J1 |
ALIM 3.3v |



Abri anti-rayonnement
L’abri protège le capteur des rayonnements du soleil et de la pluie tout en assurant la circulation d’air autour du capteur. Il est réalisé à l’imprimante 3D, pour l’instant en PLA pour le prototype, mais l’ASA (acrylonitrile styrene acrylate) sera plus résistant aux UV et aux intempéries. Il est réalisé avec OpenScad.
Le matériel nécessaire pour le boitier :
- 4x Boulon M4x80
- 5x écrous M4
- 5x Vis à tôle 2.9×6.5 ou 2.9×9.5
Les écrous sont noyés dans le plastique, ainsi il est nécessaire de mettre l’impression en pause après la dernière couche des emplacements des écrous.



Les fichiers stl sont disponibles sur Thingiverse.
Le programme
#include <LowPower.h>
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <Wire.h>
#include <stdint.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
/* -------CONFIG---------*/
#define LOGDEBUG 0
/* --------------------- */
#define NODE_ID 1
#define RF24_CH 25
/* --------------------- */
#define SLEEP_DATA 37 //5min , 8s par cycle
#define SLEEP_VOLT 450 //1h
/* --------------------- */
#define VT_PIN 14 //A0
#define RF24_ON 6
#define LED_PIN 5
/* --------------------- */
//DEBUG
#if LOGDEBUG==1
#define DEBUG_PRINT(x) Serial.print(x)
#define DEBUG_PRINTDEC(x) Serial.print(x, DEC)
#define DEBUG_PRINTLN(x) Serial.println(x)
#define DEBUG_RADIO() radio.printDetails()
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTDEC(x)
#define DEBUG_PRINTLN(x)
#define DEBUG_RADIO()
#endif
/* --------------------- */
uint16_t nodeId = NODE_ID;
uint8_t node_address[5] = {"1Node"};
uint8_t server_address[5] = {"2Node"};
/* --------------------- */
Adafruit_BME280 bme280;
RF24 radio(9,10);
uint8_t radioBuffer[32] = {0};
uint16_t cntDATA = SLEEP_DATA;
uint16_t cntVOLT = SLEEP_VOLT;
float humidity = 0;
float temperature = 0;
float pressure = 0;
float voltage = 0;
void radioSetup(){
radio.begin();
radio.setChannel(RF24_CH);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);
radio.setCRCLength(RF24_CRC_16);
radio.setRetries(10, 15);
radio.setAutoAck(1);
radio.openReadingPipe(1, node_address);
radio.openWritingPipe(server_address);
DEBUG_RADIO();
}
void setup() {
delay(500);
#if LOGDEBUG==1
Serial.begin(115200);
printf_begin();
#endif
pinMode(RF24_ON, OUTPUT);
digitalWrite(RF24_ON, HIGH);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
//flash led
digitalWrite(LED_PIN, HIGH);
delay(250);
digitalWrite(LED_PIN, LOW);
//1.1V internal voltage reference
analogReference(INTERNAL);
bme280.begin(0x76);
bme280.setSampling( Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // temperature
Adafruit_BME280::SAMPLING_X4, // pressure
Adafruit_BME280::SAMPLING_X1, // humidity
Adafruit_BME280::FILTER_OFF );
//flash led
delay(500);
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);
}
void loop() {
DEBUG_PRINTLN("Start loop");
if( (cntDATA >= SLEEP_DATA) || (cntVOLT >= SLEEP_VOLT)){
//power on radio
digitalWrite(RF24_ON, LOW);
delay(100);
radioSetup();
DEBUG_PRINTLN("Radio up");
if(cntDATA >= SLEEP_DATA){
bme280.takeForcedMeasurement();
temperature = bme280.readTemperature();
humidity = bme280.readHumidity();
pressure = bme280.readPressure();
//sea level correction, sensor altitude is 104m above sea level
pressure = bme280.seaLevelForAltitude(104.0, pressure);
DEBUG_PRINT("T=");
DEBUG_PRINT(temperature);
DEBUG_PRINT(", H=");
DEBUG_PRINT(humidity);
DEBUG_PRINT(", P=");
DEBUG_PRINTLN(pressure);
memcpy(radioBuffer, &nodeId, 2);
memcpy(radioBuffer+2, "DATA", 4);
memcpy(radioBuffer+6, &temperature, 4);
memcpy(radioBuffer+10, &humidity, 4);
memcpy(radioBuffer+14, &pressure, 4);
memset(radioBuffer+18, 0, 14);
if(radio.write(radioBuffer, 32)){
cntDATA = 0;
}
else{
if(cntDATA >= (SLEEP_DATA+5)){
//retry up to 5 cycles of 8s.
cntDATA = 0;
}
}
}
delay(250);
radio.flush_tx();
if(cntVOLT >= SLEEP_VOLT){
voltage = analogRead(VT_PIN);
voltage = voltage * 1.1 * ((1670000.0)/470000.0) / 1024.0;
DEBUG_PRINT("V=");
DEBUG_PRINTLN(voltage);
memcpy(radioBuffer, &nodeId, 2);
memcpy(radioBuffer+2, "VOLT", 4);
memcpy(radioBuffer+6, &voltage, 4);
memset(radioBuffer+10, 0, 22);
if(radio.write(radioBuffer, 32)){
cntVOLT = 0;
}
else{
if(cntVOLT >= (SLEEP_VOLT+5)){
//retry up to 5 cycles of 8s.
cntVOLT = 0;
}
}
}
delay(50);
//power down radio
radio.powerDown();
digitalWrite(RF24_ON, HIGH);
}
++cntDATA;
++cntVOLT;
//flash led
digitalWrite(LED_PIN, HIGH);
delay(1);
digitalWrite(LED_PIN, LOW);
DEBUG_PRINTLN("Sleep for 8 seconds");
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
6 réflexions sur « Station météo : capteur de température, humidité et pression (BME280) »
hello
Arduino-IDE displays an error on the line: ‘NODE_ID’ was not declared in this scope
Tell me what is the mistake?
Hello,
Sorry, it was a copy paste mistake, I forgot a #define : #define NODE_ID 1 before.
Any number can be defined here, it’s to identify which node send the message.
Je ne suis qu’un débutant. S’il vous plaît aider. Ce qui devrait être indiqué dans les lignes:
uint16_t nodeId = NODE_ID;
uint8_t node_address [5] = {« 1Node »};
uint8_t adresse_serveur [5] = {« 2Node »};
peut un exemple
node_address [5] is the current node address on five bytes.
adresse_serveur [5] is the receiver node address. Another node on the network must have this address and must be in listen mode. Soon, a new article will explain how to make an ethernet gateway tu listen data packets.
Bonjour,
y a t-il une suite pour la station météo? Sur quoi sont reçues les données du capteur?
merci
Bonjour,
Oui une suite arrive bientôt, avec une nouvelle version du capteur qui fonctionnera avec une cellule solaire ainsi que d’autres extensions.
Les données sont reçues sur une station de base qui fonctionne avec un ESP32.
Bonne journée 🙂