# 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