Arduino-milieumonitoring
Componenten en benodigdheden
| × | 1 | ||||
| × | 1 |
Benodigde gereedschappen en machines
|
Apps en online services
| ||||
|
Over dit project
Inleiding
We hadden enkele omgevingskliksensoren bij de hand, dus besloten we ze aan te sluiten op de Arduino MKR1000 en ze te visualiseren op WolkAbout IoT Platform. Het idee was om elke minuut een meting te doen en de resultaten elke 15 minuten te publiceren. Als het publiceren van sensormetingen mislukt (vanwege een druk netwerk of een ander probleem), moeten de resultaten worden bewaard in het Flash-geheugen van het apparaat. Met een potentieel maximum van 96 schrijfbewerkingen per dag, minimaliseren we de kans dat het Flash-geheugen in een verkeerde staat terechtkomt (Arduino garandeert 10.000 schrijfcycli).
Hardware-installatie
De omgevingskliksensor wordt aangesloten op de I2C-communicatiepinnen (namelijk 11 en 12 op de MKR1000), Vcc en aarde.
Software-installatie
We hebben een aantal bibliotheken gebruikt om dit project mogelijk te maken, die allemaal kunnen worden geïnstalleerd vanuit de bibliotheekmanager van Arduino IDE, of door.zip-archieven te downloaden van GitHub-repositories die in de bijlagen worden vermeld en ze vervolgens toe te voegen aan Arduino IDE. De vereiste bibliotheken zijn:
- WiFi101
- Adafruit Unified Sensor Driver
- Adafruit BME680-bibliotheek
- RTCZero
- FlashStorage
- WolkConnect
Zodra alle vereiste bibliotheken zijn geïnstalleerd, gaat u verder en kopieert u de inhoud van Omgevingsbewaking schets van de bijlagen in Arduino IDE.
Het implementeert een structuur van een cirkelvormige buffer en gebruikt deze om de meetresultaten op te slaan. Er is ook een implementatie van hoe die structuur in Flash-geheugen kan worden opgeslagen met behulp van de FlashStorage-bibliotheek. Getimed lezen en publiceren van de gegevens wordt bereikt door gebruik te maken van de RTCZero-bibliotheek. In eerste instantie sturen we, nadat we verbinding hebben gemaakt met wifi, een ping naar WolkAbout IoT Platform om het huidige tijdperk te krijgen dat in de RTC-bibliotheek wordt ingevoerd, zodat de sensormetingen correct kunnen worden voorzien van een tijdstempel.
Een alarmonderbreking verandert vlaggen voor taken die moeten worden uitgevoerd (lezen en publiceren) en de rest van het werk wordt afgehandeld in de loop-functie. Hier controleren we of we moeten lezen of publiceren. Voor een minimaal stroomverbruik staat wifi net als de MKR1000 in een energiezuinige modus. De sensor op de Milieuklik gaat automatisch op laag vermogen totdat een meting wordt gevraagd.
Wijzigingen die in de schets moeten worden aangebracht, zijn onder meer het invoeren van WiFi-inloggegevens op lijn 33 en 34:
const char* ssid ="<*UW SSID*>";
const char* wifi_pass ="<*UW WIFI PASWOORD*>";
evenals het invoeren van apparaatgegevens van WolkAbout IoT Platform.
Om deze inloggegevens te krijgen, moet u eerst een apparaat maken door een apparaattype te gebruiken.
Het apparaattype voor dit project, Environment click-deviceType.json, is beschikbaar in de bijlagen van het project, dus maak er een kopie van. Log in op of maak uw account aan op WolkAbout IoT Platform en open het Apparaat Beheer applicatie.
Selecteer het Apparaat Type Beheer tabblad en druk vervolgens op de + teken en selecteer Uploaden optie, navigeer naar uw lokale kopie van het apparaattype.
Nu er een apparaattype beschikbaar is, kunt u er een apparaat van maken door op Maken te klikken apparaat .
Hier moet u uw apparaat een naam geven, het Verbindingstype . instellen naar MQTT en vink het selectievakje aan voor Standaard maken Semantisch (nodig om later widgets op je dashboard te maken).
Druk op Opslaan en het formulier met apparaatgegevens wordt weergegeven. Sla deze informatie op zoals u dat wilt en voer het vervolgens in uw schets in Arduino IDE in:
const char *device_key ="device_key";
const char *device_password ="device_password";
Nu kun je doorgaan, deze schets verifiëren en uploaden naar je bord, maar je moet nog steeds een manier bedenken om de ontvangen sensorgegevens weer te geven.
Om deze gegevens weer te geven, schakelt u over naar Visualisatie en toezicht sectie op WolkAbout IoT Platform en maak een nieuw dashboard door op + Dashboard toevoegen te drukken en een naam voor het dashboard invoeren en het bereik instellen op wat de apparaatnaam ook is. Vervolgens kunt u widgets aan uw dashboard toevoegen door op Toevoegen . te drukken widget.
Selecteer Trending
en selecteer vervolgens Temperatuur vanaf uw apparaat.
Herhaal het proces voor Druk en Vochtigheid . Maak nog een widget van het type Lezen, selecteer Hoogte en maak nog een kaartwidget voor Gas Weerstand . Je kunt de widgets herschikken zoals je wilt.
Na het toevoegen van widgets voor de hele individuele sensormeting die u van uw apparaat verwacht te ontvangen, is het volgende dashboard gereed om de gegevens van uw apparaat te ontvangen.
Dus ga je gang en implementeer het apparaat in de omgeving die je hebt gekozen en bewaak de omstandigheden op afstand.
Conclusie
Door Arduino MKR1000 en Environment Click te verbinden met het WolkAbout IoT Platform, creëerde je een energiezuinige manier om de omgevingscondities te rapporteren van de plaats die je op afstand wilt monitoren. Deze oplossing kan worden uitgebreid door het gebruik van de rule engine van WolkAbout IoT Platform, waarmee u verschillende soorten meldingen kunt ontvangen als een bepaalde waarde een door u gedefinieerde drempel overschrijdt.
Voor meer informatie over de rule engine en andere functies van WolkAbout IoT Platform, kunt u onze pagina Gebruikershandleidingen bezoeken.
Code
- Omgevingsbewakingsschets
- Omgeving click-deviceType.json
OmgevingsbewakingsschetsArduino
Importeer deze schets in Arduino IDE en bewerk de WiFi-referenties en apparaatreferenties#include#include #include #include #include #include #include #include "WolkConn.h"#include "MQTTClient.h"/*Aantal outbound_message_t om op te slaan*/#define STORAGE_SIZE 32#define SEALEVELPRESSURE_HPA (1013.25)/ *Circulaire buffer om uitgaande berichten op te slaan om te blijven bestaan*/typedef struct{ boolean valid; outbound_message_t outbound_messages [STORAGE_SIZE]; uint32_t hoofd; uint32_t staart; booleaans leeg; boolean full;} Berichten;statische Berichtengegevens;/*Verbindingsdetails*/const char* ssid ="ssid";const char* wifi_pass ="wifi_pass";const char *device_key ="device_key";const char *device_password ="device_password ";const char* hostname ="api-demo.wolkabout.com";int portno =1883;WiFiClient espClient;PubSubClient-client(espClient);/* WolkConnect-Arduino Connector-context */static wolk_ctx_t wolk;/* Init flash-opslag * /FlashStorage(flash_store, Berichten);/*Init i2c-sensorcommunicatie*/Adafruit_BME680 bme;RTCZero rtc;bool read;/*Lees de sensor elke minuut. Als u deze parameter wijzigt, zorg er dan voor dat deze <60*/const byte readEvery =1;bool publish;/*Publish every 10 minutes is. Als u deze parameter wijzigt, zorg er dan voor dat deze <60*/const byte publishEvery =10;byte publishMin;/*Flash-opslag en implementatie van aangepaste persistentie*/void _flash_store(){ data.valid =true; flash_store.write(data);}void toename_pointer(uint32_t* pointer){ if ((*pointer) ==(STORAGE_SIZE - 1)) { (*pointer) =0; } else { (*pointer)++; }}void _init(){ data =flash_store.read(); if (data.valid ==false) { data.head =0; gegevens.staart =0; data.leeg =waar; data.full =onwaar; }}bool _push(outbound_message_t* outbound_message){ if(data.full) {verhoging_pointer(&data.head); } memcpy(&data.outbound_messages[data.tail], outbound_message, sizeof(outbound_message_t)); verhoging_pointer(&data.tail); data.leeg =onwaar; data.full =(data.tail ==data.head); return true;}bool _peek(outbound_message_t* outbound_message){ memcpy(outbound_message, &data.outbound_messages[data.head], sizeof(outbound_message_t)); return true;}bool _pop(outbound_message_t* outbound_message){ memcpy(outbound_message, &data.outbound_messages[data.head], sizeof(outbound_message_t)); verhoging_pointer(&data.head); data.full =onwaar; data.empty =(data.tail ==data.head); return true;}bool _is_empty(){ return data.empty;}void init_wifi(){ if (WiFi.status()!=WL_CONNECTED) { while (WiFi.begin(ssid, wifi_pass)!=WL_CONNECTED) { delay(1000 ); } }} ongeldig setup_wifi() { delay(10); if (WiFi.status()!=WL_CONNECTED) { int numAttempts =0; while (WiFi.begin(ssid, wifi_pass) !=WL_CONNECTED) { numAttempts++; if(numAttempts ==10){ Serial.println("Kan wifi niet bereiken!"); pauze; } vertraging (1000); } }} ongeldige setup () { pinMode (LED_BUILTIN, OUTPUT); digitalWrite (LED_BUILTIN, LAAG); /*Initialiseer de circulaire bufferstructuur*/ _init(); init_wifi(); wolk_init(&wolk, NULL, NULL, NULL, NULL, device_key, device_password, &client, hostnaam, portno, PROTOCOL_JSON_SINGLE, NULL, NULL); wolk_init_custom_persistence(&wolk, _push, _peek, _pop, _is_empty); /*De ingebouwde LED gaat aan als er iets mis is gegaan*/ if(!bme.begin()) { digitalWrite(LED_BUILTIN, HIGH); } /*Sensor init*/ bme.setTemperatureOversampling(BME680_OS_8X); bme.setHumidityOversampling (BME680_OS_2X); bme.setPressureOversampling (BME680_OS_4X); bme.setIIRFilterSize(BME680_FILTER_SIZE_3); bme.setGasHeater(320, 150); // 320*C voor 150 ms vertraging (200); lezen =waar; publiceren =waar; /*Haal het huidige tijdperk van de server*/ wolk_connect(&wolk); vertraging (100); wolk_update_epoch(&wolk); while (!(wolk.pong_received)) { wolk_process(&wolk); digitalWrite (LED_BUILTIN, HOOG); vertraging (1000); } digitalWrite (LED_BUILTIN, LAAG); wolk_disconnect(&wolk); rtc.begin(); rtc.setEpoch(wolk.epoch_time); rtc.setAlarmTime(rtc.getHours(), (rtc.getMinutes() + readEvery) % 60, rtc.getSeconds()); rtc.enableAlarm(rtc.MATCH_MMSS); rtc.attachInterrupt(alarmMatch); publishMin =(rtc.getMinutes() + publishEvery) % 60; WiFi.lowPowerMode();}void loop() { /*Om de interruptroutine zo kort mogelijk te houden, stelt routine alleen de uit te voeren taken in read =true betekent dat de sensormeting moet worden uitgevoerd publish =true betekent dat de meetwaarden moeten op het platform worden gepubliceerd of in flash worden bewaard als de verbinding niet beschikbaar is */ if(read) { read =false; if (!bme.performReading()) {digitalWrite(LED_BUILTIN, HIGH); } wolk_add_numeric_sensor_reading(&wolk, "T", bme.temperature, rtc.getEpoch()); wolk_add_numeric_sensor_reading(&wolk, "H", bme.humidity, rtc.getEpoch()); wolk_add_numeric_sensor_reading(&wolk, "P", bme.pressure / 100.0, rtc.getEpoch()); wolk_add_numeric_sensor_reading(&wolk, "GR", bme.gas_resistance, rtc.getEpoch()); wolk_add_numeric_sensor_reading(&wolk, "A", bme.readAltitude(SEALEVELPRESSURE_HPA), rtc.getEpoch()); /*stel nieuw alarm*/ int alarmMin =(rtc.getMinutes() + readEvery) % 60; rtc.setAlarmMinuten(alarmMin); vertraging (100); } if(publish) { publish =false; setup_wifi(); wolk_connect(&wolk); if(!wolk.is_connected) { _flash_store(); } vertraging(100); if(wolk_publish(&wolk) ==W_TRUE) { _flash_store(); } /*set nieuwe publicatietijd*/ publishMin =(rtc.getMinutes() + publishEvery) % 60; vertraging (100); wolk_disconnect(&wolk); vertraging (100); } vertraging(100); }/*Timed interrupt routine*/void alarmMatch(){ read =true; if(publishMin ==rtc.getMinutes()) { publish =true; }}
Omgeving click-deviceType.jsonJSON
Apparaattype dat wordt gebruikt om een apparaat aan te maken op WolkAbout IoT Platform[ { "name":"Environment click", "description":"Apparaattype voor de BME680-sensor op MikroElektronika's board Environment Click", "guid":" def68ff6-63c5-4f9c-a066-bcc944b7bd2d", "deviceType":"STANDARD", "protocol":"JSON", "connectivityType":null, "firmwareUpdateType":null, "feeds":[ { "name":" Temperatuur", "description":null, "reference":"T", "unit":{ "name":"CELSIUS", "guid":"7c805d10-a879-11e9-83cd-0a0027000005" } }, { " name":"Vochtigheid", "description":null, "reference":"H", "unit":{ "name":"HUMIDITY_PERCENT", "guid":"7c8080a3-a879-11e9-83cd-0a0027000005" } }, { "name":"Druk", "description":null, "reference":"P", "unit":{ "name":"MILLIBAR", "guid":"7c807980-a879-11e9-83cd -0a0027000005" } }, { "name":"Gasweerstand", "description":null, "reference":"GR", "unit":{ "name":"OHM", "guid":"7c805890- a879-11e9-83cd-0a0027000005" } }, { "naam":"Hoogte", "beschrijving":null, "referenc e":"A", "unit":{ "name":"METRE", "guid":"7c805a59-a879-11e9-83cd-0a0027000005" } } ], "actuators":[], "alarmen":[], "configs":[], "attributes":[ { "name":"CONNECTIVITY_TYPE", "dataType":"ENUM", "validationRegex":"^(MQTT|HTTP)$", "options":[ "MQTT", "HTTP" ], "defaultValue":"MQTT", "required":true, "readOnly":true }, { "name":"FIRMWARE_UPDATE_ENABLED", "dataType":"BOOLEAN", "validationRegex ":"^(true|false)$", "options":null, "defaultValue":null, "required":false, "readOnly":true }, { "name":"FIRMWARE_VERSION", "dataType":"STRING", "validationRegex":null, "options":null, "defaultValue":null, "required":false, "readOnly":true }, { "name":"FILE_DIRECT_DOWNLOAD_ENABLED", "dataType":"BOOLEAN ", "validationRegex":"^(true|false)$", "options":null, "defaultValue":null, "required":false, "readOnly":true }, { "name":"FILE_URL_DOWNLOAD_ENABLED", "dataType":"BOOLEAN", "validationRegex":"^(true|false)$", "options":null, "defaultValue":null, "required":false, " readOnly":true } ] }]
WolkOver omgevingsbewaking
Deze repository bevat de Arduino-schets die in dit project wordt gebruikthttps://github.com/Wolkabout/Wolk-Arduino-Environment-MonitoringArduino WiFi 101 Shield
Wifi-bibliotheek voor het Arduino WiFi 101 Shieldhttps://github.com/arduino-libraries/WiFi101Adafruit Unified Sensor Driver
Uniforme sensorbibliotheek vereist voor alle sensorenhttps://github.com/adafruit/Adafruit_SensorAdafruit BME680-bibliotheek
Bibliotheek gebruikt voor het milieu klik om sensormetingen te krijgenhttps://github.com/adafruit/Adafruit_BME680RTC-bibliotheek voor Arduino
RTC-bibliotheek voor op SAMD21 gebaseerde borden https://github.com/arduino-libraries/RTCZeroFlashStorage-bibliotheek voor Arduino
Een handige manier om gegevens op te slaan in Flash-geheugen op de ATSAMD21https://github.com/cmaglie/FlashStorageWolkConnect-Arduino
Arduino-bibliotheek die gemakkelijke connectiviteit biedt met WolkAbout IoT Platform.https://github.com/Wolkabout/WolkConnect-ArduinoSchema's
Productieproces