【安信可LoRa模组专题②】快速搭建远程控制灯LoRa智能灯控【51单片机篇】

本LoRa模组系列博客学习由 安信可科技 - 官方博客 技术分享,如有疑问请留言或联系邮箱。

前言

    今天我们来深度解析一下Lora在照明设备中的应用原理。

    这里Lora的优势以及劣势我就不多加赘述了,大家可以上网搜索一下,做过或者接触过物联网设备开发的朋友应该比较清楚,无线模块在这个行业中所占的比重,无线控制其实就是A端发送一个信号,B端收到以后做出相应动作的一个过程

设备组成

    今天我们用的设备比较简单,就是入门级的STC主控MCU加上含一片SX1278芯片的Ra-01模块,需要两个,外加两根弹簧天线。

    安信可淘宝店是默认一个Ra-01模组配送一根433MHz弹簧天线的,很方便。 推荐bug一个!

    另外生成的HEX文件,用串口烧录。

    如果不明白的朋友可以看我们的上一篇文章,其中有介绍这个主控的详细接线以及烧录测试流程。

【安信可LoRa模组专题①】安信可LoRa快速入门指南
在这里插入图片描述

一.远程灯控(开关)

1.1原理分析

     我们目前手上有两个同样的设备,烧录同样的程序,程序运行在MCU中,通过外接的SPI驱动Ra-01射频模块发射和接收数据,接收端接收到这个数据做出响应,实现一个远程控制灯开和关的方案。

1.2基本通信

首先需要两个模组间能够进行通信,代码中需要编辑发射机以及接收机;
     这里我们定义出接收机和发送机的逻辑代码,完成发送和接收,这部分我直接放在了主函数中了,可以把他放在单独文件中这样就便于观察条理了。

else {
			P32 = 1;
			RF_EX0_STATUS = SX1276ReadBuffer( REG_LR_IRQFLAGS);
			if (RF_EX0_STATUS > 0) {
				if ((RF_EX0_STATUS & 0x40) == 0x40) {
					CRC_Value = SX1276ReadBuffer( REG_LR_MODEMCONFIG2);
					if (CRC_Value & 0x04 == 0x04) {
						SX1276WriteBuffer(REG_LR_FIFOADDRPTR, 0x00);
						SX1278_RLEN = SX1276ReadBuffer(REG_LR_NBRXBYTES);
						lpTypefunc.lpSwitchEnStatus(enOpen);
						lpTypefunc.lpByteWritefunc(0x00);
						
						for (RF_REC_RLEN_i = 0; RF_REC_RLEN_i < SX1278_RLEN;RF_REC_RLEN_i++) {
							recv[RF_REC_RLEN_i] = lpTypefunc.lpByteReadfunc();
						}
						lpTypefunc.lpSwitchEnStatus(enClose);
						recv[RF_REC_RLEN_i] = '\0';
						RF_RECEIVE();						
						uartSendString(recv);

							
						P17 = 0;
					}
				} 
				else if ((RF_EX0_STATUS & 0x04) == 0x04) {
					if ((RF_EX0_STATUS & 0x01) == 0x01) { //表示CAD 检测到扩频信号 模块进入了接收状态来接收数据
						SX1276LoRaSetOpMode(Stdby_mode);
						SX1276WriteBuffer(REG_LR_IRQFLAGSMASK, IRQN_RXD_Value); //打开发送中断
						SX1276WriteBuffer(REG_LR_HOPPERIOD, PACKET_MIAX_Value);
						SX1276WriteBuffer( REG_LR_DIOMAPPING1, 0X02);
						SX1276WriteBuffer( REG_LR_DIOMAPPING2, 0x00);
						SX1276LoRaSetOpMode(Receiver_mode);
					} 
					else {                          
						SX1276LoRaSetOpMode(Stdby_mode);
						SX1276WriteBuffer(REG_LR_IRQFLAGSMASK,IRQN_SEELP_Value);   //打开发送中断
						SX1276WriteBuffer( REG_LR_DIOMAPPING1, 0X00);
						SX1276WriteBuffer( REG_LR_DIOMAPPING2, 0X00);
						SX1276LoRaSetOpMode(Sleep_mode);
						//PA_SEELP_OUT();
					}
				}
				else {
					SX1276LoRaSetOpMode(Stdby_mode);
					SX1276WriteBuffer(REG_LR_IRQFLAGSMASK, IRQN_RXD_Value);  //打开发送中断
					SX1276WriteBuffer(REG_LR_HOPPERIOD, PACKET_MIAX_Value);
					SX1276WriteBuffer( REG_LR_DIOMAPPING1, 0x02);
					SX1276WriteBuffer( REG_LR_DIOMAPPING2, 0x00);
					SX1276LoRaSetOpMode(Receiver_mode);
				}
				RF_REC_RLEN_i = 0;
				SX1276WriteBuffer( REG_LR_IRQFLAGS, 0xff);
				Delay1s(300);
			} else {
				P17 = 1;
			}
		}

编辑通信内容代码
     我们定义两组通信,分别为内容分别为1和2,这个对应后面逻辑中的两个按键。

SX1276WriteBuffer( REG_LR_IRQFLAGS, 0xff);
			FUN_RF_SENDPACKET("1",1);
			Delay1s(1000);
			SX1276WriteBuffer( REG_LR_IRQFLAGS, 0xff);
SX1276WriteBuffer( REG_LR_IRQFLAGS, 0xff);
			FUN_RF_SENDPACKET("2",1);
			Delay1s(1000);
			SX1276WriteBuffer( REG_LR_IRQFLAGS, 0xff);

1.3应用层逻辑设计

     如上所示,我们的通信步骤就完成了,接下来就是触发逻辑以及响应逻辑的应用层代码了,这一部分
     我就需要结合我们的应用设备功能来设计,如设备组成图所示,我们的硬件资源一共有10个LED和两个按键,我们就以目前资源来来做一个按键控制灯的逻辑。
按照原理图定义IO口

#ifndef __GPIO_H
#define __GPIO_H

#define KEY                                  P30
#define KEY2                                 P31

#define led                                  P16
#define led2                                 P35

#define UART_TX_PIN                          P31

按键控制逻辑

		if (P30 == 0) {
			P17 = 1;
			P32 = 0;
			SX1276WriteBuffer( REG_LR_IRQFLAGS, 0xff);
			FUN_RF_SENDPACKET("1",1);
			Delay1s(1000);
			SX1276WriteBuffer( REG_LR_IRQFLAGS, 0xff);
		} 
		else if (P31 == 0) {
			P17 = 1;
			P32 = 0;
			SX1276WriteBuffer( REG_LR_IRQFLAGS, 0xff);
			FUN_RF_SENDPACKET("2",1);
			Delay1s(1000);
			SX1276WriteBuffer( REG_LR_IRQFLAGS, 0xff);
		}
						if(recv[0] == '1') 
						{
							P35 = ~P35;
						}
						else if(recv[0] == '2')
						{
							P16=0;
							P35=1;
						}

至此我们就完成了远程控制灯开关的逻辑编写了,很简单,我们利用提供的源码稍作修改就能做出这个效果。

二.远程灯控(指定设备)

2.1原理分析

上述的设备应用在实际场景中已经能做到星型组网,但是这个组网的通信方式就不是很符合灯控设备的控制逻辑。
因为在我们上述所写的代码中,这个设备是全频段通信的,也就是说同一个固件,我烧录在不同设备中,只要我按下按键,所有的设备都会响应。
所以我们接下来做的操作就是在这个代码的基础上做出修改让我们的主控可以随意控制多个设备。
一对多单个控制的话方式很多,我先来做一种最简单的方法,按键A控制发射在470频段,按键B控制发送在480频段。

2.2主机代码

下面是我们计算好的频段

unsigned char Frequency[3] = { 0x6c, 0x80, 0x00 };//470Mhz
//unsigned char Frequency[3] = { 0x6c, 0x80, 0x00 };//430Mhz 频率设置
//unsigned char Frequency[3] = { 0x6c, 0x80, 0x12 };//475.5Mhz 频率设置
//unsigned char Frequency[3] = { 0x78, 0x10, 0x00 };//480.25Mhz 频率设置
//unsigned char Frequency[3] = { 0x78, 0x20, 0x00 };//480.5Mhz 频率设置

在按键B处定义出按键数组,表示按下按键B模块跳到480频段发送数据2

		} else if (P31 == 0) {
			Frequency[0] = 0x78;
			Frequency[1] = 0x20;
			Frequency[2] = 0x00;
			SX1276LoRaSetRrequency();
		    SX1276WriteBuffer( REG_LR_IRQFLAGS, 0xff);
			FUN_RF_SENDPACKET("2",1);
			Delay1s(1000);
			SX1276WriteBuffer( REG_LR_IRQFLAGS, 0xff);
		}
#define IRQN_TXD_Value                               0xF7
#define IRQN_RXD_Value                               0x9F
#define IRQN_CAD_Value                               0xFA
#define IRQN_SEELP_Value                             0xFF
#define PACKET_MIAX_Value                            0xff
extern unsigned char Frequency[3];

2.3从机代码

在这里,我们要单独生成480和470频段的接收机代码固件,分别烧录到我们的从机模块中,我们只要控制以下代码段就可以完成对不同频段的控制效果。(这里的从机代码,我们可以直接使用第一节中的灯控代码即可)

unsigned char Frequency[3] = { 0x6c, 0x80, 0x00 };//470Mhz
//unsigned char Frequency[3] = { 0x6c, 0x80, 0x00 };//430Mhz 频率设置
//unsigned char Frequency[3] = { 0x6c, 0x80, 0x12 };//475.5Mhz 频率设置
//unsigned char Frequency[3] = { 0x78, 0x10, 0x00 };//480.25Mhz 频率设置
//unsigned char Frequency[3] = { 0x78, 0x20, 0x00 };//480.5Mhz 频率设置

总结

第一步:我们首先要确保能够通信,然后在通信的基础上我们再来对收到的值进行判断,并且做出相对的输出结果(控制灯的方案)到这里我们完成了最主要的内容——通信部分。
第二步:然后我们考虑需要实现的一个主机控制不同的设备,这样我们可以把从机工作在不同频段,主机切换频段来完成通信。

     本篇文章主要在于介绍Lora的多点控制的原理,非常简单,只是其中的一种方案,后面有机会我再介绍LoRa其他的控制收发的原理,其他方案更贴近于实际的设备控制如果需要源码的小伙伴可以点击下方邮箱私信。

联系我们

公司官网:https://www.ai-thinker.com
开发资料:https://docs.ai-thinker.com/
官方论坛:http://bbs.ai-thinker.com
商务合作:sales@aithinker.com
技术支持:support@aithinker.com
联系地址:广东省深圳市宝安区西乡街道华丰智慧创新港C座410室
联系电话:0755-29162996