IoT Verklikker

Januari 2018: Een simpele IoT (Internet of Things) toepassing met de ESP8266: een lampje waarbij de kleur je energiegebruik op dat moment weergeeft.

Energieverklikker
De energie-verklikker, met wat verschillende kleuren:
bij veel gebruik (rood) tot aan levering (groen-blauw).

Het idee

Om je bewust te worden van je energiegebruik is het handig gelijk 'feedback' (terugkoppeling) te krijgen: je ziet wat je gebruikt. Dat kan natuurlijk met een tablet of zo, maar die moet je toch weer pakken.

Ik heb daarom een 'IoT'-lampje gemaakt dat op ieder moment door de kleur weergeeft wat mijn energiegebruik op dat moment is. Gebruik ik veel energie, dan wordt het rood, leveren mijn zonnepanelen veel op dan wordt'ie blauw-groen, en een heel kleurenpalet daar tussenin, zie de foto's links. De grote afbeelding is bij neutraal gebruik (was haast 0 Watt, bewolkte hemel dus het beetje energie dat geleverd werd ging de computer in: groen met een beetje rood).

Werkt leuk, en je ziet gelijk 'wat je huis doet'. Zet de magnetron aan: vuurrood... En zo ook voor zowat alle andere apparaten die warmte (moeten) produceren. Wasmachine, koffiezetter, broodrooster. Al je LED-lampen zijn daarentegen nauwelijks zichtbaar als kleurverandering, gebruik is verwaarloosbaar vergeleken met een magnetron. Maar, ze staan natuurlijk wel langer aan, dus telt toch ook op.

De kleur wordt elke 10 seconden bijgewerkt (beperking van de smart meter), rap genoeg om snel te zien wat er gebeurt.


MQTT dataflow
MQTT dataflow van de smart meter naar de verklikker

De globale werking

IoT: Internet of things... Alles via het internet aan elkaar geknoopt. Zo werkt dit ook ongeveer:

  • Mijn 'slimme meter' geeft elke 10 seconden het elektriciteitsgebruik op zijn seriële P1-poort,
  • dit wordt opgevangen op de USB-poort van mijn Raspberry, en in de MQTT database gepubliceerd,
  • mijn draadloze lampje is 'geabonneerd' op de MQTT-waarde voor de energie, krijgt daardoor elke 10 seconden van de Raspberry een update,
  • en past zijn kleur op de waarde van het energiegebruik aan.

Overigens is het bij mij meer 'Intranet of Things', de informatie blijft in huis, en gaat niet naar externe servers. De slimme meter is met een serieel kabeltje aan de Raspberry verbonden, en die publiceert met MQTT de binnenkomende data alleen op het eigen netwerk... Minder kans op hackers, wat niet aan het grote internet hangt kan ook niet gehackt worden (de kans is in ieder geval een heel stuk kleiner).

Het lampje

De controller (op de bovenste foto zelf niet te zien) is een klein kastje en is gebaseerd op een 'Arduino'-achtig printje met de ESP8266 WiFi-processor. Eerst ontwikkeld op de Wemos, daarna overgezet naar een goedkope 'serial WiFi' print, zie mijn Arduino-pagina. Ik had nog een 3x1 Watt RGB-LED liggen op een koelvin, dus die als lamp gebruikt. De meeste onderdelen komen sowieso uit de rommelbak.

Opbouw van de verklikker
De opbouw van de Energie-verklikker (schema beneden)

Hiernaast is het open kastje met inhoud te zien (schema onderaan deze pagina). Bovenin rechts de 'serial WiFi' print, plus een drukknopje ('rondje' links van de print in het kastje, met het grijs-witte draadje). In de onderste helft rechts de USB-aansluiting, en in het midden een handgefreesd printje met 3 MOSFET transistoren, plus drie (vier...) weerstanden om de stroom door de LED's te beperken. En links op de foto de LED op koelvin, met een kabeltje met connector. Het geheel is wat houtje-touwtje in elkaar gezet, maar is dan ook een zondagmiddag projectje (iets meer, OK).

De software

De ESP8266 Arduino-omgeving wordt geleverd met de hele internet-library; hoef ik dus niet veel zelf aan te doen. Dat maakt dit project niet al te moeilijk. De basis-opbouw is als volgt:

  • Initialiseer de hardware, timers en zo voort
  • Log in op het lokale netwerk en de MQTT server
  • Abonneer op de MQTT service: waarde van energiegebruik, en de tijd
  • Ga in een eindeloze loop, en wacht op MQTT berichten:
    • Bij een binnenkomend bericht wordt een callback-functie aangeroepen, die het bericht in de rij (queue) zet
      • Op deze manier wordt het zware werk vanuit de callback naar het hoofdprogramma uitbesteed. Houdt callbacks en interrupt-routines zo licht mogelijk!
    • Als er een energiebericht in de queue staat (elke 10 seconden): bereken de kleurwaarde en zet de PWM-waardes voor de LEDs
    • Als er een tijdsbericht in de queue staat: bereken de gewenste helderheid
      • In de nacht de LEDS vrij gedimd, overdag bij zonnig weer (hoge energie-leveringswaarde) juist extra helder

Veel meer is het niet. Ik had al wat gespeeld met de Sonoff, dus wist de grote lijnen al. Maar, zitten wat leuke details in wat betreft gebruik van MQTT en zo, komt nog...

De details moet ik nog opschrijven; wordt zeker vervolgt... Voor wie de source al wil: SerialWiFiEnergy.ino

Opzetten MQTT client

OK, een stukje vast (om voor mezelf te documenteren)... Het aanmelden aan de MQTT server gebeurt met onderstaande stukjes code:

WiFiClient espClient;
PubSubClient mqttClient(mqtt_server, mqtt_port, mqttCallback, espClient);

...

if (mqttClient.connect("Serwi1 Client",      // Name of the system
      mqtt_user, mqtt_password,              // Login data for the MQTT server
      mqtt_topicLog, 0, false, "Serwi1 died...")) // plus the 'last will' in case we terminate
{
    mqttClient.subscribe(mqtt_topicPwm);     // Subscribe on the interesting topics, e.g.
    mqttClient.subscribe(mqtt_topicTime);    // "Kees/Time" for current time
    mqttClient.publish(mqtt_topicLog, "Serwi1 online"); // There we are...    
}

Wat gebeurt hier zoal (let op, gebeurt hierdoor ook een en ander automatisch 'achter de schermen' op de Raspberry):

  • Er wordt een PubSubClient genaamd mqttClient aangemaakt, met:
    • de gegevens van de MQTT server (IP adres van de Raspberry, poort-nummer van de mosquitto MQTT server)
    • de te gebruiken callback functie mqttCallback voor als er berichten binnenkomen
    • een link naar de WiFiClient
  • De connect functie van het eerder aangemaakte mqttClient wordt gebruikt om aan te melden bij de MQTT server.
    • Bij het aanmelden kan je een 'laatste wil' meegeven. Als je systeem crasht (of de stekker wordt er gewoon uitgetrokken) zal de MQTT server dit merken, en je laatste wil publiceren naar de systemen die daarop geabonneerd zijn. Als dus andere systemen van je afhankelijk zijn, kunnen ze de fout netjes opvangen. Hier wordt dan dus "Serwi1 died..." gepubliceerd naar mqtt_topicLog ("Kees/Log").
  • Na het aanmelden kan je je abonneren (subscribe) op onderwerpen (topics) waarin je bent geïnteresseerd, hier de energiewaarde en de tijd
  • En bij aanmelding publiceer ik dat het systeem online is naar mijn Log-topic, zodat andere systemen op mijn netwerk (als ze geïnteresseerd zijn) dit te weten komen
    • Bijvoorbeeld: op de Raspberry loopt een Python-script geabonneerd op "Kees/Log" die alle binnenkomende berichten op dit topic wegschrijft naar een log file, samen met tijd/datum.
    • Ook op de MQTT Dash op mijn tablet krijg ik de log-meldingen te zien
  • Let op: weggelaten in bovenstaande code is de 'else' bij het if-statement, met de fout-afhandeling.

Verdere code-fragmenten en details nog een andere keer uit te werken...

Het schema

Basis is de 'Serial Wifi' print, met een ESP-07 module met ESP8266 en Flash geheugen. De print voegt daar not een 5Volt naar 3.3Volt convertor en level converters voor de seriële aansluiting aan toe, plus een reset-schakelaar, etc. Al met al een eenvoudige module, direct vanuit USB te voeden. Het heeft als nadeel dat de I/O aansluitingen niet mooi op pinnen/connectors zitten. Ik heb dus een en ander direct op de aansluitingen van de ESP-07 gesoldeerd.

Schema van de IoT lamp
Schema van de Energie-verklikker (zie foto boven voor de opbouw)

Het schema laat de Serial Wifi module zien, met daarop de ESP-07. Deze laat een externe Wifi-antenne toe, maar ik gebruik hier de antenne op de module. De module kan met 5 Volt gevoed worden, en is hier direct op de 5 Volt uit de USB connector aangesloten (rechts).

De drie LEDs worden gestuurd via drie MOSFETs vanwege de stroomsterkte, 330 mA is te veel om direct door de module te leveren. De drie MOSFETs (3x BSO304SN, geschikt voor 3 Volt aansturing) worden door de ESP8266 aangestuurd (groen/geel/oranje draadjes op de foto's), op GPIO 12, 13 en 14 (let op de volgorde op de module...). Dit gebeurt met behulp van PWM (puls-breedte modulatie) voor de helderheid van de drie kleuren. De ESP8266 processor maakt niet zo'n heel mooie PWM, maar voor de aansturing van LEDs prima.

MOSFET op printjeDe SMD mosfets zitten op een 'gefreesd' printje (dremel met cirkelzaagblad, rechte lijnen), om makkelijker te kunnen bedraden, en om eventuele hitte af te voeren. Nu zal dit met deze LEDs niet zo nodig zijn, maar ik gebruik die module misschien nog wel eens voor iets anders. De gates zitten met 100 kOhm naar aarde: als een draad los schiet gaat de FET 'uit'. De onderste FET op het plaatje links heb ik schematisch weergegeven, beter te zien hoe het zit.

De rode LED heeft wat minder spanning nodig dan de groene en de blauwe, heeft daarom een andere weerstand gekregen om op 330 mA uit te komen: 10 Ohm ipv 6.8 Ohm; de 10 Ohm is gemaakt door een weerstand van 15 Ohm parallel te schakelen aan een van 33 Ohm (rommelbak...). De LEDs worden overigens nooit allemaal op 100% aangestuurd, in de praktijk is het gebruik minder (maximaal twee LED's ivm de gekozen kleuren). De helderheid is ook nog afhankelijk van de tijd van de dag. De voeding van de LEDs komt via een zekering voor het geval er iets mis gaat. Is een 500 mA 'poly-fuse' zekering, herstelt zichzelf als de overbelasting wordt opgeheven.

De schakelaar S1 (die op het moment geen functie heeft, maar tijdens het testen wel is gebruikt) zit direct op GPIO 0 en aarde. De pull-up weerstand zit in de ESP8266 (softwarematig aangezet). GPIO 0 wordt ook gebruikt om de ESP-07 in programmeermode te zetten, maar is daarna vrij bruikbaar.

Op de opbouw-foto is te zien dat ik de 5 Volt naar de Serial Wifi los kan koppelen (rode draadje rechts naar de 4-pins connector van de Serial WiFi): dan kan ik makkelijk mijn programmer er op aan sluiten, zonder dat de LEDs ongecontroleerd aan kunnen gaan (de externe USB voeding is dan niet aangesloten).

En Verder

Ik denk dat ik het software-gedeelte dat het energiegebruik naar kleur omzet er uit haal, en op de Raspberry laat lopen (als een Python script). De Raspberry geeft dan ruwe RGB-waardes door naar mijn lampje. Op die manier kan ik makkelijk de functie van de lamp wijzigen, mocht ik iets anders willen laten zien.

En misschien nog eens die vermogensweerstanden bij de LEDs wegwerken. Zou toch mogelijk moeten zijn die door de goede waarde spoel (plus diode) te vervangen, zodat je een geschakelde voeding hebt. Wordt tenslotte al met PWM aangestuurd. Aan de andere kant, om zoveel vermogen gaat het ook niet, en als het schakelen misgaat en de mosfet constant aan gaat, krijg je een veel te grote stroom door de LEDs...