Smarthome Zentrale mit ArduiTouch Teil 7 - Gerät für I2C Sensoren BMP280 und BME 280

Entre autres petites extensions, je voudrais présenter aujourd’hui un autre dispositif distant qui fournit des valeurs mesurées des capteurs I2C BMP280 et/ou BME280 à notre siège social intelligent.

Le circuit est basé sur un D1 Mini et les capteurs BMP280 Et BME280. Étant donné que ces capteurs peuvent avoir une adresse I2C de 0X77 ou 0X76, le programme découvre automatiquement quel capteur a été connecté avec quelle adresse. Sans modification fournie par AZ Delivery, le BMP280 a l’adresse 0X77 et le BME 280 l’adresse 0X76.

Le circuit est très simple. L’horloge I2C est connectée à D1 de la D1 Mini et à la ligne de données À D2 de la D1 Mini. Pour le BMP280, la ligne Chipselect doit être connectée à 3,3 V afin que le BMP280 commence en mode I2C. Sur la D1 Mini, nous connectons l’entrée RESET à la broche D0 (ligne violette). Le programme met l’ESP8266 dans le sommeil profond après le travail a été fait. Cette connexion réveille l’ESP8266 après l’heure fixée. Cependant, vous devez supprimer cette connexion pour clignoter.

dessin:

 

/*
 Capteur de pression WLAN BMP280 et ou BME280
 ESP maintenant à ArduiTouch SmartHome
 Si l’appareil n’a pas d’adresse MAC serveur valide
 une recherche sera effectuée pour trouver un WLAN avec SSID ATSmartHome
 L’adresse MAC du serveur sera sauvegardée tant que l’alimentation 
 ne sera pas interrompu.
 Le protocole ESP Now est très presque le courant le plus élevé pour le wiil réseau être
 consommé pendant une courte période (nous) seulement. Après l’envoi des valeurs, l’appareil
 passe pendant cinq minutes dans un mode de sommeil profond avec une consommation d’énergie très faible.
*/

bibliothèque pour WiFi
#include <ESP8266WiFi.H (en)>
bibliothèques d’utiliser BMP280 et BME280
#include <Adafruit_Sensor.H (en)>
#include <Adafruit_BME280.H (en)>
#include <Adafruit_BMP280.H (en)>
bibliothèque pour le protocole de message utilisé
#include "AT_MessageBuffer.h"


bibliothèque pour ESP Now
Externe "C" {   #include <espnow espnow.H (en)>
}

SSID à la recherche de
#define GW_SSID "ATSmartHome"

drapeau pour changer les messages de débogic à larine
#define Debug Vrai

#define SEND_TIMEOUT 2000  2 secondes de temps d’arrêt 

définir les canaux des deux capteurs
#define CHANNEL_TEMP_BME 0
#define CHANNEL_PRESS_BME 1
#define CHANNEL_ALT_BME 2
#define CHANNEL_HUM_BME 3
#define CHANNEL_TEMP_BMP 4
#define CHANNEL_PRESS_BMP 5
#define CHANNEL_ALT_BMP 6
 
#define SEALEVELPRESSURE_HPA (1013.25)

Structure de données pour enregistrer l’adresse MAC du serveur
et un checksum dans la mémoire du CRTC
Struct MEMORYDATA (EN) {   uint32_t crc32; checksum pour validation   uint8_t Mac[6];
};


Variables globales
Volatile Bool rappelCalled;


Boolean hasBme = 0;
Boolean hasBmp = 0;

Adresse MAC et canal Wi-Fi
MEMORYDATA (EN) statinfo;

AT_MessageBuffer Msg;

Adafruit_BME280 Bme; I2c I2c
Adafruit_BMP280 Bmp; I2c I2c

fonction de calculer le checksum
uint32_t calculateCRC32(Const uint8_t *Données, Size_t Longueur)
{   uint32_t Crc = 0xffffffffffff;   Tandis que (Longueur--) {     uint8_t C = *Données++;     Pour (uint32_t Ⅰ. = 0x80; Ⅰ. > 0; Ⅰ. >>= 1) {       Bool Peu = Crc & 0x8000000000;       Si (C & Ⅰ.) {         Peu = !Peu;       }       Crc <<= 1;       Si (Peu) {         Crc ^= 0x04c11db7;       }     }   }   Retour Crc;
}

écrire le serveur MAC et le checksum à la mémoire du CCF
Vide Mise à jourRtcMemory() {     uint32_t crcOfData = calculateCRC32(((uint8_t*) &statinfo) + 4, Sizeof(statinfo) - 4);     statinfo.crc32 = crcOfData;     Esp.rtcUserMemoryWrite(0,(uint32_t*) &statinfo, Sizeof(statinfo));
}

recherche du point d’accès
Vide ScanForSlave() {   Bool esclaveFound = 0;      int8_t scanResults = Wifi.scanNetworks (scanNetworks)();   réinitialiser chaque analyse   Si (Debug) Série.println("Scan fait");   Si (scanResults == 0) {     Si (Debug) Série.println("Pas d’appareils WiFi trouvés en mode AP");   } Autre {     Si (Debug) Série.Imprimer("Trouvé");      Si (Debug) Série.Imprimer(scanResults);      Si (Debug) Série.println(" dispositifs ");     Pour (Int  = 0;  < scanResults; ++) {       Imprimer SSID et RSSI pour chaque appareil trouvé       String Ssid = Wifi.Ssid();       int32_t RSSI RSSI = Wifi.RSSI RSSI();       int32_t Lch = Wifi.Canal();       String BSSIDstr = Wifi.BSSIDstr();       Si (Debug) {         Série.Imprimer( + 1);         Série.Imprimer(": ");         Série.Imprimer(Ssid);         Série.Imprimer(" /");         Série.Imprimer(Lch);         Série.Imprimer(" (");         Série.Imprimer(RSSI RSSI);         Série.Imprimer(")");         Série.println("");       }       Retard(10);       Vérifiez si l’appareil actuel commence par ATSmartHome'       Si (Ssid == GW_SSID) {         SSID d’intérêt         Si (Debug) {           Série.println("J’ai trouvé un esclave.");           Série.Imprimer( + 1); Série.Imprimer(": "); Série.Imprimer(Ssid); Série.Imprimer(" ["); Série.Imprimer(BSSIDstr); Série.Imprimer("]"); Série.Imprimer(" ("); Série.Imprimer(RSSI RSSI); Série.Imprimer(")"); Série.println("");         }         Int Mac[6];         obtenir le serveur MAC et enregistrer à la mémoire RTC         Si ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c",  &Mac[0], &Mac[1], &Mac[2], &Mac[3], &Mac[4], &Mac[5] ) ) {           Pour (Int  = 0;  < 6; ++ ) {             statinfo.Mac[] = (uint8_t) Mac[];           }           Mise à jourRtcMemory();         }         esclaveFound = 1;         plus de recherche après AP a été trouvé         Pause;       }     }   }         Si (Debug) {     Si (esclaveFound) {       Série.println("Esclave trouvé, le traitement..");     } Autre {       Série.println("Esclave pas trouvé, essayant à nouveau.");     }   }   libérer RAM   Wifi.scanDelete();
}

fonction pour initiliser le capteur BME
essayez les deux adresses valides 77 ou 76
Boolean initBme() {   Boolean Statut = Bme.Commencer(0x77);     Si (!Statut) Statut = Bme.Commencer(0x76);   Si (!Statut) {       Série.println("Impossible de trouver un capteur BME280 valide, vérifier le câblage!");       hasBme = Faux;       Tandis que (1);   }   Retour Statut;
}

fonction pour initiliser le capteur BMP
essayez les deux adresses valides 77 ou 76
Boolean initBmp() {   Boolean Statut = Bmp.Commencer(0x77);     Si (!Statut) Statut = Bmp.Commencer(0x76);   Si (!Statut) {       Série.println("Impossible de trouver un capteur BME280 valide, vérifier le câblage!");       hasBme = Faux;       Tandis que (1);   }   Si (Statut) {   /Paramètres par défaut à partir de la feuille de données. */     Bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /mode d’exploitation. */                   Adafruit_BMP280::SAMPLING_X2,     Temp. sursachants /                   Adafruit_BMP280::SAMPLING_X16,    /- Suréchantillon de pression //                   Adafruit_BMP280::FILTER_X16,      (filtrer. */                   Adafruit_BMP280::STANDBY_MS_500); /- Temps de veille. */   }   Retour Statut;
}

Vide Configuration() {   Si (Debug) {     Série.Commencer(115200);      Série.println("Démarrer");   }   obtenir l’adresse LOCALE MAC de l’utiliser comme id appareil   String strmac strmac = Wifi.macAddress macAddress (en)();   Si (Debug) {     Série.Imprimer("Mon adresse MAC ");     Série.println(strmac strmac);   }   Msg.setId setId(strmac strmac);   Msg.Clair();   hasBme = initBme();   Si (hasBme && Debug) {     Série.println("Capteur trouvé BME");   }   hasBmp = initBmp();   Si (hasBmp && Debug) {     Série.println("Capteur trouvé BMP");   }   lire le serveur MAC de la mémoire du CCF   Esp.rtcUserMemoryLiez(0, (uint32_t*) &statinfo, Sizeof(statinfo));   Si (Debug) Série.println("RTC fait");   uint32_t crcOfData = calculateCRC32(((uint8_t*) &statinfo) + 4, Sizeof(statinfo) - 4);   Wifi.Mode(WIFI_STA); Mode station pour nœud de capteur esp-now   Si (Debug) Série.println("WifiMode");   Si (statinfo.crc32 != crcOfData) { si checksum différent, nous n’avons pas un serveur valide MAC     Si (Debug) Série.println("Scan pour esclave");     ScanForSlave();     pour (uint8_t i '0; i’lt;6;i') statinfo.mac[i] - gwmac[i];     Si (Debug) {       Série.Printf("Ce mac: %s",, Wifi.macAddress macAddress (en)().c_str());        Série.Printf("cible mac: %02x%02x%02x%02x%02x%02x%02x", statinfo.Mac[0], statinfo.Mac[1], statinfo.Mac[2], statinfo.Mac[3], statinfo.Mac[4], statinfo.Mac[5]);      }   }   Si (esp_now_init() != 0) {     Si (Debug) Série.println("ESP_Now init a échoué");     Esp.Redémarrer();   }   ESP Maintenant Contrôleur   Wifi.setAutoConnect(Faux);   esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);   uint8_t Ch = esp_now_get_peer_channel(statinfo.Mac);   Si (Debug) Série.Printf("Canal - %i’r"n",Ch);   initialiser les données peer   Int Res = esp_now_add_peer(statinfo.Mac, ESP_NOW_ROLE_CONTROLLER, 1, Null, 0);   Si (Res==0) Série.println("Avec succès jumelé");   rappel d’enregistrement   esp_now_register_send_cb([](uint8_t* Mac, uint8_t sendStatus) {     Si (Debug) {       Série.Imprimer("send_cb, statut "); Série.Imprimer(sendStatus);        Série.Imprimer(", à mac: ");        Char Char macString (en)[50] = {0};       Sprintf(macString (en),"%02X:%02X:%02x:%02X:%02X:%02X", statinfo.Mac[0], statinfo.Mac[1], statinfo.Mac[2], statinfo.Mac[3], statinfo.Mac[4], statinfo.Mac[5]);       Série.println(macString (en));     }     rappelCalled = Vrai;   });      mettre le drapeau à faux   rappelCalled = Faux;      commencer la mesure   lire les valeurs et économiser pour l’envoi   Si (hasBme) {     Si (Debug){       Série.Imprimer("Température ");       Série.Imprimer(Bme.lireTemperature());       Série.println(" C");          Série.Imprimer("Pression ");          Série.Imprimer(Bme.lirePressure() / 100.0F);       Série.println("hPa");          Série.Imprimer("Approx. Altitude - ");       Série.Imprimer(Bme.lireAltitude(SEALEVELPRESSURE_HPA));       Série.println("m");          Série.Imprimer("Humidité ");       Série.Imprimer(Bme.lireHumidity());       Série.println(" %");           }     Msg.addCelsius(Bme.lireTemperature(), CHANNEL_TEMP_BME);     Msg.addHektoPascal(Bme.lirePressure()/100.0F, CHANNEL_PRESS_BME);     Msg.addMeter(Bme.lireAltitude(SEALEVELPRESSURE_HPA), CHANNEL_ALT_BME);     Msg.addPercent(Bme.lireHumidity(), CHANNEL_HUM_BME);   }   Si (hasBmp) {     Si (Debug) {       Série.Imprimer(Q("Température "));       Série.Imprimer(Bmp.lireTemperature());       Série.println(" C");          Série.Imprimer(Q("Pression "));       Série.Imprimer(Bmp.lirePressure());       Série.println("Pa");          Série.Imprimer(Q("Altitude approximative "));       Série.Imprimer(Bmp.lireAltitude(SEALEVELPRESSURE_HPA)); /- Ajusté aux prévisions locales! */       Série.println("m");            }     Msg.addCelsius(Bmp.lireTemperature(), CHANNEL_TEMP_BMP);     Msg.addHektoPascal(Bmp.lirePressure()/100.0F, CHANNEL_PRESS_BMP);     Msg.addMeter(Bmp.lireAltitude(SEALEVELPRESSURE_HPA), CHANNEL_ALT_BMP);   }   copier des données structure dans sendbuffer   uint8_t Buf Buf[255];   uint8_t Sz;   Sz = 255;   Si (Msg.fillBuffer (en)(&Buf Buf[0], &Sz)) esp_now_send(Null, Buf Buf, Sz); NULL signifie envoyer à tous les pairs
}

Vide Boucle() {   attendre que les données soient envoyées   Si (rappelCalled || (Millis() > SEND_TIMEOUT)) {     Si (Debug) Série.println("Dormir");     Retard(100);     passer 10 secondes en mode sommeil profond     réveil par réinitialisation     la réinitialisation ne supprime pas les données dans RTCmemory     Esp.deepSleep(10E6);   }
}

 

Pour que cette esquisse soit compilée, en plus des bibliothèques pour les capteurs, vous avez besoin de la dernière version de mon ATMessageBuffer Bibliothèque.

Le code de l’esquisse se trouve également dans les exemples de la nouvelle version de la ATSmartHome (en) Bibliothèque.

Une fois que le siège de Smart-Home a été mis à jour, nous compilons le croquis et le chargeons dans la D1 Mini. Après une courte période, l’adresse MAC de la D1 Mini devrait apparaître dans la barre bleue inférieure du siège social de Smarthome. Nous cliquons une fois longtemps (plus de 3 s) sur cette adresse MAC. La page d’inscription est affichée. Nous pouvons donner un nom à l’appareil et après avoir cliqué sur Enregistrer, nous devrions voir les nouvelles lectures sur l’écran. Si d’autres appareils ont déjà été enregistrés au siège social de Smarthome, les nouveaux canaux peuvent également apparaître sur l’une des autres pages. L’enregistrement automatique recherche des places gratuites dans l’écran et affiche les nouveaux canaux comme de petits widgets.

En cliquant longtemps sur les widgets, vous arrivez à leur page de configuration et peut changer l’apparence et la position. L’image suivante montre une configuration possible si nous utilisons les deux capteurs BMx en même temps.

Affichage

 

Enfin, une petite extension sur le site du siège de Smarthome. Si un widget actionneur est affiché, vous avez la possibilité d’allumer ou de désactiver l’appareil enlevé comme sur le centre d’accueil intelligent lui-même, en cliquant sur ou hors tension. Pour le widget actionneur voir aussi partie 3 de cette série

Ici encore les liens vers toutes les parties précédentes:

Amusez-vous :)

 

 

 

Esp-8266Projekte für fortgeschritteneSensorenSmart home

10 commentaires

Franz Patzal

Franz Patzal

Hi Greg,

look in part 6:

Ein wichtiger Hinweis zu Beginn!

Die ArduiTouch Smarthome Zentrale funktioniert nur mit dem ESP32 stabil. Es zeigte sich, dass auf Grund des deutlich geringeren RAM des ESP8266 kein stabiler Betrieb möglich ist. Ich habe daher die Version für den ESP8266 wieder aus dem Repository entfernt. Die aktuelle Version der ATSmartHome Bibliothek kann nicht mehr mit dem Sketch für ESP8266 kompiliert werden!

Greg

Greg

Hi. I am trying to follow the examples fro the SmartHome project, but it refers to the library ESP8266WiFi.H, even for ESP32 examples . Where can I find this library?
Many thanks!
Greg.

Wolfgang Händel

Wolfgang Händel

Hallo Herr Lechner….
Bis auf die etwas begrenzte Reichweite der Arduitouch Zentrale funktioniert bei mir alles recht gut.
Was das Herz des Smarthome Einsteigers natürlich höher schlagen lassen würde, wäre ein Sensormodul für ein binäres Signal (Klingeltaster, Bewegungssensor, Dämmerungssensor uvm.)
Das binäre Signal eines solchen Moduls müsste in der Zentrale ausgewertet werden und bestimmte Funktionen (wie z.B. das Relaismodul aus Teil 3) auslösen.
Haben sie so etwas geplant? Meines Erachtens gehört so etwas zu den Standard-Features eines SmartHome-Systems.
Ansonsten vielen Dank für die interessanten Blogs zum Thema SmartHome und für die Mühe, die sie sich damit gegeben haben bzw. noch geben..
Wolfie

Siegl Reinhard

Siegl Reinhard

Hallo
Ich bekomme die Smart Home V" nicht zum laufen.Es stoppt schon bei #include “SPIFFS.h”.
Bei der alten Smart Home konnte ich alle Beiträge nachbauen.
Danke für die Unterstützung schon im Vorraus.

Matthias H.

Matthias H.

Hallo Herr Lechner,
könnte man die Stimmungslaterne https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/mehrere-feuer-programme-fuer-unsere-stimmungslaterne?pos=3&_sid=3afeceff9&ss=r nicht mit der Smarthome Zenrale steuern?

Reinhard Schneider

Reinhard Schneider

Wie das mit den Fehlern so ist, es hat sich auch bei mir einer eingeschlichen.
Richtig muss es für 5 min deep-sleep heißen:

ESP.deepSleep(300*10E6);

Reinhard Schneider

Reinhard Schneider

Leider haben sich in das o.g. Programm einige kleine Fehler eingeschlichen:
1. /function to initilize BMP Sensor
….
Richtig:
Serial.println(“Could not find a valid BMP280 sensor, check wiring!”);
hasBmp = false;

2. In der Beschreibung heißt es
….
After sending the values, the device switches for five minutes into a deep sleep mode with very low power consumption.
Der Code ist aber in void loop()
….
//go for 10 seconds into deep sleep mode
//wakeup by reset
//reset does not delete data in RTCmemory
ESP.deepSleep(10E6);

Für 5 Minuten müsste es heißen:

ESP.deepSleep(600*10E6);

Reinhard  Schneider

Reinhard Schneider

Das obige Programm läuft nur mit der Version 0.15.0 von “ESPiLight”.
Die aktuelle Version 0.16.0 erzeugt Fehlermeldungen.
Ist eine Anpassung des ino-Files geplant?

Joe

Joe

Bei den Daten der beiden Sensoren kann man sagen das es Roh-Daten sind.
Jetzt muß man nur eine Kalibrierung mit einem Referenz-Meßgerät höherer Genauigkeit durchführen. Und dann die Rohdaten entsprechen mit einem Justage-Wert belegen.
Es wird immer eine geringfügige Abweichung zwischen den Sensoren geben.
(Rauschen, Eigentemperatur etc, Meßfehler).
Die redudante Messung ist in Bereichen bei denen der Ausfall, starker Unterschied der Meßwerte, ermittelt werden muß. Rreinraum, technische zu überwachende Prozeße.
Temperatur-Differenzen werden auch genutzt um Strömungen, in dem Fall Luft, zu ermitteln.

Also nicht vergessen Justage-Wert und Kalibrierung.

Marcus Klein

Marcus Klein

Beide Sensoren sind offenbar recht nah beieinander untergebracht. Sie messen trotzdem eine Differenz von einem kompletten Grad Celsius. Das ist ein absolutes No-Go, wenn man damit versucht Heimautomatisierung zu betreiben und die Heizung zu steuern. Daraus folgt direkt, dass der Heizkreis am Sensor mit der kleineren Temperatur immer heizt und der Kreis am Sensor mit der größeren Temperatur immer aus ist. Bei einem Grad Unterschied und nicht verschlossenen Türen zwischen den beiden Räumen und gut isolierter Hütte, wandert die Wärme ausreichend zwischen den beiden Räumen. Das trägt nicht wirklich zum Wohnkomfort bei, sondern stört diesen besonders.
Wie gedenken Sie, diesen Fehler zu kompensieren?

Laisser un commentaire

Tous les commentaires sont modérés avant d'être publiés