## 功能描述
<font size=3>这是一个加湿器,上电开始工作,面板如图
屏幕为0.96寸OLED,某宝6-7元,屏幕显示4行,第1行to:XX%为设置湿度,当湿度到达预设值时,停止雾化,当湿度小于预设值时,开始雾化;第2行now:XX%为当前湿度,由DTH11传感器获取;第3行为水量,不同长度的导线伸入水中,通过ULN2803信号放大得到数据;最后一行是时间,esp32连接网络后获取
![image.png](//image.lceda.cn/pullimage/DWVYEPfKHJuPQ5syl9tSDNuQHjy4Kb1uiBiZFpjy.png)
电源指示灯,当接通电源,雾化器开始工作时亮起o(esp32开始运行,屏幕开始显示数据,读取到DTH11传感器的获取数据,并不一定开始雾化)
![image.png](//image.lceda.cn/pullimage/X2g4Snu0IU0M0d0sQvLH0rYqoVfvWdg7jxtKhTyO.png)
当设备故障时亮起,目前包括:
1.水位低于最低水位
2.esp32无法连接网络
3.esp32无法读取DTH11的数据
![image.png](//image.lceda.cn/pullimage/cNRpoGKoLhX4ASQiPzZQEXFl3nbLKvJyTW9y2jAH.png)
一共四个按钮,上箭头按钮是提高湿度预设值,每次提高1%,下箭头按钮是降低湿度预设值;后面两个按钮为功能预留
![image.png](//image.lceda.cn/pullimage/jX9SBEA74F2feXDenKxMj0oHIeYXDoxq3zlMgbv7.png)
## 模块框图
![加湿器.drawio.png](//image.lceda.cn/pullimage/JQ1lmw5dVNoDrVnh5gqLuUSX1AjNPCLQVj2RNgJR.png)
## 模块简介
### 雾化
<font size=3>~~~~
ESP32给Q2基极高电平,Q2对地导通,拉低Q1栅极,Q1导通。
震荡部分使用EN555典型无稳态电路进行震荡,可调电阻PR1微调振荡频率,Q3(NMOS)漏极连接三脚升压电感(该电感经常用于整人电击玩具)初级,震荡使Q3快速导通截止,L1自耦升压,压电陶瓷开始工作</font>
![image.png](//image.lceda.cn/pullimage/ggiOa8O2IolISBaXLqpyt3Q08kOfk7iwdogbL6Rm.png)
### 交互
#### 显示
<font size=3>放置0,96寸OLED作为用户交互,用于显示当前湿度,设定湿度,以及本地IP等设备信息,使用IIC接口于ESP32 通讯</font>
![image.png](//image.lceda.cn/pullimage/dlNGIgnN8NJsGOhQGSTZptgDMPFVrQ0umg6Q39Kr.png)
#### 按键控制
<font size=3>四个按键,分别用(于开启/关闭)(增加湿度设定值)(减少湿度设定值)(预留按键)。R13~R16四个电阻为下拉电阻,确保按键没有按下时,io口为低电平状态,并且预留消抖电容接口,如果可以通过程序来控制,则不焊接
![image.png](//image.lceda.cn/pullimage/WVObu568TV847CqzTq66Kof1Ix2jZHBA8gxs4AK5.png)
### 传感器
#### 水位
<font size=3>因为水的导电性差,使用ULN2803达林顿驱动器放大信号,该芯片内部有8个达林顿管,可代替大量的三极管,可以把水位分成8份,原先打算用ULN2003,但是ULN2003内部是7组达林顿管,不太容易被100整除,所系选择8组达林顿管的LUN2803</font>
![image.png](//image.lceda.cn/pullimage/Q8QTxcTBx0NLiSp9iSr5pmwKFi9teQ9uYOZuZQmY.png)
![image.png](//image.lceda.cn/pullimage/L19fTnatQSv7GmvoucvEKGzyFH4LmV0d5dZ82FSe.png)
#### 湿度
<font size=3>湿度传感器用DHT11或者DHT22传感器采集,DHT11数字温湿度传感器包含已校准数字信号输出,包含电阻式感湿元件和一个 NTC(负温度系数) 测温元件,还有一个 八位单片机,所以可以一根 DATA 线进行数据的收发
通讯一次时间 4ms 左右,数据分整数部分、小数部分和校验位,具体为: 8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据 + 8bit 校验位。
DHT11 工作参数:
湿度测量范围:20~90%RH
湿度测量精度:±5%RH
温度测量范围:0~50℃
温度测量精度:±2℃
工作电压:DC 3.3V/5V
![image.png](//image.lceda.cn/pullimage/fHMbmpzNPNBXYwLy8NIxOmhmTgFmE7aYglcKwAeM.png)
### 主控
<font size=3>使用ESP32作为主控,采集传感器数据,控制雾化器的启停,通过蓝牙/WIFI功能连接手机/电脑发送传感器数据,并通过手机/电脑控制雾化器
![image.png](//image.lceda.cn/pullimage/urqFBdXMIYWZ8zy1OtQb2RKwxomqTL7a7tJ9a1br.png)
## 程序
```c++
/* 连接wifi*/
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
String ip;
/*获取时间 */
const char* ssid = "老白的超级私人WIFI"; //wifi nane
const char* password = "laobaiNB1314. "; // wifi password
const char* ntpServer = "pool.ntp.org"; //网络时间服务器
const long gmtOffset_sec = 8 * 3600; //时区设置函数,东八区(UTC/GMT+8:00)写成8*3600
const int daylightOffset_sec = 0; //夏令时填写3600,否则填0
struct tm timeinfo;
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float h;
float t;
float th = 30;
/* 使用 I2C 同步寻协议
Adafruit 库写入显示器
使用的是 128×64 OLED 显示屏 */
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//#include <SSD1306Wire.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // (-1) 参数表示 OLED 显示器没有 RESET 引脚
/* 按键定义 */
const int upButtonPin = 16;
const int downButtonPin = 17;
const int leftButtonPin = 18;
const int rightButtonPin = 19;
/* 水位 */
float theWater = 0;
const int wl1Pin = 34;
const int wl2Pin = 35;
const int wl3Pin = 32;
const int wl4Pin = 33;
const int wl5Pin = 25;
const int wl6Pin = 25;
const int wl7Pin = 26;
const int wl8Pin = 14;
const int Humidifier = 5;
const int errLEDPin = 15;
void setup() {
Serial.begin(115200); //115200 的波特率初始化串行监视器以进行调试
//按键为输入模式
pinMode(upButtonPin, INPUT);
pinMode(downButtonPin, INPUT);
pinMode(leftButtonPin, INPUT);
pinMode(rightButtonPin, INPUT);
//水位输入模式
pinMode(wl1Pin, INPUT);
pinMode(wl2Pin, INPUT);
pinMode(wl3Pin, INPUT);
pinMode(wl4Pin, INPUT);
pinMode(wl5Pin, INPUT);
pinMode(wl6Pin, INPUT);
pinMode(wl7Pin, INPUT);
pinMode(wl8Pin, INPUT);
pinMode(errLEDPin, OUTPUT);
digitalWrite(errLEDPin, LOW);
pinMode(Humidifier, OUTPUT);
digitalWrite(Humidifier, LOW);
// 连接到Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("连接到Wi-Fi...");
}
Serial.println("连接到Wi-Fi成功!");
Serial.println(WiFi.localIP());
//server.begin();
dht.begin();
//检测oled屏幕
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;)
;
}
//display.flipScreenVertically();
}
void loop() {
oled();
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
Serial.print("IP address: ");
Serial.println(ip);
button();
water();
MyDht();
openHumidifier();
}
void openHumidifier() {
if (h > th) {
digitalWrite(Humidifier, LOW);
} else {
digitalWrite(Humidifier, HIGH);
}
}
//获取DTH传感器的湿度
void MyDht() {
h = dht.readHumidity();
t = dht.readTemperature();
// 检查是否读取到传感器数据
if (isnan(h) || isnan(t)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
// 串口打印数据日志
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.println();
delay(1000);
}
//按键控制
void button() {
if (digitalRead(upButtonPin) == HIGH) {
Serial.println("upButtonPin");
th = th + 1;
}
if (digitalRead(downButtonPin) == HIGH) {
Serial.println("downButtonPin");
th = th - 1;
}
if (digitalRead(leftButtonPin) == HIGH) {
Serial.println("leftButtonPin");
digitalWrite(Humidifier, HIGH);
}
if (digitalRead(rightButtonPin) == HIGH) {
Serial.println("rightButtonPin");
digitalWrite(Humidifier, LOW);
}
}
void water() {
if (digitalRead(wl8Pin) == HIGH) {
//theWater = 100;
} else if (digitalRead(wl8Pin) == LOW && digitalRead(wl7Pin) == HIGH) {
theWater = 87.5;
} else if (digitalRead(wl7Pin) == LOW && digitalRead(wl6Pin) == HIGH) {
theWater = 75;
} else if (digitalRead(wl6Pin) == LOW && digitalRead(wl5Pin) == HIGH) {
theWater = 62.5;
} else if (digitalRead(wl5Pin) == LOW && digitalRead(wl4Pin) == HIGH) {
theWater = 50;
} else if (digitalRead(wl4Pin) == LOW && digitalRead(wl3Pin) == HIGH) {
theWater = 37.5;
} else if (digitalRead(wl3Pin) == LOW && digitalRead(wl2Pin) == HIGH) {
theWater = 25;
} else if (digitalRead(wl2Pin) == LOW && digitalRead(wl1Pin) == HIGH) {
theWater = 12.5;
} else if (digitalRead(wl1Pin) == LOW) {
digitalWrite(errLEDPin, HIGH);
digitalWrite(Humidifier, LOW);
theWater = 0;
}
}
//显示
void oled() {
delay(1000);
//显示湿度阈值
display.clearDisplay(); // 清除显示
display.setTextSize(2); // 设置文本大小
display.setTextColor(WHITE); // 设置文本颜色
display.setCursor(0, 0); //设置显示坐标
display.print("to :");
display.print(th);
display.println("%");
display.display();
display.print("now:");
display.println(h);
display.display();
display.print("wat:");
display.print(theWater);
display.println("%");
display.display();
display.println(&timeinfo, "%T");
display.display();
}
void printLocalTime() {
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%F %T %A"); // 格式化输出
}
9
12
收藏到专辑