# V0.1 完成mqtt连接发送

This commit is contained in:
jxh
2025-03-20 13:33:27 +08:00
commit 21d5bb5147
7 changed files with 330 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

10
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

37
include/README Normal file
View File

@ -0,0 +1,37 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the convention is to give header files names that end with `.h'.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README Normal file
View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into the executable file.
The source code of each library should be placed in a separate directory
("lib/your_library_name/[Code]").
For example, see the structure of the following example libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
Example contents of `src/main.c` using Foo and Bar:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
The PlatformIO Library Dependency Finder will find automatically dependent
libraries by scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

18
platformio.ini Normal file
View File

@ -0,0 +1,18 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp12e]
platform = espressif8266
board = esp12e
framework = arduino
monitor_speed = 115200
lib_deps =
bblanchon/ArduinoJson@^7.3.1
knolleary/PubSubClient@^2.8

203
src/main.cpp Normal file
View File

@ -0,0 +1,203 @@
#include <Arduino.h>
#include <ArduinoJson.h> // JSON解析库推荐V6+
#include <ESP8266WiFiMulti.h> // 多WiFi连接支持
#include <PubSubClient.h> // MQTT客户端
ESP8266WiFiMulti wifiMulti; // 多WiFi连接实例
WiFiClient espClient;
PubSubClient mqttClient (espClient); // MQTT客户端实例
void parseJSON (String jsonStr); // JSON解析函数
void serialEvent (); // 串口接收中断处理函数
void mqtt_callback (char *topic, byte *payload,
unsigned int length); // MQTT消息回调函数
void publishSensorData (); // MQTT发布函数
void reconnectMQTT (); // MQTT重连函数
void checkWifiConnection (); // WiFi连接检查函数
// MQTT相关配置信息
const char *mqtt_broker_addr = "mqtt.lovelyqi.cn"; // 服务器地址
const uint16_t mqtt_broker_port = 1883; // 服务端口号
const char *mqtt_username = "wireless"; // 账号(非必须)
const char *mqtt_password = "charge"; // 密码(非必须)
const uint16_t mqtt_client_buff_size = 4096; // 客户端缓存大小(非必须)
String mqtt_client_id = "wireless_charge_client"; // 客户端ID
const char *mqtt_topic_pub = "esp32/wireless_charge/pub"; // 需要发布到的主题
const char *mqtt_topic_sub = "esp32/wireless_charge/sub"; // 需要订阅的主题
// 定义SensorData结构体
struct SensorData
{
float voltage;
float current;
float power;
float temp;
float humidity;
};
SensorData sensorData; // 声明一个SensorData类型的全局变量
// 初始化函数
void
setup ()
{
Serial.begin (115200);
Serial.println ("");
wifiMulti.addAP ("TP-F1D4", "15579241521");
// wifiMulti.addAP ("WiFi_SSID2", "password2"); // 可扩展多个
while (wifiMulti.run () != WL_CONNECTED)
{
delay (500);
Serial.print (".");
}
Serial.println ("wiFi connected");
Serial.print ("IP address: ");
Serial.println (WiFi.localIP ());
// 设置MQTT客户端
mqttClient.setServer (mqtt_broker_addr, mqtt_broker_port);
// mqttClient.setBufferSize (mqtt_client_buff_size);
mqttClient.setCallback (mqtt_callback);
}
void
loop ()
{
unsigned long currentMillis = millis (); // 读取当前时间
// 1. 处理串口数据接收
if (Serial.available () > 0)
{
String jsonStr = Serial.readStringUntil ('\n');
if (jsonStr.startsWith ("{"))
{
parseJSON (jsonStr);
}
}
Serial.println ("Serial read Done");
// 2. 维护MQTT连接
if (!mqttClient.connected ())
{
reconnectMQTT (); // MQTT重连函数
}
// mqttClient.loop (); // 维持MQTT心跳
Serial.println ("mqttClient.connected()");
// 3. 定时上传数据10秒间隔
static unsigned long lastUpload = 0;
if (millis () - lastUpload > 10000)
{
publishSensorData ();
lastUpload = millis ();
}
// 4. 处理低功耗需求
#ifdef LOW_POWER_MODE
ESP.deepSleep (30e6); // 30秒深度睡眠
#endif
delay (100);
}
// JSON解析函数
void
parseJSON (String jsonStr)
{
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson (doc, jsonStr);
if (!error)
{
sensorData.voltage = doc["voltage"]; // 充电器电压
sensorData.current = doc["current"]; // 充电器电流
sensorData.power = doc["power"]; // 充电器功率
sensorData.temp = doc["temperature"]; // 充电器温度
sensorData.humidity = doc["humidity"]; // 充电器湿度
// 数据验证
if (sensorData.voltage < 4.5)
Serial.println ("电压异常!");
}
}
// 串口中断接收
void
serialEvent ()
{
String jsonData = Serial.readStringUntil ('\n');
if (jsonData.startsWith ("{"))
parseJSON (jsonData);
}
// MQTT消息回调函数该函数会在PubSubClient对象的loop方法中被调用
void
mqtt_callback (char *topic, byte *payload, unsigned int length)
{
Serial.printf ("Message arrived in topic %s, length %d\n", topic, length);
Serial.print ("Message:");
for (int i = 0; i < length; i++)
{
Serial.print ((char)payload[i]);
}
Serial.println ("\n----------------END----------------");
}
// MQTT发布函数
void
publishSensorData ()
{
StaticJsonDocument<200> doc;
doc["voltage"] = sensorData.voltage;
doc["current"] = sensorData.current;
doc["power"] = sensorData.power;
doc["temperature"] = sensorData.temp;
doc["humidity"] = sensorData.humidity;
doc["timestamp"] = millis (); // 添加时间戳
char payload[256];
serializeJson (doc, payload);
if (mqttClient.publish ("homeassistant/charger/state", payload))
{
Serial.println ("Data published");
}
else
{
Serial.println ("Publish failed");
}
}
// MQTT重连函数
void
reconnectMQTT ()
{
Serial.println ("Trying Connect to MQTT ...");
mqttClient.connect ((mqtt_client_id + String (WiFi.macAddress ())).c_str (),
mqtt_username, mqtt_password); // 连接MQTT服务器
delay (100);
if (mqttClient.connected ()) // 每个客户端需要有唯一的ID不然上线时会把其他相同ID的客户端踢下线
{
Serial.println ("MQTT Connected");
mqttClient.publish (mqtt_topic_pub,
"hello mqtt!"); // 连接成功后可以发送消息
mqttClient.subscribe (mqtt_topic_sub); // 连接成功后可以订阅主题
}
else
{
Serial.println ("MQTT Connect Failed");
}
}
// WiFi连接检查
void
checkWifiConnection ()
{
if (WiFi.status () != WL_CONNECTED)
{
WiFi.reconnect ();
}
}

11
test/README Normal file
View File

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html