器件介绍:
开发板:core ESP32 S3 A10开发板
继电器:一路光耦继电器*2
温湿度传感器:DHT11
气体传感器:MQ2
功能介绍:
- 加入温湿度传感器
- 加入云端可控LED灯
- 加入MQ2气体传感器
- 加入控制电机继电器
- 加入报警流水灯继电器
- 加入报警蜂鸣器效果
- 任意阈值超过设定范围,出发报警效果
- 云端显示温度湿度有害气体百分比,可控led按键
连线方式:
LCD
9, 8, 3, 5, 6, 7—–>rs, enable, d4, d5, d6, d7
Vo、R/W、C–>GND
A—>220欧姆电阻—>5V
OLED
11—->SDA
12—->SCL
DHT11
4——->data
MQ-2
10号引脚
蜂鸣器
一边17引脚,一边GND
电机继电器1
2号引脚,供电12V
流水灯继电器2
18号引脚,供电5V
LED
1号引脚
程序部分:
main.cpp
```main.cpp
/*
1. 加入温湿度传感器
2. 加入可控LED灯
3. 加入MQ2气体传感器
4. 加入控制电机继电器
5. 加入报警流水灯继电器
6. 加入报警蜂鸣器效果
7. 任意阈值超过设定范围,出发报警效果
*/
#include <Arduino.h>
#include <WiFi.h>
#include "PubSubClient.h" ////A client library for MQTT messaging.
#include "DHT.h"
#include <ArduinoJson.h>
#include <LiquidCrystal.h> // includes the LiquidCrystal Library
#include <Adafruit_SSD1306.h> // 包含SSD1306 OLED屏幕库
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define LED 1
#define LED2 2 //电机继电器1
#define LED3 18 //流水灯继电器2
#define buzzerPin 17 // 蜂鸣器连接到数字引脚17
#define DHTPIN 4 // Defines pin number to which the sensor is connected
LiquidCrystal lcd(9, 8, 3, 5, 6, 7); // Creates an LCD object. Parameters: (rs, enable, d4, d5, d6, d7)
// 定义MQ-2烟雾传感器连接的模拟输入引脚
const int smokeSensorPin = 10;
// 定义OLED屏幕的宽度和高度(以像素为单位)
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// 设置OLED显示屏的I2C地址(通常是0x3C或者0x3D)
#define OLED_RESET -1 // 由于ESP32足够智能,可以设置为 -1 使用默认复位引脚
// 创建一个Adafruit_SSD1306对象。这里传递屏幕宽度、高度、I2C总线指针和复位引脚
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define DHTTYPE DHT11 // DHT 22
DHT dht(DHTPIN, DHTTYPE); // Creats a DHT object
/* 连接WIFI SSID和密码 */
#define WIFI_SSID "abd"
#define WIFI_PASSWD "00000010"
/* 设备的三元组信息*/
#define PRODUCT_KEY "a1LG0hp3NmR"
#define DEVICE_NAME "LittleCoke"
#define DEVICE_SECRET "50d122d3e0ec5af748ccf8253f6b6a04"
#define REGION_ID "cn-shanghai"
/* 线上环境域名和端口号,不需要改 */
#define MQTT_SERVER PRODUCT_KEY".iot-as-mqtt."REGION_ID ".aliyuncs.com"
#define MQTT_PORT 1883
#define MQTT_USRNAME DEVICE_NAME"&"PRODUCT_KEY
#define CLIENT_ID "a1LG0hp3NmR.LittleCoke|securemode=2,signmethod=hmacsha256,timestamp=1712915665471|"
#define MQTT_PASSWD "07de62017cbc5135916c5f3d205cd40fe41c7e4f0f180cf62e094908d8591a8c"
//宏定义订阅主题
#define ALINK_BODY_FORMAT "{\"id\":\"LittleCoke\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
const char* TOPIC = "/sys/a1uGtexAdr7/LittleCoke/thing/service/property/set";
unsigned long lastMs = 0;
WiFiClient espClient;
PubSubClient client(espClient);
// 函数声明
void alarmEffect();
float soil_data ;
float tep;
float smokePercentage;
//连接wifi
void wifiInit()
{
WiFi.begin(WIFI_SSID, WIFI_PASSWD);
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
Serial.println("WiFi not Connect");
}
}
//mqtt连接
void mqttCheckConnect()
{
while (!client.connected())
{
Serial.println("Connecting to MQTT Server ...");
if(client.connect(CLIENT_ID, MQTT_USRNAME, MQTT_PASSWD))
{
Serial.println("MQTT Connected!");
}
else{
Serial.print("MQTT Connect err:");
Serial.println(client.state());
delay(5000);
}
}
}
#include <Arduino.h> // 引入Arduino库以使用random函数
void alarmEffect() {
// 报警效果
for (int i = 0; i < 10; i++) {
tone(buzzerPin, 1000); // 1000Hz频率
delay(random(30, 70)); // 随机延迟时间
noTone(buzzerPin);
delay(random(30, 70)); // 随机延迟时间
}
}
//上传温湿度、二氧化碳浓度
void mqttIntervalPost()
{
char param[32];
char jsonBuf[128];
//====================upload humidity======================================//
soil_data = dht.readHumidity();
sprintf(param, "{\"humidity\":%2f}", soil_data);
sprintf(jsonBuf, ALINK_BODY_FORMAT, param);
Serial.println(jsonBuf);
boolean b = client.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
if(b){
Serial.println("publish Humidity success");
}else{
Serial.println("publish Humidity fail");
}
//====================Upload temperature======================================//
tep =dht.readTemperature();
sprintf(param, "{\"temperature\":%2f}",tep);
sprintf(jsonBuf, ALINK_BODY_FORMAT, param);
Serial.println(jsonBuf);
boolean c = client.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
if(c){
Serial.println("publish Temperature success");
}else{
Serial.println("publish Temperature fail");
}
//====================upload qiti======================================//
int smokeValue = analogRead(smokeSensorPin); // 读取MQ-2烟雾传感器的模拟值
// 将模拟值转换为百分比,这里的4095是ESP32 ADC的最大值
smokePercentage = (smokeValue / 4095.0) * 100.0;
sprintf(param, "{\"smoke\":%2f}", smokePercentage);
sprintf(jsonBuf, ALINK_BODY_FORMAT, param);
Serial.println(jsonBuf);
boolean d = client.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
if(d){
Serial.println("publish smoke success");
}else{
Serial.println("publish smoke fail");
}
const float TempThreshold = 30.0; // 设置温度阈值
const float HumThreshold = 60.0; // 设置湿度阈值
const float smokeThreshold = 60.0; // 设置烟雾阈值
if ((smokePercentage > smokeThreshold) || (soil_data > HumThreshold) || (tep > TempThreshold)) {
digitalWrite(LED2,HIGH);
digitalWrite(LED3,HIGH);
alarmEffect();
}
else{
digitalWrite(LED2,LOW);
digitalWrite(LED3,LOW);
}
}
//回调函数
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic); // 打印主题信息
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]); // 打印主题内容
}
Serial.println();
DynamicJsonDocument doc(1024); //创建了一个名为 doc 的动态 JSON 文档
deserializeJson(doc, String((char *)payload)); //从一个名为 payload 的数据中解析 JSON 数据并将其填充到 doc 中
// DynamicJsonDocument params = doc["params"];
if(doc["params"].containsKey("deng"))
{
Serial.println("GOT DENG CMD");
digitalWrite(LED, doc["params"]["deng"]);
}
}
void setup()
{
pinMode(LED, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(buzzerPin, OUTPUT);
Serial.begin(115200);
dht.begin();
wifiInit();
client.setServer(MQTT_SERVER, MQTT_PORT); /* 连接MQTT服务器 */
client.setCallback(callback); //设定回调方式,当ESP32收到订阅消息时会调用此方法
digitalWrite(LED,LOW);
digitalWrite(LED2,LOW);
digitalWrite(LED3,LOW);
digitalWrite(buzzerPin,LOW);
lcd.begin(16,2); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display
pinMode(smokeSensorPin, INPUT); // 设置MQ-2传感器所连接的引脚为输入模式
// 自定义I2C引脚
Wire.begin(11, 12); // SDA引脚设为11, SCL引脚设为12
// 初始化OLED屏幕,传入电源类型和I2C地址
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306初始化失败");
for(;;); // 如果初始化失败,无限循环停在这里
}
display.clearDisplay(); // 清除屏幕内容到默认空状态
// 在屏幕上绘制一个像素点
display.drawPixel(10, 10, SSD1306_WHITE);
// 设置文本大小和颜色
display.setTextSize(1); // 文本大小为1
display.setTextColor(SSD1306_WHITE); // 文本颜色为白色
// 设置文本开始位置
display.setCursor(0,0);
display.println("Hello! ESP32!"); // 在屏幕上打印文本
// 将上述内容更新到显示屏上
display.display();
}
void loop() {
if (millis() - lastMs >= 5000) {
lastMs = millis();
mqttCheckConnect();
mqttIntervalPost();
}
client.loop();
lcd.setCursor(0,0);
lcd.printf("Temp:%.2f ", tep);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0,1);
lcd.printf("Humi:%.2f ", soil_data);
lcd.print("%RH");
// 在OLED屏幕上更新显示
display.clearDisplay(); // 清除旧的显示内容
display.setCursor(0, 10);
display.print("Temp: ");
display.print(tep, 2);
display.print((char)223);
display.println("C");
display.setCursor(0, 20);
display.print("Humi: ");
display.print(soil_data, 2);
display.println("%RH");
display.setCursor(0, 30);
display.print("Smoke: ");
display.print(smokePercentage, 2);
display.println("%");
display.display(); // 实际更新显示内容
delay(2000);
}
platformio.ini
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
lib_deps =
knolleary/PubSubClient@^2.8
adafruit/Adafruit Unified Sensor@^1.1.13
beegee-tokyo/DHT sensor library for ESPx@^1.19
adafruit/DHT sensor library@^1.4.4
bblanchon/ArduinoJson@^6.21.3
arduino-libraries/LiquidCrystal@^1.0.7
adafruit/Adafruit SSD1306@^2.5.9
应用方法:
修改注释为/* 连接WIFI SSID和密码 */的部分
修改注释为/* 设备的三元组信息*/的部分
修改:CLIENT_ID
修改:MQTT_PASSWD
修改:TOPIC