基于 Arduino MKR1000 与 Samsung ARTIK Cloud 的游泳池实时监测系统
组件与物料清单
| 组件 | 数量 |
|---|---|
| Arduino MKR1000 | 1 |
| 跳线若干 | 1 |
| DFRobot pH 计模块 | 1 |
| 4.75kΩ 电阻 | 1 |
| 温度探头 (DS18B20 等单总线) | 1 |
所需软件与在线服务
- Samsung ARTIK Cloud for IoT
- Arduino IDE
项目简介
I. 目标
本项目旨在利用 Samsung ARTIK Cloud 监测游泳池的 pH 值和温度水平。
II. ARTIK Cloud 设置
步骤 1:创建设备类型
- 注册并登录 ARTIK Cloud 开发者站点。
- 创建新的 "Device Type",填写显示名称和唯一名称。
- 创建 Manifest(清单),定义字段名(如 ph、temp)及描述。
- 保存后进入 "Activate Manifest" 标签页,点击激活完成设备类型创建。

步骤 2:创建应用
- 进入 ARTIK Cloud Applications,新建应用。
- 填写应用名称和认证重定向 URL(如 https://localhost/index/)。
- 设置应用权限为读写,关联之前创建的设备类型并保存。

步骤 3:连接设备
- 进入 "My Devices",点击 "Connect Another Device"。
- 选择刚创建的设备类型,完成连接。
- 记下 Device ID 和 Device Token,后续代码中需填入。

III. 硬件传感器搭建
步骤 1:连接温度与 pH 传感器到 MKR1000
接线如下:
- 温度探头 GND → MKR1000 GND
- 温度探头 OUT → MKR1000 数字引脚 1
- 温度探头 VCC → MKR1000 5V
- 4.7kΩ 电阻连接在温度探头 VCC 与 OUT 之间(上拉)
- pH 计 GND → MKR1000 GND
- pH 计 OUT → MKR1000 模拟引脚 A1
- pH 计 VCC → MKR1000 5V


为方便拆卸温度探头,笔者额外加装了航空插头(可选)。
步骤 2:配置所需软件库
在 Arduino IDE 中添加 MKR1000 开发板支持(板管理器搜索 "mkr1000" 安装)。
安装以下库:
- ArduinoJson — 用于构建发送给 ARTIK Cloud 的 JSON 数据
- ArduinoHttpClient — HTTPS 通信客户端
- OneWire — 读取单总线温度传感器
- DallasTemperature — DS18B20 温度传感器库
步骤 3:上传程序
将 MKR1000 连接电脑,从 GitHub 下载代码,修改以下配置后上传:
- WiFi SSID 与密码
- ARTIK Cloud Device ID 与 Device Token

注意: WiFi 必须能访问互联网。
IV. 现场测试
已在私人、公共、学校游泳池进行实测,收集数据分析硬件性能。可将 MKR1000 与传感器置于防水盒中漂浮池面,远程监测水质并指导投药调节。

V. 结果与展望
本教程帮助你构建 DIY 游泳池水质监测设备,提升对水质安全的关注,降低检测成本与资源浪费。祝制作愉快!
核心代码 (Arduino MKR1000 C/C++)
/******************** Water Quality Monitoring for ARTIK Cloud ********************/
#include <WiFi101.h>
#include <WiFiClient.h>
#include <ArduinoJson.h>
#include <ArduinoHttpClient.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
/** Temperature Sensor **/
#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 = "your_device_id";
String deviceToken = "your_device_token";
/** pH Meter **/
#define SensorPin A1
#define Offset 0.00
#define samplingInterval 20
#define ArrayLength 40
int pHArray[ArrayLength];
int pHArrayIndex = 0;
/** WiFi **/
#define WIFI_AP "your_wifi_ssid"
#define WIFI_PWD "your_wifi_password"
WiFiSSLClient wifi;
HttpClient client = HttpClient(wifi, server, port);
void setup() {
Serial.begin(9600);
startWifi();
}
void loop() {
// 读取温度
float celsius = 0;
sensors.requestTemperatures();
celsius = sensors.getTempCByIndex(0);
// 读取 pH 值(滑动平均滤波)
static unsigned long samplingTime = millis();
static float pHValue, voltage;
if (millis() - samplingTime > samplingInterval) {
pHArray[pHArrayIndex++] = analogRead(SensorPin);
if (pHArrayIndex == ArrayLength) pHArrayIndex = 0;
voltage = averageArray(pHArray, ArrayLength) * 5.0 / 1024;
pHValue = 3.5 * voltage + Offset;
samplingTime = millis();
}
// 构建 JSON 并发送
Serial.println("Sending data to ARTIK Cloud...");
int len = loadBuffer(celsius, pHValue);
String auth = "Bearer " + deviceToken;
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("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print("Connecting to "); Serial.println(WIFI_AP);
WiFi.begin(WIFI_AP, WIFI_PWD);
delay(10000);
}
}
// 滑动平均去极值
double averageArray(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;
}
long amount = 0;
int minVal = min(arr[0], arr[1]);
int maxVal = max(arr[0], arr[1]);
for (int i = 2; i < number; i++) {
if (arr[i] < minVal) { amount += minVal; minVal = arr[i]; }
else if (arr[i] > maxVal) { amount += maxVal; maxVal = arr[i]; }
else amount += arr[i];
}
return (double)amount / (number - 2);
}
// 构建 JSON 缓冲区
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();
}
原理图

制造工艺
- 树莓派与 Python 构建远程温度传感器:分步实战指南
- 家庭能源中心:树莓派与 Moteino 监测光伏、光热与室温
- DIY 家酿温控系统:Arduino 监测与调节发酵温度
- 树莓派 3 配合 PubNub 实现远程气象监测
- 智能室内空气质量与垃圾监测系统
- Arduino 与智能手机打造智能电压表——简单易做的 DIY 项目
- 通过 Arduino IoT Cloud 用 Alexa 控制电视:分步指南
- 驾驭 SaaS 与云:为何严谨数据管理至关重要
- 拓展云疆界:新可用区、容器与多云策略
- 掌握云应用监控:IT领导者的关键洞见
- Cloud Linux如何提升共享主机的安全性、稳定性与性能
- 气体监测方案如何保障工业与汽车环境安全