* 導師視頻講解:[**去聽課**](https://www.bilibili.com/video/BV1Cb4y1171H?p=16)
>[success] **技術支持說明**
> 1.**客服**提供簡單的技術支持,一般自主學習為主
> 2.可到官方問答社區中提問:[**去提問**](https://bbs.csdn.net/forums/nb-iot)
> 3.工程師**會盡快**解答社區問題,但他們是一線開發,【**難以保證**】解答時效,解答辛苦,感謝理解!
<br/>
>[danger] 本項目為課外學習內容,其內容較為復雜且有一定難度,因此:**未學習前面章節者**,**請止步**!
<br/>
## **數據通信任務說明**
打開task_nbiot.c 文件,可以看到基于NB-IoT的數據通信任務,代碼如下:
```
#include "task_nbiot.h"
#include "svc_plugins.h"
#include "svc_log.h"
#include "svc_task.h"
#include "svc_msg.h"
#include <stdio.h>
#include <string.h>
enum {
TASK_NBIOT_AT_TEST = 0,
TASK_NBIOT_AT_TEST_RSP,
TASK_NBIOT_DISABLE_PSM,
TASK_NBIOT_DISABLE_PSM_RSP,
TASK_NBIOT_SET_BAND,
TASK_NBIOT_SET_BAND_RSP,
TASK_NBIOT_DHCP,
TASK_NBIOT_DHCP_RSP,
TASK_NBIOT_MQTT_OPEN,
TASK_NBIOT_MQTT_OPEN_RSP,
TASK_NBIOT_MQTT_CONNECT,
TASK_NBIOT_MQTT_CONNECT_RSP,
TASK_NBIOT_GET_TEMP_HUMI,
TASK_NBIOT_MQTT_PRE_SEND,
TASK_NBIOT_MQTT_SEND,
TASK_NBIOT_MQTT_CLOSE,
TASK_NBIOT_FINISH,
};
static void taskNbiotRunner(uint8_t, void *);
static void taskNbiotDebug(const uint8_t *msg, uint8_t len);
static int taskNbiotDefaultCheck(void);
static int taskNbiotDHCPCheck(void);
static int taskNbiotMqttOpenCheck(void);
static int taskNbiotMqttConnectCheck(void);
void taskNbiotInit()
{
svcLogWriteLcd(!(0), (uint8_t *)"Task: NBIoT", 0, 0, 0);
svcTaskAdd(2000, 1, taskNbiotRunner, 0);
}
void taskNbiotRunner(uint8_t id, void *args)
{
int temp, humi;
char dbg[64], data[64];
const char *topic = "topic/pub";
static int taskNbiotCnt = 0;
static int taskNbiotStep = TASK_NBIOT_AT_TEST;
switch (taskNbiotStep) {
/* AT Test */
case TASK_NBIOT_AT_TEST:
svcLogWriteLcd(!(0), (uint8_t *)"CMD: AT", 0, 0, 0);
svcMsgWriteString("AT\r\n");
taskNbiotStep++;
break;
/* Response: AT Test */
case TASK_NBIOT_AT_TEST_RSP:
svcLogWriteLcd(!(0), (uint8_t *)"RSP: AT", 0, 0, 0);
if (taskNbiotDefaultCheck() == 0) taskNbiotStep++;
else taskNbiotStep--;
break;
/* Disable PSM */
case TASK_NBIOT_DISABLE_PSM:
svcLogWriteLcd(!(0), (uint8_t *)"CMD: QSCLK=0", 0, 0, 0);
svcMsgWriteString("AT+QSCLK=0\r\n");
taskNbiotStep++;
break;
/* Response: Disable PSM */
case TASK_NBIOT_DISABLE_PSM_RSP:
svcLogWriteLcd(!(0), (uint8_t *)"RSP: QSCLK=0", 0, 0, 0);
if (taskNbiotDefaultCheck() == 0) taskNbiotStep++;
else taskNbiotStep--;
break;
/* Set Band */
case TASK_NBIOT_SET_BAND:
svcLogWriteLcd(!(0), (uint8_t *)"CMD: QBAND=8", 0, 0, 0);
svcMsgWriteString("AT+QBAND=1,8\r\n");
taskNbiotStep++;
break;
/* Response: Set Band */
case TASK_NBIOT_SET_BAND_RSP:
svcLogWriteLcd(!(0), (uint8_t *)"RSP: QBAND=8", 0, 0, 0);
if (taskNbiotDefaultCheck() == 0) taskNbiotStep++;
else taskNbiotStep--;
break;
/* DHCP */
case TASK_NBIOT_DHCP:
svcLogWriteLcd(!(0), (uint8_t *)"CMD: DHCP", 0, 0, 0);
svcMsgWriteString("AT+CGPADDR?\r\n");
taskNbiotStep++;
taskNbiotCnt = 0;
break;
/* Response: DHCP */
case TASK_NBIOT_DHCP_RSP:
svcLogWriteLcd(!(0), (uint8_t *)"RSP: DHCP", 0, 0, 0);
if (++taskNbiotCnt > 2) {
if (taskNbiotDHCPCheck() == 0) taskNbiotStep++;
else taskNbiotStep--;
}
break;
/* MQTT Open */
case TASK_NBIOT_MQTT_OPEN:
svcLogWriteLcd(!(0), (uint8_t *)"CMD: QMTOPEN", 0, 0, 0);
svcMsgWriteString("AT+QMTOPEN=0,\"1.15.27.206\",1883\r\n");
taskNbiotStep++;
taskNbiotCnt = 0;
break;
/* Response: MQTT Open */
case TASK_NBIOT_MQTT_OPEN_RSP:
svcLogWriteLcd(!(0), (uint8_t *)"RSP: QMTOPEN", 0, 0, 0);
if (++taskNbiotCnt > 2) {
if (taskNbiotMqttOpenCheck() == 0) taskNbiotStep++;
else taskNbiotStep--;
}
break;
/* MQTT Connect */
case TASK_NBIOT_MQTT_CONNECT:
svcLogWriteLcd(!(0), (uint8_t *)"CMD: QMTCONN", 0, 0, 0);
svcMsgWriteString("AT+QMTCONN=0,\"iotdevice\"\r\n");
taskNbiotStep++;
taskNbiotCnt = 0;
break;
/* Response: MQTT Connect */
case TASK_NBIOT_MQTT_CONNECT_RSP:
svcLogWriteLcd(!(0), (uint8_t *)"RSP: QMTCONN", 0, 0, 0);
if (++taskNbiotCnt > 3) {
if (taskNbiotMqttConnectCheck() == 0) taskNbiotStep++;
else taskNbiotStep = TASK_NBIOT_MQTT_CLOSE;
}
break;
/* Get Temp and Humi */
case TASK_NBIOT_GET_TEMP_HUMI:
svcLogWriteLcd(!(0), (uint8_t *)"CMD: Temp&Humi", 0, 0, 0);
if (svcPluginsGetTempHumi(&temp, &humi) == 0) {
sprintf(dbg, "T: %dC, H: %d%%", temp, humi);
svcLogWriteLcd(!(0), (uint8_t *)"CMD: Temp&Humi", (uint8_t *)dbg, 0, 0);
taskNbiotStep++;
}
break;
/* MQTT Pre-Send */
case TASK_NBIOT_MQTT_PRE_SEND:
svcLogWriteLcd(!(0), (uint8_t *)"CMD: QMTPUB", 0, 0, 0);
sprintf(data, "{\"temp\":%d,\"humi\":%d}", temp, humi);
sprintf(dbg, "AT+QMTPUB=0,0,0,0,\"%s\",%d\r\n", topic, strlen(data));
svcMsgWriteString(dbg);
taskNbiotStep++;
break;
/* MQTT Send */
case TASK_NBIOT_MQTT_SEND:
svcLogWriteLcd(!(0), (uint8_t *)"CMD: SEND", 0, 0, 0);
svcMsgWriteString(data);
taskNbiotStep++;
break;
/* MQTT Close */
case TASK_NBIOT_MQTT_CLOSE:
svcLogWriteLcd(!(0), (uint8_t *)"CMD: CLOSE", 0, 0, 0);
svcMsgWriteString("AT+QMTDISC=0\r\n");
taskNbiotStep++;
break;
/* Finish */
case TASK_NBIOT_FINISH:
svcLogWriteLcd(!(0), (uint8_t *)"CMD: Finish", 0, 0, 0);
taskNbiotStep++;
break;
default: break;
}
}
void taskNbiotDebug(const uint8_t *msg, uint8_t len)
{
uint8_t str[16 + 1];
memset(str, 0, sizeof(str));
for (uint8_t i = 0, j = 0, k = 2; i < len && k < 5; i++) {
str[j++] = msg[i];
if ((i != 0 && i % 15 == 0) || i + 1 == len) {
if (k == 2) svcLogWriteLcd(0, 0, str, 0, 0);
else if (k == 3) svcLogWriteLcd(0, 0, 0, str, 0);
else if (k == 4) svcLogWriteLcd(0, 0, 0, 0, str);
j = 0;
k++;
memset(str, 0, sizeof(str));
}
}
}
int taskNbiotDefaultCheck()
{
uint16_t len;
uint8_t buf[SVC_MSG_BUF_MAX + 1];
memset(buf, 0, sizeof(buf));
len = svcMsgRead(buf, sizeof(buf));
if (len == 0) return -1;
taskNbiotDebug(buf, len);
if (strstr((char *)buf, "OK") != NULL) return 0;
return -1;
}
int taskNbiotDHCPCheck()
{
uint16_t len;
uint8_t buf[SVC_MSG_BUF_MAX + 1];
memset(buf, 0, sizeof(buf));
len = svcMsgRead(buf, sizeof(buf));
if (len == 0) return -1;
taskNbiotDebug(buf, len);
if (strstr((char *)buf, "OK") == NULL) return -1;
char *start = strstr((char *)buf, "+CGPADDR: ");
if (start == NULL) return -1;
char *ip = start + 13;
char *end = strchr(ip, '"');
if (end == NULL) return -1;
*end = 0;
if (strlen(ip) < 7) return -1;
return 0;
}
int taskNbiotMqttOpenCheck()
{
uint16_t len;
uint8_t buf[SVC_MSG_BUF_MAX + 1];
memset(buf, 0, sizeof(buf));
len = svcMsgRead(buf, sizeof(buf));
if (len == 0) return -1;
taskNbiotDebug(buf, len);
if (strstr((char *)buf, "+QMTOPEN: ") != NULL) return 0;
return -1;
}
int taskNbiotMqttConnectCheck()
{
uint16_t len;
uint8_t buf[SVC_MSG_BUF_MAX + 1];
memset(buf, 0, sizeof(buf));
len = svcMsgRead(buf, sizeof(buf));
if (len == 0) return -1;
taskNbiotDebug(buf, len);
if (strstr((char *)buf, "+QMTCONN: ") != NULL) return 0;
return -1;
}
```
<br/>
<br/>
## **商務合作**
如有以下需求,可掃碼添加管理員好友,注明“**商務合作**”
* 項目定制開發,技術范圍:**NB-IoT**、**CATn(4G)**、**WiFi**、**ZigBee**、**BLE Mesh**以及**STM32**、**嵌入式Linux**等;
* 入駐平臺,成為講師;
* 接項目賺外快;
* 善學坊官網:[www.sxf-iot.com](https://www.sxf-iot.com/)

(非商務合作**勿擾**,此處**非**技術支持)
- 課程介紹
- 配套資源下載
- 配套開發套件簡介
- 簡介
- 硬件組成 & 技術參數
- 電路原理圖 & PCB圖
- 撥碼開關使用說明
- 第一部分:無線通信 開發指南
- 1.1.1 NB-IoT:技術簡介
- 1.1.2 NB:CH34x USB轉串口驅動安裝
- 1.1.3 NB:AT 指令開發與測試
- 1.1.4 NB:基礎指令集簡介
- 1.1.5 NB:云端服務器
- 1.1.5.1 PuTTY 簡介與安裝
- 1.1.5.2 登錄云端服務器
- 1.1.6 NB:移遠官方工具簡介
- 1.1.7 NB:使用UDP協議與云端服務器通信
- 1.1.8 NB:使用TCP協議與云端服務器通信
- 1.1.9 NB:使用MQTT協議與云端服務器通信
- 進階課程
- 第二部分:STM32 開發指南
- 2.1 搭建開發環境
- 2.1.1 Keil MDK 簡介與安裝
- 2.1.2 STM32 Pack 簡介與安裝
- 2.1.3 CH34x 驅動簡介與安裝
- 2.1.4 其他開發工具
- 2.2 STM32 開發基礎
- 2.2.1 新建工程
- 2.2.2 實現第1個程序
- 2.2.3 Hex 文件燒錄詳解
- 2.3 移植官方標準工程模板
- 2.4 GPIO實驗——LED燈
- 2.5 系統延時應用
- 2.6 GPIO實驗——按鍵
- 2.7 GPIO中斷實驗——按鍵觸發
- 2.8 使用定時器TIM3
- 2.9 串口通信實驗
- 2.10 ADC 實驗
- 2.11 OLED顯示器實驗
- 2.12 SDK 設計思想
- 2.13 SDK 架構解析
- 2.14 多任務應用
- 2.15 輸入型任務:按鍵輸入
- 2.16 輸入型任務:串口接收
- 課外篇:項目實戰
- 基于STM32+NB-IoT的溫濕度采集
- 系統簡介
- 系統搭建
- 系統詳解
- 1.代碼編譯與架構說明
- 2.DHT11溫濕度傳感器
- 3. 數據通信任務說明
- 版權聲明與免責聲明