Echtzeit-Schwimmbadüberwachung mit Arduino MKR1000 & Samsung ARTIK Cloud
Komponenten und Zubehör
| Arduino MKR1000 | × | 1 |
| Jumper-Kabel (diverse) | × | 1 |
| DFRobot pH-Meter | × | 1 |
| Widerstand 4,75 kΩ | × | 1 |
| Temperaturfühler (DS18B20 / OneWire) | × | 1 |
Apps und Onlinedienste
- Samsung ARTIK Cloud for IoT
- Arduino IDE
Projektbeschreibung
I. Ziel
Primäres Ziel ist die Überwachung von pH-Wert und Wassertemperatur in Schwimmbädern mittels Samsung ARTIK Cloud.
II. ARTIK Cloud Einrichtung
Schritt 1: Neuen Gerätetyp erstellen
- Bei ARTIK Cloud registrieren/anmelden.
- Auf der Developer-Seite „Device Type“ → „New“ wählen.
- Anzeigenamen und eindeutigen Namen vergeben.
- „New Manifest“ erstellen: Felder definieren (z. B.
ph,tempals Numerisch). - Manifest speichern und dann „Activate Manifest“ klicken.
Schritt 2: Anwendung (Application) erstellen
- Zu „ARTIK Cloud Applications“ navigieren → „New Application“.
- Namen und „Authentication Redirect URL“ eingeben (z. B.
https://localhost/index/). - Berechtigungen auf „Read“ und „Write“ setzen, Gerätetyp zuordnen, speichern.
- Client ID und Client Secret notieren (werden im Code benötigt).
Schritt 3: Gerät verbinden
- Zu „My Devices“ → „Connect Another Device“.
- Den zuvor erstellten Gerätetyp wählen → „Connect Device“.
- In den Geräteeinstellungen Device ID und Device Token notieren (für den Arduino-Code nötig).
III. Hardware & Sensoren anschließen
Schritt 1: Temperatursensor & pH-Meter an MKR1000
- Temp GND → MKR1000 GND
- Temp OUT → MKR1000 Digital Pin 1
- Temp VCC → MKR1000 5 V
- 4,7 kΩ Widerstand zwischen Temp VCC und Temp OUT (Pull-up)
- pH GND → MKR1000 GND
- pH OUT → MKR1000 Analog Pin A1
- pH VCC → MKR1000 5 V
Hinweis: Ein optionaler Klinkenstecker (Audio Jack) erleichtert das Abnehmen des Temperatursensors.
Schritt 2: Software-Vorbereitung in der Arduino IDE
- Boardverwalter: „Arduino SAMD Boards“ installieren → MKR1000 auswählen.
- Benötigte Bibliotheken über Bibliotheksverwalter installieren:
- ArduinoJson (für JSON-Daten an ARTIK Cloud)
- ArduinoHttpClient (HTTPS-Verbindung zur API)
- OneWire (für DS18B20)
- DallasTemperature (DS18B20-Bibliothek)
Schritt 3: Programm hochladen
- MKR1000 per USB anschließen.
- Code von GitHub herunterladen.
- Im Code folgende Werte anpassen:
WIFI_AP(WLAN-SSID)WIFI_PWD(WLAN-Passwort)deviceID(ARTIK Cloud Device ID)deviceToken(ARTIK Cloud Device Token)
- Code kompilieren und hochladen.
Voraussetzung: Das WLAN muss Internetzugang haben.
IV. Feldtest
Getestet in privaten, öffentlichen und Schul-Schwimmbädern. Die Hardware wurde in einer wasserdichten Box montiert und am Beckenrand platziert (nicht im Wasser!). So lassen sich pH-Wert und Temperatur kontinuierlich überwachen und durch gezielte Chemikaliendosierung normalisieren.
Eine Anleitung zum Einbau der Elektronik in das Gehäuse folgt in einem separaten Tutorial.
V. Ergebnisse & Ausblick
Dieses DIY-Gerät ermöglicht effiziente, ressourcenschonende Wasserqualitätsprüfung. Es soll das Bewusstsein für die Wichtigkeit der Schwimmbadwasserqualität schärfen – oft wird mehr auf Annehmlichkeiten als auf Sicherheit geachtet.
Viel Spaß beim Nachbauen! 😊
Arduino MKR1000 Code (C/C++)
Der vollständige Sketch ist auf GitHub verfügbar. Hier die Kernlogik:
/******************** Water Quality Monitoring für ARTIK Cloud ********************/
#include <WiFi101.h>
#include <WiFiClient.h>
#include <ArduinoJson.h>
#include <ArduinoHttpClient.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// Temperatur-Sensor (OneWire an Pin 1)
#define ONE_WIRE_BUS 1
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// ARTIK Cloud REST
char server[] = "api.artik.cloud";
int port = 443;
char buf[200];
String deviceID = "IHRE_DEVICE_ID";
String deviceToken = "IHR_DEVICE_TOKEN";
// pH-Meter (DFRobot an A1)
#define SensorPin A1
#define Offset 0.00
#define samplingInterval 20
#define ArrayLenth 40
int pHArray[ArrayLenth];
int pHArrayIndex = 0;
// WLAN
#define WIFI_AP "IHR_WLAN_SSID"
#define WIFI_PWD "IHR_WLAN_PASSWORT"
WiFiSSLClient wifi;
HttpClient client = HttpClient(wifi, server, port);
void setup() {
Serial.begin(9600);
startWifi();
}
void loop() {
// Temperatur lesen
float celsius = 0;
sensors.requestTemperatures();
celsius = sensors.getTempCByIndex(0);
// pH-Wert lesen (Mittelwertbildung)
static unsigned long samplingTime = millis();
static float pHValue, voltage;
if (millis() - samplingTime > samplingInterval) {
pHArray[pHArrayIndex++] = analogRead(SensorPin);
if (pHArrayIndex == ArrayLenth) pHArrayIndex = 0;
voltage = avergearray(pHArray, ArrayLenth) * 5.0 / 1024;
pHValue = 3.5 * voltage + Offset;
samplingTime = millis();
}
// JSON-Payload bauen & senden
Serial.println("===========================================");
Serial.print("data: { ph: "); Serial.print(pHValue);
Serial.print(" , temp: "); Serial.print(celsius); Serial.println("} ");
String contentType = "application/json";
String auth = "Bearer " + deviceToken;
int len = loadBuffer(celsius, pHValue);
client.beginRequest();
client.post("/v1.1/messages");
client.sendHeader("Authorization", auth);
client.sendHeader("Content-Type", "application/json");
client.sendHeader("Content-Length", len);
client.endRequest();
client.print(buf);
int statusCode = client.responseStatusCode();
String response = client.responseBody();
Serial.print("Status: "); Serial.println(statusCode);
Serial.print("Response: "); Serial.println(response);
delay(1000);
}
void startWifi() {
Serial.println("Verbinde MKR1000 mit WLAN...");
int status = WL_IDLE_STATUS;
while (status != WL_CONNECTED) {
Serial.print("Versuche: "); Serial.println(WIFI_AP);
WiFi.begin(WIFI_AP, WIFI_PWD);
delay(10000);
status = WiFi.status();
}
}
// Mittelwertbildung mit Ausreißerentfernung (SparkFun ML8511 Methode)
double avergearray(int* arr, int number) {
if (number <= 0) return 0;
if (number < 5) {
long sum = 0;
for (int i = 0; i < number; i++) sum += arr[i];
return (double)sum / number;
}
int min = min(arr[0], arr[1]);
int max = max(arr[0], arr[1]);
long amount = 0;
for (int i = 2; i < number; i++) {
if (arr[i] < min) { amount += min; min = arr[i]; }
else if (arr[i] > max) { amount += max; max = arr[i]; }
else amount += arr[i];
}
return (double)amount / (number - 2);
}
// JSON-Buffer befüllen
int loadBuffer(float temp, float ph) {
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
root["sdid"] = deviceID;
root["type"] = "message";
JsonObject& data = root.createNestedObject("data");
data["temp"] = temp;
data["ph"] = ph;
root.printTo(buf, sizeof(buf));
return root.measureLength();
}
Schaltplan
Herstellungsprozess
- SaaS und Cloud navigieren: Warum sorgfältiges Datenmanagement entscheidend ist
- Cloud-Horizonte erweitern: Neue Zonen, Container und Multicloud-Strategien
- Cloud-Applikations-Monitoring meistern: Einblicke für IT-Führungskräfte
- Warum Cloud Linux Security, Stabilität und Performance im Shared Hosting boostet
- Fern-Temperatursensor mit Raspberry Pi & Python bauen – Schritt-für-Schritt-Anleitung
- Home Energy Centre: Solar PV, Thermische Panels & Raumtemperaturen mit Raspberry Pi & Moteino überwachen
- DIY Heimbrau-Temperaturregelung: Überwachen & Steuern mit Arduino
- Remote-Wetterüberwachung mit Raspberry Pi 3 & PubNub
- Smartes System zur Luftqualitäts- & Abfallüberwachung mit Raspberry Pi, Arduino & IOTA
- Wie Gasüberwachungslösungen Sicherheit in Industrie- und Automobilumgebungen erhöhen