?我们上一篇提到了NB-IoT智能门磁硬件的谈谈如何通过涂鸦构建智能门磁硬件MCU SDK快速实现NB门磁的功能代码。
??涂鸦NM1模块一般烧录涂鸦通用固件,只根据涂鸦MCU对接串口协议可以通过向模块发送各种串口指令来报告和发布设备的在线云和数据,而MCU SDK它可以帮助我们专注于应用开发而不需要太多的关注MCU与模块之间的数据收发过程
1.创建产品
- 进入涂鸦智能IoT点击创建产品的平台。选择安全传感器->门窗磁
- 选择自定义方案,选择门磁,为您的产品命名,选择联网方式NB-IoT,功耗类型选择PSM,点击创建产品。
- 门磁和电池电量的功能选择。
- 选择完APP面板完成后,点击下一步:硬件开发。然后将页面拉到底部,点击下载所有按钮,下载开发数据后再使用。
2.模组调试
??安装涂鸦模块调试助手,打开后将功能点调试文件引入主界面设置栏(即下载的开发数据中.json文件),波特率设置9600,功耗模式 选择psm,连接方式isp,然后用串口工具连接NM点击开始调试模块:
对照NB-IoT串口协议观察界面左侧的模块MCU如果看到模块发送报告网络状态3的数据(55 AA 00 02 00 01 03 XX),这意味着模块没有异常,并成功地连接到运营商平台,但设备没有绑定到涂鸦云。
3.移植MCU SDK
使用STM32CubeMX生产MCU初始工程代码工程代码MCU_SDK涂鸦移植开始移植MCU SDK。
??下载前面的mcu_sdk文件加入工程后,直接编译,然后根据报错提示进行修改:
- uart_transmit_output()函数按#函数按#函数error处理后注释提示信息即可。
- 完善
uart_receive_input()
函数按照#error
处理后注释提示信息即可。
nbiot_uart_service()
函数按照#error
处理后注释提示信息即可。
nbiot_protocol_init()
函数按照#error
处理后注释提示信息即可。
- 接下来便是
all_data_update()
函数将自动报告系统中的所有函数dp个人不需要调用信息。
4.功能实现
- 新建一个user_func.h将门磁设备的各种状态定义为文件。
// 传感器上报标志 typedef enum{ STATE_IDLE = 0, STATE_DOOR_NEED_UP, STATE_POWER_UP, STATE_UP_FINISH, }sensor_state_t; // 门开关状态 typedef enum{ STATE_CLOSE = 0, STATE_OPEN = 1 }door_state_t; typedef struct{ door_state_t door_state; sensor_state_t sensor_state; unsigned char door_up_lock; // 报锁门状态 unsigned char remaining_power; // 设备剩余电量,单位百分比 }device_status_t;
- 在新建的user_func.c在文件中实现一些自定义功能函数nbiot.h在文件中添加头文件#include "user_func.h"。
- 在main.c文件中:
添加头文件#include "nbiot.h"
MCU上电启动后,进入while(1){}循环前,除常规配置外IO口、串口、ADC此外,还需要执行:
nbiot_protocol_init(); ///使用低功耗模式时钟 __HAL_RCC_PWR_CLK_ENABLE(); //初始化NB模块唤醒脚的电平 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
在while(1){}
循环内:
while (1) { nbiot_uart_service(); power_detect_poll(); user_sensor_up_poll(); }
nbiot_uart_service()是SDK对串口数据处理函数进行分析和处理NB-IoT模块返回的数据。
power_detect_poll()是电池电量检测函数,通过函数ADC大概的剩余电量是通过采样和量并保存。由开发者自行实现。
- user_sensor_up_poll()根据传感器上报的任务处理函数NB判断模块的设备状态等因素是否进行报告数据发送处理,是否需要允许MCU进入STOP低功耗模式。由开发者自己实现。
void user_sensor_up_poll(void) { if(device_status_s.door_up_lock) { // 判断未处理的门状态报告任务,开始向任务报告NB模块发送报告数据。 if(STATE_DOOR_NEED_UP == device_status_s.sensor_state) { mcu_dp_bool_update(DPID_DOORCONTACT_STATE, device_status_s.door_state); device_status_s.door_up_lock = 0; } else if(STATE_POWER_UP == device_status_s.sensor_state) { mcu_dp_value_update(DPID_BATTERY_PERCENTAGE, device_status_s.remaining_power); device_status_s.door_up_lock = 0; }else if(STATE_UP_FINISH == device_status_s.sensor_state) { device_status_s.sensor_state = STATE_IDLE; device_status_s.door_up_lock = 0; // 打开NB模组PSM休眠锁 //mcu_set_nbiot_sleeplock(0); // MCU进入低功耗模式 enter_lowpower_mode(); } } }
- 实现进出低功耗模式两个函数:
void enter_lowpower_mode() { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET); lowpower_gpio_init(); HAL_ADC_Stop(&hadc1); HAL_ADC_DeInit(&hadc1); HAL_UART_DeInit(&huart3); // HAL_TIM_Base_DeInit(&htim3); // 关闭时钟 __HAL_RCC_DMA1_CLK_DISABLE(); __HAL_RCC_GPIOB_CLK_DISABLE(); __HAL_RCC_GPIOC_CLK_DISABLE(); __HAL_RCC_GPIOC_CLK_DISABLE(); __HAL_RCC_GPIOD_CLK_DISABLE(); __HAL_RCC_GPIOF_CLK_DISABLE(); HAL_SuspendTick(); // 进入stop模式 HAL_PWR_EnterSTOPMode(PWR_MAIREGULATOR_ON,PWR_STOPENTRY_WFI);
}
void leave_lowpower_mode()
{
SystemClock_Config();
MX_GPIO_Init();
// MX_TIM3_Init();
MX_USART3_UART_Init();
__HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE);
MX_ADC1_Init();
HAL_ADC_Start(&hadc1);
// 拉高引脚唤醒NB模组
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);
delay_ms(200);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
// 传感器需要上报门开关状态
device_status_s.sensor_state = STATE_DOOR_NEED_UP;
}
- MCU的stop低功耗模式主要由中断来唤醒,所以需要在中断回调函数中调用
nbiot_uart_service()
并记录门的开关状态:
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
leave_lowpower_mode();
device_status_s.door_state = STATE_OPEN;
}
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
leave_lowpower_mode();
device_status_s.door_state = STATE_CLOSE;
}
- 由于NB模组从PSM模式中唤醒需要重新连接涂鸦云,所以mcu需要等待模组连接成功后才开始上报dp数据。在
system.c
文件下data_handle
函数的工作状态回码处理case中添加代码实现:
case NBIOT_STATE_CMD: //工作状态
nbiot_work_state = nbiot_uart_rx_buf[offset + DATA_START];
nbiot_uart_write_frame(NBIOT_STATE_CMD,0);
if (NB_STATE_DEVICE_BINDED == mcu_get_nbiot_work_state()) {
//当模组连接涂鸦云时打开门磁上报锁,允许进行dp上报
device_status_s.door_up_lock = 1;
}else {
device_status_s.door_up_lock = 0;
}
break;
- 在
system.c
文件下data_handle
函数的上报回码处理case中添加代码:
case STATE_UPLOAD_CMD:
// 判断result的值,确认收到模块返回的信息后,打开门状态上报锁,准备下一次上报
device_status_s.door_up_lock = 1;
device_status_s.sensor_state++;
break;
5.设备绑定
- 完成MCU固件的编译和烧录后,即可绑定使用设备。
- 打开涂鸦智能APP,点右上角的+号,开启扫描二维码
- 扫描NM1模组板子上的二维码,绑定设备
- 绑定成功后设备即可上传门磁开关状态到APP上