用Arduino打造智能水位监控系统:从硬件搭建到云端报警

在智能家居和物联网应用场景中,水位监控是一个常见但极其实用的功能。无论是鱼缸水质管理、家庭植物自动灌溉,还是地下室积水预警,一个可靠的水位监测系统都能帮我们避免许多麻烦。本文将带你使用Arduino开发板和光电液位传感器,从零开始构建一个完整的智能水位监控解决方案。

1. 项目规划与硬件选型

1.1 系统功能设计

我们的智能水位监控系统将实现以下核心功能:

  • 实时水位检测:通过光电传感器持续监测水位变化
  • 多级报警机制:当水位异常时触发声光报警
  • 状态可视化:LED指示灯显示当前水位状态
  • 数据记录:可选添加SD卡模块记录水位变化历史
  • 远程通知:通过Wi-Fi模块实现手机端报警(进阶功能)

1.2 硬件组件清单

下表列出了本项目所需的主要硬件组件及其功能说明:

组件 型号示例 数量 用途说明
主控板 Arduino Uno R3 1 系统控制核心
液位传感器 光电式水位开关 1-2 水位检测
报警模块 有源蜂鸣器 1 声音报警
状态指示 LED灯(红/绿/蓝) 3 水位状态显示
连接线 杜邦线(公对公) 若干 电路连接
扩展模块 ESP8266 Wi-Fi模块 1(可选) 网络连接

提示:光电液位传感器相比浮球式更不易受水质影响,且没有机械活动部件,寿命更长。

2. 硬件连接与电路搭建

2.1 传感器工作原理

光电液位传感器利用光线在不同介质中的折射率差异来检测液位。当传感器探头处于空气中时,LED发出的光几乎全部被内部棱镜反射回接收器;当探头浸入液体中,大部分光线会折射到液体中,接收器检测到的光强显著降低,从而触发状态变化。

2.2 接线示意图

将各组件按照以下方式连接到Arduino:

  1. 光电传感器

    • VCC → 5V
    • GND → GND
    • OUT → 数字引脚2
  2. 蜂鸣器

    • 正极 → 数字引脚3
    • 负极 → GND
  3. LED指示灯

    • 红色LED → 数字引脚4(水位过低)
    • 绿色LED → 数字引脚5(水位正常)
    • 蓝色LED → 数字引脚6(水位过高)
// 引脚定义
#define SENSOR_PIN 2
#define BUZZER_PIN 3
#define LED_LOW 4
#define LED_NORMAL 5
#define LED_HIGH 6

3. 核心代码实现与逻辑解析

3.1 基础报警功能

以下代码实现了最基本的水位检测与报警功能:

void setup() {
  pinMode(SENSOR_PIN, INPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(LED_LOW, OUTPUT);
  pinMode(LED_NORMAL, OUTPUT);
  pinMode(LED_HIGH, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int sensorState = digitalRead(SENSOR_PIN);
  
  if (sensorState == HIGH) {
    // 传感器未检测到水(水位低)
    digitalWrite(LED_LOW, HIGH);
    digitalWrite(LED_NORMAL, LOW);
    digitalWrite(LED_HIGH, LOW);
    triggerAlarm();
  } else {
    // 传感器检测到水(水位正常/高)
    digitalWrite(LED_LOW, LOW);
    digitalWrite(LED_NORMAL, HIGH);
    digitalWrite(LED_HIGH, LOW);
    noTone(BUZZER_PIN);
  }
  delay(100); // 适当延时减少CPU负载
}

void triggerAlarm() {
  tone(BUZZER_PIN, 1000); // 发出1kHz警报音
  delay(500);
  noTone(BUZZER_PIN);
  delay(500);
}

3.2 多级水位检测进阶版

使用两个传感器可以实现更精确的三级水位监控(低/正常/高):

// 新增高水位传感器引脚
#define SENSOR_HIGH_PIN 7

void setup() {
  // ...保持其他初始化代码不变...
  pinMode(SENSOR_HIGH_PIN, INPUT);
}

void loop() {
  int lowState = digitalRead(SENSOR_PIN);
  int highState = digitalRead(SENSOR_HIGH_PIN);
  
  if (lowState == HIGH && highState == HIGH) {
    // 水位低于低传感器
    setStatus(LED_LOW, 1000); // 快速闪烁红灯
  } else if (lowState == LOW && highState == HIGH) {
    // 水位在正常范围
    setStatus(LED_NORMAL, 0); // 常亮绿灯
  } else {
    // 水位超过高传感器
    setStatus(LED_HIGH, 500); // 慢速闪烁蓝灯
    triggerAlarm();
  }
  delay(100);
}

void setStatus(int ledPin, int interval) {
  static unsigned long prevMillis = 0;
  unsigned long currMillis = millis();
  
  if (interval == 0) {
    digitalWrite(ledPin, HIGH);
  } else if (currMillis - prevMillis >= interval) {
    prevMillis = currMillis;
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
}

4. 系统优化与功能扩展

4.1 防误报处理

光电传感器可能会因水泡、污垢等产生误报,我们可以通过软件滤波提高可靠性:

#define SAMPLE_SIZE 5

int getStableSensorState() {
  int readings[SAMPLE_SIZE];
  
  for (int i = 0; i < SAMPLE_SIZE; i++) {
    readings[i] = digitalRead(SENSOR_PIN);
    delay(10);
  }
  
  // 取多数值作为最终结果
  int highCount = 0;
  for (int i = 0; i < SAMPLE_SIZE; i++) {
    if (readings[i] == HIGH) highCount++;
  }
  
  return (highCount > SAMPLE_SIZE/2) ? HIGH : LOW;
}

4.2 添加Wi-Fi远程通知

使用ESP8266模块可将报警信息推送到手机:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>

const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
const char* host = "api.pushingbox.com";

void setup() {
  // ...保持其他初始化代码...
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
}

void sendNotification(String message) {
  WiFiClient client;
  if (!client.connect(host, 80)) return;
  
  String url = "/pushingbox?devid=YOUR_DEVICE_ID&message=" + message;
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  delay(10);
  client.stop();
}

4.3 电源管理与低功耗优化

对于电池供电的应用,可以大幅降低功耗:

#include <avr/sleep.h>

void enterSleep() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();
  // 程序会在此处暂停,直到外部中断唤醒
  sleep_disable();
}

void setup() {
  // 配置中断唤醒
  attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), wakeUp, CHANGE);
}

void wakeUp() {
  // 空函数,仅用于唤醒
}

void loop() {
  checkWaterLevel();
  enterSleep(); // 进入低功耗模式
}

5. 实际应用案例与故障排除

5.1 鱼缸自动补水系统

将本系统与小型水泵结合,可以实现鱼缸自动补水:

  1. 当水位低于最低标记时,启动水泵补水
  2. 水位达到正常位置时停止水泵
  3. 如果补水超时(如水管堵塞),触发紧急报警
#define PUMP_PIN 8
#define MAX_FILL_TIME 300000 // 5分钟超时

void controlPump() {
  static unsigned long fillStart = 0;
  int level = getStableSensorState();
  
  if (level == HIGH && fillStart == 0) {
    // 开始补水
    digitalWrite(PUMP_PIN, HIGH);
    fillStart = millis();
  } else if (level == LOW) {
    // 停止补水
    digitalWrite(PUMP_PIN, LOW);
    fillStart = 0;
  } else if (fillStart > 0 && 
            (millis() - fillStart) > MAX_FILL_TIME) {
    // 补水超时
    digitalWrite(PUMP_PIN, LOW);
    fillStart = 0;
    triggerAlarm();
    sendNotification("补水超时,请检查系统!");
  }
}

5.2 常见问题与解决方案

下表列出了实际应用中可能遇到的问题及解决方法:

问题现象 可能原因 解决方案
传感器始终显示有水 探头脏污或损坏 清洁探头或更换传感器
报警器误触发 水面波动或气泡干扰 增加软件滤波,调整传感器位置
Wi-Fi连接不稳定 信号弱或配置错误 检查SSID/密码,增强信号覆盖
电池消耗过快 未启用低功耗模式 优化代码,增加睡眠周期

注意:安装传感器时应避免阳光直射,以免干扰光电检测。对于不透明液体,可能需要调整传感器灵敏度或选用其他类型的传感器。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐