Smart home center con ArduiTouch parte 3 - dispositivo attuatore con D1Mini e relè

Diesmal wollen wir unser SmartHome um ein passives Gerät erweitern, das mit einem Relais dazu geeignet ist auch Steckdosen oder Netzverbraucher zu schalten. Wir verwenden wieder einen D1Mini zusammen mit einem Relais-ModulDie Schaltung dazu ist sehr einfach.

 

Sketch:

 

//libraria per WiFi
#include <ESP8266WiFi.h>

//library per il protocollo di messaggio utilizzato
#include "AT_MessageBuffer.h"

//library for ESP Now
esterno "C" {   #include <espnow.h>
}

//SSID da cercare
#definire GW_SSID "ATSmartHome"

//flag per attivare i messaggi di debug
#definire DEBUG vero

#definire SEND_TIMEOUT 2000  // 2 Sekunden timeout 

#definire INTERVALL 10000 //intervall = 10 secondi

//definire i canali per i relais
#definire CHANNEL_RELAIS 0

//Pins per collegare i sensori
#definire RELAIS_PIN 2 //PIO2

Struttura //Dati per salvare l'indirizzo MAC del server
//e una memoria inRTC checksum
struct MEMORYDATA {   uint32_t crc32; //checksum per la convalida   uint8_t mac[6];
};

Indirizzo //MAC e canale WLAN
MEMORYDATA statinfo;
// ora quando ultimo inviato
uint32_t last_sent = 0; //Timestamp per l'ultima spedizione
uint8_t relais_status = 0; // stato attuale del relais
Stringa mymac; // proprio indirizzo mac

// abbiamo due buffer di messaggi per l'invio e la ricezione
AT_MessageBuffer sendmsg;
AT_MessageBuffer rcvmsg;

//scrivere il server MAC e il checksum alla memoria RTC
vuoto AggiornaRtcMemory() {     uint32_t crcOfData =AT_CalculateCRC32(((uint8_t*) &statinfo) + 4, dimensione(statinfo) - 4);     statinfo.crc32 = crcOfData;     ESP.rtcUserMemoryWrite(0,(uint32_t*) &statinfo, dimensione(statinfo));
}

// cerca il punto di accesso
vuoto ScanForSlave() {   bool schiavo trovato = 0;      int8_t scanRisultati = WiFi.scanNetworks();   // reimpostare su ciascuna scansione   se (DEBUG) Serial.println("Scansione fatta");   se (scanRisultati == 0) {     se (DEBUG) Serial.println("Nessun dispositivo WiFi trovato in modalità AP");   } altro {     se (DEBUG) Serial.stampa("Trovato");      se (DEBUG) Serial.stampa(scanRisultati);      se (DEBUG) Serial.println(" dispositivi ");     per (int i = 0; i < scanRisultati; ++i) {       // Stampa SSID e RSSI per ogni dispositivo trovato       Stringa SSID = WiFi.SSID(i);       int32_t RSSI = WiFi.RSSI(i);       int32_t chl = WiFi.canale(i);       Stringa BSSIDstr = WiFi.BSSIDstr(i);       se (DEBUG) {         Serial.stampa(i + 1);         Serial.stampa(": ");         Serial.stampa(SSID);         Serial.stampa(" /");         Serial.stampa(chl);         Serial.stampa(" (");         Serial.stampa(RSSI);         Serial.stampa(")");         Serial.println("");       }       ritardo(10);       // Controlla se il dispositivo corrente inizia con ATSmartHome`       se (SSID == GW_SSID) {         // SSIDE di interesse         se (DEBUG) {           Serial.println("Ho trovato uno schiavo.");           Serial.stampa(i + 1); Serial.stampa(": "); Serial.stampa(SSID); Serial.stampa(" ["); Serial.stampa(BSSIDstr); Serial.stampa("]"); Serial.stampa(" ("); Serial.stampa(RSSI); Serial.stampa(")"); Serial.println("");         }         int mac[6];         // ottenere il server MAC e salvare nella memoria RTC         se ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c",  &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) {           per (int ii = 0; ii < 6; ++ii ) {             statinfo.mac[ii] = (uint8_t) mac[ii];           }           AggiornaRtcMemory();         }         schiavo trovato = 1;         //non è stata trovata più ricerca dopo l'AP         rompere;       }     }   }         se (DEBUG) {     se (schiavo trovato) {       Serial.println("Slave Found, processing ...");     } altro {       Serial.println("Slave Not Found, provando di nuovo.");     }   }   // rilascia RAM   WiFi.scanDelete();
}

vuoto sendData() {   uint8_t buf[100]; //buffer per esp   uint8_t sz = 100;   Buffer di messaggi //cleari   sendmsg.chiaro();   se (DEBUG) {     Serial.println("He hears"+mymac);   }   sendmsg.setId(mymac);   //aggiungi lo stato attuale dei relais come messaggio booleano al buffer   sendmsg.addSwitchOut(relais_status != 0,CHANNEL_RELAIS);   // riempire il buffer e inviare il contenuto al centro di controllo   se (sendmsg.fillBuffer(buf,&sz)) _Esp_now_send(NULL, buf, sz);   //ricorda il tempo per calcolare l'intervallo   last_sent=millis();
}

//callback su ricezione messaggi da ESP-Now
vuoto readESPNow(uint8_t *mac_addr, uint8_t *r_date, uint8_t data_len) {   ATDATAPACKET dati;   uint32_t newstatus;   //copia dati ricevuti nel buffer di messaggi di ricezione   rcvmsg.readBuffer(r_date);   se (mymac.equalsIgnoreCase(rcvmsg.getId())) {     //accetta solo i messaggi per questo dispositivo     se (rcvmsg.getPackets() > 0) {       //abbiamo ricevuto un pacchetto dati       dati = rcvmsg.getData(0);       se (DEBUG) {         Serial.printf("Devono dati per il valore del canale %i %i \n",dati.canale, dati.valore[0]);       }         se (dati.canale == CHANNEL_RELAIS) {         //se i dati fossero per il canale giusto impostare il nuovo stato         newstatus = dati.valore[0];         se (newstatus != relais_status) {           //se lo stato è cambiato lo esportiamo al relais           relais_status = newstatus;           digitalWrite(RELAIS_PIN,relais_status);           se (DEBUG){             Serial.printf("Stato dei relais = %i\n",relais_status);           }         }       }     }   }
}

vuoto configurazione() {   se (DEBUG) {     Serial.iniziare(115200);      Serial.println("Inizia");   }   pinMode(RELAIS_PIN,OUTPUT);   digitalWrite(RELAIS_PIN,relais_status);   //ottenere l'indirizzo MAC locale per usarlo come id del dispositivo   mymac = WiFi.macAddress();   se (DEBUG) {     Serial.stampa("Il mio indirizzo MAC =");     Serial.println(mymac);   }   ESP.rtcUserMemoryRead(0, (uint32_t*) &statinfo, dimensione(statinfo));   se (DEBUG) Serial.println("Fatto RTC");   uint32_t crcOfData = AT_CalculateCRC32(((uint8_t*) &statinfo) + 4, dimensione(statinfo) - 4);   WiFi.modalità(WIFI_STA); Modalità // Stazione per nodo aktor esp-now   se (DEBUG) Serial.println("WifiMode");   se (statinfo.crc32 != crcOfData) { //se checksum differente non abbiamo un server MAC valido     se (DEBUG) Serial.println("Scansione per schiavo");     ScanForSlave();     //for (uint8_t i = 0; i<6;i++) statinfo.mac[i] = gwmac[i];     se (DEBUG) {       Serial.printf("Questo mac: %s",, WiFi.macAddress().c_str());        Serial.printf("target 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]);      }   }   se (esp_now_init() != 0) {     se (DEBUG) Serial.println("*** ESP_Now init failed");     ESP.riavviare();   }   //ESP Ora Controller   WiFi.setAutoConnect(falso);   esp_now_set_self_role(3); //(ESP_NOW_ROLE_CONTROLLER);   uint8_t ch = esp_now_get_peer_channel(statinfo.mac);   se (DEBUG) Serial.printf("Canale = %i\r\n",ch);   //inizializza i dati Peer   int res = esp_now_add_peer(statinfo.mac, ESP_NOW_ROLE_CONTROLLER, 1, NULL, 0);   se (res==0) Serial.println("Accoppiato riuscito");   //register callback   esp_now_register_recv_cb(readESPNow); 
}

vuoto ciclo() {   //inviare messaggi al centro di controllo su una base regolare   se ((millis() - last_sent) > INTERVALL) {  //intervall per inviare i dati cambia questo se necessario     sendData();   }
}

 

 

Für das Programm benötigt die ESP8266Wifi.h und die espnow.h Bibliothek für den ESP8266. Zusätzlich wird noch die Bibliothek ATMessageBuffer für SmartHome benötigt.

Auch die SmartHome Zentrale muss mit den neuesten Bibliotheken ATMessagebuffer, ATSmartHome und TouchEvent kompiliert werden. In den Beispielen zu ATSmartHome findet ihr auch obigen Sketch.

Nachdem die Programma ESP8266Switch und ATSmartHome aus den Beispielen der AT_SmartHome Bibliothek kompiliert und auf den D1Mini bzw. auf den ArduiTouch hochgeladen wurden, sollte zuerst auf der SmartHome-Zentrale das FileSystem formatiert werden, dasich die Datenstruktur des Konfig-Files bei diesem Update geändert hat. Das ist aber weiter nicht schlimm da wir in den bisherigen Versionen noch keine manuellen Einstellungen vornehmen konnten.

Nach einem Reset der Zentrale und dem Start des D1Mini sollte dessen MAC-Adresse im unteren blauen Balken angezeigt werden.

Fare doppio clic su questa barra ci porterà alla pagina di registrazione.

Dopo aver fatto doppio clic su Registra, il display tornerà alla pagina principale e dovremmo vedere la seguente immagine.

Se tocchi brevemente questo pulsante, accendere il reais e spegnerlo di nuovo con un altro tocco breve. Il colore di sfondo del pulsante cambia da grigio a verde brillante.

È possibile utilizzare sia il sensore dei moduli che l'interruttore simultaneamente (vedere l'immagine del titolo).

Divertiti a provare e sperimentare.

Esp-8266Projekte für fortgeschritteneSmart home

6 Kommentare

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.

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert