In het kader van mijn serie van artikelen „Mijn pad naar het IoT“ heb ik onder meer de ESP 32 Pico Kit gebruikt om sensordata naar verschillende cloudplatforms te sturen. Daarmee kunnen gebruikers data van hun eigen sensoren visualiseren op gepersonaliseerde webpagina’s, die ze zelf kunnen aanpassen. Het is heel goed mogelijk om miljoenen sensoren te registreren, zoals bijvoorbeeld bij het cloudplatform Amazon Web Services (zie deel 25), dat ook door professionele klanten wordt gebruikt. Het spreekt vanzelf dat daarbij betrouwbare versleuteling moet worden gebruikt. In deel 25 hebben we laten zien, hoe een ESP 32 via TLS en Secure MQTT sensorwaarden naar AWS kan sturenn.

Sensordata open source

Het cloudplatform dat ik in dit artikel uitprobeer, dient een heel ander doel. De sensordata die wordt verzameld en gevisualiseerd moeten wel openbaar toegankelijk zijn. Om scholieren enthousiast te maken voor milieumeettechniek (of voor wetenschap en techniek in het algemeen), heeft het Institut für Geoinformatik van de universiteit van Münster een paar jaar geleden een hardwarekit samengesteld, die een Arduino-kaart en verschillende sensoren bevat. Er is intussen ook een breed verkrijgbare versie van de SenseBox, waarmee elke geïnteresseerde sensordata kan verzamelen. En er is een cloudplatform ontwikkeld onder de naam openSenseMap. Hier kunnen gebruikers gemakkelijk een account aanmaken en data uploaden en openbaar toegankelijk publiceren. Alle SenseBoxen worden weergegeven op een kaart die gebaseerd is op OpenStreetMap. Het is niet per se nodig om daarbij de SenseBox-hardware te gebruiken; ook data die met een andere kaart is geregistreerd kan op het Internet worden gezet. openSenseMap heeft een zogenaamde REST-interface, waarmee we data kunnen up- en downloaden. Om sensordata te publiceren, sturen we de meetwaarden met het HTTP-protocol naar de server. Handig voor beginners: Bij het registreren van een SenseBox krijgt u een sketch toegestuurd, waarmee u de data op die manier kunt versturen. U hoeft die alleen nog maar aan te passen om uw eigen sensoren uit te kunnen lezen. Op https://edu.books.sensebox.de staat een goede handleiding voor beginners.

Maar HTTP is maar één van de manieren om meetwaarden op openSenseMap te publiceren. Het gaat ook via MQTT, en u had misschien al geraden dat ik daarvoor heb gekozen. In tegenstelling tot de cloudplatforms die ik tot nu toe had getest, heeft openSenseMap geen eigen MQTT-broker, maar alleen een MQTT-client. Die abonneert zich op sensorberichten onder een door de gebruiker te bepalen topic bij een openbaar toegankelijke broker, die de gebruiker ook zelf moet kiezen.

Na registratie op https://opensensemap.org en het aansluiten van een eerste apparaat (dat ook bij mij „senseBox“ heet), moest ik de juiste gegevens invullen onder de menukeuze Edit -> MQTT.

Zoals u kunt zien in het screenshot, heb ik gekozen voor de al vaker gebruikte Mosquitto-testbroker (test.mosquitto.org) en het topic „/ElektorMyJourneyIoT/SenseBox/light“.



Ik heb mijn SenseBox „LIGHT_ ESP 32“ genoemd. Er is maar één sensor beschikbaar, dus die gebruik ik als meetgrootheid met als naam „Light“ en als eenheid „RAW“. Dat laatste omdat ik geen gekalibreerde lichtsensor gebruik, maar gewoon de onbewerkte data van een ADC naar het Internet stuur.

Demoproject

Als hardware heb ik de ESP 32 Pico Kit met een rode test-LED, een RGB -LED voor het weergeven van de status van de verbinding en een lichtgevoelige weerstand op pen 36 gebruikt. De hardware en de werking van de software zijn beschreven in deel 23. Als basis voor de ESP 32-Arduino-sketch heb ik de software uit deel 25 (Amazon Web Services) van mijn serie van artikelen gebruikt. Ik moest daarin de volgende veranderingen aanbrengen:
  1. In plaats van TLS en Secure MQTT worden nu weer het gewone TCP- en MQTT-protocol gebruikt. Daarom maak ik gebruik van de klassen TCPClient en MQTTClient in plaats van TCPClientSecure en MQTTClientSecure.
  2. Bij het verbinden met de MQTT-broker gebruik ik, om dezelfde reden, nu de poort 1883 in plaats van 8883. Het broker-adres moet door de gebruiker worden ingevuld in het webformulier (een uitgebreide beschrijving van de ESP32-webserver en het configuratieformulier is te vinden in de delen 19 t/m 22). Als client-ID wordt de device-ID uit het webformulier gebruikt. De client-ID is bij openSenseMap van ondergeschikt belang. Ik heb hier gekozen voor „ElektorMyJourneyIoT“. Let op: U moet deze device-ID niet verwarren met de ID van de hele SenseBox (die heb ik in de software niet gebruikt).
  3. De functie void SendSensorDateToxxx(string SensorName, byte SensorDate)
    heet nu void PublishSensorDate(string SensorName, byte SensorDate).
    Hier worden het topic en de payload van het MQTT-bericht samengesteld voor het publiceren van de sensorwaarde. Omdat elk cloudplatform een specifiek formaat voor die gegevens eist, waren hier de meeste veranderingen nodig.

Bij openSenseMap is het topic vrij te kiezen. Ik heb dus gekozen voor „/ElektorMyJourneyIoT/SenseBox/light“. Als payload moeten we een JSON-expressie in een bepaald formaat gebruiken. Hier moet (als enige kleine geheimpje, dat bijdraagt aan de veiligheid) de sensor-ID worden meegegeven, die ons door openSenseMap is toegewezen toen we de SenseBox en de sensor registreerden. De payload wordt opgebouwd volgens het volgende patroon:
 
{“SENSORID“:“VALUE“}

VALUE is de meetwaarde. Bij pure getallen kunnen we de aanhalingstekens ook weglaten, dus een geldige payload kan bijvoorbeeld zijn:
 
{“5bf000000000000000341“:30}

De door mijn ADC ingelezen digitale waarden (afkomstig van de spanning over de lichtgevoelige weerstand) variëren tussen 0 en 4095, wat ik gereduceerd heb tot 0…63 door de bits naar rechts te schuiven.



In het screenshot ziet u het resultaat van mijn inspanningen. Ter bescherming van mijn privacy heb ik als locatie van mijn sensorbox niet mijn huis, maar het station Keulen-Ehrenfeld ingevoerd. Daar in de buurt is trouwens ook de SenseBox van een school te vinden, waarmee weergegevens worden verzameld. Het hele concept van openSenseMap bevalt me: hier wisselen burgers omgevingsdata uit met burgers. Maar ook de weergave van de kaart is geslaagd. Meetwaarden worden weergegeven in een diagram. Met de zoomfunctie kunnen we interessante gedeelten van de grafiek van meetwaarden nader bekijken (hier de lichtcondities bij wisselende bewolking vroeg in de middag).

Trouwens: als u zelf een klein weerstation wilt opzetten en de meetwaarden op openSenseMap publiceert, kan Elektor helpen. In het januari/februarinummer van ons blad ElektorLabs vindt u het project „Weerstation met ESP 32“. In onze shop worden dan alle onderdelen van een weerstation (naast een wind- en regenmeter) en een bouwkit voor een ESP 32-controllerkaart aangeboden. Het geheel is al voorbereid om data op openSenseMap te publiceren.

Flexibele Software

Eigenlijk zou ik op dit punt kunnen stoppen. Maar ik vond het niet netjes om alleen te vertellen dat u de sketch kunt downloaden, maar dan nog handmatig moet aanpassen, door uw sensor-ID in te vullen. Bovendien wilde ik niet bij het programmeren van nieuwe sketches telkens de functie, waarin het topic en de payload worden samengesteld tot een bericht, specifiek voor elk cloudplatform moeten aanpassen (ik ben nieuwsgierig, en wil er graag meer leren kennen).

Daarom heb ik het configuratieformulier uitgebreid met 7 invoervelden. Naast de al bekende parameters SSID, PASSWORD, BROKER ADDRESS en DEVICE ID zijn er nu ook een parameter SENSOR ID/TOKEN en de velden TOPIC en PAYLOAD. Bij DEVICE ID voert u in, welke client-ID moet worden gebruikt bij het opbouwen van de verbinding met de MQTT-broker. In ons geval is dat gewoon „ElektorMyJourneyIoT“. Bij SENSOR ID voert u de sensor-ID in, die u van openSenseMap hebt gekregen.

Het topic en de payload van elk bericht worden bij elk cloudplatform samengesteld uit de bovengenoemde parameters en de sensorwaarde. Om dit algemeen te kunnen formuleren, heb ik een codering bedacht. De uitdrukking $D$ staat voor de ingevoerde Device/Client-ID en $S$ staat voor de sensor-ID. Voor $V$ wordt de meetwaarde ingevuld en $N$ staat voor de naam van de sensor (in mijn geval „light“), die we meegeven aan de functie void PublishSensorDate(string SensorName, byte SensorDate). Bovendien worden hekjes (#) vervangen door aanhalingstekens.

In ons geval moeten we als PAYLOAD in het webformulier invullen:
{#$S$#:$V$}

De functie PublishSensorDate maakt er dan een expressie van, zoals bijvoorbeeld:
{“5bf…341“:30}

Voor TOPIC kon ik nu in het webformulier invullen:
/$D$/SenseBox/$N$
om „/ElektorMyJourneyIoT/SenseBox/light“ te krijgen.

Als u mijn pogingen wilt reproduceren, kunt u als volgt te werk gaan:
  1. Bouw de hardware zoals in deel 23 is beschreven, de ESP32 Pico Kit is verkrijgbaar in de Elektor-shop.
  2. Download de software onderaan deze pagina, compileer de sketch en upload hem naar het board.
  3. Maak verbinding met de webserver van de ESP32 via 192.168.4.1 in een browser (bijvoorbeeld op uw smartphone). Voer de SSID en het wachtwoord van uw netwerk in. Voer ook het brokeradres test.mosquitto.org in en als topic de bovengenoemde uitdrukking. Na het verzenden zal de ESP32 verbinding maken met de testserver en meteen berichten gaan verzenden. Dat is te zien aan het groen knipperen van de RGB-LED.
  4. De ESP32 stuurt nu sensordata naar het netwerk, die door openSenseMap.org wordt opgevraagd en gevisualiseerd.
  5. Registreer u bij openSenseMap en haal uw sensor-ID op. Configureer MQTT op uw „SenseBox“ zoals in het screenshot helemaal bovenaan deze pagina. Maak nu opnieuw verbinding met het webformulier van de ESP32 en voer de sensor-ID en als payload de bovenbeschreven uitdrukking in.
Veel plezier bij het experimenteren met openSenseMap!