#include <Arduino.h>
#include <Wire.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include "DHT.h"
#include <HardwareSerial.h>
#include <BH1750.h>
unsigned char item[8] = {0x01, 0x03, 0x00, 0x1E, 0x00, 0x03, 0x65, 0xCD};
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
// 定义温湿度全局变量
float t;
float h;
// 火焰传感器
int val;
int fire_sensor = 34;
String data = "{\"\":\"\"}";
#define ADDR 0b0100011
int L = 0; // 初始化光照值
int value = 0; // 初始化变量value
// TX 16
// RX 17 R485
int sense_Pin = 35; // 土壤传感器输入接模拟引脚 A0
const char *ssid = "XXXXXX"; // ESP32连接的WiFi账号
const char *password = "XXXXXX"; // WiFi密码
const char *mqttServer = "XXXXXX"; // 要连接到的服务器IP
const int mqttPort = 1883; // 要连接到的服务器端口号
const char *mqttUser = "XXXXXX"; // MQTT服务器账号
const char *mqttPassword = "XXXXXX"; // MQTT服务器密码
WiFiClient espClient; // 定义wifiClient实例
PubSubClient client(espClient); // 定义PubSubClient的实例
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.print("来自订阅的主题:"); // 串口打印:来自订阅的主题:-
Serial.println(topic); // 串口打印订阅的主题
Serial.print("信息:"); // 串口打印:信息:
for (int i = 0; i < length; i++) // 使用循环打印接收到的信息
{
Serial.print((char)payload[i]);
}
Serial.println();
Serial.println("-----------------------");
}
// void pubMQTTmsg(String topic, String str)
// {
// static int value; // 客户端发布信息用数字
// // 客户端发布信息的主题名称
// // 建立发布主题。主题名称以Taichi-Maker-为前缀,后面添加设备的MAC地址。
// // 这么做是为确保不同用户进行MQTT信息发布时,ESP8266客户端名称各不相同,
// String topicString = topic;
// char publishTopic[topicString.length() + 1];
// strcpy(publishTopic, topicString.c_str());
// // 建立发布信息。信息内容以Hello World为起始,后面添加发布次数。
// String messageString = str;
// char publishMsg[messageString.length() + 1];
// strcpy(publishMsg, messageString.c_str());
// // 实现ESP8266向主题发布信息
// if (client.publish(publishTopic, publishMsg))
// {
// Serial.println("Publish Topic:");
// Serial.println(publishTopic);
// Serial.println("Publish message:");
// Serial.println(publishMsg);
// }
// else
// {
// Serial.println("Message Publish Failed.");
// }
// }
// String json(String key, String value)
// {
// return "{\"" + key + "\":\"" + value + "\"}";
// }
// String addjson(String json1, String json2)
// {
// return json1.substring(0, json1.length() - 1) + "," + json2.substring(1);
// }
void dht11()
{
h = dht.readHumidity();
t = dht.readTemperature(); // 将湿度值赋给hum
Serial.print("Tempeature:"); // 打印出Tempeature:
Serial.println(t); // 打印温度结果
Serial.print("Humidity:"); // 打印出Humidity:
Serial.print(h); // 打印出湿度结果
Serial.println("%"); // 打印出
String temperature = String(t);
String humidity = String(h);
// 构建一个 JSON 格式的payload的字符串
String payload = "{";
payload += "\"temperature\":";
payload += temperature;
payload += ",";
payload += "\"humidity\":";
payload += humidity;
payload += "}";
// Send payload
char attributes[100];
payload.toCharArray(attributes, 100);
// boolean publish(const char* topic, const char* payload);
client.publish("plant/01", attributes);
Serial.print("[publish]-->>");
Serial.println(attributes);
}
void light_w()
{
L = lightMeter.readLightLevel();
String light = String(L);
// 构建一个 JSON 格式的payload的字符串
String payload = "{";
payload += "\"light\":";
payload += L;
payload += "}";
// Send payload
char attributes[100];
payload.toCharArray(attributes, 100);
// boolean publish(const char* topic, const char* payload);
client.publish("plant/02", attributes);
Serial.print("[publish]-->>");
Serial.println(attributes);
}
void flame()
{
val = analogRead(fire_sensor);
String fire = String(val);
// 构建一个 JSON 格式的payload的字符串
String payload = "{";
payload += "\"fire\":";
payload += val;
payload += "}";
// Send payload
char attributes[100];
payload.toCharArray(attributes, 100);
// boolean publish(const char* topic, const char* payload);
client.publish("plant/03", attributes);
Serial.print("[publish]-->>");
Serial.println(attributes);
if (val >= 600)
{ // 没有检测到火焰,传感器引脚输出高电平
Serial.println("火焰传感器未检测到火焰");
}
else
{ // 检测到火焰,传感器引脚输出低电平
Serial.println("火焰传感器检测到火焰");
}
}
void NPK()
{
String data = "";
char buff[128]; // 定义存储传感器数据的数组
String info[11];
for (int i = 0; i < 8; i++)
{ // 发送测温命令
Serial2.write(item[i]); // write输出
}
delay(100); // 等待测温数据返回
data = "";
while (Serial2.available())
{ // 从串口中读取数据
unsigned char in = (unsigned char)Serial2.read(); // read读取
// Serial.print(in, HEX);
// Serial.print(',');
data += in;
data += ',';
}
if (data.length() > 0)
{ // 先输出一下接收到的数据
// Serial.print(data.length());
// Serial.println();
// Serial.println(data);
int commaPosition = -1;
// 用字符串数组存储
for (int i = 0; i < 11; i++)
{
commaPosition = data.indexOf(',');
if (commaPosition != -1)
{
info[i] = data.substring(0, commaPosition);
data = data.substring(commaPosition + 1, data.length());
}
else
{
if (data.length() > 0)
{
info[i] = data.substring(0, commaPosition);
}
}
}
}
Serial.print("氮元素含量:");
Serial.print(info[4]);
Serial.println("mg");
Serial.print("磷元素含量:");
Serial.print(info[6]);
Serial.println("mg");
Serial.print("钾元素含量:");
Serial.print(info[8]);
Serial.println("mg");
String N = String(info[4]);
String P = String(info[6]);
String K = String(info[8]);
// 构建一个 JSON 格式的payload的字符串
String payload = "{";
payload += "\"N\":";
payload += N;
payload += ",";
payload += "\"P\":";
payload += P;
payload += ",";
payload += "\"K\":";
payload += K;
payload += "}";
// Send payload
char attributes[100];
payload.toCharArray(attributes, 100);
// boolean publish(const char* topic, const char* payload);
client.publish("plant/04", attributes);
Serial.print("[publish]-->>");
Serial.println(attributes);
}
void soil_dht()
{
value = analogRead(sense_Pin); // 模拟数据读取(A0脚输入的数据)
value = value / 100; // 上面的value值除以十赋值给value
Serial.print(value);
Serial.println("%");
String soil_humidity = String(value);
// 构建一个 JSON 格式的payload的字符串
String payload = "{";
payload += "\"soil_humidity\":";
payload += soil_humidity;
payload += "}";
// Send payload
char attributes[100];
payload.toCharArray(attributes, 100);
// boolean publish(const char* topic, const char* payload);
client.publish("plant/05", attributes);
Serial.print("[publish]-->>");
Serial.println(attributes);
}
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(sense_Pin, INPUT);
Serial2.begin(9600);
dht.begin();
Wire.begin();
lightMeter.begin();
while (WiFi.status() != WL_CONNECTED) // 若WiFi接入成功WiFi.status()会返回 WL_CONNECTED
{
Serial.println("连接wifi中"); // 串口输出:连接wifi中
WiFi.begin(ssid, password); // 接入WiFi函数(WiFi名称,密码)重新连接wif
delay(1500); // 若尚未连接WiFi,则进行重连WiFi的循环
}
Serial.println("wifi连接成功"); // 连接wifi成功之后会跳出循环,串口并输出:wifi连接成功
client.setServer(mqttServer, mqttPort); // MQTT服务器连接函数(服务器IP,端口号)
client.setCallback(callback); // 设定回调方式,当ESP32收到订阅消息时会调用此方法
while (!client.connected()) // 是否连接上MQTT服务器
{
Serial.println("连接服务器中"); // 串口打印:连接服务器中
if (client.connect("ESP32_wang", mqttUser, mqttPassword)) // 如果服务器连接成功
{
Serial.println("服务器连接成功"); // 串口打印:服务器连接成功
}
else
{
Serial.print("连接服务器失败"); // 串口打印:连接服务器失败
Serial.print(client.state()); // 重新连接函数
delay(2000);
}
// }
client.subscribe("plant/01"); // 连接MQTT服务器后订阅主题
Serial.print("已订阅主题,等待主题消息...."); // 串口打印:已订阅主题,等待主题消息
client.publish("plant/01", "Hello from ESP32"); // 向服务器发送的信息(主题,内容)
pinMode(fire_sensor, INPUT); // 接收火焰传感器
}
}
void loop()
{
// put your main code here, to run repeated
dht11();
flame();
light_w();
client.loop();
NPK();
soil_dht();
delay(11000);
}
ESP32实现连接服务器传输温湿度等数据
于 2023-10-30 20:00:17 首次发布