ESP32发送MQTT数据等相关使用模板

使用于23.4.15     23.11.5   

目录

发送MQTT数据模板:

或者(这里以RS485检测土壤N、P、K 为例)

基于ESP32的模块疑难代码

舵机的多角度调节

语音控制4个舵机旋转+多环境数据模块等等等


发送MQTT数据模板:

#include <Arduino.h>

#include <WiFi.h>

#include <PubSubClient.h>

#include <Wire.h>

#include <DHT.h>

#include "SoftwareSerial.h"

#include <ArduinoJson.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#include "DFRobotDFPlayerMini.h"

const char *ssid = "";

const char *password = "";

const char *mqtt_server = ""; // 要连接到的服务器IP

const int mqtt_port = ;               // 要连接到的服务器端口号

const char *mqtt_username = "";       // MQTT服务器账号

const char *mqtt_password = ""; // MQTT服务器密码

const char *mqtt_topic = "topic/01";

void setupWiFi();

void setupMQTT();

WiFiClient espClient;

PubSubClient client(espClient);

void setup()

{

        Serial.begin(9600);        

        setupWiFi();

        setupMQTT();

}

//----------------------------------------------------------------------------------------------

void loop()

{

               

// 发送JSON消息到MQTT

  DynamicJsonDocument jsonDoc(128);           // 动态JSON文档,可以在运行时构建

  JsonObject json = jsonDoc.to<JsonObject>(); // 将文档转换为JSON对象

  // 当前状态和次数

  // json["peopleDetected"] = (peopleDetected > 0) ? 1 : 0;

  // json["detections"] = peopleDetected;

  json["smokeSensorValue"] = smokeSensorValue;

  // json["HuoYan"] = HuoYan ? "0" : "1";

  json["HuoYan"] = val;

  json["WenDu"] = String(temperature, 0); // 格式化温度数据

  json["ShiDu"] = String(humidity, 0);    // 格式化湿度数据

char jsonBuffer[128];

  serializeJson(json, jsonBuffer);

  if (client.connected())

  {

    if (client.publish(mqtt_topic, jsonBuffer))

    {

      Serial.println("成功发布JSON消息到MQTT。");

    }

    else

    {

      Serial.println("无法发布JSON消息到MQTT。");

      // 如果发布失败,尝试重新连接到MQTT代理

      client.disconnect();

      setupMQTT();

    }

  }

  else

  {

    // 如果未连接,尝试重新连接到MQTT代理

    setupMQTT();

  }

  delay(500);

}

//----------------------------------------------------------------------------------------------

void setupWiFi()

{

  delay(10);

  // Connect to Wi-Fi

  Serial.println();

  Serial.print("Connecting to ");

  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)

  {

    delay(500);

    Serial.print(".");

  }

  Serial.println();

  Serial.print("Connected to ");

  Serial.println(ssid);

}

void setupMQTT()

{

  client.setServer(mqtt_server, mqtt_port);

  // client.setCallback(callback);

  // Connect to MQTT

  while (!client.connected())

  {

    Serial.print("Connecting to MQTT...");

    if (client.connect("ESP32Client", mqtt_username, mqtt_password))

    {

      Serial.println("connected");

      // client.publish(mqtt_topic, "ESP32 connected");

    }

    else

    {

      Serial.print("failed with state ");

      Serial.print(client.state());

      delay(2000);

    }

  }

}

或者(这里以RS485检测土壤N、P、K 为例)

// TX 16

// RX 17   R485

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

String data = "{\"\":\"\"}";

#define ADDR 0b0100011

// TX 16

// RX 17   R485

int sense_Pin = 35; // 土壤传感器输入接模拟引脚 A0

const char *ssid = "";               // ESP32连接的WiFi账号

const char *password = "";      // WiFi密码

const char *mqttServer = ""; // 要连接到的服务器IP

const int mqttPort = ;               // 要连接到的服务器端口号

const char *mqttUser = "";           // MQTT服务器账号

const char *mqttPassword = ""; // 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 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("topic/01", 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);

  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("xxx", 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()

{

  client.loop();

  NPK();

  delay(11000);

}

基于ESP32的模块疑难代码

舵机的多角度调节

尝试了很多代码后并不是很好用,最终用的是:

// 舵机部分

// 主要通过rotationDuration转动的毫秒数时间来表示旋转角度 ,350为大半圈

int rotationDuration = 350; // 舵机旋转的持续时间(毫秒)

int pwmChannel1 = 3;        // 使用3号通道,定时器1共有16个通道

void rotateServo(int servoPin, int pwmChannel);

const int servoPin1 = 25;

bool isRunning = true; // 控制舵机是否运行

unsigned long oneDayMillis = 24 * 60 * 60 * 1000; // 1天的毫秒数

//--------------------------------------------

//setup初始化

  // 舵机

  ledcSetup(pwmChannel1, pwmFrequency, pwmResolution); // 设置PWM通道1

  ledcAttachPin(servoPin1, pwmChannel1);               // 将引脚绑定到PWM通道1

// loop

 if (isRunning)

    {

    //   rotateServo(servoPin1, pwmChannel1);

    //   rotateServo(servoPin2, pwmChannel2);

    //   rotateServo(servoPin3, pwmChannel3);

      rotateServo(servoPin4, pwmChannel4);

      isRunning = false;

    }

//函数控制旋转方向

void rotateServo(int servoPin, int pwmChannel)

{

  // 正向旋转

  ledcWrite(pwmChannel, 52);

  delay(rotationDuration);

  // // 停止

  ledcWrite(pwmChannel, 77);

  delay(1000);

  // 反向旋转

  ledcWrite(pwmChannel, 102);

  delay(rotationDuration);

  // // // 停止

  ledcWrite(pwmChannel, 77);

  delay(rotationDuration);

}

语音控制多个舵机旋转+多环境数据模块等等等

附完整代码

#include <Arduino.h>

#include <WiFi.h>

#include <PubSubClient.h>

#include <Wire.h>

#include <DHT.h>

#include "SoftwareSerial.h"

#include <ArduinoJson.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#include "DFRobotDFPlayerMini.h"

const char *ssid = "";

const char *password = "";

// const char *mqtt_server = "broker.emqx.io"; // 要连接到的服务器IP

// const int mqtt_port = 1883;               // 要连接到的服务器端口号

// const char *mqtt_username = "";       // MQTT服务器账号

// const char *mqtt_password = ""; // MQTT服务器密码

// const char *mqtt_topic = "topic/01";

const char *mqtt_server = ""; // 要连接到的服务器IP

const int mqtt_port = ;               // 要连接到的服务器端口号

const char *mqtt_username = "";       // MQTT服务器账号

const char *mqtt_password = ""; // MQTT服务器密码

const char *mqtt_topic = "";

void setupWiFi();

void setupMQTT();

// void callback(char* topic, byte* payload, unsigned int length);

//   //   小一  纸张  废电池  剩菜  尘土

WiFiClient espClient;

PubSubClient client(espClient);

const int infraredPin = 12; // 红外传感器

// OLED屏幕分辨率

Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);

// 火焰 35   用A口

int fire_sensor = 35;

// 舵机部分

int rotationDuration = 350; // 舵机旋转的持续时间(毫秒)

int pwmChannel1 = 3;        // 使用3号通道,定时器1共有16个通道

int pwmChannel2 = 4;        // 使用4号通道

int pwmChannel3 = 5;

int pwmChannel4 = 6;

int pwmFrequency = 50;  // PWM频率为50Hz

int pwmResolution = 10; // PWM分辨率为10位,范围是0-1024

void rotateServo(int servoPin, int pwmChannel);

const int servoPin1 = 25;

const int servoPin2 = 26;

const int servoPin3 = 27;

const int servoPin4 = 14;

int peopleDetected = 0;

bool isRunning = true; // 控制舵机是否运行

// 01、  MQ-2烟雾传感器  34

const int smokeSensorPin = 34;

int smokeSensorValue = 0;

// E18-D80NK 光电传感器

const int sensorPin = 18;       // 光电传感器信号引脚

unsigned long lastHighTime = 0; // 上次检测到高电平的时间

int highCount = 0;              // 高电平计数

int highCount01 = 12;

int highCount02 = 5;

// int highCount03 = 20;

unsigned long oneDayMillis = 24 * 60 * 60 * 1000; // 1天的毫秒数

// 定义 DHT11 传感器的数据引脚

#define DHTPIN 4

// DHT11 传感器类型

#define DHTTYPE DHT11

// 创建 DHT11 对象

DHT dht(DHTPIN, DHTTYPE);

// 读取温度和湿度数据

float temperature;

float humidity;

SoftwareSerial mySoftwareSerial(16, 17);

DFRobotDFPlayerMini myDFPlayer;

void playAudio(int audioFile);

//-------------------------------------------------------------------------------------------

void setup()

{

  // Serial.begin(115200);

  Serial.begin(9600);

  mySoftwareSerial.begin(9600);

  myDFPlayer.begin(mySoftwareSerial);

  myDFPlayer.volume(30);

  // 显示屏

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  display.clearDisplay();

  display.setTextSize(2);

  display.setTextColor(SSD1306_WHITE);

  display.setCursor(0, 0);

  display.display();

  pinMode(sensorPin, INPUT);

  setupWiFi();

  setupMQTT();

  // 火焰

  pinMode(fire_sensor, INPUT); // 接收火焰传感器

  // 舵机

  ledcSetup(pwmChannel1, pwmFrequency, pwmResolution); // 设置PWM通道1

  ledcAttachPin(servoPin1, pwmChannel1);               // 将引脚绑定到PWM通道1

  ledcSetup(pwmChannel2, pwmFrequency, pwmResolution); // 设置PWM通道2

  ledcAttachPin(servoPin2, pwmChannel2);               // 将引脚绑定到PWM通道2

  ledcSetup(pwmChannel3, pwmFrequency, pwmResolution); // 设置PWM通道1

  ledcAttachPin(servoPin3, pwmChannel3);

  ledcSetup(pwmChannel4, pwmFrequency, pwmResolution); // 设置PWM通道1

  ledcAttachPin(servoPin4, pwmChannel4);

  // 初始化 DHT11 传感器

  dht.begin();

}

//-------------------------------------------------------------------------------------------

void loop()

{

  temperature = dht.readTemperature();

  humidity = dht.readHumidity();

  int sensorValue = analogRead(smokeSensorPin);

  float airQuality = map(sensorValue, 0, 4095, 0, 100); // 根据传感器输出值映射到0-100范围

  display.clearDisplay();

  display.setCursor(0, 0);

  display.setTextColor(SSD1306_WHITE);

  display.println("Tem:" + String(temperature));

  display.println("Hum:" + String(humidity) + "%");

  display.println("Air:" + String(airQuality) + "%");

  display.display();

  // int HuoYan = digitalRead(fire_sensor);

  // if (HuoYan)

  // { // 没有检测到火焰,传感器引脚输出高电平

  //   Serial.println("没有检测到火焰。");

  // }

  // else

  // { // 检测到火焰,传感器引脚输出低电平

  //   Serial.println("检测到火焰。");

  //   playAudio(8);

  // }

  // delay(1000); // 火灭后LED多亮1秒

  int val = analogRead(fire_sensor);

  // data = addjson(data, json("fire", String(val)));

  if (val >= 600)

  { // 没有检测到火焰,传感器引脚输出高电平

    Serial.println("火焰传感器未检测到火焰");

  }

  else

  { // 检测到火焰,传感器引脚输出低电平

    Serial.println("火焰传感器检测到火焰");

    playAudio(8);

  }

  if (digitalRead(infraredPin) == HIGH) // 如果红外传感器检测到有人

  {

    Serial.println("Detect:1");

    peopleDetected++;

    playAudio(7);

    if (isRunning)

    {

      rotateServo(servoPin1, pwmChannel1);

      rotateServo(servoPin2, pwmChannel2);

      rotateServo(servoPin3, pwmChannel3);

      rotateServo(servoPin4, pwmChannel4);

      isRunning = false;

    }

  }

  else

  {

    Serial.println("Detect:0");

    isRunning = true; // 设置为true,以允许下一次检测到人时触发旋转

  }

  if (Serial.available() > 0)

  {

    String command = Serial.readString();

    int commandInt = command.toInt(); // 将字符串转换为整数

    //   //   小一  纸张  废电池  剩菜  尘土

    if (commandInt == 1)

    {

      playAudio(5);

    }

    else if (commandInt == 2)

    {

      playAudio(1);

      if (isRunning)

      {

        rotateServo(servoPin1, pwmChannel1);

        isRunning = false;

      }

      isRunning = true;

    }

    else if (commandInt == 3)

    {

      playAudio(2);

      if (isRunning)

      {

        rotateServo(servoPin2, pwmChannel2);

        isRunning = false;

      }

      isRunning = true;

    }

    else if (commandInt == 4)

    {

      playAudio(3);

      if (isRunning)

      {

        rotateServo(servoPin3, pwmChannel3);

        isRunning = false;

      }

      isRunning = true;

    }

    else if (commandInt == 5)

    {

      playAudio(4);

      if (isRunning)

      {

        rotateServo(servoPin4, pwmChannel4);

        isRunning = false;

      }

      isRunning = true;

    }

    else

    {

      // 处理未知命令或错误

      Serial.println("Received unknown command");

    }

  }

  // 读取MQ-2传感器浓度值

  smokeSensorValue = analogRead(smokeSensorPin);

  Serial.print("Smoke Sensor Value: ");

  Serial.println(smokeSensorValue);

  // 光电传感器

  if (digitalRead(sensorPin) == HIGH)

  {

    // 如果检测到高电平,增加高电平计数

    highCount++;

    lastHighTime = millis(); // 更新上次检测到高电平的时间

    Serial.println("GuangDian: 1");

  }

  else

  {

    Serial.println("GuangDian: 0");

  }

  // 检查是否达到20次高电平或超过1天

  if (highCount >= 20 || (millis() - lastHighTime) >= oneDayMillis)

  {

    Serial.println("垃圾可能已满!");

    playAudio(6);

    highCount = 0;

    lastHighTime = millis();

  }

  delay(500); // 每次循环间隔0.5秒

  // --------------------------------------------------------------------------------------------------

  // 发送JSON消息到MQTT

  DynamicJsonDocument jsonDoc(128);           // 动态JSON文档,可以在运行时构建

  JsonObject json = jsonDoc.to<JsonObject>(); // 将文档转换为JSON对象

  // 当前状态和次数

  // json["peopleDetected"] = (peopleDetected > 0) ? 1 : 0;

  // json["detections"] = peopleDetected;

  json["smokeSensorValue"] = smokeSensorValue;

  // json["HuoYan"] = HuoYan ? "0" : "1";

  json["HuoYan"] = val;

  json["WenDu"] = String(temperature, 0); // 格式化温度数据

  json["ShiDu"] = String(humidity, 0);    // 格式化湿度数据

  json["highCount"] = highCount;          // 添加highCount值

  json["highCount01"] = highCount01;      // 添加highCount值

  json["highCount02"] = highCount02;      // 添加highCount值

  // json["highCount03"] = highCount03; // 添加highCount值

  char jsonBuffer[128];

  serializeJson(json, jsonBuffer);

  if (client.connected())

  {

    if (client.publish(mqtt_topic, jsonBuffer))

    {

      Serial.println("成功发布JSON消息到MQTT。");

    }

    else

    {

      Serial.println("无法发布JSON消息到MQTT。");

      // 如果发布失败,尝试重新连接到MQTT代理

      client.disconnect();

      setupMQTT();

    }

  }

  else

  {

    // 如果未连接,尝试重新连接到MQTT代理

    setupMQTT();

  }

  delay(500);

}

//-------------------------------------------------------------------------------------------

void playAudio(int audioFile)

{

  myDFPlayer.playFolder(1, audioFile);

  Serial.println(audioFile);

  delay(1000);

}

void rotateServo(int servoPin, int pwmChannel)

{

  // 正向旋转

  ledcWrite(pwmChannel, 52);

  delay(rotationDuration);

  // 停止

  ledcWrite(pwmChannel, 77);

  delay(1000);

  // 反向旋转

  ledcWrite(pwmChannel, 102);

  delay(rotationDuration);

  // 停止

  ledcWrite(pwmChannel, 77);

  delay(rotationDuration);

}

void setupWiFi()

{

  delay(10);

  // Connect to Wi-Fi

  Serial.println();

  Serial.print("Connecting to ");

  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)

  {

    delay(500);

    Serial.print(".");

  }

  Serial.println();

  Serial.print("Connected to ");

  Serial.println(ssid);

}

void setupMQTT()

{

  client.setServer(mqtt_server, mqtt_port);

  // client.setCallback(callback);

  // Connect to MQTT

  while (!client.connected())

  {

    Serial.print("Connecting to MQTT...");

    if (client.connect("ESP32Client", mqtt_username, mqtt_password))

    {

      Serial.println("connected");

      // client.publish(mqtt_topic, "ESP32 connected");

    }

    else

    {

      Serial.print("failed with state ");

      Serial.print(client.state());

      delay(2000);

    }

  }

}

// void callback(char* topic, byte* payload, unsigned int length) {

// 处理MQTT消息   回调函数

// Serial.print("Message received on topic: ");

// Serial.println(topic);

// Serial.print("Message content: ");

// for (int i = 0; i < length; i++) {

//   Serial.print((char)payload[i]);

// }

// Serial.println();

// // 在这里执行您的操作,根据消息内容执行相应的逻辑

// if (strcmp(topic, "your/mqtt/topic") == 0) {

//   // 处理特定主题的消息

//   if (strcmp((char*)payload, "1") == 0) {

//     // 执行相关操作,例如打开舵机等

//   } else if (strcmp((char*)payload, "0") == 0) {

//     // 执行相关操作,例如关闭舵机等

//   }

// }

// }

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值