七、云端下发命令控制单片机LED灯的亮灭

说完了怎么把数据上传到云端,那么来说说怎么在云端下发命令到设备端吧,接下来讲解怎么在云端下发命令控制单片机上LED灯的亮灭。

同样在云端上要定义一个服务来实现这个功能。怎么定义前面已经说过了,不同的就是参数的设置不同,下面是我定义的控制LED灯亮灭的服务。

 我们把BC28模块的拨码开关拨到“To BC28”,在云平台上下发命令,然后在串口调试助手上看看收到什么内容。

指令下发的步骤 :

确定之后显示指令下发成功即可。然后再串口调试助手上查看指令下发后收到的返回值。(前提是BC28模块已经联网) 

如果显示指令下发成功,但是在串口调试助手上没有收到返回值,那是因为在一段时间内云平台与设备没有进行数据互传,NBIOT模块进入了低功耗模式。所以这时在指令下发开始到指令超时时间内发送一条数据到云端,我们就可以看到指令下发后的返回值了。在上图中可以看到我设置的指令超时时间是66s,所以在这66s发送一条指令到云端重新建立连接,就可以看到发送指令的返回值了。

 知道怎么下发指令之后,现在来讲讲MCU怎么接收和解析下发指令收到的返回值,从而控制LED灯的亮灭。

首先是对LED灯引脚的配置,我的是PB7控制绿灯状态,这里我就使用这个引脚。

 之前有说过MCU是直接通过串口3与BC28模块进行数据互传,从而与云平台通信。其实云平台下发指令的返回值是存储在串口3的数组里面的,所以我们要从这个数据里面收到的东西进行解析。我采用的是串口中断的方式进行接收数据,之前配置串口3的时候已经使能中断。

首先写一个中断回调函数,在main.c文件下合适位置即可,这是一个内部函数,不需要调用和声明

/*是一个UART接收中断的回调函数,当UART接收到数据时,会调用该函数*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if (huart->Instance == USART3)//过判断huart->Instance来确定是哪个UART实例触发了中断(这里是USART3)
	{
		if(g_uart3_bytes< sizeof(g_uart3_rxbuf))/*判断g_uart3_bytes是否小于sizeof(g_uart3_rxbuf),如果是,则将接收到的数据存储到g_uart3_rxbuf数组中,并将g_uart3_bytes+1*/
		{
			g_uart3_rxbuf[g_uart3_bytes++] = s_uart3_rxch;
		}
		else/*如果g_uart3_bytes已经达到数组的大小,说明数组已满,需要重新开始存储数据,以将g_uart3_bytes重置0,并将接收到的数据存储到g_uart3_rxbuf数组的第1个位置*/
		{
			g_uart3_bytes = 0;
			g_uart3_rxbuf[g_uart3_bytes++] = s_uart3_rxch;
		}
		HAL_UART_Receive_IT(&huart3,&s_uart3_rxch,1);/*通过调用HAL_UART_Receive_IT函数来重新启动UART接收中断,以便继续接收下一个数据*/
	}
}

定义变量s_uart3_rxch

* USER CODE BEGIN 0 */

static int report_tempRH_json(void);//采集温湿
extern int setup_nbiot();//NBIOT联网
int fstr_to_hex(char *fstr, unsigned int fstrlen, char *out);

static uint8_t s_uart3_rxch;

/* USER CODE END 0 */

下面修改while()的代码来实现功能

while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	  report_tempRH_json();
	  HAL_Delay(3000);

/*控制LED灯状态*/
	  HAL_UART_Receive_IT(&huart3,&s_uart3_rxch,200);
	  HAL_Delay(1000);
	  printf("%s\r\n",g_uart3_rxbuf);
	  if (strstr(g_nbiot_rxbuf,"0101"))/*判断是否下发1指令*/
	  {
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);/*下发指令1就点亮灯*/
		  memset(g_uart3_rxbuf,0,sizeof(g_uart3_rxbuf));
	  }
	  if (strstr(g_nbiot_rxbuf,"0100") && strstr(g_nbiot_rxbuf,"061F52"))/*判断是否下发0指令*/
	  {
		 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);/*下发指令0就把灯熄灭*/
		 memset(g_uart3_rxbuf,0,sizeof(g_uart3_rxbuf));
	  }
  }

 判断条件是根据数据收到的返回值来确定的,在上面用串口调试助手接收下发指令的返回值我们可以知道,下发1指令有“0101”这子串;下发0指令的时候有“0100”这个字串,但是因为上传数据的时候也会有返回值,而且也会返回“0100”这个字串,从而不能判断是否下发了0指令,所以又增加了一个判断条件“061F52”,这样才能唯一判断是否下发了指令0。

编译运行代码,在云端可以看到温湿度间隔一定时间上报,然后在云端下发指令1可以看到LED灯被点亮,下发指令0看到LED熄灭。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值