Der Weihnachtsbaum wird "smart"

Steeds meer apparaten worden "slim", waarom niet de kerstboom ook. Dit project gaat over de controle van de kerstboom fairy lights via browser en Alexa. In de browser en via LED ' s op de hardware kan ook het waterpeil in de basis van de kerstboom worden bewaakt. Natuurlijk kan ook een timer worden geconfigureerd om de verlichting regelmatig aan en uit te zetten. De volledige configuratie wordt gedaan in de browser. Dus ga door, waar wacht je op!

 

Vereiste hardware

Er worden twee varianten beschreven.

Vrije constructie Zonder behuizing:

Aantal

Component

Opmerking

1

D1-Mini

 

1

relaismodule

 

1

Capacitieve vochtigheidssensor

Voor Waterniveau Sensor

3

LED ' s Rood, geel en groen

Voor Waterniveau Sensor

4

Weerstanden 3 x 220 Ohm 1 x 220 kOhm

Voor Waterniveau Sensor

 

De componenten voor de waterpeilsensor zijn optioneel als deze functie wordt gebruikt.

Gebouwd op een dual-base shield met een behuizing van de 3D-printer:

Aantal

Component

Opmerking

1

D1-Mini

 

1

Relais Schild

 

1

Dual Base Shield

 

1

Prototypeschild voor D1-Mini

Voor Waterniveau Sensor

1

Capacitieve vochtigheidssensor

Voor Waterniveau Sensor

3

LED ' s Rood, geel en groen

Voor Waterniveau Sensor

4

Weerstanden 3 x 220 Ohm 1 x 220 kOhm

Voor Waterniveau Sensor

1

Hoekige pin header 3-pins

Voor Waterniveau Sensor

1

Behuizing van het onderste deel van de 3D-printer

 

1

Behuizingsdeksel zonder sensor

 

1

Behuizingsdeksel met sensor

Voor Waterniveau Sensor

1

Afdeksensor Deel1

Voor Waterniveau Sensor

1

Afdeksensor Deel2

Voor Waterniveau Sensor

 

De componenten voor de waterpeilsensor zijn optioneel als deze functie wordt gebruikt.

We hebben ook een video voorbereid voor de blog:

 

 

circuit

Vrije constructie Zonder behuizing:

circuit

Met dubbel Bas-schild en relaisschild:

Aansluitschema

Structuur van variant 2

Als de Waterpeilsensor optie wordt gebruikt, moet de D1-Mini worden uitgerust met de gecombineerde pin en veerstrips, zodat het sensorschild vervolgens kan worden aangesloten. Het heeft niets met het Relaisschild te maken. Het Dual Base Shield is voorzien van de meegeleverde veerstrips.

foto van de modules

Het Sensorschild is gebaseerd op het D1-Mini Prototyping Shield. Eerst moeten de weerstanden, dan de pin headers en ten slotte de lichtgevende diodes worden geïnstalleerd. De opstelling van de componenten werd gekozen, zodat de bedrading kan worden gedaan met kale draden. Alleen voor de aarddraad (in de volgende figuur in paars weergegeven) moet een geïsoleerde draad worden gebruikt.
Structuur als tekening
Structuur als afbeelding


Software

Om de schets te compileren, moet de Arduino IDE dienovereenkomstig worden voorbereid. De Arduino IDE ondersteunt standaard een groot aantal boards met verschillende microcontrollers, maar niet de ESP8266. Daarom, om programma ' s voor de ESP8266 te maken en te uploaden, moet een softwarepakket voor het ondersteunen van de ESP8266 worden geïnstalleerd.

esp8266-ondersteuning

Eerst, moet u de Arduino IDE vertellen waar te om de extra gegevens te vinden u voor ESP8266 nodig hebt. Om dit te doen, opent u het Voorkeuren-item in het menu Bestand. In het venster Voorkeuren is er een invoerveld genaamd "extra Board Administrator URL 's". Als u op het pictogram rechts van het invoerveld klikt, wordt een venster geopend waarin u de URL kunt invoeren

https://arduino.esp8266.com/stable/package_esp8266com_index.json kan naar binnen.

Selecteer nu het board management in de Arduino IDE onder Tool → Board.


Er wordt een venster geopend waarin alle beschikbare pakketten worden weergegeven. Om de lijst te beperken, voert u "esp8266" in het zoekveld in. Dan krijg je maar één vermelding in de lijst.

ESP8266 Board selectie

Voor de Alexa-interface hebt u twee bibliotheken nodig die niet via bibliotheekbeheer kunnen worden geïnstalleerd. Deze moeten eerst worden gedownload als een ZIP-bestand. De asynchrone webserver van https://github.com/me-no-dev/ESPAsyncWebServer en asynchrone TCP van https://github.com/me-no-dev/ESPAsyncTCP. Om te downloaden, klikt u op de groene knop code en selecteer "Download ZIP".

Om de gedownloade ZIP-bestanden in de Arduino IDE te installeren, gaat u naar Sketch -> bibliotheek opnemen -> in het menu.Voeg ZIP-bibliotheek op de top. Een bestand selectie dialoog verschijnt door het selecteren van de gedownloade bestanden. Dat is alles wat er te doen is.

Tot slot zijn er nog twee bibliotheken nodig, die kunnen worden geïnstalleerd via het Arduino-bibliotheekbeheer. Dit is de bibliotheek "ESPFauxmo", die de interface naar Alexa implementeert en de bibliotheek" AsyncWebConfig", die de configuratie via de browser implementeert.

 Bibliotheek fauxmo

 AsyncWebConfig-Bibliotheek

Wanneer alle bibliotheken zijn geïnstalleerd, kan de sketch worden gecompileerd en geüpload naar de hardware.

schets

 

#include <ESP8266WiFi.h>     // WiFi ondersteuning
#include <ESP8266mDNS.h>     // Voor nameservers om namen te gebruiken in plaats van IP 
#include <MAGNEETSCHAKELAAR.h>              // Tijdzone dfinities voor klok
#include <AsyncWebConfig.h>  // Bibliotheek voor configuratie
#include <ESPAsyncWebServer.h> // Asynchrone webserver
#include <fauxmoESP.h>       // Interface voor Alexa

// Pinnen gebruikt voor LED en relais
#define PIN-RELAIS D1
#define PINEMPTY D2
#define PINHALF D3
#define PINFULL D4

#define LVLFULL 300
#define LVLEMPTY 600

#define TIJDSZONE TZ_Europe_Berlin

#define VERBINDEN 300 // seconden om te wachten op Opnieuw verbinden na de verbinding verbreken

// Vorm voor configuratie, JSON geformatteerd
String params = "["
  "{"
  "'name': 'ssid',"
  "'label': 'Name of the WLAN',"
  ""type":"+String(INPUTTEXT)+","
  "'default':""
  "},"
  "{"
  "'name': 'pwd',"
  "'label': 'WLAN-wachtwoord',"
  ""type":"+String(Inputwachtwoord)+","
  "'default':""
  "},"
  "{"
  "'name': 'alexaname',"
  "'label': 'naam voor Alexa',"
  ""type":"+String(INPUTTEXT)+","
  "'default': 'Christmas tree'"
  "},"
  "{"
  "'name': 'ntpserver',"
  "'label': 'NTP Server',"
  ""type":"+String(INPUTTEXT)+","
  "'default': 'pool.ntp.org '"
  "},"
  "{"
  "'name': 'showlevel',"
  "'label': 'Toon waterpeil',"
  ""type":"+String(INPUTCHECKBOX)+","
  "'default': '1'"
  "},"
  "{"
  "'name': 'usetimer',"
  "'label': 'gebruik timer',"
  ""type":"+String(INPUTCHECKBOX)+","
  "'default': '0'"
  "},"
  "{"
  "'name': 'starttime',"
  "'label': 'inschakeltijd',"
  ""type":"+String(Invoertijd)+","
  "'default': '18: 30'"
  "},"
  "{"
  "'name': 'stoptime',"
  "'label': 'shutdown time',"
  ""type":"+String(Invoertijd)+","
  "'default': '23: 00'"
  "}"
"]";

const karakter HTML[] PROGMEM =
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"configuratie \n"
"\n"
"\n"
"\n"
"
\n" " "
\n" "
< / div>\n" "
\n" "
waterstand< / div>\n" "
< / div>\n" "
< / div>\n" "
< / div>< / div>\n" "
"\n" "\n" "\n"; // Globale variabelen AsyncWebServer server(80); AsyncWebConfig conf; fauxmoESP fauxmo; uint32_t laden = 0;      // gebruikt voor getimede acties boolean timeron = ware; // markering als de timer is ingeschakeld boolean aangesloten = vals; // true als we een routerverbinding hebben uint16_t nextTry = 0;    // tweede teller voor opnieuw verbinden // huidige kleuren voor waterniveau const karakter *bgfull; const karakter *bghalf; const karakter *bgempty; const karakter* bgbtn; const karakter *btnnaam; const karakter *btnlabel; const karakter *toonniveau; float opac; // char buf[2048]; // constanten te gebruiken voor webpagina const karakter bgbtnon[] = "blauw"; const karakter btnnameon[] = "op"; const karakter btnlabelon[] = "OP"; const karakter bgbtnoff[] = "lichtgrijs"; const karakter btnnameoff[] = "van"; const karakter btnlabeloff[] = "VAN"; const karakter colfull[] = "groen"; const karakter halve[] = "geel"; const karakter colempty[] = "rode"; const karakter colnon[] = "lichtgrijs"; const karakter tonen[] = "zichtbaar"; const karakter hideit[] = "verborgen"; // Start WiFi-verbinding boolean initWiFi() {    boolean aangesloten = vals;    draadloos.mode(WIFI_STA);    Serie.afdruk("Verbinden met ");    Serie.println(conf.getValue("SSID broadcast"));    // als SSID is geconfigureerd proberen we een verbinding tot stand te brengen    als (conf.getValue("SSID broadcast") != "") {      draadloos.beginnen(conf.waarde[0]._str(),conf.waarde[1]._str());      uint8_t CNT ' s = 0;      // wacht 10 Seconden      terwijl ((draadloos.status() != _VERBONDEN) && (CNT ' s<20)){        vertraging(500);        Serie.afdruk(".");        CNT ' s++;      }      Serie.println();      // indien succesvol verbonden wordt het IP-adres afgedrukt      als (draadloos.status() == _VERBONDEN) {        Serie.afdruk("IP address=");        Serie.println(draadloos.localIP());        aangesloten = ware;      }    }    // als er geen SSID was geconfigureerd of de verbinding niet tot stand kon worden gebracht    // we starten een access point om configuratie te maken    als (!aangesloten) {          draadloos.mode(WIFI_AP);          draadloos.SoftAP(conf.getApName(),"",1);          nextTry = 0;      }    terug aangesloten; } // krijg minuten van een tijd string geformatteerd hh: mm uint16_t getMinutes(String Tim) {  uint16_t h = Tim.substring(0,2).toInt();  uint16_t m = Tim.substring(3).toInt();  terug h*60+m; } // controleer of de timer binnen bereik is en schakelrelais indien nodig vervallen checkTimer() {  // get minutes for now  _tijd nu = tijd(nullptr); //momenteel  struct tm * s_tijd = localtime(&nu); // Tijdstructuur opgesplitst in Jaar, Maand, Dag, uren, minuten en seconden  uint16_t minuten = s_tijd->tm_hour * 60 + s_tijd->tm_min;  // krijg minuten voor start en stop  uint16_t begintijd = getMinutes(conf.getString("starttijd"));  uint16_t stoptijd = getMinutes(conf.getString("stoptime"));  als (begintijd <= stoptijd) { // relais aan binnen het bereik    als (((minuten >= begintijd) && (minuten <= stoptijd)) && (!timeron)) {      timeron = ware;      setRelay(ware);    }    als (((minuten < begintijd) || (minuten > stoptijd)) && (timeron)) {      timeron = vals;      setRelay(vals);    }  } anders { // Relais buiten het bereik    als (((minuten >= begintijd) && (minuten <= stoptijd)) && (timeron)) {      timeron = vals;      setRelay(vals);    }    als (((minuten < begintijd) || (minuten > stoptijd)) && (!timeron)) {      timeron = ware;      setRelay(ware);    }  } } // schakel het relais in of uit vervallen setRelay(boolean op) {  digitaal schrijven(PIN-RELAIS,op);  als (op) {    bgbtn = bgbtnon;    btnnaam = btnnameon;    btnlabel = btnlabelon;    opac = 1;  } anders {    bgbtn = bgbtnoff;    btnnaam = btnnameoff;    btnlabel = btnlabeloff;    opac = 0.2;  } } // controleer het vloeistofniveau en stel correesponding LEDs in vervallen setLEDs(){  // lees van vochtsensor  // lage waarde indien nat  int x = analoog(A0);  Serie.printf("Analoog lezen: % i\n",x);  // output laag om LED aan te zetten  bgempty = colnon;  bghalf = colnon;  bgfull = colnon;  als (x > LVLEMPTY) {    digitaal schrijven(PINEMPTY,0);    digitaal schrijven(PINHALF,1);    digitaal schrijven(PINFULL,1);    bgempty = colempty;  } anders als ((x <= LVLEMPTY) && (x >= LVLFULL)) {    digitaal schrijven(PINEMPTY,1);    digitaal schrijven(PINHALF,0);    digitaal schrijven(PINFULL,1);    bghalf = halve;  } anders als (x < LVLFULL) {    digitaal schrijven(PINEMPTY,1);    digitaal schrijven(PINHALF,1);    digitaal schrijven(PINFULL,0);    bgfull = colfull;  } } // * * * * * callback functies voor webserver vervallen handleRoot(Asyncwebserververzoek *verzoek){  // als we niet verbonden zijn tonen we de configuratiepagina  als (!aangesloten) {    handleConfig(verzoek);  } anders {    // we tonen de homepage    als (verzoek->hasArg("op")) setRelay(vals);    als (verzoek->hasArg("van")) setRelay(ware);    karakter buf[2048];    sprintf(buf,HTML,bgbtn,opac,bgfull,bghalf,bgempty,toonniveau,btnnaam,btnlabel);    verzoek->verzenden(200,"tekst / html",buf);  } } vervallen handleConfig(Asyncwebserververzoek *verzoek){  conf.handleform request(verzoek);  als (verzoek->hasArg("OPSLAAN")) {    toonniveau = hideit;    als (conf.getBool("showlevel")) toonniveau = tonen;  } } vervallen handleNotFound(Asyncwebserververzoek *verzoek){  / voor fauxmo  String lichaam = (verzoek->hasParam("lichaam", ware)) ? verzoek->getParam("lichaam", ware)->waarde() : String();  als (fauxmo.proces(verzoek->klant(), verzoek->methode() == HTTP_GET, verzoek->URL(), lichaam)) terug;  // Handle andere niet gevonden Verzoeken hier... } vervallen handlebodyverzoek(Asyncwebserververzoek *verzoek, uint8_t *gegevens, grootte_t len, grootte_t index, grootte_t volledig){  Serie.println(verzoek->URL());  als (fauxmo.proces(verzoek->klant(), verzoek->methode() == HTTP_GET, verzoek->URL(), String((karakter *)gegevens))) terug;  // Behandel elk ander lichaam verzoek hier... } vervallen handleAlexa(ondertekend karakter apparaat_id, const karakter * apparaat_naam, bool staat, ondertekend karakter waarde) {  Serie.printf("[MAIN] apparaat # % D (%s) Status: % s waarde: % d\n", apparaat_id, apparaat_naam, staat ? "OP" : "VAN", waarde);  setRelay(staat);       } // init de Alexa interface vervallen initAlexa() {  Serie.println("Init Alexa");  // Stel fauxmoESP in om geen interne TCP-server aan te maken en verzoeken om te leiden naar de server op de gedefinieerde poort  // De tcp-poort moet 80 zijn voor gen3-apparaten (standaard is 1901)  // Dit moet gedaan worden voor de oproep om()  fauxmo.createServer(vals);  fauxmo.setPort(80); // Dit is vereist voor gen3 apparaten  // Je moet inschakelen(true) bellen zodra je een WiFi-verbinding hebt  // U kunt de bibliotheek op elk moment in-of uitschakelen  // Uitschakelen zal voorkomen dat de apparaten worden ontdekt en geschakeld  fauxmo.inschakelen(ware);  // Virtuele apparaten toevoegen  fauxmo.AddDevice(conf.getValue("alexaname"));  fauxmo.onSetState(handleAlexa); }
vervallen Setup() {  Serie.beginnen(74880);  // Alle pinnen gebruikt als output  pinMode(PIN-RELAIS,OUTPUT);  pinMode(PINFULL,OUTPUT);  pinMode(PINHALF,OUTPUT);  pinMode(PINEMPTY,OUTPUT);  // Configuratieformulier voorbereiden en bestaande configuratie lezen  conf.Omschrijving instellen(params);  conf.readConfig();  toonniveau = hideit;  als (conf.getBool("showlevel")) toonniveau = tonen;  aangesloten = initWiFi();  // we starten de webserver zelfstandig op als we een internet hebben  // verbinding of een toegangspunt  server.op("/",handleRoot);  server.op("/configuratiebestand",handleConfig);  server.onRequestBody(handlebodyverzoek);  server.onNotFound(handleNotFound);  server.beginnen();  als (aangesloten) { // als we een internetverbinding hebben    initAlexa();    // init de interne klok    configTime(TIJDSZONE, conf.getValue("ntpserver"));  }  // Reset getimede gebeurtenis  laden = millis();  setRelay(vals);  setLEDs();  MDNS.beginnen(String(conf.getApName())+".lokaal"); } vervallen loop() {  fauxmo.is();  // actie elke seconde  als ((millis() - laden) > 1000) {    als (draadloos.status() != _VERBONDEN) {      als (++nextTry > VERBINDEN) {        initWiFi();      } anders {        nextTry = 0;      }    }    laden = millis();    setLEDs();    als (conf.getBool("usetimer")) checkTimer();  }  MDNS.update(); }

Attentie!!
Als het kleine verkeerslicht met gemeenschappelijke grondlijn wordt gebruikt in plaats van de individuele LED ' s, moet de functie setLeds () worden gewijzigd:

vervallen setLEDs(){
  // lees van vochtsensor
  // lage waarde indien nat
  int x = analoog(A0);
  Serie.printf("Analoog lezen: % i\n",x);
  // output laag om LED aan te zetten
  bgempty = colnon;
  bghalf = colnon;
  bgfull = colnon;
  als (x > LVLEMPTY) { 
    digitaal schrijven(PINEMPTY,1);
    digitaal schrijven(PINHALF,0);
    digitaal schrijven(PINFULL,0);
    bgempty = colempty;
  } anders als ((x <= LVLEMPTY) && (x >= LVLFULL)) {
    digitaal schrijven(PINEMPTY,0);
    digitaal schrijven(PINHALF,1);
    digitaal schrijven(PINFULL,0);
    bghalf = halve;
  } anders als (x < LVLFULL) {
    digitaal schrijven(PINEMPTY,0);
    digitaal schrijven(PINHALF,0);
    digitaal schrijven(PINFULL,1);
    bgfull = colfull;
  }
}

Download de sketch

Inbedrijfstelling

Als de sketch zonder fouten is gecompileerd en geüpload, zal het programma starten. Aangezien er nog geen configuratiegegevens beschikbaar zijn, wordt een toegangspunt gestart. De SSID wordt gevormd uit het MAC-adres van de D1 mini. Een verbinding met dit toegangspunt kan nu worden gemaakt met een smartphone of een andere WLAN-computer. Toegang is open, dus er is geen wachtwoord vereist. Nadat de WLAN-verbinding tot stand is gebracht, kunt u het adres in de browser invoeren bel 192.168.4.1. De configuratiepagina wordt weergegeven.

Schermafdruk van de configuratie

De naam van het toegangspunt zal later worden gebruikt als de DNS-naam. Dit wordt gevolgd door de toegangsgegevens tot het WLAN.
De naam voor Alexa is de naam van het apparaat te gebruiken in de Alexa app.
De NTP-server wordt gebruikt om de interne klok te synchroniseren. Fritz zou hier bijvoorbeeld ook kunnen zijn.als de Fritz-Box moet worden gebruikt als tijdserver.
Het selectievakje waterniveau weergeven bepaalt of het huidige waterniveau op de homepage wordt weergegeven of niet.
Dit wordt gevolgd door een ander selectievakje om de timer te activeren. Als de timer wordt gebruikt, moet ook een in-en uitschakeltijd worden ingesteld.
Met de "Save" knop wordt de configuratie opgeslagen in het flash bestandssysteem van de D1 mini.
De configuratie wordt ook opgeslagen met de" Restart " knop en dan wordt de D1-Mini opnieuw gestart.
De initiële configuratie moet worden beëindigd met" Restart", omdat de D1-Mini na de herstart verbinding moet maken met het WLAN. Als de verbinding succesvol is, wordt er geen toegangspunt gestart.
Het zou nu mogelijk moeten zijn om de homepage te openen met de URL .dus, in het geïllustreerde voorbeeld met een kerstboom.bel de lokale politie. Als uw router geen mDNS ondersteunt, moet u het IP-adres gebruiken dat via de seriële monitor is verstrekt.

Alexa Inschakelen

Om dit te doen, je nodig hebt om de Alexa app te starten op uw smartphone. Tik op apparaten onderaan de werkbalk en tik op de Apparaatpagina die wordt weergegeven op het pluspictogram rechtsboven.
Selecteer Nu Apparaat toevoegen.
De selectie van het apparaattype wordt weergegeven. Ga helemaal naar beneden en selecteer "Diversen". Op de volgende pagina kunt u het zoeken naar apparaten starten. Controleer vooraf of de D1-Mini correct is gestart en de homepage kan weergeven.
Na enige tijd, de Alexa app moet laten zien dat een lamp is gevonden en aangesloten. Lamp wordt weergegeven omdat de bibliotheek een Philips HUE lamp emuleert.
Tik Op Apparaat Instellen. U kunt nu het nieuwe apparaat toewijzen aan een groep.
Tot slot ontvangt u het bericht "kerstboom is ingesteld en klaar voor gebruik". Als u een andere naam hebt geconfigureerd, staat deze naam en niet "kerstboom" in het bericht.
Nu kan de verlichting worden ingeschakeld met de spraakopdracht "Alexa, kerstboom aan".

Het aansluiten van de lichtsnoer

Elke lichtsnoer die een tweedraads aansluitkabel gebruikt en werkt met spanningen onder 40V kan worden gebruikt. Voor de aansluiting wordt een van de twee draden doorgeknipt en wordt het relais ertussen geschakeld. Een USB-kabel is vereist om de D1 mini van stroom te voorzien.

Borduurwerk "kerst wensen"

Blog post als PDF

 

Veel plezier met het recreëren en hebben een aangename Advent seizoen!

Esp-8266Projekte für anfängerSensoren

1 Kommentar

Jochen

Jochen

Hallo zusammen,

zugegeben, Adventszeit ist rum, Weihnachtsbaum schon wieder weg, aber dennoch:
Ich habe versucht das Teil nachzubauen, ist ja “eigentlich” kein Hexenwerk, leider versagt der am wenigsten durchsichtige Step:
Das Hinzufügen zur AlexaApp funktioniert nicht. Selbst wenn ich in der FauxmoESp die Debugs anmache, sehe ich, dass Interaktion mit dem Device stattfindet. Die App meldet aber immer, dass kein Device gefunden wurde…
Hab ich was übersehen?

Danke und Grüße
Jochen

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert