| |
— | projets:automate2:prog [2019/08/13 10:16] (Version actuelle) – créée - modification externe 127.0.0.1 |
---|
| ====== Programme ====== |
| |
| Le programme est le dernier mis à jour avec l'afficheur OLED.\\ |
| Il est encore en phase de test, mais on peu y trouver quasi toutes les fonctions.\\ |
| Reste a agencer ça. |
| |
| ===== Synoptique ===== |
| |
| Initiation |
| Boucle principale |
| Boucle tant que et temps limite |
| Test de connexion MQTT |
| Si réception message MQTT |
| Affichage |
| Exécution de l'ordre |
| ( mise à jour des seuils, |
| Commande volet, |
| ) |
| Récupération de l'heure / min |
| Affichage |
| Récupération des données interne (temp, humidité) / 5min |
| Affichage |
| Récupération des commandes du BP (interruption) |
| Affichage/exécution en fonction |
| BP 1 fois - Affiche Temp, humidité, lumière externe |
| BP 2 fois - Affiche pression |
| BP 3 fois - désactive/réactive volets |
| Envoi info au serveur MQTT / 10min |
| Fin boucle |
| |
| ===== Code ===== |
| |
| <code c++> |
| /* |
| Projet de sonde luminosité, température et humidité. |
| Ajout de commande des volets roulants pour une gestion de la température du logement. |
| |
| Basé sur l'exemple Basic ESP8266 MQTT |
| |
| Il cherche une connexion sur un serveur MQTT puis : |
| - Il affiche les luminosités/humidités, lunière, pression baro intener (et externe). |
| - Il envoie tout cela en MQTT |
| - La température interne, (externe) |
| - L'humidité interne, (externe) |
| - La lumiére |
| - La pression barométrique et les autres parmêtres du BMP180 |
| |
| En fonction des paramètres lumiére, température, |
| il pourra monter ou descendre le volets roulants. |
| |
| Affichage normal : (heure option) Tempéarute, Humidité |
| Si BP = 1s -> (peut étre 1 pression) |
| Affiche Temp int/ext, Lum int/ext, hum int/ext |
| Si BP = 3S -> |
| Affiche pression, (prévisions météos options) |
| Si BP = 10s -> désactivation volets |
| |
| FUTUR : |
| On pourra définir les paramètres via une instruction MQTT |
| |
| Fonction accessoire : |
| It will reconnect to the server if the connection is lost using a blocking |
| reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to |
| achieve the same result without blocking the main loop. |
| |
| Exemples : |
| MQTT: |
| https://github.com/aderusha/IoTWM-ESP8266/blob/master/04_MQTT/MQTTdemo/MQTTdemo.ino |
| Witty: |
| https://blog.the-jedi.co.uk/2016/01/02/wifi-witty-esp12f-board/ |
| Module tricapteur: |
| http://arduinolearning.com/code/htu21d-bmp180-bh1750fvi-sensor-example.php |
| |
| |
| */ |
| |
| #include <ESP8266WiFi.h> |
| #include <PubSubClient.h> |
| #include <DHT.h> |
| // Include the correct display library |
| // For a connection via I2C using Wire include |
| #include <Wire.h> // Only needed for Arduino 1.6.5 and earlier |
| #include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` |
| |
| // Include custom images |
| #include "WeatherStationImages.h" |
| #include "WeatherStationFonts.h" |
| |
| // DHT 11 sensor |
| #define DHTPIN 2 |
| #define DHTTYPE DHT11 |
| |
| |
| // Utilisation d’une photo-résistance |
| // Et ports pour cmd volet |
| const int port = A0; // LDR |
| #define haut 12 |
| #define arret 13 |
| #define bas 15 |
| #define lbp 14 |
| |
| // Update these with values suitable for your network. |
| // Buffer pour convertir en chaine de l'adresse IP de l'appareil |
| char buffer[20]; |
| const char* ssid1 = "FREEBOX_xxx_EXT"; |
| const char* ssid2 = "FREEBOX_xxx_P2"; |
| const char* password = "xxxx"; |
| const char* mqtt_server = "192.168.0.x"; |
| |
| // Création objet |
| WiFiClient espClient; |
| PubSubClient client(espClient); |
| // DHT sensor |
| DHT dht(DHTPIN, DHTTYPE, 15); |
| |
| // Variables |
| int valeur = 0; |
| float vin = 0; |
| char msg[50]; |
| int value = 0; |
| unsigned long readTime; |
| //Buffer qui permet de décoder les messages MQTT reçus |
| char message_buff[100]; |
| long lastMsg = 0; //Horodatage du dernier message publié sur MQTT |
| long lastRecu = 0; |
| bool debug = false; //Affiche sur la console si True |
| bool mess = false; // true si message reçu |
| String sujet = ""; |
| String mesg = ""; |
| |
| // Initialize the OLED display using Wire library |
| SSD1306 display(0x3c, 4, 5); |
| |
| //======================================== |
| void setup_wifi() { |
| |
| int cpt = 0; |
| boolean ssid = true; |
| delay(10); |
| int ss = 1; |
| |
| display.setTextAlignment(TEXT_ALIGN_LEFT); |
| display.setFont(ArialMT_Plain_10); |
| display.drawString(0, 0, "Connexion au WiFi"); |
| |
| // We start by connecting to a WiFi network |
| while (WiFi.status() != WL_CONNECTED) { |
| if (ssid) { |
| WiFi.begin(ssid1, password); |
| } |
| else { |
| ss = 2; |
| WiFi.begin(ssid2, password); |
| } |
| if (debug) { |
| Serial.println(); |
| Serial.print("Connecting to "); |
| if (ss == 1) { |
| Serial.println(ssid1); |
| } else { |
| Serial.println(ssid2); |
| } |
| } |
| |
| int counter = 0; |
| while ((WiFi.status() != WL_CONNECTED) && (cpt <= 20)) { |
| delay(500); |
| Serial.print("."); |
| display.clear(); |
| display.setTextAlignment(TEXT_ALIGN_LEFT); |
| display.drawString(24, 0, "Connecting to WiFi"); |
| display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbole : inactiveSymbole); |
| display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbole : inactiveSymbole); |
| display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbole : inactiveSymbole); |
| display.display(); |
| |
| counter++; |
| cpt=cpt+1; |
| // Serial.print("."); |
| } |
| |
| if (cpt >= 20) { |
| if (ssid) { |
| ssid=false; |
| } else { |
| ssid=true; |
| } |
| } |
| } |
| |
| // Connexion au serveur MQTT |
| display.clear(); |
| display.setTextAlignment(TEXT_ALIGN_LEFT); |
| display.setFont(ArialMT_Plain_10); |
| display.drawString(32, 0, "WiFi connecté"); |
| display.drawString(32, 20, "IP address"); |
| // On récupère et on prépare le buffer contenant l'adresse IP attibué à l'ESP-01 |
| IPAddress ip = WiFi.localIP(); |
| String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]); |
| ipStr.toCharArray(buffer, 20); |
| display.drawString(30, 30, String(ipStr)); |
| display.display(); |
| delay(2000); |
| display.clear(); |
| display.setTextAlignment(TEXT_ALIGN_LEFT); |
| display.setFont(ArialMT_Plain_10); |
| display.drawString(25, 0, "Connecting to MQTT"); |
| display.drawString(32, 20, mqtt_server); |
| display.display(); |
| delay(2000); |
| if ( debug ) { |
| Serial.println(""); |
| Serial.println("WiFi connected"); |
| Serial.print("IP address: "); |
| Serial.println(WiFi.localIP()); |
| |
| Serial.print("Connecting to "); |
| Serial.println(mqtt_server); |
| } |
| /* Serial.print(" as "); |
| Serial.println(clientName); |
| */ |
| } |
| |
| //======================================== |
| // Déclenche les actions à la réception d'un message |
| // D'après http://m2mio.tumblr.com/post/30048662088/a-simple-example-arduino-mqtt-m2mio |
| void callback(char* topic, byte* payload, unsigned int length) { |
| |
| // pinMode(lbp,OUTPUT); |
| int i = 0; |
| if ( debug ) { |
| Serial.println("Message recu => topic: " + String(topic)); |
| Serial.print(" | longueur: " + String(length,DEC)); |
| } |
| sujet = String(topic); |
| // create character buffer with ending null terminator (string) |
| for(i=0; i<length; i++) { |
| message_buff[i] = payload[i]; |
| } |
| message_buff[i] = '\0'; |
| |
| String msgString = String(message_buff); |
| mesg = msgString; |
| if ( debug ) { |
| Serial.println("Payload: " + msgString); |
| } |
| mess = true; |
| |
| } |
| |
| /* |
| void callback(char* topic, byte* payload, unsigned int length) { |
| Serial.print("Message arrived ["); |
| Serial.print(topic); |
| Serial.print("] "); |
| for (int i = 0; i < length; i++) { |
| Serial.print((char)payload[i]); |
| } |
| Serial.println(); |
| |
| // Switch on the LED if an 1 was received as first character |
| if ((char)payload[0] == '1') { |
| digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level |
| // but actually the LED is on; this is because |
| // it is acive low on the ESP-01) |
| } else { |
| digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH |
| } |
| |
| } |
| */ |
| |
| //======================================== |
| void reconnect() { |
| // Loop until we're reconnected |
| int counter = 0; |
| int compt = 0; |
| boolean noconnect = true; |
| // tant qu'il ne trouve pas un serveur affiche rond |
| while ((!client.connected()) && (noconnect == true)) { |
| display.clear(); |
| display.setTextAlignment(TEXT_ALIGN_LEFT); |
| display.setFont(ArialMT_Plain_10); |
| display.drawString(0, 0, "Attempting MQTT connection"); |
| display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbole : inactiveSymbole); |
| delay(500); |
| display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbole : inactiveSymbole); |
| delay(500); |
| display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbole : inactiveSymbole); |
| display.display(); |
| counter++; |
| delay(500); |
| |
| if (debug ) { |
| Serial.print("Attempting MQTT connection..."); |
| } |
| // Attempt to connect |
| if (client.connect("ESP8266Client")) { |
| display.clear(); |
| display.setTextAlignment(TEXT_ALIGN_LEFT); |
| display.setFont(ArialMT_Plain_16); |
| display.drawString(23, 20, "Connecté sur"); |
| display.drawString(18, 38, "Serveur MQTT !"); |
| display.display(); |
| if (debug ) { |
| Serial.println("connected"); |
| } |
| // Once connected, publish an announcement... |
| client.publish("cuisine", "hello world"); |
| // ... and resubscribe |
| client.subscribe("#"); |
| noconnect=true; |
| } else { |
| display.clear(); |
| display.setTextAlignment(TEXT_ALIGN_LEFT); |
| display.setFont(ArialMT_Plain_10); |
| display.drawString(2, 0, "On réessaye dans 3 sec"); |
| display.setFont(ArialMT_Plain_16); |
| display.drawString(5, 20, "Erreur !"); |
| display.drawString(0, 38, "Non Connecté !"); |
| display.display(); |
| if ( debug ) { |
| Serial.print("failed, rc="); |
| Serial.print(client.state()); |
| Serial.println(" try again in 5 seconds"); |
| } |
| // Wait 5 seconds before retrying |
| if (compt <= 3) { |
| delay(3000); |
| counter=0; |
| compt++; |
| } else { |
| noconnect=false; |
| } |
| } |
| |
| } |
| delay(1500); |
| } |
| |
| //======================================== |
| void sensorRead() { |
| readTime = millis(); |
| // Reading temperature or humidity takes about 250 milliseconds! |
| // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) |
| |
| float h = dht.readHumidity(); |
| // Read temperature as Celsius (the default) |
| float t = dht.readTemperature(); |
| // Read temperature as Fahrenheit (isFahrenheit = true) |
| // float f = dht.readTemperature(true); |
| |
| // Check if any reads failed and exit early (to try again). |
| if (isnan(h) || isnan(t)) { // || isnan(f)) { |
| Serial.println("Failed to read from DHT sensor!"); |
| return; |
| } |
| |
| display.clear(); |
| display.setTextAlignment(TEXT_ALIGN_LEFT); |
| display.setFont(ArialMT_Plain_10); |
| display.drawString(8, 0, "Temp + Humidité interne"); |
| display.setFont(ArialMT_Plain_16); |
| display.drawString(6, 20, "Température=" + String(t)+" °C"); |
| display.drawString(10, 38, "Humidité=" + String(h)+" %"); |
| display.display(); |
| // delay(500); |
| |
| char buffer[20]; |
| strcpy(msg, "Température "); |
| dtostrf(t,3, 2, buffer); |
| // On concatene les 2 tab de char |
| strcat(msg, buffer); |
| client.publish("cuisine",msg); |
| //Serial.println(buffer); |
| strcpy(msg, "Humiditée "); |
| dtostrf(h,3, 2, buffer); |
| strcat(msg, buffer); |
| client.publish("cuisine",msg); |
| |
| //client.publish("cuisine",sprintf(buf, "%f", h)); |
| /*Serial.print("Humidity: "); |
| Serial.print(h); |
| Serial.print(" %\t"); |
| Serial.print("Temperature: "); |
| Serial.print(t); |
| Serial.print(" *C "); |
| /*Serial.print(f); |
| Serial.print(" *F\t"); |
| Serial.print("Heat index: "); |
| Serial.print(hic); |
| Serial.print(" *C "); |
| Serial.print(hif); |
| Serial.println(" *F"); */ |
| } |
| |
| //======================================== |
| void setup() { |
| pinMode(haut, OUTPUT); // Initialize le mvmt haut |
| pinMode(arret, OUTPUT); // Initialize le mvmt arret |
| pinMode(bas, OUTPUT); // Initialize le mvmt bas |
| pinMode(lbp, INPUT); // Initialize le BP |
| Serial.begin(115200); |
| // Initialising the UI will init the display too. |
| display.init(); |
| display.clear(); |
| |
| //delay(500); |
| |
| display.flipScreenVertically(); |
| display.setTextAlignment(TEXT_ALIGN_LEFT); |
| display.setFont(ArialMT_Plain_16); |
| display.drawString(30, 31, "Bonjour"); |
| // delay(1000); |
| |
| display.setFont(ArialMT_Plain_10); |
| display.drawString(32, 0, "Hello world"); |
| display.display(); |
| delay(1500); |
| |
| |
| setup_wifi(); |
| client.setServer(mqtt_server, 1883); |
| client.setCallback(callback); |
| dht.begin(); // initialize temperature sensor |
| client.subscribe("mod_cuisine"); |
| } |
| |
| //======================================== |
| void loop() { |
| // test de connection, sinon reconnecte |
| //int counter = 0; |
| if (!client.connected()) { |
| reconnect(); |
| } |
| client.loop(); |
| //Serial.println("Lecture du capteur"); |
| |
| // affiche message reçu en MQTT |
| if ( mess ) { |
| pinMode(lbp,OUTPUT); |
| display.clear(); |
| display.setTextAlignment(TEXT_ALIGN_LEFT); |
| display.setFont(ArialMT_Plain_10); |
| display.drawString(25, 0, "Message de MQTT"); |
| display.drawString(32, 20, sujet); |
| display.drawString(32, 30, mesg); |
| display.display(); |
| delay(1500); |
| if ( sujet == "mod_cuisine" ) { |
| if ( mesg == "ON" ) { |
| digitalWrite(lbp,HIGH); |
| } else { |
| digitalWrite(lbp,LOW); |
| } |
| } |
| pinMode(lbp,INPUT); |
| mess = false; |
| } |
| |
| |
| // renvoie le niveau de la ldr tous les 10 sec |
| long now = millis(); |
| if (now - lastMsg > 5000) { |
| lastMsg = now; |
| ++value; |
| snprintf (msg, 50, "hello world #%ld", value); |
| //Serial.print("Publish message: "); |
| //Serial.println(msg); |
| client.publish("cuisine", msg); |
| |
| // Lit l’entrée analogique A0 |
| valeur = analogRead(port); |
| //Serial.print("valeur = "); |
| //Serial.println(valeur); |
| // convertit l’entrée en volt |
| vin = (valeur * 3.3) / 1024.0; |
| //Serial.print("volt = "); |
| //Serial.println(vin); |
| display.clear(); |
| display.setTextAlignment(TEXT_ALIGN_LEFT); |
| display.setFont(ArialMT_Plain_10); |
| display.drawString(14, 0, "Luminosité interne"); |
| display.setFont(ArialMT_Plain_16); |
| display.drawString(25, 20, "Niv=" + String(valeur)); |
| display.drawString(18, 38, "Volts=" + String(vin)); |
| display.display(); |
| delay(1500); |
| snprintf (msg, 50, "Luminosité %ld", valeur); |
| client.publish("cuisine", msg); |
| |
| while (now - lastMsg > 10000) { |
| Serial.print("compteur: "+ (now-lastMsg)); |
| } |
| |
| //Serial.println("Lecture du capteur"); |
| sensorRead(); |
| delay(1500); |
| } |
| } |
| |
| |
| /* |
| void DHT11() { |
| |
| // Grab the current state of the sensor |
| int humidity_data = (int)dht.readHumidity(); |
| int temperature_data = (int)dht.readTemperature(); |
| |
| // Publish data |
| if (! temperature.publish(temperature_data)) |
| Serial.println(F("Failed to publish temperature")); |
| else |
| Serial.println(F("Temperature published!")); |
| |
| if (! humidity.publish(humidity_data)) |
| Serial.println(F("Failed to publish humidity")); |
| else |
| Serial.println(F("Humidity published!")); |
| |
| // Setup feeds for temperature & humidity |
| const char TEMPERATURE_FEED[] PROGMEM = AIO_USERNAME "/feeds/temperature"; |
| Adafruit_MQTT_Publish temperature = Adafruit_MQTT_Publish(&mqtt, TEMPERATURE_FEED); |
| |
| const char HUMIDITY_FEED[] PROGMEM = AIO_USERNAME "/feeds/humidity"; |
| Adafruit_MQTT_Publish humidity = Adafruit_MQTT_Publish(&mqtt, HUMIDITY_FEED); |
| |
| } |
| */ |
| |
| </code> |