NB-IoT下發指令控制stm32LED燈

2020-09-30 12:00:51

NB-IoT簡單介紹

NB-Iot(窄頻物聯網),本次實驗用到的型號是stm32F051 + NB86-G。NB-IOT 節點控制模組是有 1.44 寸 LCD 液晶屏、NB-IOT 模組、和感測器節點介面組成。底部有 miniUSB 轉串列埠,方便單獨就一個底板進行偵錯。
下圖為 NB-IOT 一鍵還原+溫溼度模組的硬體圖片:在這裡插入圖片描述

NB-IoT串列埠通訊介紹

其他不做介紹,這裡只介紹NB串列埠通訊,stm32有兩個uart,分別為uart1和uart2,其中uart1用作stm32與串列埠偵錯助手通訊的,uart2用作stm32與NB86-G進行通訊的。所以如果想要在串列埠偵錯助手看到uart2 的資料資訊,就需要進行資料透傳,也就是,從uart2接收的資料發給uart1,uart1接收到的資料再發給uart2,這樣就可以在串列埠偵錯助手看到資料資訊。

NB-IoT上報和下發指令方式

本文章實現的是通過ctwing電信雲平臺下發指令給開發板,開發板接收到指令之後,分別進行開燈和關燈。
電信雲平臺提供了python、go、Java等語言的SDK,所以我們除了在平臺下發指令介面點選下發指令完成指令的下發,還可以通過平臺提供的API介面完成指令的上報和下發功能(當然SDK包提供了多個API介面,根據需求進行使用)。

實驗環境

硬體環境

NB-IOT 一鍵還原板(開發板,包括stm32F051)
ST-Link 下載器
USB 轉串列埠線

軟體環境

STM32CubeMX
MDK-Keil5
串列埠偵錯助手
電信雲平臺
VS Code(用python呼叫API介面)

實驗步驟

在實驗開始之前,要先搭建好環境,保證開發板啟動之後自動上雲,雲平臺產品、裝置、應用提前搭建好,本文章不做介紹。

硬體連線,使用CubeMx生成初始化程式碼

CubeMx設定如下:
在這裡插入圖片描述
把PB1 GPIO口設定為輸出模式,用於LED燈,uart1和uart2設為非同步通訊模式,波特率為9600。
uart1基本引數,改下波特率,其他預設:
在這裡插入圖片描述
uart1使能中斷:
在這裡插入圖片描述
uart2基本引數,改下波特率,其他預設:
在這裡插入圖片描述
uart2使能中斷:
在這裡插入圖片描述
設定完成之後,點選GENERATE CODE生成初始化程式碼。

使用KEIL5編寫業務程式碼

main.c中新增重定向函數、全域性變數:

int fputc(int c, FILE *stream)
{
  unsigned char ch = c;
  HAL_UART_Transmit(&huart1, &ch, 1, HAL_MAX_DELAY);
  return ch;
}
unsigned char uart_recv_char[20];
unsigned char buf[1024];
unsigned int i=0;

這樣就可以直接使用printf函數,往串列埠上傳送資料。

main.c中新增uart2接收中斷使能

HAL_UART_Receive_IT(&huart2,uart_recv_char,1);//使能接收中斷

main.c中新增串列埠接收回撥函數

這裡一邊把接收到的資料發給uart1串列埠顯示,一邊把字元一個一個儲存到buf中,大小為1024,如果大於這個了,就清空重新存。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *uartHandle)
{
	HAL_UART_Transmit(&huart1,uart_recv_char,1,100);
	if(i>1023)
	{
		memset(buf,0,1024);
		i=0;
	}
	buf[i++]=uart_recv_char[0];
	HAL_UART_Receive_IT(&huart2,uart_recv_char,1);
}

在main.c的main函數的while(1)中新增開燈、關燈程式碼

if(buf[strlen((char *)buf)-3]=='1')
{
	HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,0);
}
else if(buf[strlen((char *)buf)-3]=='2')
{
	HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,1);
}

這裡我用16進位制01命令代表開燈,02命令代表關燈,命令是在雲連線完成之後下發的,所以,命令始終存在buf的最後幾位,接收到的命令格式:’’+NNMI:1,02’’,最後兩位就為傳送的16進位制,這裡只需要對最後一位進行判斷是1還是2就ok。那麼為什麼是strlen(buf)-3呢,原因是字串後自跟了\r\n。
這就完成了指令下發並控制LED燈的功能。

使用VS Code 編寫python程式碼,呼叫API介面

首先下載python的SDK包,在電信雲應用介面可以下載。

def send_cmd(cmd):
    result = aep_device_command.CreateCommand('4ywcD78fdig', 'aFBjbqD2xc', '59d8fa3ce589413cb353204b34f735ba', '{"productId":10095853,"deviceId":"2cd6f0cf603d4efea480592e896264c3","operator":"wyy","content":{"dataType":2,"payload":'+'\"'+cmd+'\"'+'}}')
    print('result='+str(result))

引數:(App Key,App Secret,MasterKey,(產品ID,裝置ID,操作者,下發指令的內容)
其中cmd命令通過傳參形式進行設定。

測試

初始化雲連線測試

開發板上電,編譯程式碼,把程式碼燒進開發板,復位:
在這裡插入圖片描述
出現此介面即為初始化成功,並且成功連線雲。

開燈、關燈測試

現在下發一個01指令用於開燈:
在這裡插入圖片描述
檢視串列埠接收到的指令:+NNMI:1,01
在這裡插入圖片描述
現在下發一個02指令用於關燈:
在這裡插入圖片描述
檢視串列埠接收到的指令:+NNMI:1,02
在這裡插入圖片描述
此時可以看到開發板的LED燈亮滅了,如果雲平臺顯示下發指令成功,而串列埠助手並沒有列印出來命令,可能有延時,這時候復位開發板,就可以看到命令輸出到串列埠了。

Python呼叫API測試

點選開燈按鈕執行下發指令01的函數,點選關燈按鈕執行下發指令02的函數,這兩個函數為同一個函數,只是傳參不同。
在這裡插入圖片描述
現在點選開燈:
在這裡插入圖片描述
可以看到command的值為01,即為下發指令成功,對應燈也會亮,並且可以在雲平臺檢視下發指令紀錄檔。
現在點選關燈:
在這裡插入圖片描述
可以看到command的值為02,即為下發指令成功,對應燈也會滅,並且可以在雲平臺檢視下發指令紀錄檔。

總結

本文章主要介紹如何使用uart2和uart1進行通訊以及如何下發指令,如何使用SDK包呼叫API介面完成指令的下發。其他部分沒有詳細介紹。你,學會了嗎???