Le système est compatible KNX (éventuellement MQTT peut être aussi utilisé avec une mise à jour du logiciel relativement simple)
Les mesures sont effectuée par un capteru BM280 AZ Delivery 5 €
Le détecteur infrarouge est du type HC-SR501 AZ Delivery 7 €
L’intelligence est pourvue par un Node MCU D1 mini ESP8266 7 €
Alimentation:
Coût total 25 € en comptant le PLA de la boite
Connexion Du BM280 au nodeMCU (Via SCL et SDA), vérifier les pin SCL et SDA dans la doc de votre module.
Wemos D1 Mini to BME280:
Connexion du détecteur infrarouge manuel
Boitier en PLA download 3mf
L’IDE arduino à été utilisé, veillez à bien choisir le board correspondant à celui acheté
Les librairies suivantes doivent être installées
Une fois laprogrammation effectuée, le node doit être configuré pour l’usage en KNX, le système n’est pas compatible avec ETS, il faut donc configurer les adresses de groupe via l’interface web.
Avec un navigateur accéder à l’ adresse IP configurée et configurer les adresses de groupe
Callback: choisir la variable lue pour un READ par adresse de groupe (eg. Read temperature pour lecture de 7/7/7)
Configuration: Définir l’adress knx matérielle de l’appareil (eg. 7.7.7)
Configuration 2
Save to Eprom (sauvegarde des paramètre dans l’EPROM, à faire absolument avant de faire un reboot.
Le Logiciel
/*
* This is a sketch showing a simple environment sensor based on a BME280 attached via I2C.
* It is complemented by an IR presence detector
* the system connects a KNX installation via UDP and is configured groupwise
* via a web interface
* This sketch was tested on a WeMos D1 mini
*/
#include <Adafruit_BME280.h>
#include <esp-knx-ip.h>
// Configuration du WiFi (à modifier suivant votre réseau)
const char* ssid = "wlanSSID";
const char* pass = "lemotdepasse";
IPAddress ip(192, 168, 0, 100);
IPAddress dns(192, 168, 0, 1);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
const char* hostname = "esp32-knx-test";
#define LED_PIN D4
#define UPDATE_INTERVAL 10000
#define OUT_PIN D7
#define pirPin D7
unsigned long next_change = 0;
float last_temp = 0.0;
float last_hum = 0.0;
float last_pres = 0.0;
config_id_t temp_ga, hum_ga, pres_ga, presence_ga;
config_id_t hostname_id;
config_id_t update_rate_id, send_rate_id;
config_id_t enable_sending_id;
config_id_t enable_reading_id;
int val = 0;
bool motionState = false; // We start with no motion detected.
Adafruit_BME280 bme;
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(pirPin, INPUT);
Serial.begin(115200);
hostname_id = knx.config_register_string("Hostname", 20, String("env"));
// setup the knx callback routines, cb registers and web interface for their setup
enable_sending_id = knx.config_register_bool("Send on update", true);
update_rate_id = knx.config_register_int("Update rate (ms)", UPDATE_INTERVAL);
temp_ga = knx.config_register_ga("Temperature", show_periodic_options);
hum_ga = knx.config_register_ga("Humidity", show_periodic_options);
pres_ga = knx.config_register_ga("Pressure", show_periodic_options);
presence_ga = knx.config_register_ga("Presence", show_periodic_options);
knx.callback_register("Read Temperature", temp_cb);
knx.callback_register("Read Humidity", hum_cb);
knx.callback_register("Read Pressure", pres_cb);
knx.callback_register("Read Presence", presence_cb);
knx.feedback_register_float("Temperature (°C)", &last_temp);
knx.feedback_register_float("Humidity (%)", &last_hum);
knx.feedback_register_float("Pressure (hPa)", &last_pres, 0);
knx.feedback_register_bool("IR Presence detector", &motionState);
//
// Load previous config from EEPROM (The KNX group addresses configured via the web interface are saved in EEPROM)
//
knx.load();
//
// Initialisation du capteur BE280
//
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
}
//
// Initialisation du WiFi
//
WiFi.config(ip, gateway, subnet, dns);
WiFi.hostname(knx.config_get_string(hostname_id));
WiFi.begin(ssid, pass);
Serial.println("");
Serial.print("[Connecting]");
Serial.print(ssid);
digitalWrite(LED_PIN, LOW);
while (WiFi.status() != WL_CONNECTED) {
digitalWrite(LED_PIN, HIGH);
delay(250);
Serial.print(".");
digitalWrite(LED_PIN, LOW);
delay(250);
}
digitalWrite(LED_PIN, HIGH);
//
// Start knx it needs the WiFi connection
//
knx.start();
Serial.println();
Serial.println("Connected to wifi");
Serial.println(WiFi.localIP());
}
//
// start the processing loop
//
void loop() {
knx.loop();
unsigned long now = millis();
// read the PIR pin
val = digitalRead(pirPin);
// If motion is detected (pirPin = HIGH), do the following:
if (val == HIGH) {
digitalWrite(LED_PIN, LOW); // Turn on the on-board LED.
// Change the motion state to true (motion detected):
if (motionState == false) {
Serial.println("Motion detected!");
motionState = true;
knx.write_1bit(knx.config_get_ga(presence_ga), motionState);
}
}
// If no motion is detected (pirPin = LOW), do the following:
else {
digitalWrite(LED_PIN, HIGH); // Turn off the on-board LED.
// Change the motion state to false (no motion):
if (motionState == true) {
Serial.println("Motion ended!");
motionState = false;
knx.write_1bit(knx.config_get_ga(presence_ga), 0);
}
}
if (next_change < now)
{
// knx.config_get_int(update_rate_id) is the update rate as programmed via the web interface
next_change = now + knx.config_get_int(update_rate_id);
// read the environment measures
last_temp = bme.readTemperature();
last_hum = bme.readHumidity();
last_pres = bme.readPressure()/100.0f;
// print them on serial (debug check)
Serial.print("T: ");
Serial.print(last_temp);
Serial.print("°C H: ");
Serial.print(last_hum);
Serial.print("% P: ");
Serial.print(last_pres);
Serial.println("hPa");
// knx.config_get_bool(enable_sending_id) configured by the web interface,
// if true send the environement data on the KNX bus
if (knx.config_get_bool(enable_sending_id))
{
knx.write_2byte_float(knx.config_get_ga(temp_ga), last_temp);
knx.write_2byte_float(knx.config_get_ga(hum_ga), last_hum);
knx.write_2byte_float(knx.config_get_ga(pres_ga), last_pres);
knx.write_1bit(knx.config_get_ga(presence_ga),motionState);
}
}
delay(50);
}
bool show_periodic_options()
{
return knx.config_get_bool(enable_sending_id);
}
bool enable_reading_callback()
{
return knx.config_get_bool(enable_reading_id);
}
// callback routines executed when a read on the KNX group is detected
// the routine send back the corresponding value
void temp_cb(message_t const &msg, void *arg)
{
switch (msg.ct)
{
case KNX_CT_READ:
{
knx.answer_2byte_float(msg.received_on, last_temp);
Serial.print("Sending Temperature on ga: ");
Serial.print(last_temp);
break;
}
}
}
void hum_cb(message_t const &msg, void *arg)
{
switch (msg.ct)
{
case KNX_CT_READ:
{
knx.answer_2byte_float(msg.received_on, last_hum);
Serial.print("Sending Humidity on ga: ");
Serial.println(last_hum);
break;
}
}
}
void pres_cb(message_t const &msg, void *arg)
{
switch (msg.ct)
{
case KNX_CT_READ:
{
knx.answer_2byte_float(msg.received_on, last_pres);
Serial.print("Sending Pressure on ga: ");
Serial.println(last_pres);
break;
}
}
}
void presence_cb(message_t const &msg, void *arg)
{
switch (msg.ct)
{
case KNX_CT_READ:
{
knx.answer_1bit(msg.received_on, motionState);
Serial.print("Sending Presence on ga: ");
Serial.print(knx.config_get_string(presence_ga));
Serial.print(" ");
Serial.println(motionState);
break;
}
}
}