ESP32实现连接服务器传输温湿度等数据

#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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值