Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Echtzeit-Umweltmonitoring mit Arduino MKR1000 & Environment Click Sensoren

Komponenten und Zubehör

Arduino MKR1000 × 1
MikroE Environment Click (BME680 Sensor: Temperatur, Luftfeuchte, Druck, Gas, IAQ) × 1

Benötigte Werkzeuge

Apps und Online-Dienste

Über dieses Projekt

Einführung

Wir hatten Environment Click Sensoren zur Hand und entschieden, sie an den Arduino MKR1000 anzuschließen und die Daten auf der WolkAbout IoT Platform zu visualisieren. Ziel: Alle Minute messen, alle 15 Minuten publizieren. Bei Publikationsfehler (Netzwerkprobleme) werden Ergebnisse im Flash-Speicher gepuffert (max. 96 Schreibvorgänge/Tag – Flash garantiert 10.000 Zyklen).

Hardware-Aufbau

Environment Click wird an I2C-Pins (11 und 12 am MKR1000), VCC und GND angeschlossen.

Software-Aufbau

Benötigte Bibliotheken (über Bibliotheksverwalter oder GitHub installierbar):

Sketch Environment monitoring in Arduino IDE kopieren. Er implementiert einen Ringpuffer für Messwerte und persistiert diesen im Flash via FlashStorage. Zeitgesteuertes Lesen/Publizieren via RTCZero. Nach WLAN-Verbindung wird ein Ping an WolkAbout gesendet, um die aktuelle Epoch-Zeit für Zeitstempel zu erhalten.

Ein Alarm-Interrupt setzt Flags für Lesen/Publizieren; die eigentliche Arbeit erledigt loop(). Für minimalen Stromverbrauch: WLAN im Low-Power-Mode, MKR1000 Schlafmodus, Sensor geht automatisch in Low-Power bis zur nächsten Messung.

Notwendige Anpassungen im Sketch

  1. WLAN-Zugangsdaten (Zeilen 33–34):
    const char* ssid = "<*DEINE_SSID*>";
    const char* wifi_pass = "<*DEIN_WLAN_PASSWORT*>";
  2. Geräte-Zugangsdaten von WolkAbout IoT Platform:
    const char *device_key = "device_key";
    const char *device_password = "device_password";

Geräte-Zugangsdaten erhalten: Auf WolkAbout IoT Platform anmelden, Device Management öffnen. Device Type Management Tab → + → Upload → Gerätetyp Environment click-deviceType.json (in Anhängen) hochladen. Dann Create device: Namen vergeben, Connectivity Type MQTT, Haken bei Create Default Semantic (für Dashboard-Widgets). Speichern → Anmeldeinformationen werden angezeigt → in Sketch eintragen.

Dashboard erstellen

Auf WolkAbout: Visualisation and Monitoring → + Add dashboard → Name & Scope (Gerätenamen). Add widget → Trending → Temperature vom Gerät wählen. Wiederholen für Pressure, Humidity. Reading Widget für Altitude, Card Widget für Gas Resistance. Widgets anordnen. Fertiges Dashboard empfängt Daten vom Gerät.

Fazit

Durch die Anbindung von Arduino MKR1000 und Environment Click an WolkAbout IoT Platform entstand eine energieeffiziente Fernüberwachung von Umgebungsbedingungen. Erweitbar durch WolkAbouts Rule Engine für Benachrichtigungen bei Schwellwertüberschreitung. Mehr Infos in den User Guides.

Code

Environment monitoring sketch (Arduino)

In Arduino IDE importieren, WLAN- & Geräte-Zugangsdaten eintragen.

#include <Adafruit_Sensor.h>
#include <Adafruit_BME680.h>
#include <bme680_defs.h>
#include <bme680.h>
#include <WiFi101.h>
#include <RTCZero.h>
#include <FlashStorage.h>
#include "WolkConn.h"
#include "MQTTClient.h"

#define STORAGE_SIZE 32
#define SEALEVELPRESSURE_HPA (1013.25)

typedef struct {
  boolean valid;
  outbound_message_t outbound_messages[STORAGE_SIZE];
  uint32_t head;
  uint32_t tail;
  boolean empty;
  boolean full;
} Messages;

static Messages data;

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);
static wolk_ctx_t wolk;

FlashStorage(flash_store, Messages);

Adafruit_BME680 bme;
RTCZero rtc;

bool read;
const byte readEvery = 1;   // jede Minute
bool publish;
const byte publishEvery = 10; // alle 10 Minuten
byte publishMin;

void _flash_store() {
  data.valid = true;
  flash_store.write(data);
}
void increase_pointer(uint32_t* pointer) {
  if ((*pointer) == (STORAGE_SIZE - 1)) (*pointer) = 0;
  else (*pointer)++;
}
void _init() {
  data = flash_store.read();
  if (!data.valid) {
    data.head = 0; data.tail = 0; data.empty = true; data.full = false;
  }
}
bool _push(outbound_message_t* msg) {
  if (data.full) increase_pointer(&data.head);
  memcpy(&data.outbound_messages[data.tail], msg, sizeof(outbound_message_t));
  increase_pointer(&data.tail);
  data.empty = false;
  data.full = (data.tail == data.head);
  return true;
}
bool _peek(outbound_message_t* msg) {
  memcpy(msg, &data.outbound_messages[data.head], sizeof(outbound_message_t));
  return true;
}
bool _pop(outbound_message_t* msg) {
  memcpy(msg, &data.outbound_messages[data.head], sizeof(outbound_message_t));
  increase_pointer(&data.head);
  data.full = false;
  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);
  }
}
void setup_wifi() {
  delay(10);
  if (WiFi.status() != WL_CONNECTED) {
    int attempts = 0;
    while (WiFi.begin(ssid, wifi_pass) != WL_CONNECTED) {
      if (++attempts == 10) { Serial.println("Couldn't reach WiFi!"); break; }
      delay(1000);
    }
  }
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  _init();
  init_wifi();
  wolk_init(&wolk, NULL, NULL, NULL, NULL, device_key, device_password, &client, hostname, portno, PROTOCOL_JSON_SINGLE, NULL, NULL);
  wolk_init_custom_persistence(&wolk, _push, _peek, _pop, _is_empty);
  if (!bme.begin()) digitalWrite(LED_BUILTIN, HIGH);
  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);
  delay(200);
  read = true; publish = true;
  wolk_connect(&wolk);
  delay(100);
  wolk_update_epoch(&wolk);
  while (!wolk.pong_received) {
    wolk_process(&wolk);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
  }
  digitalWrite(LED_BUILTIN, LOW);
  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() {
  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());
    int alarmMin = (rtc.getMinutes() + readEvery) % 60;
    rtc.setAlarmMinutes(alarmMin);
    delay(100);
  }
  if (publish) {
    publish = false;
    setup_wifi();
    wolk_connect(&wolk);
    if (!wolk.is_connected) _flash_store();
    delay(100);
    if (wolk_publish(&wolk) == W_TRUE) _flash_store();
    publishMin = (rtc.getMinutes() + publishEvery) % 60;
    delay(100);
    wolk_disconnect(&wolk);
    delay(100);
  }
  delay(100);
}

void alarmMatch() {
  read = true;
  if (publishMin == rtc.getMinutes()) publish = true;
}

Environment click-deviceType.json (JSON)

Gerätetyp für WolkAbout IoT Platform (BME680 Sensoren: Temperatur, Luftfeuchte, Druck, Gaswiderstand, Höhe).

[
  {
    "name": "Environment click",
    "description": "Device type for the BME680 sensor on MikroElektronika's board Environment Click",
    "guid": "def68ff6-63c5-4f9c-a066-bcc944b7bd2d",
    "deviceType": "STANDARD",
    "protocol": "JSON",
    "connectivityType": null,
    "firmwareUpdateType": null,
    "feeds": [
      { "name": "Temperature", "reference": "T", "unit": { "name": "CELSIUS", "guid": "7c805d10-a879-11e9-83cd-0a0027000005" } },
      { "name": "Humidity", "reference": "H", "unit": { "name": "HUMIDITY_PERCENT", "guid": "7c8080a3-a879-11e9-83cd-0a0027000005" } },
      { "name": "Pressure", "reference": "P", "unit": { "name": "MILLIBAR", "guid": "7c807980-a879-11e9-83cd-0a0027000005" } },
      { "name": "Gas Resistance", "reference": "GR", "unit": { "name": "OHM", "guid": "7c805890-a879-11e9-83cd-0a0027000005" } },
      { "name": "Altitude", "reference": "A", "unit": { "name": "METRE", "guid": "7c805a59-a879-11e9-83cd-0a0027000005" } }
    ],
    "actuators": [],
    "alarms": [],
    "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 }
    ]
  }
]

Weiterführende Links

Schaltplan

Als Bild verfügbar (I2C-Verdrahtung MKR1000 ↔ Environment Click).

Herstellungsprozess

  1. Bluetooth-gesteuerter Arduino-Spybot bauen – Überwachungsroboter mit IP-Kamera
  2. K30 CO₂-Sensor: Echtzeit-Luftqualitätsmessung mit Arduino
  3. FlickMote: Gestensteuerung per Ultraschall & IR für Smart Home (Arduino 101)
  4. DIY Arduino TV-B-Gone: Universelle TV-Aus-Fernbedienung
  5. Einen eigenen LED-Master-Clock mit Alarm bauen – aus 12 Metern Entfernung ablesbar
  6. Find Me: Smarter Gegenstands-Finder mit Arduino und Bluetooth
  7. Optimierte Stromversorgungslösungen für Arduino-Projekte
  8. Arduino Tic Tac Toe mit MAX7219 LED-Matrix und Karton-Gehäuse
  9. Intelligenten Arduino-Vierbeiner-Roboter bauen: Schritt-für-Schritt-Anleitung
  10. Berührungsloses Temperatur-Überwachungstor für schnelles Screening