NB-IoT 智能门磁代码快速实现
Posted 三明治开发社区
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NB-IoT 智能门磁代码快速实现相关的知识,希望对你有一定的参考价值。
在上一篇我们提到了NB-IoT智能门磁硬件搭建,接下来就来说说如何通过涂鸦MCU SDK快速实现NB门磁的功能代码。
涂鸦NM1模组一般都烧录了涂鸦通用固件,只需根据涂鸦MCU对接串口协议向模组发送各种串口指令即可实现设备的联网上云和数据的上报下发,而MCU SDK可以帮助我们将精力集中在应用开发上,无需过多关心MCU与模组之间的数据收发过程
1.创建产品
- 进入涂鸦智能IoT平台,点击创建产品。选择安防传感->门窗磁
- 选择自定义方案,选择门磁,为你的产品起一个名字,选择联网方式为NB-IoT,功耗类型选择PSM,点击创建产品。
- 功能选择门磁和电池电量。
- 选择完APP面板后,点击下一步:硬件开发。然后将页面拉到最下面,点击下载全部按钮,下载开发资料以待后用。
2.模组调试
安装涂鸦模组调试助手,打开后在主界面设置栏里导入功能点调试文件(即下载的开发资料中的.json文件),波特率设置9600,功耗模式 选择psm,连接方式isp,然后用串口工具连接NM1模组,点击开始调试:
对照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_MAINREGULATOR_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;![在这里插入图片描述](https://img-blog.csdnimg.cn/20210407185629211.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Nzk1MDYzNw==,size_16,color_FFFFFF,t_70#pic_center)
}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上
以上是关于NB-IoT 智能门磁代码快速实现的主要内容,如果未能解决你的问题,请参考以下文章