# V0.1 完成mqtt连接发送
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal 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
10
.vscode/extensions.json
vendored
Normal 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
37
include/README
Normal 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
46
lib/README
Normal 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
18
platformio.ini
Normal 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
203
src/main.cpp
Normal 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
11
test/README
Normal 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
|
Reference in New Issue
Block a user