Smarthome Zentrale mit ArduiTouch Teil 3  - Aktor Device mit D1Mini und Relais - AZ-Delivery

Esta vez queremos expandir nuestro SmartHome con un dispositivo pasivo que sea adecuado con un relé para cambiar los enchufes o los consumidores de la red. Usaremos uno de nuevo D1Mini  junto con uno Módulo de relé. El circuito para esto es muy simple.

 

Bosquejo:

 

// biblioteca para WiFi
#include <ESP8266WiFi.h>

// biblioteca para el protocolo de mensaje utilizado
#include "AT_MessageBuffer.h"

// biblioteca para ESP Now
externo "C" {   #include <saber.h>
}

// SSID para buscar
#definir GW_SSID "ATSmartHome"

// marca para activar los mensajes de depuración
#definir DEPURACIÓN cierto

#definir SEND_TIMEOUT 2000  // Tiempo de espera de 2 segundos 

#definir INTERVALO 10000 // intervalo = 10 segundos

// define canales para el relé
#definir CHANNEL_RELAIS 0

// Pines para conectar los sensores
#definir RELAIS_PIN 2 // GPIO2

// Estructura de datos para guardar la dirección MAC del servidor
// y una suma de comprobación en la memoria RTC
estructura DATOS DE MEMORIA {   uint32_t crc32; // suma de comprobación para validación   uint8_t mac[6];
};

// dirección MAC y canal WLAN
DATOS DE MEMORIA statinfo;
// hora de la última vez que se envió
uint32_t last_sent = 0; // Marca de tiempo para el último enviado
uint8_t relé_estado = 0; // estado actual del relé
Cadena mymac; // dirección mac propia

// tenemos dos buffers de mensajes para enviar y recibir
AT_MessageBuffer sendmsg;
AT_MessageBuffer rcvmsg;

// escribe el servidor MAC y la suma de comprobación en la memoria RTC
nulo UpdateRtcMemory() {     uint32_t crcOfData =AT_CalculateCRC32(((uint8_t*) &statinfo) + 4, tamaño de(statinfo) - 4);     statinfo.crc32 = crcOfData;     ESP.rtcUserMemoryWrite(0,(uint32_t*) &statinfo, tamaño de(statinfo));
}

// busca el punto de acceso
nulo ScanForSlave() {   bool slaveFound = 0;      int8_t scanResults = WiFi.scanNetworks();   // restablecer en cada escaneo   si (DEPURACIÓN) De serie.println("Escaneo hecho");   si (scanResults == 0) {     si (DEPURACIÓN) De serie.println("No se encontraron dispositivos WiFi en modo AP");   } otra cosa {     si (DEPURACIÓN) De serie.imprimir("Encontrado");      si (DEPURACIÓN) De serie.imprimir(scanResults);      si (DEPURACIÓN) De serie.println("dispositivos");     para (int yo = 0; yo < scanResults; ++yo) {       // Imprimir SSID y RSSI para cada dispositivo encontrado       Cadena SSID = WiFi.SSID(yo);       int32_t RSSI = WiFi.RSSI(yo);       int32_t chl = WiFi.canal(yo);       Cadena BSSIDstr = WiFi.BSSIDstr(yo);       si (DEPURACIÓN) {         De serie.imprimir(yo + 1);         De serie.imprimir(": ");         De serie.imprimir(SSID);         De serie.imprimir(" /");         De serie.imprimir(chl);         De serie.imprimir(" (");         De serie.imprimir(RSSI);         De serie.imprimir(")");         De serie.println("");       }       retrasar(10);       // Comprueba si el dispositivo actual comienza con ATSmartHome`       si (SSID == GW_SSID) {         // SSID de interés         si (DEPURACIÓN) {           De serie.println("Encontré un esclavo".);           De serie.imprimir(yo + 1); De serie.imprimir(": "); De serie.imprimir(SSID); De serie.imprimir(" ["); De serie.imprimir(BSSIDstr); De serie.imprimir("]"); De serie.imprimir(" ("); De serie.imprimir(RSSI); De serie.imprimir(")"); De serie.println("");         }         int mac[6];         // obtener el servidor MAC y guardar en la memoria 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] ) ) {           para (int ii = 0; ii < 6; ++ii ) {             statinfo.mac[ii] = (uint8_t) mac[ii];           }           UpdateRtcMemory();         }         slaveFound = 1;         // no más búsquedas después de encontrar AP         romper;       }     }   }         si (DEPURACIÓN) {     si (slaveFound) {       De serie.println("Esclavo encontrado, procesando ..");     } otra cosa {       De serie.println("Esclavo no encontrado, intentándolo de nuevo".);     }   }   // liberar RAM   WiFi.scanDelete();
}

nulo sendData() {   uint8_t buf[100]; // buffer para esp   uint8_t sz = 100;   // borrar el búfer de mensajes   sendmsg.claro();   si (DEPURACIÓN) {     De serie.println("Enviar"+mymac);   }   sendmsg.setId(mymac);   // agrega el estado actual del relé como un mensaje booleano al búfer   sendmsg.addSwitchOut(relé_estado != 0,CHANNEL_RELAIS);   // llena el búfer y envía el contenido al centro de control   si (sendmsg.fillBuffer(buf,&sz)) esp_now_send(CERO, buf, sz);   // recuerda el tiempo para calcular el intervalo   last_sent=millis();
}

// devolución de llamada al recibir mensajes de ESP-Now
nulo readESPNow(uint8_t *mac_addr, uint8_t *r_data, uint8_t data_len) {   PAQUETE DE DATOS datos;   uint32_t newstatus;   // copia los datos recibidos en el búfer de mensajes recibidos   rcvmsg.readBuffer(r_data);   si (mymac.equalsIgnoreCase(rcvmsg.getId())) {     // acepta solo mensajes para este dispositivo     si (rcvmsg.getPackets() > 0) {       // obtuvimos un paquete de datos       datos = rcvmsg.getData(0);       si (DEPURACIÓN) {         De serie.printf("Obtuve datos para el canal% i valor% i \ n",datos.canal, datos.valor[0]);       }         si (datos.canal == CHANNEL_RELAIS) {         // si los datos fueran para el canal correcto, establezca el nuevo estado         newstatus = datos.valor[0];         si (newstatus != relé_estado) {           // si el estado ha cambiado, lo exportamos al relé           relé_estado = newstatus;           digitalWrite(RELAIS_PIN,relé_estado);           si (DEPURACIÓN){             De serie.printf("Estado del relé =% i \ n",relé_estado);           }         }       }     }   }
}

nulo configuración() {   si (DEPURACIÓN) {     De serie.comenzar(115200);      De serie.println("Inicio");   }   pinMode(RELAIS_PIN,SALIDA);   digitalWrite(RELAIS_PIN,relé_estado);   //obtener la dirección MAC local para usarla como dispositivo id   mymac = WiFi.macAddress();   si (DEBUG) {     Serial.imprimir("Mi dirección MAC = ");     Serial.println(mymac);   }   ESP.rtcUserMemoryRead(0, (uint32_t*) &statinfo, tamaño de(statinfo));   si (DEBUG) Serial.println("RTC Hecho");   uint32_t crcOfData = AT_CalculateCRC32(((uint8_t*) &statinfo) + 4, tamaño de(statinfo) - 4);   WiFi.modo(WIFI_STA); Modo // Estación para el nodo de aktor esp-now   si (DEBUG) Serial.println("WifiMode");   si (statinfo.crc32 != crcOfData) { // si checksum diferente no tenemos un servidor MAC válido     si (DEBUG) Serial.println("Escanea para esclavos");     ScanForSlave();     //for (uint8_t i = 0; i<6;i++) statinfo.mac[i] = gwmac[i];     si (DEBUG) {       Serial.printf("Este mac: %s,", WiFi.macAddress().c_str());        Serial.printf("objetivo mac: %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) Serial.println("*** ESP_Now init failed");     ESP.reiniciar();   }   //ESP Controlador ahora   WiFi.setAutoConnect(falso);   esp_now_set_self_role(3); //(ESP_NOW_ROLE_CONTROLLER);   uint8_t ch = esp_now_get_peer_channel(statinfo.mac);   si (DEPURACIÓN) De serie.printf("Canal =% i \ r \ n",ch);   // inicializar datos de pares   int res = esp_now_add_peer(statinfo.mac, ESP_NOW_ROLE_CONTROLLER, 1, CERO, 0);   si (res==0) De serie.println("Exitoso emparejado");   // registrar devolución de llamada   esp_now_register_recv_cb(readESPNow); 
}

nulo bucle() {   // envía mensajes al centro de control de forma regular   si ((millis() - last_sent) > INTERVALO) {  // intervalo para enviar datos cambie esto si es necesario     sendData();   }
}

 

 

Para el programa ESP8266Wifi.h y el espnow.h Biblioteca para el ESP8266. Además, la biblioteca ATMessageBuffer necesario para SmartHome.

La sede de SmartHome también debe tener las últimas bibliotecas. ATMessage buffer, ATSmartHome y TouchEvent ser compilado En los ejemplos de ATSmartHome también encontrará el boceto anterior.

Después de que los programas ESP8266Switch y ATSmartHome de los ejemplos de la biblioteca AT_SmartHome se hayan compilado y cargado en el D1Mini o en el ArduiTouch, el sistema de archivos debe formatearse en el centro SmartHome, que cambió la estructura de datos del archivo de configuración con esta actualización. Pero eso no es malo, ya que no pudimos hacer ninguna configuración manual en las versiones anteriores.

Después de reiniciar la unidad central e iniciar el D1Mini, su dirección MAC debe mostrarse en la barra azul inferior.

Un doble clic en esta barra nos lleva a la página de registro.

Después de hacer doble clic en Registrar, la pantalla vuelve a la página principal y deberíamos ver la siguiente imagen.

Si toca este botón brevemente, Reais debería encenderse y apagarse nuevamente con otro toque breve. El color de fondo del botón cambia de gris a verde claro.

Por supuesto, puede usar los módulos Sensor y Switch al mismo tiempo (vea la imagen del título).

Diviértete probando y experimentando.

Esp-8266Projekte für fortgeschritteneSmart home

7 comentarios

Birger T

Birger T

Das in der Einleitung verlinkte Relais mit Kontakten für 50V/3 ist nicht zum Schalten von Steckdosen und Netzverbrauchern geeignet. Wollte ich nur mal erwähnen, weil ich auch diesen Blog Beitrag gelesen habe
https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/entwurf-sicherheit-sicherheit

Jörg Reinisch

Jörg Reinisch

@OGGIN→
Ich weiß ja beim besten Willen nicht was ich noch alles versuchen soll.
Ich habe die Erweiterung des Sketch, so wie du es hier geschrieben hast, auch eingegeben.
Ich habe einen D1 Mini Pro, von der Beschaltung her eigentlich nicht anders.
Nur kann ich beim besten Willen in keinem Fall das zweite Relais ansteuern, obwohl ich es auch auf meiner Anzeige im Display als Switch 1 stehen habe,
Ich kann dir ja gern mal den Sketch zukommen lassen, vielleicht findest du ja den Fehler den ich verzweifelt suche.

Jörg

Jörg

Die ganze Schaltung und Programmierung an sich ist schon wirklich ein wunderbares Spielfeld.
Im Großen und Ganzen macht die Schaltung ja auch genau das was sie eigentlich machen sollte……
eigentlich!?!?
Ich hab nur das Problem dass wenn ich mein Relais auschalten lassen will, diese eingeschaltet wird und genau auch umgekehrt. Ich bin auch schier am Verzweifeln und finde nicht die Stelle an der ich diesen ominösen Umstand umkehren kann…..
Kann mir einer auf die Sprünge helfen?

Oggin

Oggin

Hallo Sven,
ich habe den ESP8266Switch.ino Sketch erweitert für zwei Relais (den Namen Relais habe ich nach Relais1 u. 2 erweitert). Habe den Code Auszugsweise in mehren Teil-Abschnitten des Sketchs kopiert, wie folgt:

//Pins to connect the sensors
#define RELAIS2_PIN 2 //GPIO2 ESP8266-01
#define RELAIS1_PIN 0 //GPIO0 ESP8266-01

// Beide Relais werden invers angesteuert
uint8_t relais1_status = 1; //current status of the relais
uint8_t relais2_status = 1; //current status of the relais

sendData:
sendmsg.addSwitchOut(relais1_status != 0,CHANNEL_RELAIS1);
sendmsg.addSwitchOut(relais2_status != 0,CHANNEL_RELAIS2);

if (data.channel == CHANNEL_RELAIS1) {
//if the data were for the right channel set the new status
newstatus = data.value0;
if (newstatus != relais1_status) {
//if the status has changed we export it to the relais
relais1_status = newstatus;
digitalWrite(RELAIS1_PIN,!(relais1_status));
if (DEBUG){
Serial.printf(“Relais1 status = %i\n”,relais1_status);
}
}
}
if (data.channel == CHANNEL_RELAIS2) {
//if the data were for the right channel set the new status
newstatus = data.value0;
if (newstatus != relais2_status) {
//if the status has changed we export it to the relais
relais2_status = newstatus;
digitalWrite(RELAIS2_PIN,!(relais2_status));
if (DEBUG){
Serial.printf(“Relais2 status = %i\n”,relais2_status);
}
}
}
}
}

Setup:
pinMode(RELAIS1_PIN,OUTPUT);
pinMode(RELAIS2_PIN,OUTPUT);
digitalWrite(RELAIS1_PIN,!(relais1_status));
digitalWrite(RELAIS2_PIN,!( relais2_status));

-——————
Das ist es im Wesentlichen.
Kann Dir den Sketch auch per Mail schicken, dazu brauche ich aber Deine Mail-Adr.
Gruß
Oggin

Sven Hesse

Sven Hesse

Jetzt muss ich einfach mal fragen – entweder habe ich einen Denkfehler oder ich mache etwas falsch.

Man kann doch mit dem D1 Mini auch mehrere Relais steuern …..wie aber bekomme ich die Informationen dazu ( Relais_Channel, Relais_Pin) auch in den Sketch.
Ich habe nun schon so viel probiert, bekomme es aber einfach nicht hin :-(.
Kann mir jemand einen Denkanstoß geben?

Sven Hesse

Sven Hesse

Die Registrierungsseite für neue Geräte (ESP8266/D1 Mini) wird nicht mittels Doppelklick auf den blauen Balken erreicht, sondern indem man lange auf den blauen Balken drückt.

In der SmartHome.ino wird auch ein AP-Passwort initiiert, im Sketch für den D1 Mini jedoch nicht definiert.
Entweder man definiert hier kein AP-Passwort oder initiiert eben eines für die D1-Mini.

Peter Necas

Peter Necas

Zu meinem gestrigen Kommentar betreffend Display bleibt dunkel.
Inzwischen habe ich die Zeilen:
#ifdef ARDUITOUCH0102
digitalWrite(TFT_LED, LOW);
gefunden. Damit ist mein Kommentar gegenstandslos,

Besten Dank,
Peter.

Deja un comentario

Todos los comentarios son moderados antes de ser publicados