Détecteur IR et mesures

Réalisation d’un détecteur de présence avec sonde de Température - Humidité et Pression atmosphérique.

  • 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:

    • chargeur USB 2,39 € action
    • câble USB-A vers USB-Micro (en fonction du contrôleur choisit), 2,49 € action

Coût total 25 € en comptant le PLA de la boite

Intégration dans FHEM et Homeassistant (en jaune FHEM en dessous Homeassistant).

Montage

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:

  • D1 (SCL) -> BME280 SDA
  • D2 (SDA) -> BME280 SCL
  • 3V3 -> BME280 VCC
  • GND -> BME280 GND
connexions

Connexion du détecteur infrarouge manuel

  • Weemos D1 pin D7 to PIR pin OUT
  • Weemos D1 5 volts to PIR pin VCC
  • Weemos D1 GND to PIR GND
PIR WiringAssemblage

Boitier en PLA download 3mf

Terminé

Programmation

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

Page de configuration
  • 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

    • Hostname
    • knxwrite lors de la mise à jour (timer)
    • Timer de mise à jour
    • adresses de groupe des variable lues
  • 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;
    }
}
}