生活随笔
收集整理的這篇文章主要介紹了
NB驱动层MQTT发布和订阅数据的代码实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
1 代碼實現
首先看一下收到數據后的回調函數:
如下為代碼實現:
#include <string.h>
#include <stdio.h>
#include "main.h"
#include "at_parse.h"
#include "app_debug.h"
#include "at_net.h"#include "FreeRTOS.h"
#include "task.h"#define AT_CMD_AT "AT"
#define AT_CMD_ATE0 "ATE0"
#define AT_CMD_GET_IMEI "AT+GSN"
#define AT_CMD_GET_IMSI "AT+CIMI"
#define AT_CMD_SET_APN "AT*MCGDEFCONT=\"IP\",\"\""
#define AT_CMD_CFUN0 "AT+CFUN=0"
#define AT_CMD_CFUN1 "AT+CFUN=1"
#define AT_CMD_CPIN "AT+CPIN?"
#define AT_CMD_CSQ "AT+CSQ"
#define AT_CMD_CEREG "AT+CEREG?"
#define AT_CMD_CGACT "AT+CGACT?"
#define AT_CMD_CGCONTRDP "AT+CGCONTRDP"
#define AT_CMD_PSM_REPORT "AT+CPSMSTATUS=1"
#define AT_CMD_PSM_ON "AT+CPSMS=1,,,\"01001010\",\"00000000\""
#define AT_CMD_PSM_OFF "AT+CPSMS=0"
#define AT_REPORT_PSM "+CPSMSTATUS:"#define AT_CMD_CMQNEW "AT+CMQNEW"
#define AT_CMD_CMQTTSNEW "AT+CMQTTSNEW"
#define AT_CMD_CMQCON "AT+CMQCON"
#define AT_CMD_CMQSUB "AT+CMQSUB"
#define AT_CMD_CMQUNSUB "AT+CMQUNSUB"
#define AT_CMD_CMQDISCON "AT+CMQDISCON"
#define AT_CMD_CMQPUB "AT+CMQPUB"
#define AT_CMD_CMQALICFG "AT+CMQALICFG"
#define AT_CMD_CMQALICON "AT+CMQALICON"
#define AT_CMD_CREVHEX "AT+CREVHEX=1"
#define AT_RECV_MQTT "+CMQPUB:"
#define AT_RECV_MQTT_DISCON "+CMQDISCON:"#define STATUS_IS_ON() (!HAL_GPIO_ReadPin(M_STA_GPIO_Port,M_STA_Pin))
#define STATUS_IS_OFF() (HAL_GPIO_ReadPin(M_STA_GPIO_Port,M_STA_Pin))
#define PWRKEY_HIGH() HAL_GPIO_WritePin(M_PWR_GPIO_Port,M_PWR_Pin,GPIO_PIN_RESET)
#define PWRKEY_LOW() HAL_GPIO_WritePin(M_PWR_GPIO_Port,M_PWR_Pin,GPIO_PIN_SET)#define SIM_RECV_BUF_SIZE 150
#define SIM_SEND_BUF_SIZE 150
#define SIM_RECV_TOPIC_SIZE 100struct sim7020_control_t
{char recv_buf
[SIM_RECV_BUF_SIZE
];uint16_t recv_len
;char recv_topic
[SIM_RECV_TOPIC_SIZE
];char send_buf
[SIM_SEND_BUF_SIZE
];uint8_t socket
;
}sim_ctl
;
static bool is_inited
=false;
static mqtt_recv_callback mqtt_callback
=NULL;static bool sim7020_at_ok()
{uint16_t err
=0;while (err
<3){err
++;if(at_send_wait_reply(AT_CMD_AT
,true,"OK","ERROR",NULL,NULL,1000)==false)continue;if(at_send_wait_reply(AT_CMD_ATE0
,true,"OK","ERROR",NULL,NULL,1000)==false)continue;return true;}return false;}bool sim7020_pwr_on()
{uint16_t err
=0;DEBUG("sim7020 pwr on");if(STATUS_IS_ON())return true;while(err
<3){err
++;PWRKEY_HIGH();vTaskDelay(200);PWRKEY_LOW();vTaskDelay(1000);PWRKEY_HIGH();vTaskDelay(500);if(!STATUS_IS_ON())continue;if(sim7020_at_ok()==false)continue;return true;}return false;
}bool sim7020_pwr_off()
{uint16_t err
=0;DEBUG("sim7020 pwr off");if(STATUS_IS_OFF())return true;while(err
<3){err
++;PWRKEY_HIGH();vTaskDelay(200);PWRKEY_LOW();vTaskDelay(1500);PWRKEY_HIGH(); vTaskDelay(500);if(!STATUS_IS_OFF())continue;return true;}return false;
}bool sim7020_reboot()
{if(STATUS_IS_ON()){if(sim7020_pwr_off()==false)return false;}return sim7020_pwr_on();
}static bool sim7020_send_atcmd(char *cmd
,char *prefix
,uint32_t timeout
)
{memset(sim_ctl
.recv_buf
,0,SIM_RECV_BUF_SIZE
);sim_ctl
.recv_len
=SIM_RECV_BUF_SIZE
;return at_send_wait_reply
(cmd
,true,prefix
,"ERROR",sim_ctl
.recv_buf
,&sim_ctl
.recv_len
,timeout
);
}static bool sim7020_get_imei()
{uint16_t err
=0;while(err
<3){err
++;vTaskDelay(100);if(sim7020_send_atcmd(AT_CMD_GET_IMEI
,"86",1000)!=true)continue;return true;}return false;
}static bool sim7020_check_sim()
{uint16_t err
=0;while(err
<3){err
++;vTaskDelay(500);if(sim7020_send_atcmd(AT_CMD_CPIN
,"+CPIN: READY",1000)!=true)continue;return true;}return false;
}static bool sim7020_set_apn()
{uint16_t err
=0;while(err
<3){err
++;vTaskDelay(100);if(sim7020_send_atcmd(AT_CMD_CFUN0
,"OK",5000)!=true)continue;vTaskDelay(100);if(sim7020_send_atcmd(AT_CMD_SET_APN
,"OK",1000)!=true)continue;vTaskDelay(100);if(sim7020_send_atcmd(AT_CMD_CFUN1
,"+CPIN: READY",5000)!=true)continue;return true;}return false;
}static bool sim7020_check_net()
{uint16_t err
=0;while(err
<300){err
++;vTaskDelay(100);if(sim7020_send_atcmd(AT_CMD_CSQ
,"+CSQ:",1000)!=true)continue;vTaskDelay(100);if(sim7020_send_atcmd(AT_CMD_CEREG
,"+CEREG: 0,1",1000)!=true)continue;vTaskDelay(100);if(sim7020_send_atcmd(AT_CMD_CGACT
,"+CGACT: 1,1",1000)!=true)continue;vTaskDelay(100);if(sim7020_send_atcmd(AT_CMD_CGCONTRDP
,"+CGCONTRDP:",1000)!=true)continue;return true;}return false;}bool sim7020_deinit()
{DEBUG("sim7020 deinit");is_inited
=false;sim7020_pwr_off();at_parse_deinit();memset(&sim_ctl
,0,sizeof(sim_ctl
));return true;
}
static void sim7020_mqtt_recv_handler(char *pdata
,uint16_t data_len
,void *arg
)
{int a
,b
,c
,d
;memset(sim_ctl
.recv_buf
,0,SIM_RECV_BUF_SIZE
);memset(sim_ctl
.recv_topic
,0,SIM_RECV_TOPIC_SIZE
);sscanf(pdata
,"%*[^/] %[^\"] %*[^,],%d,%d,%d,%d %*[^\"]\"%[^\"]",sim_ctl
.recv_topic
,&a
,&b
,&c
,&d
,sim_ctl
.recv_buf
);sim_ctl
.recv_len
=d
;if(mqtt_callback
!=NULL){mqtt_callback(sim_ctl
.recv_topic
,sim_ctl
.recv_buf
,sim_ctl
.recv_len
);}}bool sim7020_init()
{uint16_t err
=0;DEBUG("sim7020 init");if(at_parse_init()!=true)return false;at_register_callback(AT_RECV_MQTT
,sim7020_mqtt_recv_handler
,NULL);while(err
<3){err
++;memset(&sim_ctl
,0,sizeof(sim_ctl
));if(sim7020_reboot()!=true)continue;if(sim7020_get_imei()!=true)continue;if(sim7020_check_sim()!=true)continue;if(sim7020_set_apn()!=true)continue;if(sim7020_check_net()!=true)continue;vTaskDelay(100);DEBUG("sim7020 init ok");is_inited
=true;return true;}sim7020_deinit();return false;}bool sim7020_mqtt_connect(char *server
,uint16_t port
,char *prokey
,char *devname
,char *devsecret
)
{uint16_t err
=0;if(is_inited
==false)return false;while(err
<3){err
++;if(sim7020_pwr_on()!=true)continue;if(sim7020_check_net()!=true)continue;memset(sim_ctl
.send_buf
,0,SIM_SEND_BUF_SIZE
);snprintf(sim_ctl
.send_buf
,SIM_SEND_BUF_SIZE
,"%s=\"%s\",\"%d\",12000,1024",AT_CMD_CMQNEW
,server
,port
);if(sim7020_send_atcmd(sim_ctl
.send_buf
,"+CMQNEW:",10000)!=true)continue;sim_ctl
.socket
=sim_ctl
.recv_buf
[9]-0x30;vTaskDelay(50);memset(sim_ctl
.send_buf
,0,SIM_SEND_BUF_SIZE
);snprintf(sim_ctl
.send_buf
,SIM_SEND_BUF_SIZE
,"%s=%d,\"%s\",\"%s\",\"%s\"",AT_CMD_CMQALICFG
,sim_ctl
.socket
,prokey
,devname
,devsecret
);if(sim7020_send_atcmd(sim_ctl
.send_buf
,"OK",10000)!=true)continue;memset(sim_ctl
.send_buf
,0,SIM_SEND_BUF_SIZE
);snprintf(sim_ctl
.send_buf
,SIM_SEND_BUF_SIZE
,"%s=%d,600,1",AT_CMD_CMQALICON
,sim_ctl
.socket
);if(sim7020_send_atcmd(sim_ctl
.send_buf
,"OK",10000)!=true)continue;return true;}return false;
}static bool sim7020_enter_psm()
{uint16_t err
=0;uint16_t counter
=0;while(err
<2){err
++;if(sim7020_send_atcmd(AT_CMD_PSM_OFF
,"OK",2000)!=true)continue;vTaskDelay(2000);if(sim7020_send_atcmd(AT_CMD_PSM_ON
,"OK",2000)!=true)continue;counter
=0;while (counter
<15){counter
++;DEBUG("wait enter psm ...");vTaskDelay(1000);if(STATUS_IS_OFF())return true;} }return sim7020_pwr_off();
}bool sim7020_mqtt_disconnect(void)
{if(is_inited
==false)return false;memset(sim_ctl
.send_buf
,0,SIM_SEND_BUF_SIZE
);snprintf(sim_ctl
.send_buf
,SIM_SEND_BUF_SIZE
,"%s=%d",AT_CMD_CMQDISCON
,sim_ctl
.socket
);sim7020_send_atcmd(sim_ctl
.send_buf
,"OK",10000);return sim7020_enter_psm();
}bool sim7020_mqtt_pub(char *topic
,char *mes
,uint16_t mes_len
)
{uint16_t err
=0;if(is_inited
==false)return false;while(err
<3){err
++;memset(sim_ctl
.send_buf
,0,SIM_SEND_BUF_SIZE
);snprintf(sim_ctl
.send_buf
,SIM_SEND_BUF_SIZE
,"%s=%d,\"%s\",1,0,0,%d,\"%s\"",AT_CMD_CMQPUB
,sim_ctl
.socket
,topic
,mes_len
,mes
);if(sim7020_send_atcmd(sim_ctl
.send_buf
,"OK",10000)!=true)continue;return true;}return false;
}
bool sim7020_mqtt_sub(char *topic
)
{uint16_t err
=0;if(is_inited
==false)return false;while(err
<3){err
++;memset(sim_ctl
.send_buf
,0,SIM_SEND_BUF_SIZE
);snprintf(sim_ctl
.send_buf
,SIM_SEND_BUF_SIZE
,"%s=%d,\"%s\",1",AT_CMD_CMQSUB
,sim_ctl
.socket
,topic
);if(sim7020_send_atcmd(sim_ctl
.send_buf
,"OK",10000)!=true)continue;return true;}return false;
}
bool sim7020_mqtt_unsub(char *topic
)
{uint16_t err
=0;if(is_inited
==false)return false;while(err
<3){err
++;memset(sim_ctl
.send_buf
,0,SIM_SEND_BUF_SIZE
);snprintf(sim_ctl
.send_buf
,SIM_SEND_BUF_SIZE
,"%s=%d,\"%s\"",AT_CMD_CMQUNSUB
,sim_ctl
.socket
,topic
);if(sim7020_send_atcmd(sim_ctl
.send_buf
,"OK",10000)!=true)continue;return true;}return false;
}
bool sim7020_mqtt_recv_register(mqtt_recv_callback cb
)
{if(is_inited
==false)return false;mqtt_callback
=cb
;return true;
}at_net_dev_t dev_sim7020
={.init
=sim7020_init
,.deinit
=sim7020_deinit
,.mqtt_connect
=sim7020_mqtt_connect
,.mqtt_disconnect
=sim7020_mqtt_disconnect
,.mqtt_pub
=sim7020_mqtt_pub
,.mqtt_sub
=sim7020_mqtt_sub
,.mqtt_unsub
=sim7020_mqtt_unsub
,.mqtt_recv_register
=sim7020_mqtt_recv_register
,
};
測試代碼如下:
void StartDefaultTask(void const * argument
)
{float temp
,humi
;uint8_t write_buf
[]="1234567890";uint8_t read_buf
[20];uint16_t read_len
;#define TEST_NAME 0X0001uint8_t buf
[5];char reply_buf
[30];uint16_t reply_len
;debug_init();led_init();key_init();led_blink(2,5);sht30_init();#define SERVER "a1gPAyS0jai.iot-as-mqtt.cn-shanghai.aliyuncs.com"#define PRO_KEY "a1gPAyS0jai"#define DEV_NAME "s0001"#define DEV_SECRET "abd7aff3aa5dd6a44d85ec03561c733c"#define TOPIC_SUB "/sys/a1gPAyS0jai/s0001/thing/model/down_raw"#define TOPIC_PUB "/sys/a1gPAyS0jai/s0001/thing/model/up_raw"at_net_dev_register(&dev_sim7020
);at_net_init();at_net_mqtt_connect(SERVER
,1883,PRO_KEY
,DEV_NAME
,DEV_SECRET
);at_net_mqtt_recv_register(mqtt_recv_handler
);at_net_mqtt_sub(TOPIC_PUB
);at_net_mqtt_pub(TOPIC_PUB
,"3132333435",10);vTaskDelay(10000);at_net_mqtt_disconnect();for(;;){ osDelay(1000);}
}
總結
以上是生活随笔為你收集整理的NB驱动层MQTT发布和订阅数据的代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。