Hij is binnen gekomen! De ESP8266 WiFi module is een aantal dagen geleden afgeleverd door de vriendelijke meneer van de PostNL.
De ESP8266 is een hartstikke leuke chipset. In de basis is het een 32 bits microprocessor die een aantal netwerk functionaliteit voor zijn rekening neemt. Deze chip heeft de mogelijkheid om als accesspoint, als client of als beide. Daarnaast kan je met 3 simpele commando's een TCP of UDP connectie opzetten, wat data verzenden en deze zelfde connectie weer afsluiten. Daarnaast heeft de chip ook nog eens de mogelijkheid om buiten UART ook nog eens kan communiceren over SPI. Het leukste van dit alles is dat de ESP8266 bijna niks kost. Ik heb voor de mijne $3.04 inclusief verzendkosten vanuit China betaald. Omgerekend is dat nog geen 3 euro.
Dus dan wordt het maar eens tijd om te kijken hoe de module precies werkt. Laat ik als eerst maar eens even de nodige vertaalde documentatie er bij pakken en de pinout er bij pakken. Aangezien de originele datasheet alleen in Chinees te krijgen is, ben ik echter aangewezen op slecht vertaalde documentatie :(
Om de module aan te sluiten moet je 3.3 volt op de VCC aansluiten, GND moet uiteraard op aarde / negatief aangesloten worden. URXD is de UART receive lijn en UTXD is de UART transmit lijn. Deze mogen aangesloten kruislings aangesloten worden. Dus ESP8266 URXD moet aan de TX van UART interface en de UTXD moet aan de RX van de UART interface. Daarnaast moet je niet vergeten om CH_PD aan VCC aan te sluiten anders wil de ESP8266 niet opstarten. Dat heeft mij namelijk een goed uur uitzoekwerk gekost ;) (lees: RTFM!)
Na dit leuke puzzeltje wordt het maar eens tijd om te gaan kijken of de ESP8266 ook echt werkt. Om te testen of dat zo was, heb ik de ESP8266 aangesloten op een simpele
USB naar TTL interface gebasseerd op een PL2303 chip. Puur als test heb ik de ESP8266 mijn prive WiFi netwerk (genaamd "Starfleet") laten joinen. Wat je niet moet vergeten is dat de ESP8266 niet(!!) compatible is met een breadboard layout (zie foto hieronder).
Zoals je kan zien in de screenshots hieronder, heeft het redelijk wat moeite gekost om de ESP8266 module online te krijgen. Maar eerst even een kleine tabel waarin de meest gebruikte commando's kunnen bekijken (bron: nurdspace) .
Hieronder zie je 2 screenshots waarin ik de ESP8266 verbinding heb laten leggen met mijn WiFi netwerk. Je ziet herin wel wat "ERROR" meldingen terug komen, ik vermoed dat dit gekomen is door het gebruik van backspace of dat ik te snel commando's wou doorgeven aan de module.
Maar uiteindelijk is het dan ook gelukt!
Nu duidelijk is dat de ESP8266 werkt, wordt het maar eens tijd om in een Arduino omgeving te gaan verwerken. Gezien de hoeveelheid werk die het kostte om via een USB naar TTL seriele interface de ESP8266 te laten werken, heb ik besloten op zoek te gaan naar een Arduino library. Het eisenpakket stelt allemaal niet zo heel erg veel voor. De library moest vooral klein, functioneel en duidelijk zijn. Na wat googlen en rondspeuren op Github kwam ik ESP8266wifi van ekstrand tegen op Github (link).
Maar voor dat ik aan het programmeren kan, zal ik als eerst de ESP8266 aan mijn Arduino moeten aansluiten. Hiervoor heb ik het volgende schema bedacht.
Ik heb de RX (receive UART lijn) via een 74HC4050 (datasheet) aangesloten op de PWM pin 3 van de Arduino omdat de ESP8266 geen 5 volt tolerante inputs heeft. De TX (transmit UART lijn) zit direct op PWM pin 2 van de Arduino aangesloten. PWM pin 12 gebruik ik op een LED aan te sturen.
Toen dat klaar was begon ik te bedenken hoe ik de Arduino ging aansturen. Mijn eerste gedachten was om dit over HTTP te doen. De reden om het over HTTP te gaan doen, was heel simpel. Het is een bewezen protocol, ik kan heel simpel met iedere taal die ik zou willen HTTP requests kunnen afhandelen en ik dacht dat de Arduino wel krachtig genoeg zou zijn om dat soort verzoeken af te handelen.
Zoals je echter kan zien in het screenshot hierboven, ging dat hem niet worden. Wat ik ook probeerde, zoals minder vaak een status ophalen of de HTTP encoding op ANSI / ISO-8851 zetten. Het mocht allemaal niet baten, mijn data kwam corrupt aan bij mijn Arduino. Dan maar terug naar de tekentafel. Na wat denken, peinzen en nog meer hersen gekraak, kwam ik tot geen andere conclusie dan zelf een simpele TCP server te gaan implementeren en om de uitdaging nog leuker te maken, heb ik besloten dit te gaan doen in Python.
Op dit moment is de TCP server vrij simpel geïmplementeerd en op basis van het voorbeeld wat ik vond in de Python documentatie. Hij ondersteund op dit moment alleen maar 1 commando en dat is "get light" en dan de naam van lamp waar je de status van wilt opvragen. Op dat moment wordt er instantie aangemaakt van de klasse "Light" en in zijn constructor wordt er 1 parameter meegegeven namelijk "lightname". Op het moment dat de functie getStatus() wordt aangeroepen van de klasse Light, wordt er een gelijknamig bestand geopend en wordt deze uitgelezen. In mijn opzet is dat de "kitchen" light. Vervolgens wordt het resultaat via een TCP connectie terug gezonden naar de Arduino. Op basis van dat resultaat zal de Arduino de LED aan of uit schakelen.
En nu komt het moment waarop ik daden bij mijn woorden zet. De source van de TCP server:
home-automation.py
lights.py
En dan de source van de Arduino client
En uiteraard hoort daar een ook een video bij hoe het er in het echt uit ziet.
Al met al is dit geen super nette implementatie, maar het voldoet voor het moment. 1 van de features die ik nog wil toevoegen is logging. Daarnaast moet er nog een complete webinterface bij komen en eigenlijk moet de huidige "bestanden" bron vervangen door een (No)SQL database. Zodat ik ook nog wat meta data kan gaan opslaan zoals de tijden waarop een lamp aan en uitgeschakeld wordt. En zoals je in de video kan zien zit er soms wat vertraging tussen de wijziging van de file en de werkelijke verandering van de LED.
Er is dus nog genoeg te doen ;)