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

MKR1000 Multi-Sensor-Deck: Blitz, Gas, UV, Temp, Feuchte & Druck – Umweltmonitoring

Komponenten und Zubehör

Arduino MKR1000 × 1
MOD-1016 Blitzsensor (AS3935) × 1
DFRobot MQ-9 Gassensor (CO/Entzündbare Gase) × 1
Adafruit HTU21D-F Temperatur- & Feuchtesensor (I2C) × 1
Adafruit BMP085/BMP180 Druck-/Höhen-/Temperatursensor (I2C) × 1
SparkFun ML8511 UV-Sensor (analog) × 1
ChronoDot RTC (DS3231, I2C, batteriegepuffert) × 1
SparkFun Photon Weather Shield (Platzhalter für Wind/Regen) × 1
Adafruit NeoPixel (WS2812B) × 1
Steckbrett & Jumperkabel × 1

Projektbeschreibung

Ich liebe Wetterbeobachtung und wollte mehr als nur Temperatur/Feuchte. Kommerzielle Stationen zeigen oft nur „Jetzt“-Werte. Mit dem Arduino MKR1000 konnte ich endlich alle gewünschten Sensoren gleichzeitig betreiben – dank 8 Hardware-Interrupts (normale Arduinos haben nur 2).

MKR1000 Multi-Sensor-Deck: Blitz, Gas, UV, Temp, Feuchte & Druck – Umweltmonitoring
MKR1000 Multi-Sensor-Deck auf Steckbrett

Sensoren auswählen: Drei Kategorien

Der MKR1000 bietet genügend Pins für alle drei Typen.

WICHTIG – Spannungspegel: MKR1000 arbeitet mit 3,3 V Logik. Sensoren mit 5 V Pegel benötigen Level-Shifter an I2C/Interrupt-Leitungen.

Die verwendeten Sensoren sind gängig (Adafruit, SparkFun, Element14), kosten 5–20 USD. Blitzdetektor (MOD-1016, AS3935) ca. 26 USD. Windmesser (Anemometer) vom Photon Weather Shield geplant. Bodentemperatur/Moisture später ergänzbar.

Pin-Belegung planen

Vor dem Aufbau auf Papier (und als Kommentar im Code) festlegen:

PinFunktionTyp
A0reserviert (DAC)Analog
A1ML8511 UV-SensorAnalog
A2Sichtbarer Lichtsensor (TEMT6000)Analog
A3TMP36 lokaler TemperatursensorAnalog
A4MQ-9 GassensorAnalog
A5Bodenfeuchte-SensorAnalog
A6Windgeschwindigkeit (analog?)Analog
0Taster (Interrupt)HW-Interrupt
1AS3935 Blitzdetektor (Interrupt)HW-Interrupt
2Wind-Anemometer (Interrupt/Umdrehung)HW-Interrupt
3Regensensor Kippwippe (Interrupt)HW-Interrupt
4,5frei–
6Piezo-Summer (geteilt mit Onboard-LED)Digital Out
7NeoPixel DatenleitungDigital Out
11I2C SDAI2C
12I2C SCLI2C

Erste Schritte: Sensor für Sensor testen

  1. Jeweils einen Sensor anschließen, Beispielcode laden, Bibliothek installieren.
  2. Pin-Zuordnung im Code anpassen, Testen per Serial Monitor.
  3. Wenn alle einzeln laufen, zum Gesamtsketch zusammenfügen.

Ich nutze zusätzlich eine ChronoDot RTC (DS3231), da der MKR1000-eigene RTC bei reiner Batteriepufferung bei mir nicht zuverlässig lief.

Auf dem Steckbrett: Orangene Jumper = 3,3 V-Versorgung pro Sensor (einzeln abziehbar zum Deaktivieren).

MKR1000 Multi-Sensor-Deck: Blitz, Gas, UV, Temp, Feuchte & Druck – Umweltmonitoring
Modulare Stromversorgung pro Sensor

Bibliotheken & Kompatibilität

Einige ältere Bibliotheken funktionieren nicht out-of-the-box mit MKR1000 / Arduino IDE 1.6.7+ (z. B. entfernte ATOMIC_*-Makros in AVR-libc). Fehlermeldungen (orange) genau lesen: Steht der Fehler in einer Bibliothek? Websuche mit „arduino“ + Fehlermeldung. Autor kontaktieren. Besser: Fertigmodule von Adafruit/SparkFun kaufen – diese pflegen ihre Bibliotheken.

WLAN & Verschlüsselung

Der MKR1000 hat onboard WiFi und eine Hardware-Krypto-Engine (ATECC508A) für sichere TLS-Verbindungen – essenziell für IoT. In diesem Projekt noch nicht genutzt, aber für „Version 2“ geplant.

Tipp: Unbedingt die neueste WiFi101-Bibliothek nutzen (GitHub), sonst erkennt der Sketch das WiFi-Modul nicht. Dank an Charif Mahmoudi für den Hinweis in seinem „Getting Started with MKR1000“-Tutorial.

MKR1000 Multi-Sensor-Deck: Blitz, Gas, UV, Temp, Feuchte & Druck – Umweltmonitoring
SAMD21 Blockdiagramm (Herz des MKR1000)

Tipps für Analog-Sensoren

Tipps für I2C-Geräte

MKR1000 Multi-Sensor-Deck: Blitz, Gas, UV, Temp, Feuchte & Druck – Umweltmonitoring
Pull-up (Bus-Ende) vs. Serienwiderstand (MCU-Seite)

Was tun mit den Daten?

Aktuell: Serial Monitor. Erweiterbar: LCD, SD-Karte, Cloud-Upload (WiFi). Vision: Mehrere Stationen mit GPS → Blitzortung durch Triangulation der Empfangssignale.

UPDATE 2017-11-29: Hardware-Interrupts auf MKR1000 funktionieren noch nicht zuverlässig. Ich nutze das Projekt nun für einen 9. Klassen-Kurs (Adalogger M0 + SD-Karte + WiFi-Modul). Lehrmaterial: arduinoclass.pbworks.com

Idea: IKEA SODERSVIK Lampe mit 20 NeoPixels + IR-Empfänger → Wind = ziehende Wolken, Farbe = Temperatur, Fernbedienung zeigt Trendwerte.

MKR1000 Multi-Sensor-Deck: Blitz, Gas, UV, Temp, Feuchte & Druck – Umweltmonitoring
IKEA SODERSVIK – Basis für NeoPixel-Wetteranzeige

Code-Beispiele

1. Haupt-Sketch (Monitoring aller Sensoren)

Vollständiger, kommentierter Code (NeoPixel & Blitzsensor auskommentiert wegen Interrupt-Bibliotheks-Problemen).

/* RTC-Weather-Sensors_v6_MKR1000 by Zonker Harris Spring 2016
 * MKR1000: 8 HW-Interrupts + WiFi + Crypto (wichtig für IoT!)
 * Viele Kommentare = keine Speicherkosten, aber Verständnis später!
 */
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>
#include <Adafruit_HTU21DF.h>
// #include <Adafruit_NeoPixel.h> // Interrupt-Konflikt, aktuell deaktiviert

Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10180);
Adafruit_HTU21DF htu = Adafruit_HTU21DF();

// Pin-Zuordnungen (siehe Tabelle oben)
int UVOUT = A1, lightOut = A2, tmp36out = A3, mq9out = A4;
int sounderPin = 6, neopixelPin = 7;

// ChronoDot RTC Variablen (BCD-Register)
int addrRTC = 0x68;
int seconds, minutes, hours, day, date, month, years;
int temprtc, tempfrtc;

void setup() {
  Serial.begin(9600); delay(1000);
  Serial.println("i2c Sensor Deck");
  pinMode(UVOUT, INPUT); pinMode(lightOut, INPUT); pinMode(tmp36out, INPUT);
  pinMode(sounderPin, OUTPUT); pinMode(neopixelPin, OUTPUT);

  if (!bmp.begin()) { Serial.println("BMP085/180 nicht gefunden!"); while(1); }
  displaySensorDetails();
  if (!htu.begin()) { Serial.println("HTU21D nicht gefunden!"); while(1); }
  // RTC initial setzen (einmalig auskommentieren, hochladen, wieder kommentieren)
  // seconds=0; minutes=41; hours=20; day=7; date=3; month=1; years=16; initChrono();
}

void loop() {
  beep(50, 2); // Start-Signal

  // 1. ChronoDot RTC auslesen (I2C 0x68)
  Wire.beginTransmission(0x68); Wire.write(0); Wire.endTransmission();
  Wire.requestFrom(0x68, 13);
  while(Wire.available()) {
    seconds = Wire.read(); minutes = Wire.read(); hours = Wire.read();
    day = Wire.read(); date = Wire.read(); month = Wire.read(); years = Wire.read();
    // Alarme, Status, Aging, Temp übersprungen für Kürze
    temprtc = Wire.read(); tempfrtc = Wire.read();
  }
  // BCD → Dezimal konvertieren
  int s10 = (seconds & 0xF0)>>4, s1 = seconds & 0x0F;
  int m10 = (minutes & 0xF0)>>4, m1 = minutes & 0x0F;
  int h10 = ((hours & 0x20)>>5)*2 + ((hours & 0x10)>>4)*1; // 24h-Modus
  int h1 = hours & 0x0F;
  years += 2000;
  temprtc = (temprtc & 0x7F) + ((tempfrtc & 0xC0)>>6)*0.25;

  get_date(); // Wochentag aktualisieren
  Serial.print("ChronoDot - ");
  Serial.print(h10); Serial.print(h1); Serial.print(":");
  Serial.print(m10); Serial.print(m1); Serial.print(":");
  Serial.print(s10); Serial.print(s1); Serial.print(" 20");
  Serial.print(years); Serial.print(" "); Serial.print(month);
  Serial.print(" "); Serial.print(date); Serial.print("\t");
  Serial.print(temprtc); Serial.println(" C");
  delay(100);

  // 2. BMP180 (I2C 0x77) – Druck & Temp
  sensors_event_t event; bmp.getEvent(&event);
  float BMPtemp; bmp.getTemperature(&BMPtemp);
  Serial.print("Temp: "); Serial.print(BMPtemp); Serial.print(" C (");
  Serial.print(BMPtemp*1.8+32); Serial.print(" F) \t");
  if (event.pressure) {
    Serial.print("BMP180 - Pres: "); Serial.print(event.pressure); Serial.print(" hPa\t");
    float seaLevel = SENSORS_PRESSURE_SEALEVELHPA; // 1013.25 hPa Standard
    Serial.print("Alt: "); Serial.print(bmp.pressureToAltitude(seaLevel, event.pressure)); Serial.println(" m");
  } else Serial.println("Sensor error");
  delay(100);

  // 3. HTU21D-F (I2C 0x40) – Feuchte & Temp
  float HTUtemp = htu.readTemperature();
  Serial.print("HTU21DF - Temp: "); Serial.print(HTUtemp); Serial.print(" C (");
  Serial.print(HTUtemp*1.8+32); Serial.print(" F)\tHum: ");
  Serial.print(htu.readHumidity()); Serial.println("%");
  delay(100);

  // 4. TMP36 (Analog A3) – lokale Temp
  int reading = averageAnalogRead(tmp36out);
  float voltage = 0.0032258064516129 * reading; // 3.3V/1023
  float tempC = (voltage - 0.5) * 100;
  Serial.print("TMP36 - temp: "); Serial.print(tempC); Serial.print(" C \t");
  Serial.print(tempC*9/5+32); Serial.print(" F, out: "); Serial.print(voltage); Serial.println("v");
  delay(100);

  // 5. TEMT6000 (Analog A2) – sichtbares Licht
  int vLevel = averageAnalogRead(lightOut);
  float vVolts = 0.0032258064516129 * vLevel;
  Serial.print("TEMT6000 out: "); Serial.println(vLevel);
  delay(100);

  // 6. ML8511 (Analog A1) – UV-Index
  int uvLevel = averageAnalogRead(UVOUT);
  float uvVolts = 0.0032258064516129 * uvLevel;
  float uvIndex = mapfloat(uvVolts, 0.99, 2.8, 0.0, 15.0);
  Serial.print("ML8511 UV out: "); Serial.print(uvLevel);
  Serial.print(" / UV Intensity (mW/cm²): "); Serial.println(uvIndex);
  delay(100);

  // 7. MQ-9 (Analog A4) – Gas (roher ADC-Wert, Kalibrierung nötig)
  int mq9val = analogRead(mq9out);
  Serial.print("MQ-9 Gas: "); Serial.println(mq9val, DEC);
  delay(100);

  Serial.println(); delay(3500); // ~5s Loop-Zeit
}

// Hilfsfunktionen: averageAnalogRead, mapfloat, beep, RTC-Funktionen, I2C-Scanner...
// (siehe vollständigen Code auf GitHub / untenstehende Snippets)

2. Mittelwertbildung für Analog-Reads (Rauschunterdrückung)

int averageAnalogRead(int pin) {
  byte n = 8; unsigned int sum = 0;
  for (byte i = 0; i < n; i++) sum += analogRead(pin);
  return sum / n;
}

3. I2C-Bus-Scanner (Adressen finden)

#include <Wire.h>
void setup() { Wire.begin(); Serial.begin(9600); Serial.println("\nI2C Scanner"); }
void loop() {
  byte error, addr; int n = 0;
  Serial.println("Scanning...");
  for (addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    error = Wire.endTransmission();
    if (error == 0) {
      Serial.print("I2C device at 0x"); if (addr<16) Serial.print("0");
      Serial.print(addr, HEX);
      // Bekannte Sensoren benennen
      if (addr == 0x03) Serial.print(" - AS3935 Blitz");
      if (addr == 0x40) Serial.print(" - HTU21D Temp/Feuchte");
      if (addr == 0x68) Serial.print(" - DS3231 RTC (ChronoDot)");
      if (addr == 0x77) Serial.print(" - BMP180 Druck/Temp");
      Serial.println(); n++;
    } else if (error == 4) {
      Serial.print("Unknown error at 0x"); if (addr<16) Serial.print("0");
      Serial.println(addr, HEX);
    }
  }
  if (n == 0) Serial.println("No I2C devices");
  Serial.println("done"); delay(5000);
}

4. ML8511 UV-Sensor Demo (angepasst für 3,3 V MCU)

int UVOUT = A1;
void setup() { Serial.begin(9600); pinMode(UVOUT, INPUT); Serial.println("ML8511 example"); }
void loop() {
  int uv = averageAnalogRead(UVOUT);
  float volts = 0.0032258064516129 * uv; // 3.3V/1023
  float uvIdx = mapfloat(volts, 0.99, 2.8, 0.0, 15.0);
  Serial.print("ML8511 out: "); Serial.print(uv);
  Serial.print(" / UV Index: "); Serial.println(uvIdx);
  delay(100);
}
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
// averageAnalogRead() wie oben

Schaltplan (Mock-up, Fritzing unvollständig)

MKR1000 Multi-Sensor-Deck: Blitz, Gas, UV, Temp, Feuchte & Druck – Umweltmonitoring
Übersichts-Skizze der Sensor-Verdrahtung

Herstellungsprozess

  1. Sensordaten in Raspberry Pi integrieren: GPS & MPU-9150 Hands-On Guide
  2. Line-Tracking-Sensor mit Raspberry Pi – Einfacher KY-033 Tür/Line Detektor
  3. Robuste Temperatur- & Sensor-API auf Raspberry Pi mit GY-91 Modul bauen
  4. Automatisiertes Aeroponik-System mit Raspberry Pi und Feuchtigkeitssensor bauen
  5. Raspberry Pi GPIO meistern: PIR-Bewegungsmelder an B+/Model 2 anschließen
  6. Acconeer A111 Pulsradar mit Raspberry Pi integrieren: Praktischer Leitfaden
  7. HC-SR501 PIR-Bewegungssensor an Raspberry Pi anschließen, kalibrieren und programmieren
  8. Python/MicroPython Sensor Logger: Sensordaten nahtlos in Google Sheets speichern
  9. Adafruit 10DOF IMU Daten von Raspberry Pi 2 an Azure Event Hubs senden (Windows 10 IoT Core)
  10. Sanftes Herunterfahren & Schlafmodus für Raspberry Pi – DIY Strommanagement-Schaltung