@@ -0,0 +1,5 @@ | |||
.pio | |||
.vscode/.browse.c_cpp.db* | |||
.vscode/c_cpp_properties.json | |||
.vscode/launch.json | |||
.vscode/ipch |
@@ -0,0 +1,6 @@ | |||
{ | |||
"configuration": "FlashFreq=80,UploadSpeed=115200,DebugLevel=none", | |||
"board": "esp32:esp32:esp32doit-devkit-v1", | |||
"port": "COM9", | |||
"sketch": "d:\\HBL\\Arduino\\test.ino" | |||
} |
@@ -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" | |||
] | |||
} |
@@ -0,0 +1,13 @@ | |||
{ | |||
"version": "2.0.0", | |||
"tasks": [ | |||
{ | |||
"type": "PlatformIO", | |||
"task": "Check", | |||
"problemMatcher": [ | |||
"$platformio" | |||
], | |||
"label": "PlatformIO: Check" | |||
} | |||
] | |||
} |
@@ -0,0 +1,22 @@ | |||
#ifndef Delay_h | |||
#define Delay_h | |||
#include <Arduino.h> | |||
#include <time.h> | |||
#include <stdio.h> | |||
class Delay | |||
{ | |||
private: | |||
time_t start = 0, end = 0; | |||
float cost = 0; | |||
bool flag = false; | |||
bool EN; | |||
public: | |||
Delay(); | |||
~Delay(); | |||
bool Start(bool IN, int PT); | |||
}; | |||
#endif |
@@ -0,0 +1,25 @@ | |||
#include <Arduino.h> | |||
#include "ModbusRtu.h" | |||
#include "MqttHelper.h" | |||
#include "Json.h" | |||
#include "Global.h" | |||
/** | |||
* @brief 电力设备 | |||
* | |||
*/ | |||
class ElectricityDevice | |||
{ | |||
private: | |||
const byte interruptPin = 21; | |||
public: | |||
ElectricityDevice(/* args */); | |||
~ElectricityDevice(); | |||
void Init(); | |||
void Start(); | |||
}; | |||
extern ElectricityDevice _electricityDevice; |
@@ -0,0 +1,19 @@ | |||
#define AISLE 8 //采集设备通道数 | |||
#ifndef _GLOBAL_H | |||
#define _GLOBAL_H | |||
struct DeviceData | |||
{ | |||
float Voltage; //电压 | |||
float Current; //电流 | |||
float Power; //功率 | |||
float Energy; //电能 | |||
}; | |||
extern struct DeviceData objDeviceData; | |||
extern float Voltage; | |||
extern float Current[AISLE]; | |||
extern DeviceData deviceModel[AISLE]; | |||
#endif |
@@ -0,0 +1,37 @@ | |||
#ifndef Json_h | |||
#define Json_h | |||
#include <Arduino.h> | |||
#include "Global.h" | |||
class Json | |||
{ | |||
private: | |||
public: | |||
Json(/* args */); | |||
~Json(); | |||
/** | |||
* @brief 设备状态Json数据上报 | |||
* | |||
*/ | |||
String StatusDataReport(); | |||
/** | |||
* @brief 电能数据josn封装 | |||
* | |||
* @return String | |||
*/ | |||
String PowerHarvesting(); | |||
/** | |||
* @brief 解析获取到的电能数据 | |||
* | |||
* @param str | |||
*/ | |||
void ParseJson(String str); | |||
}; | |||
extern Json myJson; | |||
#endif |
@@ -0,0 +1,30 @@ | |||
#include <Arduino.h> | |||
#include "ModbusRtu.h" | |||
#include "MqttHelper.h" | |||
#include "Json.h" | |||
#include "Global.h" | |||
#include <ArduinoQueue.h> | |||
#include <cJSON.h> | |||
#include <FreeRTOS.h> | |||
#define MAXITEMS 1000 | |||
#define MAXMEMORY 1000 | |||
/** | |||
* @brief 主设备 | |||
* | |||
*/ | |||
class MainDevice | |||
{ | |||
private: | |||
TaskHandle_t MqttTest; | |||
public: | |||
MainDevice(/* args */); | |||
~MainDevice(); | |||
void Init(); | |||
void Start(); | |||
}; | |||
extern MainDevice _mainDevice; |
@@ -0,0 +1,31 @@ | |||
#ifndef ModbusRtu_h | |||
#define ModbusRtu_h | |||
#include <Arduino.h> | |||
#include <ModbusMaster.h> | |||
#include "VoltageDevice.h" | |||
#include <math.h> | |||
#include "Global.h" | |||
#define RE 22 | |||
#define DE 23 | |||
#define Status 2 | |||
// #define AISLE 8 //采集设备通道数 | |||
class ModbusRtu | |||
{ | |||
private: | |||
ModbusMaster myMaster; | |||
public: | |||
ModbusRtu(/* args */); | |||
~ModbusRtu(); | |||
void Init(); | |||
void Start(); | |||
void Test(); | |||
}; | |||
extern ModbusRtu myRtu; | |||
#endif |
@@ -0,0 +1,44 @@ | |||
#ifndef MqttHelper_h | |||
#define MqttHelper_h | |||
#include <Arduino.h> | |||
#include <WiFi.h> | |||
#include <PubSubClient.h> | |||
#include <MQTT.h> | |||
class MqttHelper | |||
{ | |||
private: | |||
const char *id = "HBL1"; | |||
const char *psw = "bpa.1qaz@WSX"; | |||
const char *mqttServer = "10.2.1.21"; | |||
const int mqttPort = 1883; //服务器TCP协议的端口号 | |||
const char *mqttUser = "emqx_u_block"; //登录服务器所需的用户名 | |||
const char *mqttPsw = "emqx_p_admin8765490789"; //密码 | |||
const char *HeartbeatTopic = "UP/ENERGY_POWER/BUSINESS/0"; | |||
// const char *id = "pert"; | |||
// const char *psw = "12345678"; | |||
// const char *mqttServer = "111.9.47.105"; | |||
// const int mqttPort = 18883; //服务器TCP协议的端口号 | |||
// const char *mqttUser = "admin"; //登录服务器所需的用户名 | |||
// const char *mqttPsw = "admin8765490789"; //密码 | |||
// const char *HeartbeatTopic = "UP/ENERGY_POWER/BUSINESS/0"; | |||
String clientId; | |||
public: | |||
MqttHelper(/* args */); | |||
~MqttHelper(); | |||
void Init(); | |||
void Loop(); | |||
void publish(String message); | |||
void ReConnect(); | |||
}; | |||
extern MqttHelper _mqttHelper; | |||
#endif |
@@ -0,0 +1,39 @@ | |||
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 usual convention is to give header files names that end with `.h'. | |||
It is most portable to use only letters, digits, dashes, and underscores in | |||
header file names, and at most one dot. | |||
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 |
@@ -0,0 +1,33 @@ | |||
#ifndef VoltageDevice_h | |||
#define VoltageDevice_h | |||
#include <Arduino.h> | |||
#include "Delay.h" | |||
class VoltageDevice | |||
{ | |||
private: | |||
byte data[25]; | |||
public: | |||
VoltageDevice(/* args */); | |||
~VoltageDevice(); | |||
/** | |||
*@brief 通过串口读取设备数据 | |||
*/ | |||
bool ReadData(); | |||
/** | |||
* @brief 字节数组转换成浮点数 | |||
* | |||
* @param len 字节长度 | |||
* @param Index 起始字节索引 | |||
* @param bl 转换倍率 | |||
* @return float | |||
*/ | |||
float DataConvert(int len, int Index, int bl = 1); | |||
}; | |||
extern VoltageDevice MyVd; | |||
#endif |
@@ -0,0 +1,46 @@ | |||
This directory is intended for project specific (private) libraries. | |||
PlatformIO will compile them to static libraries and link into executable file. | |||
The source code of each library should be placed in a an own separate directory | |||
("lib/your_library_name/[here are source files]"). | |||
For example, see a structure of the following two libraries `Foo` and `Bar`: | |||
|--lib | |||
| | | |||
| |--Bar | |||
| | |--docs | |||
| | |--examples | |||
| | |--src | |||
| | |- Bar.c | |||
| | |- Bar.h | |||
| | |- library.json (optional, 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 | |||
and a contents of `src/main.c`: | |||
``` | |||
#include <Foo.h> | |||
#include <Bar.h> | |||
int main (void) | |||
{ | |||
... | |||
} | |||
``` | |||
PlatformIO Library Dependency Finder will find automatically dependent | |||
libraries scanning project source files. | |||
More information about PlatformIO Library Dependency Finder | |||
- https://docs.platformio.org/page/librarymanager/ldf.html |
@@ -0,0 +1,21 @@ | |||
; 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:esp32doit-devkit-v1] | |||
platform = espressif32 | |||
board = esp32doit-devkit-v1 | |||
framework = arduino | |||
lib_ldf_mode = deep+ | |||
lib_deps = | |||
4-20ma/ModbusMaster@^2.0.1 | |||
khoih-prog/ESPAsync_WiFiManager@^1.12.2 | |||
knolleary/PubSubClient@^2.8 | |||
einararnason/ArduinoQueue@^1.2.5 | |||
256dpi/MQTT@^2.5.0 |
@@ -0,0 +1,38 @@ | |||
#include "Delay.h" | |||
Delay::Delay() | |||
{ | |||
} | |||
Delay::~Delay() | |||
{ | |||
} | |||
/** | |||
* @brief 定时器 | |||
* | |||
* @param IN 定时器触发条件 | |||
* @param PT 定时器时间设置 单位s | |||
* @return true 到达定时时间 | |||
* @return false 未到定时时间 | |||
*/ | |||
bool Delay::Start(bool IN, int PT) | |||
{ | |||
EN = IN; | |||
if (EN && cost < PT) | |||
{ | |||
if (!flag) | |||
{ | |||
time(&start); | |||
flag = true; | |||
} | |||
time(&end); | |||
cost = difftime(end, start); | |||
} | |||
else | |||
{ | |||
cost = 0; | |||
flag = false; | |||
} | |||
return cost >= PT; | |||
} |
@@ -0,0 +1,49 @@ | |||
#include "ElectricityDevice.h" | |||
ElectricityDevice::ElectricityDevice(/* args */) | |||
{ | |||
} | |||
ElectricityDevice::~ElectricityDevice() | |||
{ | |||
} | |||
bool IsSend = false; | |||
void DataInit() | |||
{ | |||
for (size_t i = 0; i < AISLE; i++) | |||
{ | |||
deviceModel[i].Current = 0.0; | |||
deviceModel[i].Energy = 0.0; | |||
deviceModel[i].Power = 0.0; | |||
deviceModel[i].Voltage = 0.0; | |||
Current[i] = 0; | |||
} | |||
} | |||
void blink() | |||
{ | |||
IsSend = digitalRead(21) == 1; | |||
} | |||
void ElectricityDevice::Init() | |||
{ | |||
Serial.begin(115200); // Lora 模块通讯串口 | |||
pinMode(interruptPin, INPUT_PULLDOWN); | |||
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE); | |||
myRtu.Init(); | |||
DataInit(); | |||
} | |||
void ElectricityDevice::Start() | |||
{ | |||
myRtu.Start(); | |||
IsSend = true; | |||
String SendData = "A" + myJson.PowerHarvesting() + "B"; | |||
Serial.print(SendData); | |||
while (IsSend) | |||
delay(1); | |||
} | |||
ElectricityDevice _electricityDevice; |
@@ -0,0 +1,5 @@ | |||
#include "Global.h" | |||
DeviceData deviceModel[AISLE]; | |||
DeviceData objDeviceData; | |||
float Voltage = 0.0; | |||
float Current[AISLE]; |
@@ -0,0 +1,84 @@ | |||
#include "Json.h" | |||
#include <cJSON.h> | |||
Json::Json(/* args */) | |||
{ | |||
} | |||
Json::~Json() {} | |||
// json 数据封装 带数组数据 | |||
String Json::StatusDataReport() | |||
{ | |||
cJSON *mainJson = cJSON_CreateObject(); //创建主体对象 | |||
cJSON *message = cJSON_CreateObject(); //创建消息体对象 | |||
cJSON *arrayData = cJSON_CreateArray(); //创建数组对象 | |||
cJSON_AddStringToObject(mainJson, "MessageId", "256"); | |||
cJSON_AddStringToObject(mainJson, "MessageVersion", "24"); | |||
cJSON_AddStringToObject(mainJson, "ClientId", "1"); | |||
cJSON_AddStringToObject(mainJson, "ClientType", "20"); | |||
cJSON_AddStringToObject(mainJson, "Timestamp", __TIME__); | |||
cJSON_AddStringToObject(message, "Timestamp", "0"); | |||
for (size_t i = 0; i < AISLE; i++) | |||
{ | |||
cJSON *Data = cJSON_CreateObject(); //创建消息体里面的数据对象 | |||
cJSON_AddItemToArray(arrayData, Data); | |||
cJSON_AddStringToObject(Data, "Channel", String(i + 1).c_str()); | |||
cJSON_AddStringToObject(Data, "Current", String(Current[i]).c_str()); | |||
cJSON_AddStringToObject(Data, "Voltage", String(Voltage).c_str()); | |||
cJSON_AddStringToObject(Data, "Power", String(Current[i] * Voltage).c_str()); | |||
cJSON_AddStringToObject(Data, "Energy", String(deviceModel[i].Energy).c_str()); | |||
} | |||
cJSON_AddItemToObject(message, "Datas", arrayData); | |||
cJSON_AddItemToObject(mainJson, "Message", message); | |||
char *date = cJSON_Print(mainJson); | |||
String jsondata(date); | |||
cJSON_free((void *)date); // 释放cJSON_Print ()分配出来的内存空间 | |||
cJSON_Delete(mainJson); // 释放cJSON_CreateObject ()分配出来的内存空间 | |||
return jsondata; | |||
} | |||
String Json::PowerHarvesting() | |||
{ | |||
cJSON *mainJson = cJSON_CreateObject(); | |||
cJSON_AddStringToObject(mainJson, "DeviceType", "Electricity"); | |||
cJSON_AddStringToObject(mainJson, "Voltage", String(Voltage).c_str()); | |||
for (size_t i = 0; i < AISLE; i++) | |||
{ | |||
cJSON_AddStringToObject(mainJson, ("Current" + String(i + 1)).c_str(), String(Current[i]).c_str()); | |||
} | |||
char *date = cJSON_Print(mainJson); | |||
String jsondata(date); | |||
cJSON_free((void *)date); // 释放cJSON_Print ()分配出来的内存空间 | |||
cJSON_Delete(mainJson); // 释放cJSON_CreateObject ()分配出来的内存空间 | |||
return jsondata; | |||
} | |||
void Json::ParseJson(String str) | |||
{ | |||
cJSON *mainJson = cJSON_Parse(str.c_str()); | |||
if (mainJson != NULL) | |||
{ | |||
String DeviceType = cJSON_GetObjectItem(mainJson, "DeviceType")->valuestring; | |||
if (DeviceType == "Electricity") //电力设备 | |||
{ | |||
Voltage = String(cJSON_GetObjectItem(mainJson, "Voltage")->valuestring).toFloat(); | |||
for (size_t i = 0; i < AISLE; i++) | |||
{ | |||
String ResultValue(cJSON_GetObjectItem(mainJson, ("Current" + String(i + 1)).c_str())->valuestring); | |||
Current[i] = ResultValue.toFloat(); | |||
} | |||
} | |||
else if (DeviceType == "Gas") //燃气设备 | |||
{ | |||
} | |||
else if (DeviceType == "Water") //用水设备 | |||
{ | |||
} | |||
} | |||
} | |||
Json myJson; |
@@ -0,0 +1,19 @@ | |||
{ | |||
"MessageId": 257, | |||
"MessageVersion": 24, | |||
"ClientId": 1, | |||
"ClientType": 20, | |||
"Timestamp": "2022-08-03T17:06:31.3024375+08:00", | |||
"Message": { | |||
"Timestamp": 0, | |||
"Datas": [ | |||
{ | |||
"Channel": 0, | |||
"Current": 0.0, | |||
"Voltage": 0.0, | |||
"Power": 0.0, | |||
"Energy": 0.0 | |||
} | |||
] | |||
} | |||
} |
@@ -0,0 +1,69 @@ | |||
#include "MainDevice.h" | |||
MainDevice::MainDevice(/* args */) | |||
{ | |||
} | |||
MainDevice::~MainDevice() | |||
{ | |||
} | |||
ArduinoQueue<String> MyQueue(MAXITEMS, MAXMEMORY); | |||
void TaskMqttPublish(void *pvParameters) | |||
{ | |||
while (true) | |||
{ | |||
while (MyQueue.itemCount() > 0) | |||
{ | |||
String res = MyQueue.dequeue(); | |||
myJson.ParseJson(res); | |||
_mqttHelper.publish(myJson.StatusDataReport()); | |||
_mqttHelper.Loop(); | |||
vTaskDelay(1); | |||
} | |||
_mqttHelper.Loop(); | |||
vTaskDelay(10); | |||
} | |||
} | |||
void MainDevice::Init() | |||
{ | |||
Serial2.begin(115200); // lora 模块通讯串口 | |||
Serial.begin(115200); //消息日志串口 | |||
pinMode(2, OUTPUT); | |||
_mqttHelper.Init(); | |||
digitalWrite(2, 1); | |||
xTaskCreatePinnedToCore(TaskMqttPublish, "MqttHelt", 4096, NULL, 1, &MqttTest, 0); | |||
} | |||
void MainDevice::Start() | |||
{ | |||
digitalWrite(2, 0); | |||
String res; | |||
Delay mydelay; | |||
bool StartRevice = false; | |||
while (true) | |||
{ | |||
if (Serial2.available() > 0) | |||
{ | |||
char resRead = (char)Serial2.read(); | |||
if (StartRevice && resRead == 'B') | |||
{ | |||
MyQueue.enqueue(res); | |||
digitalWrite(2, 1); | |||
return; | |||
} | |||
if (StartRevice) | |||
res += resRead; | |||
if (resRead == 'A') | |||
StartRevice = true; | |||
} | |||
if (mydelay.Start(true, 2)) | |||
{ | |||
return; | |||
} | |||
} | |||
} | |||
MainDevice _mainDevice; |
@@ -0,0 +1,101 @@ | |||
#include "ModbusRtu.h" | |||
ModbusRtu::ModbusRtu(/* args */) | |||
{ | |||
} | |||
ModbusRtu::~ModbusRtu() | |||
{ | |||
} | |||
void preTransmission() | |||
{ | |||
digitalWrite(RE, 1); | |||
digitalWrite(DE, 1); | |||
} | |||
void posTransmission() | |||
{ | |||
digitalWrite(RE, 0); | |||
digitalWrite(DE, 0); | |||
} | |||
float UshorsToFloat(uint16_t Word1, uint16_t word2) | |||
{ | |||
byte Udata[4]; | |||
Udata[3] = (byte)(Word1 >> 8); | |||
Udata[2] = (byte)(Word1); | |||
Udata[1] = (byte)(word2 >> 8); | |||
Udata[0] = (byte)(word2); | |||
float f; | |||
union change | |||
{ | |||
float d; | |||
unsigned char dat[4]; | |||
} r1; | |||
r1.dat[0] = Udata[0]; | |||
r1.dat[1] = Udata[1]; | |||
r1.dat[2] = Udata[2]; | |||
r1.dat[3] = Udata[3]; | |||
f = r1.d; | |||
return f; | |||
} | |||
void ModbusRtu::Init() | |||
{ | |||
pinMode(RE, OUTPUT); | |||
pinMode(DE, OUTPUT); | |||
pinMode(Status, OUTPUT); | |||
posTransmission(); | |||
Serial2.begin(9600); //电压采集模块串口 和 电流采集模块的串口 | |||
myMaster.begin(1, Serial2); | |||
myMaster.preTransmission(preTransmission); | |||
myMaster.postTransmission(posTransmission); | |||
} | |||
void ModbusRtu::Start() | |||
{ | |||
digitalWrite(Status, 0); | |||
preTransmission(); | |||
bool result = MyVd.ReadData(); | |||
if (result) | |||
// Serial.println("电压获取成功"); | |||
digitalWrite(Status, 1); | |||
// else | |||
// Serial.println("电压获取失败"); | |||
// float Voltage = MyVd.DataConvert(2, 3, 100); //电压 | |||
Voltage = MyVd.DataConvert(2, 3, 100); | |||
uint8_t res = myMaster.readHoldingRegisters(32, 16); | |||
if (res == myMaster.ku8MBSuccess) | |||
{ | |||
// Serial.print("读取寄存器:"); | |||
for (size_t i = 0; i < 8; i++) | |||
{ | |||
deviceModel[i].Current = UshorsToFloat(myMaster.getResponseBuffer(i * 2), myMaster.getResponseBuffer(i * 2 + 1)); | |||
deviceModel[i].Voltage = Voltage; | |||
deviceModel[i].Power = deviceModel[i].Current * Voltage; | |||
deviceModel[i].Energy = deviceModel[i].Power * 0; //电能公式 W = UIT 电压 * 电流 * 时间 | |||
Current[i] = deviceModel[i].Current; | |||
// Serial.print("电流:"); | |||
// Serial.println(deviceModel[i].Current); | |||
// Serial.print("电压:"); | |||
// Serial.println(deviceModel[i].Voltage); | |||
// Serial.print("功率:"); | |||
// Serial.println(deviceModel[i].Power); | |||
// Serial.print("电能:"); | |||
// Serial.println(deviceModel[i].Energy); | |||
} | |||
} | |||
else | |||
{ | |||
// Serial.println("Modbus rtu 读取失败"); | |||
} | |||
} | |||
ModbusRtu myRtu; |
@@ -0,0 +1,158 @@ | |||
#include "MqttHelper.h" | |||
WiFiClient espClient; //实例WiFiClient对象 | |||
PubSubClient myClient(espClient); //实例PubSubClient对象,espClient做参数 | |||
MQTTClient client(2048); | |||
MqttHelper::MqttHelper(/* args */) | |||
{ | |||
} | |||
MqttHelper::~MqttHelper() | |||
{ | |||
} | |||
void callback(char *topic, byte *payload, unsigned int length) | |||
{ | |||
Serial.print("来自订阅的主题:"); //串口打印:来自订阅的主题: | |||
Serial.println(topic); //串口打印订阅的主题 | |||
Serial.print("信息:"); //串口打印:信息: | |||
for (int i = 0; i < length; i++) //使用循环打印接收到的信息 | |||
{ | |||
Serial.print((char)payload[i]); | |||
} | |||
Serial.println(); | |||
Serial.println("-----------------------"); | |||
} | |||
void MqttHelper::Init() | |||
{ | |||
while (WiFi.status() != WL_CONNECTED) | |||
{ //判断wifi是否连接,请确保你所连接的wifi联通了互联网 | |||
delay(3000); | |||
WiFi.begin(id, psw); //连接wifi | |||
Serial.println("正在连接wifi..."); | |||
} | |||
Serial.println("WIFI 已连接!"); | |||
myClient.setServer(mqttServer, mqttPort); //设置服务器地址,端口 | |||
myClient.setCallback(callback); //设定回调方式,当ESP32收到订阅消息时会调用此方法 | |||
clientId = "ESP32Client-"; | |||
clientId += String(random(0xffff), HEX); //生成随机客户端id | |||
//测试MQTT连接 | |||
client.begin(mqttServer, mqttPort, espClient); | |||
Serial.println("正连接至MQTT服务器..."); | |||
while (!client.connect(clientId.c_str(), mqttUser, mqttPsw)) | |||
{ | |||
Serial.print("."); | |||
delay(2000); | |||
} | |||
Serial.println("MQTT 已连接!"); | |||
// while (!myClient.connected()) | |||
// { //判断是否连接到服务器 | |||
// Serial.println("正连接至MQTT服务器..."); | |||
// if (myClient.connect(clientId.c_str(), mqttUser, mqttPsw)) | |||
// { | |||
// Serial.println("MQTT 已连接!"); | |||
// } | |||
// else | |||
// { | |||
// Serial.println("连接失败"); | |||
// Serial.println(myClient.state()); //重连函数 | |||
// delay(2000); | |||
// } | |||
// } | |||
// myClient.subscribe("Down/ENERGY_POWER/BUSINESS/0"); //订阅名为ESP32的主题 | |||
Serial.println("已订阅主题,等待消息..."); | |||
} | |||
void MqttHelper::ReConnect() | |||
{ | |||
// myClient.unsubscribe("UP/ENERGY_POWER/BUSINESS/0"); | |||
// myClient.disconnect(); | |||
Serial.println("开始重连"); | |||
while (!client.connect(clientId.c_str(), mqttUser, mqttPsw)) | |||
{ | |||
Serial.print("."); | |||
delay(2000); | |||
} | |||
Serial.println("MQTT 重连成功!"); | |||
// while (!myClient.connected()) | |||
// { //判断是否连接到服务器 | |||
// Serial.println("正连接至MQTT服务器..."); | |||
// if (myClient.connect(clientId.c_str(), mqttUser, mqttPsw)) | |||
// { | |||
// Serial.println("MQTT 已连接!"); | |||
// } | |||
// else | |||
// { | |||
// Serial.println("连接失败"); | |||
// Serial.println(myClient.state()); | |||
// delay(2000); | |||
// } | |||
// } | |||
// myClient.subscribe("Down/ENERGY_POWER/BUSINESS/0"); //订阅名为ESP32的主题 | |||
// Serial.println("已订阅主题,等待消息..."); | |||
} | |||
/** | |||
* @brief MQTT 发布数据 | |||
* | |||
* @param message 需要发布的数据 | |||
* 这个库只能发布很短的消息信息,需要拆分消息发送 | |||
*/ | |||
void MqttHelper::publish(String message) | |||
{ | |||
if (!client.connected()) | |||
ReConnect(); | |||
bool res = client.publish(HeartbeatTopic, message.c_str()); | |||
if (res) | |||
Serial.println("数据发布成功"); | |||
else | |||
Serial.println("-------------------------------数-据-发-布-失-败-------------------------------"); | |||
// message.trim(); | |||
// message.replace(" ", ""); | |||
// if (!myClient.connected()) | |||
// ReConnect(); | |||
// int cut = 128; //要拆分发送的实际大小 | |||
// int json_str_len = message.length(); //总数据长度 | |||
// if (json_str_len > cut) | |||
// { | |||
// //开始发送长文件参数分别为 主题,长度,是否持续 | |||
// myClient.beginPublish(HeartbeatTopic, json_str_len, true); | |||
// int count = json_str_len / cut; | |||
// for (int i = 0; i < (count - 1); i++) | |||
// { | |||
// size_t WriteSizeof = myClient.print(message.substring(i * cut, (i * cut + cut))); | |||
// if (WriteSizeof <= 0) | |||
// { | |||
// myClient.disconnect(); | |||
// return; | |||
// } | |||
// } | |||
// myClient.print(message.substring(cut * (count - 1))); | |||
// myClient.endPublish(); //结束发送文本 | |||
// } | |||
// else | |||
// { | |||
// myClient.publish(HeartbeatTopic, message.c_str()); | |||
// } | |||
// Serial.println("MQTT 消息发布"); | |||
} | |||
void MqttHelper::Loop() | |||
{ | |||
// myClient.loop(); //回旋接收函数 等待服务器返回的数据 | |||
client.loop(); | |||
} | |||
MqttHelper _mqttHelper; |
@@ -0,0 +1,56 @@ | |||
#include "VoltageDevice.h" | |||
VoltageDevice::VoltageDevice(/* args */) | |||
{ | |||
} | |||
VoltageDevice::~VoltageDevice() | |||
{ | |||
} | |||
bool VoltageDevice::ReadData() | |||
{ | |||
for (size_t i = 0; i < sizeof(data); i++) | |||
data[i] = 0; | |||
Delay myDelay; //定时器 | |||
bool IsRun = true; | |||
int count = 0; | |||
byte read[8] = {0x01, 0x03, 0x00, 0x48, 0x00, 0x0A, 0x45, 0xDB}; | |||
Serial2.write(read, sizeof(read)); | |||
// Serial.println("写入数据:0x01, 0x03, 0x00, 0x48, 0x00, 0x0A, 0x45, 0xDB"); | |||
while (IsRun) | |||
{ | |||
if (Serial2.available() > 0 && count < sizeof(data)) | |||
{ | |||
data[count] = Serial2.read(); | |||
count++; | |||
} | |||
if (count >= sizeof(data)) | |||
return true; | |||
if (myDelay.Start(IsRun, 2)) | |||
return false; | |||
} | |||
} | |||
float VoltageDevice::DataConvert(int len, int Index, int bl) | |||
{ | |||
byte dt[len]; | |||
int tempIndex; | |||
for (size_t i = 0; i < len; i++) | |||
{ | |||
tempIndex = len + Index - 1 - i; | |||
if (tempIndex >= 0 && tempIndex < sizeof(data)) | |||
{ | |||
dt[i] = data[len + Index - 1 - i]; | |||
} | |||
} | |||
int Temp = 0; | |||
for (size_t i = 0; i < sizeof(dt); i++) | |||
{ | |||
Temp += (int)(dt[i] << (i * 8)); | |||
} | |||
return (float)(Temp / bl); | |||
} | |||
VoltageDevice MyVd; |
@@ -0,0 +1,27 @@ | |||
// #include <Arduino.h> | |||
#include "ElectricityDevice.h" | |||
#include "MainDevice.h" | |||
//电力设备程序 | |||
// void setup() | |||
// { | |||
// _electricityDevice.Init(); //电力设备程序 | |||
// } | |||
// void loop() | |||
// { | |||
// _electricityDevice.Start(); //电力设备程序 | |||
// delay(1000); | |||
// } | |||
//主设备程序 | |||
void setup() | |||
{ | |||
_mainDevice.Init(); //主设备程序 | |||
} | |||
void loop() | |||
{ | |||
_mainDevice.Start(); //主设备程序 | |||
delay(100); | |||
} |
@@ -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 |