#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include "DHTesp.h"
const float GAMMA = 0.7;
const float RL10 = 50;
#define LCD_CS 15
#define LCD_DC 2
#define DHT_PIN 17
#define BUZZER_PIN 16 // 定义蜂鸣器连接的引脚
int mode = 1;
Adafruit_ILI9341 tft = Adafruit_ILI9341(LCD_CS, LCD_DC);
DHTesp dhtSensor;
// 用于记录当前显示的背景颜色索引,实现循环切换颜色
int currentColorIndex = 0;
// 定义颜色数组,存放不同状态对应的颜色
uint16_t colors[] = {ILI9341_WHITE, ILI9341_RED, ILI9341_BLUE, ILI9341_ORANGE};
// 全局错误状态变量,初始化为 false,表示无错误
bool globalError = false;
// 读取 DHT 传感器数据的函数
TempAndHumidity readDHTSensorData() {
TempAndHumidity data = dhtSensor.getTempAndHumidity();
// 在此添加更详细的错误处理逻辑,判断传感器是否连接正常等情况
if (dhtSensor.getStatus()!= DHTesp::ERROR_NONE) {
Serial.println("DHT 传感器连接出现问题,请检查连接!");
// 设置特定的错误代码或状态标记
data.temperature = -999;
data.humidity = -999;
} else if (isnan(data.temperature) || isnan(data.humidity)) {
// 若数据无效,可设置默认值或返回错误代码
Serial.println("获取到的 DHT 传感器数据无效,请检查传感器工作状态!");
data.temperature = 0;
data.humidity = 0;
}
return data;
}
// 处理光照数据的函数
float processLightData() {
int analogValue = analogRead(27);
// 判断模拟值是否在合理范围,假设光照传感器正常范围是 0 - 4095
if (analogValue < 0 || analogValue > 4095) {
Serial.println("光照传感器模拟值异常,可能传感器故障!");
return -999; // 返回特定错误代码表示传感器故障
}
float voltage = analogValue / 4096. * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
if (isfinite(lux)) {
return lux;
} else {
Serial.println("光照强度计算结果异常,可能参数设置问题或光照过强!");
return -1; // 返回 -1 表示光照过强无法测量
}
}
// 显示数据的函数,根据湿度和温度情况设置背景色及显示相关警告信息,实现颜色循环切换
void displayData(TempAndHumidity data, float lux) {
tft.setTextWrap(false); // 设置文字不自动换行,方便手动控制对齐
// 绘制温度图标(这里简单用一个小方块表示,可替换为更合适的图标字体或图形)
tft.fillRect(10, 50, 10, 10, ILI9341_BLACK);
tft.setCursor(30, 50);
tft.setTextSize(2);
tft.setTextColor(ILI9341_BLACK);
tft.println("温度: " + String(data.temperature, 2) + "°C");
// 绘制湿度图标(类似地,用一个水滴形状图标表示,可自定义绘制)
tft.fillCircle(10, 80, 5, ILI9341_BLACK);
tft.setCursor(30, 80);
tft.setTextSize(2);
tft.setTextColor(ILI9341_BLACK);
tft.println("湿度: " + String(data.humidity, 1) + "%");
if (lux!= -1 && lux!= -999) {
// 绘制光照图标(用一个太阳形状图标表示,可进一步优化图形)
tft.fillTriangle(10, 110, 20, 130, 0, 130, ILI9341_BLACK);
tft.setCursor(30, 110);
tft.setTextSize(2);
tft.setTextColor(ILI9341_BLACK);
tft.println("光照强度: " + String(lux, 1) + " lx");
}
bool isTempHigh = data.temperature > 30;
bool isHumidityHigh = data.humidity > 50;
bool isHumidityLow = data.humidity < 10;
int colorCount = sizeof(colors) / sizeof(colors[0]);
// 根据满足的条件确定颜色索引
if (isTempHigh && isHumidityHigh) {
currentColorIndex = 1; // 对应红色(假设温度高优先)
} else if (isTempHigh && isHumidityLow) {
currentColorIndex = 2; // 对应蓝色
} else if (isHumidityHigh) {
currentColorIndex = 3; // 对应橙色
} else if (isHumidityLow) {
currentColorIndex = 4; // 对应下一种假设的颜色(这里示例中暂时没有更多,可按需扩展)
} else if (isTempHigh) {
currentColorIndex = 1; // 对应红色
} else {
currentColorIndex = 0; // 默认白色
}
// 循环切换颜色索引,防止越界
currentColorIndex %= colorCount;
tft.fillScreen(colors[currentColorIndex]);
if (currentColorIndex == 1) {
tft.setTextColor(ILI9341_WHITE); // 红色背景时文字设为白色
} else if (currentColorIndex == 3) {
tft.setTextColor(ILI9341_BLACK); // 橙色背景时文字设为黑色(可按需调整)
} else {
tft.setTextColor(ILI9341_BLACK); // 其他情况文字设为黑色(可按需调整)
}
// 设置标题字体大小稍大,更突出显示,并居左对齐
tft.setTextSize(3);
tft.setCursor(0, 0);
tft.println("环境监测数据");
// 绘制分隔线,使用虚线表示
for (int x = 0; x < tft.width(); x += 5) {
tft.drawPixel(x, 35, ILI9341_BLACK);
}
if (isTempHigh) {
tft.setTextColor(ILI9341_WHITE); // 确保警告文字颜色为白色
tft.setCursor(0, 140);
tft.println("警告:温度过高!");
}
if (isHumidityHigh) {
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(0, 160);
tft.println("警告:湿度过高!");
}
if (isHumidityLow) {
tft.setTextColor(ILI9341_BLACK);
tft.setCursor(0, 180);
tft.println("警告:湿度过低!");
}
}
// 格式化并打印串口数据的函数
void formatAndPrintSerialData(TempAndHumidity data, float lux) {
Serial.print("温度: ");
Serial.print(data.temperature, 2);
Serial.println("°C");
Serial.print("湿度: ");
Serial.print(data.humidity, 1);
Serial.println("%");
if (lux!= -1 && lux!= -999) {
Serial.print("光照强度: ");
Serial.print(lux);
Serial.println(" lx");
}
}
void setup() {
tft.begin();
Serial.begin(115200);
Serial.println("LDR infinity test");
tft.setCursor(0, 0);
tft.setTextSize(2);
tft.fillScreen(ILI9341_WHITE);
tft.setRotation(0);
tft.setTextColor(ILI9341_BLACK);
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
pinMode(BUZZER_PIN, OUTPUT); // 初始化蜂鸣器引脚为输出模式
}
void loop() {
delay(10);
TempAndHumidity data = readDHTSensorData();
float lux = processLightData();
// 根据传感器返回的错误代码更新全局错误状态变量
if (data.temperature == -999 || data.humidity == -999 || lux == -999) {
globalError = true;
} else {
globalError = false;
}
if (globalError) {
// 如果存在错误,在显示屏上显示错误提示信息,清空原有显示内容
tft.setCursor(0, 0);
tft.fillScreen(ILI9341_RED);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.println("系统出现错误,请检查传感器!");
} else {
displayData(data, lux);
formatAndPrintSerialData(data, lux);
if (data.temperature > 30) { // 当温度超过 30°C 时
digitalWrite(BUZZER_PIN, HIGH); // 打开蜂鸣器
} else {
digitalWrite(BUZZER_PIN, LOW); // 关闭蜂鸣器
}
}
delay(2000);
delay(750);
}