【Follow me第二季第2期】--进阶扩展任务--UNO R4 温湿度传感器--HA显示--MQTTX显示
[复制链接]
演示视频: task3
UNO R4的温湿度传感器,HA显示:
1、任务目标
(1)UNO R4读取温湿度传感器数据。
(2)搭建HA服务器,采用docker方式。
(3)通过ESP32-S3模块发送,HA服务端显示当前温湿度。
2、参考文档
(1)https://docs.arduino.cc/tutorials/uno-r4-wifi/qwiic/
(2)https://docs.arduino.cc/tutorials/uno-r4-wifi/wifi-examples/
(3)https://zhuanlan.zhihu.com/p/421109780
(4)https://www.emqx.com/zh/blog/the-easiest-guide-to-getting-started-with-mqtt
3、分析
(1)MQTT是一种轻量级、基于发布-订阅模式的消息传输协议。
一个典型的MQTT示意图如下图所示。图中涉及以下几个关键概念:
- MQTT客户端:发送或接受消息的设备,如图,左侧有1个客户端,右侧有3个客户端。
- MQTT broker:如图中绿色六边形,可以理解为消息传输的中心或者消息传输的中转站。所有消息都先到MQTT broker,在到客户端。
- 主题:发送或者接受消息时,为了区分消息内容所设置的主题。如图中 Temperature 就是一个主题,用于传输温度数据。
4、代码
#include <WiFiS3.h>
#include <UnoWiFiDevEd.h>
#include "Adafruit_SHT4x.h"
#include <Arduino_JSON.h>
#include <ArduinoMqttClient.h>
#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_AVR_UNO_WIFI_REV2)
#include <WiFiNINA.h>
#elif defined(ARDUINO_SAMD_MKR1000)
#include <WiFi101.h>
#elif defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h>
#elif defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_GIGA) || defined(ARDUINO_OPTA)
#include <WiFi.h>
#elif defined(ARDUINO_PORTENTA_C33)
#include <WiFiC3.h>
#elif defined(ARDUINO_UNOR4_WIFI)
#include <WiFiS3.h>
#endif
Adafruit_SHT4x sht4 = Adafruit_SHT4x();
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = "wifi_name"; // your network SSID (name)
char pass[] = "wifi_password"; // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS; // the WiFi radio's status
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = "broker.emqx.io";
int port = 1883;
const char topic[] = "homeassistant/sensor/room111/sht40";
const long interval = 1000;
unsigned long previousMillis = 0;
JSONVar jsonDat;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
// you're connected now, so print out the data:
Serial.print("You're connected to the network");
printCurrentNet();
printWifiData();
Serial.println("Find WIFI");
Serial.println("Adafruit SHT4x test");
if (! sht4.begin(&Wire1)) {
Serial.println("Couldn't find SHT4x");
while (1) delay(1);
}
Serial.println("Found SHT4x sensor");
Serial.print("Serial number 0x");
Serial.println(sht4.readSerial(), HEX);
// You can have 3 different precisions, higher precision takes longer
sht4.setPrecision(SHT4X_HIGH_PRECISION);
switch (sht4.getPrecision()) {
case SHT4X_HIGH_PRECISION:
Serial.println("High precision");
break;
case SHT4X_MED_PRECISION:
Serial.println("Med precision");
break;
case SHT4X_LOW_PRECISION:
Serial.println("Low precision");
break;
}
// You can have 6 different heater settings
// higher heat and longer times uses more power
// and reads will take longer too!
sht4.setHeater(SHT4X_NO_HEATER);
switch (sht4.getHeater()) {
case SHT4X_NO_HEATER:
Serial.println("No heater");
break;
case SHT4X_HIGH_HEATER_1S:
Serial.println("High heat for 1 second");
break;
case SHT4X_HIGH_HEATER_100MS:
Serial.println("High heat for 0.1 second");
break;
case SHT4X_MED_HEATER_1S:
Serial.println("Medium heat for 1 second");
break;
case SHT4X_MED_HEATER_100MS:
Serial.println("Medium heat for 0.1 second");
break;
case SHT4X_LOW_HEATER_1S:
Serial.println("Low heat for 1 second");
break;
case SHT4X_LOW_HEATER_100MS:
Serial.println("Low heat for 0.1 second");
break;
}
// set name
mqttClient.setUsernamePassword("test_sht40", "test_sht40");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("You're connected to the MQTT broker!");
Serial.println();
}
void loop() {
// to avoid having delays in loop, we'll use the strategy from BlinkWithoutDelay
// see: File -> Examples -> 02.Digital -> BlinkWithoutDelay for more info
unsigned long currentMillis = millis();
mqttClient.poll();
if (currentMillis - previousMillis >= interval) {
// save the last time a message was sent
previousMillis = currentMillis;
sensors_event_t humidity, temp;
uint32_t timestamp = millis();
sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
Serial.print("Temperature: ");
Serial.print(temp.temperature);
Serial.println(" degrees C");
Serial.print("Humidity: ");
Serial.print(humidity.relative_humidity);
Serial.println("% rH");
printCurrentNet();
int tempeture = temp.temperature;
int humi = humidity.relative_humidity;
jsonDat["tempeture"] = tempeture;
jsonDat["humidity"] = humi;
String strData = JSON.stringify(jsonDat);
// send message, the Print interface can be used to set the message contents
mqttClient.beginMessage(topic);
mqttClient.print(strData);
mqttClient.endMessage();
}
}
void printWifiData() {
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}
void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);
// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}
void printMacAddress(byte mac[]) {
for (int i = 0; i < 6; i++) {
if (i > 0) {
Serial.print(":");
}
if (mac[i] < 16) {
Serial.print("0");
}
Serial.print(mac[i], HEX);
}
Serial.println();
}
|