基于ESP32的智能家居环境监测系统

2025/4/13

大风

    目前还是名大二的学生,这是第二篇博客,对于刚学完C语言有对物联网感兴趣的同学可以尝试,我使用的是Vscode中的platformio的环境开发,也可以使用arduino ide,成本低,在家里可以复现,但是细节仍需要打磨完善,同时如果觉得我做的传感器比较多,可以进行删减,如果有感兴趣的可以关注一下,非常欢迎私信交流学习,我也会在周末更新博客。

一、摘要:

  本项目“基于ESP32的小型互联网系统”正是在这样的背景下应运而生。我们的目标是开发一个集成的环境监测和自动化控制系统,该系统不仅能够监测家庭环境的关键参数,还能够根据监测数据自动调节设备,实现家庭绿植的自动化生长培养和小型鱼类家庭水箱的环境监测。通过这一系统,我们希望能够实现一个无人化的居住环境,使得居住者无需亲自操作,系统便能根据环境变化自动调节,以达到最适宜居住的条件。

二、整体流程图:

三、项目实施

蜂鸣器           土壤湿度传感器      空气温湿度            OLED

水温传感器         红外传感器         光强传感器             3.3V水泵

OLED显示

蓝牙的话可以下载Bluetooth appliance.

四、项目组成部分(硬件和代码部分)

1. 微控制器

•   ESP32:主控芯片,负责处理传感器数据、控制外设和通信。

2. 传感器

•   温湿度传感器(DHT22):用于测量环境温度和湿度。

•   光强传感器(BH1750):用于测量环境光强。

•   土壤湿度传感器:用于测量土壤湿度。

•   水温传感器(DS18B20):用于测量水温。

3. 控制模块

•   继电器:用于控制水泵的开关。

•   蜂鸣器:用于发出警报声。

4. 通信模块

•   蓝牙模块(BluetoothSerial):用于通过蓝牙接收控制命令。

•   红外遥控模块(IRremote):用于通过红外遥控器接收控制命令。

5. 显示模块

•   OLED显示屏(U8G2_SSD1306_128X64_NONAME_F_HW_I2C):用于显示传感器数据。

6. 接口

  • OLED 显示屏:SCL (GPIO 22), SDA (GPIO 21)
  • DS18B20 温度传感器:DATA (GPIO 4)
  • DHT22 温湿度传感器:DATA (GPIO 32)
  • BH1750 光强传感器:SCL (GPIO 22), SDA (GPIO 21)
  • 土壤湿度传感器:ANALOG (GPIO 34)
  • 继电器:CONTROL (GPIO 2)
  • 蜂鸣器:CONTROL (GPIO 19)
  • 红外接收器:RECEIVE (GPIO 13)
  • 继电器:
  • VCC  -- 5V (电源正极) 
  • GND--  GND (电源负极)
  • IN  -- GPIO 2 (ESP32)
  • COM --  5V (电源正极) 
  • NO  --  水泵正极    

7.库文件 

  • Wire.h:用于I2C通信。
  • U8g2lib.h:用于OLED显示屏的驱动。
  • DHT.h:用于温湿度传感器的驱动。
  • BH1750.h:用于光强传感器的驱动。
  • BluetoothSerial.h:用于蓝牙通信。
  • IRremote.h:用于红外遥控的驱动。
  • OneWire.h:用于DS18B20传感器的驱动。
  • DallasTemperature.h:用于DS18B20传感器的驱动。

8.开发环境

1. 开发环境:VSCODE  PlatformIO

2.串口:同时按住window和X 点击设备管理器,寻找串口即可

3.手机端:下载Bluetooth,连接蓝牙。

4.通信:可以下载打印助手,注意设置确保了开发板和计算机之间的数据传输速率一致,我使用的是115200波特率。

 

五、核心代码

 1.传感器数据读取

void readSensors()
{
    static unsigned long lastReadTime = 0;
    const unsigned long readInterval = 2000; // 每2秒读取一次

    if (millis() - lastReadTime < readInterval)
    {
        return; // 未到读取时间
    }

    lastReadTime = millis();

    // 读取温湿度传感器数据
    float temp = dht.readTemperature();
    float hum = dht.readHumidity();
    if (isnan(temp) || isnan(hum))
    {
        temperature = -1; // 表示未连接或读取失败
        humidity = -1;
        dhtConnected = false;
        Serial.println("DHT sensor read failed");
    }
    else
    {
        temperature = temp;
        humidity = hum;
        dhtConnected = true;
        Serial.println("DHT sensor read success");
    }

    // 读取光强传感器数据
    if (lightMeter.begin())
    {
        lightLevel = lightMeter.readLightLevel();
        lightMeterConnected = true;
        Serial.println("BH1750 sensor read success");
    }
    else
    {
        lightLevel = -1; // 表示未连接或读取失败
        lightMeterConnected = false;
        Serial.println("BH1750 sensor read failed");
    }

    // 读取土壤湿度传感器数据
    if (soilMoistureConnected)
    {
        soilMoisture = analogRead(soilMoisturePin);
        if (soilMoisture == 0 || soilMoisture == 1023) // 检查是否连接
        {
            soilMoisture = -1; // 表示未连接或读取失败
            soilMoistureConnected = false;
            Serial.println("Soil moisture sensor read failed");
        }
        else
        {
            Serial.println("Soil moisture sensor read success");
        }
    }
    else
    {
        soilMoisture = -1; // 表示未连接或读取失败
        Serial.println("Soil moisture sensor not connected");
    }

    // 读取水温传感器数据
    bool waterTempReadSuccess = false;
    for (int i = 0; i < 3; i++) // 尝试读取 3 次
    {
        sensors.requestTemperatures();                 // 请求温度读取
        waterTemperature = sensors.getTempCByIndex(0); // 获取第一个设备的温度
        if (!isnan(waterTemperature))
        {
            waterTempReadSuccess = true;
            break;
        }
        delay(100); // 等待 100ms 后再次尝试
    }

    if (waterTempReadSuccess)
    {
        waterTemperatureConnected = true;
        Serial.println("Water temperature sensor read success");
    }
    else
    {
        waterTemperature = -1; // 表示未连接或读取失败
        waterTemperatureConnected = false;
        Serial.println("Water temperature sensor read failed");
    }

    // 检查蜂鸣器的连接状态
    buzzerConnected = digitalRead(buzzerPin) != -1;

    // 检查继电器的连接状态
    relayConnected = digitalRead(relayPin) != -1;
}

2.蓝牙通信

void handleBluetooth()
{
    if (SerialBT.available())
    {
        int command = SerialBT.parseInt();
        Serial.print("Received Bluetooth command: ");
        Serial.println(command);

        switch (command)
        {
        case 1: // 打开继电器(水泵)
            relayState = true;
            digitalWrite(relayPin, HIGH);
            manualControl = true; // 标记为手动控制
            SerialBT.println("Relay ON");
            Serial.println("Relay ON");
            break;
        case 2: // 关闭继电器(水泵)
            relayState = false;
            digitalWrite(relayPin, LOW);
            manualControl = true; // 标记为手动控制
            SerialBT.println("Relay OFF");
            Serial.println("Relay OFF");
            break;
        case 3: // 打开蜂鸣器
            buzzerState = true;
            controlBuzzer();
            SerialBT.println("Buzzer ON");
            Serial.println("Buzzer ON");
            break;
        case 4: // 关闭蜂鸣器
            buzzerState = false;
            controlBuzzer();
            SerialBT.println("Buzzer OFF");
            Serial.println("Buzzer OFF");
            break;
        case 5: // 播放两只老虎
            playSong(song, noteDurations, sizeof(song) / sizeof(int), buzzerPin);
            SerialBT.println("Playing 'Two Tigers'");
            Serial.println("Playing 'Two Tigers'");
            break;
        case 0: // 翻页
            currentPage = (currentPage == 1) ? 2 : 1;
            Serial.println("Page changed to " + String(currentPage)); // 添加调试信息
            displaySensors();                                         // 更新 OLED 显示
            SerialBT.println("Page changed");
            Serial.println("Page changed");
            break;
        default:
            SerialBT.println("Unknown command");
            Serial.println("Unknown command");
            break; // ... 其他命令 ...
        }
    }
}

3.继电器控制

void controlRelay()
{
    if (manualControl)
        return; // 如果是手动控制,不进行自动控制

    if (soilMoisture < soilMoistureThresholdLow)
    {
        if (!relayState)
        {
            relayState = true;
            digitalWrite(relayPin, relayState);
            SerialBT.println("Soil moisture is low. Relay ON");
        }
    }
    else if (soilMoisture >= soilMoistureThresholdHigh)
    {
        if (relayState)
        {
            relayState = false;
            digitalWrite(relayPin, relayState);
            SerialBT.println("Soil moisture is high. Relay OFF");
        }
    }
}

4.红外控制

void handleIRCommands()
{
    if (IrReceiver.decode()) // 使用默认实例 IrReceiver
    {
        Serial.print("Received IR code: ");
        Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX); // 打印接收到的红外信号编码值

        switch (IrReceiver.decodedIRData.decodedRawData) // 使用 decodedRawData
        {
        case 0xFFC23D:                                                // 按键 0
            currentPage = (currentPage == 1) ? 2 : 1;                 // 翻页
            Serial.println("Page changed to " + String(currentPage)); // 添加调试信息
            displaySensors();                                         // 更新 OLED 显示
            break;
        case 0xFF02FD:                                                // 新增处理 0 的按键
            currentPage = (currentPage == 1) ? 2 : 1;                 // 翻页
            Serial.println("Page changed to " + String(currentPage)); // 添加调试信息
            displaySensors();                                         // 更新 OLED 显示
            Serial.println("Page changed by IR");
            break;
        default:
            break;
        }
        IrReceiver.resume(); // 接收下一个值
    }
}

六、作品程序调试

1. 开发环境:VSCODE  PlatformIO

2.串口:同时按住window和X 点击设备管理器,寻找串口即可

3.手机端:下载Bluetooth,连接蓝牙。

4.通信:可以下载打印助手,注意设置确保了开发板和计算机之间的数据传输速率一致,我使用的是115200波特率。

什么是波特率?

波特率是指串口通信的速率,即每秒钟传输的二进制位数。常见波特率为9600和115200。通信双方需设定相同波特率以确保有效通信。

七、结语

大道五十 天衍四十九 人遁其一

                                                                                                        选自《周易.系辞上传》

            在学习的路上我也是个小白,但是我相信只要努力,就会有收获,即使效果渺茫,但是天道酬勤,海纳百川,正所谓“宁欺白头翁 莫欺少年穷”。

            非常感谢您的阅读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值