欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
STM32采集數據上報阿里云源程序 ADXL355+485+modbus+MQTT
[打印本頁]
作者:
匯集口
時間:
2022-11-30 18:34
標題:
STM32采集數據上報阿里云源程序 ADXL355+485+modbus+MQTT
基于STM32F103ZET6設計的一個系統
數據部分:
1、通過SPI總線采集ADXL355傳感器的三軸向數據
2、通過485+modbus協議與太陽能系統進行數據交互
阿里云:
1、通過MQTT協議打包數據上傳到阿里云服務器
單片機源程序如下:
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "string.h"
//MODBUS協議相關頭文件
#include "rs485.h"
#include "it.h"
#include "modbus_config.h"
#include "modbus_req.h"
//ADXL355傳感器相關頭文件
#include "spi.h"
#include "ADXL355.h"
//ESP8266WIFI使用相關頭文件
#include "uart2.h"
#include "wifi.h"
#include "timer3.h"
#include "structure.h"
//FreeRTOS系統相關頭文件
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
//MQTT協議相關頭文件
#include "esp8266_mqtt.h"
//MQTT初始化函數
void ES8266_MQTT_Init(void);
//MODBUS相關變量
#define SLAVE_ADDR 0x0A
MD_datstr MD_str = {0}; //一個MODBUS請求實例
u8 flag_send = 0; //發送一個讀寫命令標志
u8 saveAddr[5] = {0xaa,0x55,3,4,5}; //接收數據保存
u16 saveAddrREG[8] = {0x1234,0x5678};
//阿里云服務器的登陸配置
#define MQTT_BROKERADDRESS "iot-06z00j95cmf2y8amqttiothubaliyuncscom"
#define MQTT_CLIENTID "h05pNELZZvB.test13|securemode=2,signmethod=hmacsha256,timestamp=1669103327588|"
#define MQTT_USARNAME "test13&h05pNELZZvB"
#define MQTT_PASSWD "b1ed002d9712d538e0bfd2cd2564a16c748f19c3a1b2a9522434572451f4507f"
#define MQTT_PUBLISH_TOPIC "/sys/h05pNELZZvB/test13/thing/event/property/post"
#define MQTT_SUBSCRIBE_TOPIC "/sys/h05pNELZZvB/test13/thing/service/property/set"
char mqtt_message[300]; //MQTT的上報消息緩存
//服務器IP地址和端口號
char *IP = MQTT_BROKERADDRESS;
int Port = 1883;
//任務優先級
#define START_TASK_PRIO 1
//任務堆棧大小
#define START_STK_SIZE 128
//任務句柄
TaskHandle_t StartTask_Handler;
//任務函數
void start_task(void *pvParameters);
//任務優先級
#define LED0_TASK_PRIO 2
//任務堆棧大小
#define LED0_STK_SIZE 50
//任務句柄
TaskHandle_t LED0Task_Handler;
//任務函數
void led0_task(void *pvParameters);
//任務優先級
#define WIFI_TASK_PRIO 4
//任務堆棧大小
#define WIFI_STK_SIZE 512
//任務句柄
TaskHandle_t WIFITask_Handler;
//任務函數
void wifi_task(void *pvParameters);
//任務優先級
#define SPI_TASK_PRIO 3
//任務堆棧大小
#define SPI_STK_SIZE 512
//任務句柄
TaskHandle_t SPITask_Handler;
//任務函數
void SPI_task(void *pvParameters);
/* Uart2 - Wifi 的消息接收隊列 */
#define Wifi_MESSAGE_Q_NUM 4 //接收數據的消息隊列的數量
QueueHandle_t Wifi_Message_Queue; //信息隊列句柄
float PVE,BVE,RVE,OCT,CCT,CTE,ETE,FVN ;
u32 SensorT;
int_least32_t SensorX,SensorY,SensorZ;
//產生一個10us的定時器,給MD計時
void Time_Init(void)
{
TIM_Struct tim_str;
tim_str.NVIC_IRQChannelPreemptionPriority = 3;
tim_str.NVIC_IRQChannelSubPriority = 3;
tim_str.Period = 200;
tim_str.Prescaler = 71;
tim_str.TIMx = TIM2;
TIM_Init(&tim_str);
}
//主函數
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設置系統中斷優先級分組4
delay_init(); //初始化系統時鐘
LED_Init(); //LED初始化
uart_init(115200); //初始化串口1
uart2_init(115200); //初始化串口2
Timer3_Configuration(5); //Tim3定時器,用于wifi-uart2的接收完成
WiFi_ResetIO_Init(); //wifi - RST引腳初始化
MD_REQ_Init(9600,&MD_str);
Time_Init();
SPI2_Init();
ADXL355_Init();
printf("初始化完成,開始創建任務\r\n");
//創建開始任務
xTaskCreate((TaskFunction_t )start_task, //任務函數
(const char* )"start_task", //任務名稱
(uint16_t )START_STK_SIZE, //任務堆棧大小
(void* )NULL, //傳遞給任務函數的參數
(UBaseType_t )START_TASK_PRIO, //任務優先級
(TaskHandle_t* )&StartTask_Handler); //任務句柄
vTaskStartScheduler(); //開啟任務調度
}
//開始任務任務函數
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //進入臨界區
//創建 Uart2 - Wifi 接收消息隊列
Wifi_Message_Queue = xQueueCreate(Wifi_MESSAGE_Q_NUM,1); //隊列項數目是Wifi_MESSAGE_Q_NUM,隊列項長度是串口DMA接收緩沖區長度
//創建LED0任務
xTaskCreate((TaskFunction_t )led0_task,
(const char* )"led0_task",
(uint16_t )LED0_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED0_TASK_PRIO,
(TaskHandle_t* )&LED0Task_Handler);
//創建SPI_task任務
xTaskCreate((TaskFunction_t )SPI_task,
(const char* )"SPI_task",
(uint16_t )SPI_STK_SIZE,
(void* )NULL,
(UBaseType_t )SPI_TASK_PRIO,
(TaskHandle_t* )&SPITask_Handler);
//創建wifi_task任務
xTaskCreate((TaskFunction_t )wifi_task,
(const char* )"wifi_task",
(uint16_t )WIFI_STK_SIZE,
(void* )NULL,
(UBaseType_t )WIFI_TASK_PRIO,
(TaskHandle_t* )&WIFITask_Handler);
vTaskDelete(StartTask_Handler); //刪除開始任務
taskEXIT_CRITICAL(); //退出臨界區
}
//LED0任務函數
void led0_task(void *pvParameters)
{ u8 erro = 0;
u8 i = 0;
while(1)
{
if(MD_str.flag_listener) //發送數據后監聽
{
if(MD_str.flag_waitRelpy == MD_NO) //等待超時
{
ErroOutTime(&MD_str);
MD_str.flag_listener = 0; //停止監聽
}
if(MD_str.flag_receiveOK == MD_OK) //有數據接收到
{
erro = REQ_CallBack(&MD_str);
if(erro)
{
printf("erro = 0X%X\r\n",erro);
}else
{
printf("buff[電源電壓 電池電壓 充電電流 輸出電流 基準電壓 內部溫度 外部溫度 軟件版本 ] = {");
for(i=0;i<GETSIZE(saveAddrREG);i++)
{
printf(" %#d ",saveAddrREG[i]);
}
printf("}\r\n");
printf("OK--------------------\r\n");
}
}
}
if(flag_send )
{
REQ_Read(&MD_str,MD_READ_HOLD_REG,SLAVE_ADDR,0,8,saveAddrREG); //讀多個線圈或多個寄存器
flag_send = 0;
}
}
}
//創建SPI任務函數
void SPI_task(void *pvParameters)
{
while(1)
{
ADXL355_Data_Scan(&SensorX, &SensorY, &SensorZ, &SensorT);
printf("X: %f\r\n",(float)SensorX/256000);
printf("Y: %f\r\n",(float)SensorY/256000);
printf("Z: %f\r\n",(float)(SensorZ/256000));
printf("\r\n\r\n");
vTaskDelay(2000);
}
}
//WIFI任務函數
void wifi_task(void *pvParameters)
{
uint8_t pub_cnt = 0,pub_ret;
uint16_t Counter_MQTT_Heart = 0;
char *recv;
//MQTT協議初始化
ES8266_MQTT_Init();
while(1)
{
//心跳包發送
if(Counter_MQTT_Heart++>300)
{
Counter_MQTT_Heart = 0;
MQTT_SentHeart();
}
/* 發送數據 */
pub_cnt++;
if(0 == pub_cnt%500) //約3S發送一次數據
{
PVE = saveAddrREG[0];
BVE = saveAddrREG[1];
CCT = saveAddrREG[2];
OCT = saveAddrREG[3];
RVE = saveAddrREG[4];
CTE = saveAddrREG[5];
ETE = saveAddrREG[6];
FVN = saveAddrREG[7];
pub_cnt = 0;
memset(mqtt_message, 0, 300);
//組裝數據
sprintf(mqtt_message,
"{\"method\":\"thing.service.property.post\",\"id\":\"1234\",\"params\":{\
\"PVE\":%.1f,\"BVE\":%.1f,\"CCT\":%.1f,\"OCT\":%.1f,\"RVE\":%.1f,\"CTE\":%.1f,\"ETE\":%.1f,\"FVN\":%.1f,\"DATAX\":%.1f,\"DATAY\":%.1f,\"DATAZ\":%.1f},\"version\":\"1.0.0\"}", PVE,BVE,CCT,OCT,RVE,CTE,ETE,FVN,(float)SensorX,(float)SensorY,(float)SensorZ);
//發布數據
pub_ret = MQTT_PublishData(MQTT_PUBLISH_TOPIC,mqtt_message,0);
if(pub_ret > 0)
{
printf("消息發布成功!!! data=%.1f,data2=%.1f,data3=%.1f,data4=%.1f,data5=%.1f,data6=%.1f,data7=%.1f,data8=%.1f,data9=%.1f,data10=%.1f,data11=%.1f", PVE,BVE,CCT,OCT,RVE,CTE,ETE,FVN,(float)SensorX,(float)SensorY,(float)SensorZ);
}
else
{
printf("/r/n");
printf("消息發布失敗!!!pub_ret=%d\r\n", pub_ret);
}
}
//收到數據
if((WifiMsg.U2_RxCompleted == 1) && (USART3_RxCounter > 1))
{
printf("來自服務器數據:%d\r\n", USART3_RxCounter);
recv = strstr(USART3_RxBuff, "LED");
//下發命令后,串口2會接收到這樣的數據:
//...{"method":"thing.service.property.set","id":"1593428732","params":{"LED":1},"version":"1.0.0"}
if(recv != NULL)
{
//經過strstr函數后,recv指向了字符串:LED":0}...
//為拿到LED后面的狀態值,指針偏移5個字節
recv = recv + 3 +2; //LED占3個字節 ”:占2個字節
printf("LED=%d\r\n", (*recv)-'0');
LED0 = !((*recv)-'0'); //根據下發的命令控制PC13處的LED燈
memset(mqtt_message, 0, 300);
//組裝數據
sprintf(mqtt_message,
"{\"method\":\"thing.service.property.set\",\"id\":\"5678\",\"params\":{\
\"LED\":%d},\"version\":\"1.0.0\"}", (*recv)-'0');
//發布數據
pub_ret = MQTT_PublishData(MQTT_PUBLISH_TOPIC,mqtt_message,0);
if(pub_ret > 0)
{
printf("消息發布成功!!!pub_ret=%d\r\n", pub_ret);
}
else
{
printf("消息發布失敗!!!pub_ret=%d\r\n", pub_ret);
}
}
//將標志位和數據清空
memset(USART3_RxBuff, 0, sizeof(USART3_RxBuff));
WifiMsg.U2_RxCompleted = 0;
USART3_RxCounter = 0;
}
vTaskDelay(10);
}
}
//MQTT初始化函數
void ES8266_MQTT_Init(void)
{
uint8_t status=1;
char conn=1;
// 復位不成功,需要重新復位
// if(!WiFi_Init())
// {
// printf("ESP8266狀態初始化正常\r\n"); //串口輸出信息
// //獲取WIFI當前IP地址
// WiFi_GetIP(100);
// WifiMsg.Mode = 1; //r_flag標志置位,表示8266狀態正常,可以繼續,進行TCP連接
// status++;
// }
printf("準備復位模塊\r\n"); //串口提示數據
if(WiFi_Reset(50))
{ //復位,100ms超時單位,總計5s超時時間
printf("復位失敗,準備重啟\r\n"); //返回非0值,進入if,串口提示數據
}else printf("復位成功\r\n"); //串口提示數據
printf("準備連接路由器\r\n"); //串口提示數據
if(WiFi_JoinAP(10)){ //連接路由器,1s超時單位,總計10s超時時間
printf("連接路由器失敗,準備重啟\r\n"); //返回非0值,進入if,串口提示數據
}else printf("連接路由器成功\r\n"); //串口提示數據
printf("準備獲取IP地址\r\n"); //串口提示數據
if(WiFi_GetIP(50)){ //準備獲取IP地址,100ms超時單位,總計5s超時時間
printf("獲取IP地址失敗,準備重啟\r\n"); //返回非0值,進入if,串口提示數據
}else printf("獲取IP地址成功\r\n"); //串口提示數據
printf("準備開啟透傳\r\n"); //串口提示數據
if(WiFi_SendCmd("AT+CIPMODE=1",50)){ //開啟透傳,100ms超時單位,總計5s超時時間
printf("開啟透傳失敗,準備重啟\r\n"); //返回非0值,進入if,串口提示數據
}else printf("開啟透傳成功\r\n"); //串口提示數據
printf("準備關閉多路連接\r\n"); //串口提示數據
if(WiFi_SendCmd("AT+CIPMUX=0",50)){ //關閉多路連接,100ms超時單位,總計5s超時時間
printf("關閉多路連接失敗,準備重啟\r\n"); //返回非0值,進入if,串口提示數據
}else printf("關閉多路連接成功\r\n"); //串口提示數據
WifiMsg.Mode = 1; //r_flag標志置位,表示8266狀態正常,可以繼續,進行TCP連接
status++;
//連接阿里云IOT服務器
if(status==2)
{
printf("連接服務器:IP=%s,Port=%d\r\n",IP, Port);
conn = WiFi_Connect(IP, Port, 100);
printf("連接結果conn=%d\r\n",conn);
status++;
}
//關閉WIFI回顯
//printf("關閉回顯:%d\r\n", WiFi_Send("ATE0"));
//登陸MQTT
if(status==3)
{
//不用判斷返回值,登陸總是顯示失敗,但實際已經登陸成功了
MQTT_Connect(MQTT_CLIENTID, MQTT_USARNAME, MQTT_PASSWD);
printf("ESP8266阿里云MQTT登陸成功!\r\n");
status++;
}
//訂閱主題
if(status==4)
{
//不用判斷返回值,訂閱總是顯示失敗,但實際已經訂閱成功了
MQTT_SubscribeTopic(MQTT_SUBSCRIBE_TOPIC,0,1);
printf("ESP8266阿里云MQTT訂閱主題成功!\r\n");
}
}
//定時
void TIM2_IRQHandler(void)
{
static u32 counter_t2 = 0;
if(TIM_GetITStatus(TIM2,TIM_FLAG_Update)==SET) //判斷是不是這個中斷
{
MD_Fun_InTime(&MD_str,200); //MODBUS定時器中的函數
//間隔1秒發送數據請求
if(flag_send == 0)
{
counter_t2 ++;
if(counter_t2 > 5000)
{
counter_t2 = 0;
flag_send = 1;
}
}
TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update); //清除標志位
}
}
復制代碼
Keil代碼下載:
STM32+太陽能+阿里云(已采集數據)2022-11-25.7z
(369.31 KB, 下載次數: 93)
2022-11-30 19:57 上傳
點擊文件名下載附件
示例代碼
下載積分: 黑幣 -5
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1