搜索代码

ESP32教程46/55 - 使用HiveMQ MQTT进行远程温度监控 | SunFounder的ESP32套件

ESP32教程46/55 - 使用HiveMQ MQTT进行远程温度监控 | SunFounder的ESP32套件

在本教程中,我们将使用ESP32和MQTT协议创建一个远程温度监控系统。该项目允许我们将温度数据发布到MQTT代理,并通过网页界面远程控制LED。通过按下按钮,我们可以将温度读数发送到云端,还可以接收命令来打开或关闭LED。

esp32-47-mqt-1

ESP32是一款功能强大的微控制器,内置Wi-Fi和蓝牙,非常适合物联网(IoT)应用。在此设置中,我们将使用NTC热敏电阻测量温度,使用按钮触发读数,并使用LED指示状态。数据将发送到HiveMQ(一个流行的MQTT代理),可在远程访问(视频中00:45处)。

esp32-47-mqt-2

硬件说明

对于此项目,我们将使用以下组件:

  • ESP32微控制器:该板作为中央处理单元,处理Wi-Fi连接和MQTT通信。
  • NTC热敏电阻:该温度传感器根据温度改变其电阻。它提供ESP32可读取的模拟信号,以确定当前温度。
  • LED:该发光二极管将用于根据通过MQTT接收的命令指示状态。
  • 按钮:该按钮将触发ESP32读取温度并将其发布到MQTT代理。

数据手册详情

制造商 SunFounder
零件编号 ESP32
逻辑/IO电压 3.3 V
电源电压 5 V(通过USB)
输出电流(每通道) 最大12 mA
PWM频率指导 最高40 kHz
输入逻辑阈值 0.3 V(低),2.4 V(高)
热限制 -40至85 °C
封装 ESP32-WROOM-32

 

  • 确保正确的电压电平以避免损坏。
  • 为按钮使用上拉电阻以确保稳定的读数。
  • 去耦电容有助于稳定电源。
  • 注意热敏电阻的接线以避免错误读数。
  • 验证您的MQTT代理详细信息以确保成功连接。

接线说明

esp32-47-mqtt-wiring

要连接组件,首先连接NTC热敏电阻。将热敏电阻的一个引脚连接到ESP32上的3.3 V电源。另一个引脚连接到ESP32上的引脚36,并且还应连接一个10 kΩ电阻,该电阻再连接到地。这创建了一个分压器,使ESP32能够读取热敏电阻的电阻值。

接下来,连接LED。LED的较长引脚(阳极)通过220 Ω电阻连接到ESP32上的引脚4,而较短的引脚(阴极)连接到地。对于按钮,将一侧连接到3.3 V,另一侧连接到ESP32上的引脚14。此外,从按钮引脚连接一个10 kΩ电阻到地,以确保按钮未按下时保持稳定的低电平状态。

安装所需库

这里使用了PubSubClient库,您可以从库管理器中安装它。

esp32-47-mqtt-library

代码示例与讲解

在设置中,我们初始化串行通信,设置Wi-Fi连接,并配置MQTT服务器。以下是设置代码的片段:

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

这部分代码建立了与Wi-Fi网络的连接并设置了MQTT服务器。按钮和LED的引脚模式也在此处配置。

循环函数持续检查按钮状态,并在按下时发布温度数据。以下是循环中的重点摘录:

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  if (digitalRead(buttonPin)) {
    long now = millis();
    if (now - lastMsg > 5000) {
      lastMsg = now;
      char tempString[8];
      dtostrf(thermistor(), 1, 2, tempString);
      client.publish("SF/TEMP", tempString);
    }
  }
}

在此循环中,我们检查ESP32是否连接到MQTT代理。如果按下按钮,它会从热敏电阻读取温度并每5秒发布到主题"SF/TEMP"。

演示/预期效果

当项目设置并运行后,按下按钮会将当前温度发布到MQTT代理。您可以从任何MQTT客户端监控此数据。此外,您可以发送消息来控制LED;发送“on”将点亮它,而“off”将关闭它。请在视频15:30处观察预期行为,其中每次按下按钮后都会显示温度读数。

视频时间戳

  • 00:00 开始
  • 2:05 项目介绍
  • 7:06 免费的HiveMQ服务
  • 7:56 接线说明
  • 11:11 Arduino代码说明
  • 18:46 在Arduino IDE中选择ESP32开发板和COM端口
  • 20:30 HiveMQ Free代理演示

图像

esp32-47-mqt-1
esp32-47-mqt-1
esp32-47-mqt-2
esp32-47-mqt-2
esp32-47-mqtt-library
esp32-47-mqtt-library
esp32-47-mqtt-wiring
esp32-47-mqtt-wiring
847-ESP32 Tutorial 46/55- Arduino code for IoT Communication with MQTT
语言: C++
/*
 * :ref: https://randomnerdtutorials.com/esp32-mqtt-publish-subscribe-arduino-ide/  
 * https://docs.sunfounder.com/projects/kepler-kit/en/latest/iotproject/5.mqtt_pub.html
 */
#include <WiFi.h>
#include <PubSubClient.h>
 // #include <Wire.h>

 // 用您的SSID/密码组合替换下列变量。
const char* ssid = "SSID";
const char* password = "PASSWORD";

 // 添加您的 MQTT 代理地址,例如:
const char* mqtt_server = "broker.hivemq.com";
const char* unique_identifier = "sunfounder-client-sdgvsda";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
int value = 0;


 // LED引脚
const int ledPin = 4;
const int buttonPin = 14;

 // 当你连接到WIFI时,只有36、39、34、35、32、33引脚可以用于模拟读取。
 // 定义常量
const int thermistorPin = 36; // 连接到热敏电阻的引脚
const float referenceVoltage = 3.3;
const float referenceResistor = 10000; // 电阻值(10k)
const float beta = 3950; // 贝塔值(典型值)
const float nominalTemperature = 25; // 计算温度系数的名义温度
const float nominalResistance = 10000; // 在名义温度下的电阻值



void setup() {
  Serial.begin(115200);

 // 默认设置
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void setup_wifi() {
  delay(10);
 // 我们首先连接到一个WiFi网络。
  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.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;

  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

 // 如果在"SF/LED"主题上收到消息,你需要检查该消息是"开"还是"关"。
 // 根据消息更改输出状态。
  if (String(topic) == "SF/LED") {
    Serial.print("Changing state to ");
    if (messageTemp == "on") {
      Serial.println("on");
      digitalWrite(ledPin, HIGH);
    } else if (messageTemp == "off") {
      Serial.println("off");
      digitalWrite(ledPin, LOW);
    }
  }
}

void reconnect() {
 // 循环直到我们重新连接
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
 // 尝试连接
    if (client.connect(unique_identifier)) {
      Serial.println("connected");
 // 订阅
      client.subscribe("SF/LED");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
 // 请在重试之前等待5秒。
      delay(5000);
    }
  }
}

float thermistor() {
  int adcValue = analogRead(thermistorPin); // 读取ADC值
  float voltage = (adcValue * referenceVoltage) / 4095.0; // 计算电压
  float resistance = (voltage * referenceResistor) / (referenceVoltage - voltage); // 使用更新的配置计算热敏电阻电阻值

 // 使用贝塔参数方程计算温度
  float tempK = 1 / (((log(resistance / nominalResistance)) / beta) + (1 / (nominalTemperature + 273.15)));

  float tempC = tempK - 273.15; // 获取摄氏温度
  float tempF = 1.8 * tempC + 32.0; // 获取华氏温度

 // 打印温度
  Serial.print("Temp: ");
  Serial.println(tempC);
  delay(200); // 等待200毫秒
  return tempC;
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

 // 如果按钮被按下,发布温度到主题 "SF/TEMP"
  if (digitalRead(buttonPin)) {
    long now = millis();
    if (now - lastMsg > 5000) {
      lastMsg = now;
      char tempString[8];
      dtostrf(thermistor(), 1, 2, tempString);
      client.publish("SF/TEMP", tempString);
    }
  }
}

文件📁

没有可用的文件。