跳到主要内容

24L01 2.4G 单点对多点通信

前沿:基于前面的《2.4G点对点通信》教程,我可以知道 24L01 系列的 2.4G 通信主要用在点对点通信场景,但如果我们借鉴 RS485 这种半双工通信方式,采用一个中心点,多个 从节点的方式,也可以实现一对多星型网络的通信,只是网络中的通信需要由中心点发起,然后逐个轮询所有从节点,如果应用场景能够接受这种通信方式的话,那也未尝不是一个低成本的物美价廉方案,因为可以省掉一些场合昂贵的 485 总线走线施工及原材料成本。

一、实现原理

在《24L01 2.4G点对点通信》教程我们讲过,在通信中收发双方每包的通信数据固定为32字节,那么我们可以利用首个个字节作为我们的私有地址,然后在Lua代码中通过地址判断的方式来实现多点通信。具体实现方法可参考下面的例程代码。下面的代码实现了主节点每隔100ms轮询一个从节点,那么如果网络中有五个从节点,理想情况下轮询完所有的点需要0.5秒时间。

star_net

二、主节点参考例程

**代码功能描述:**主节点每隔100ms轮询私有地址为1~5的五个从节点,每次向从节点发送6个字节数据,其中第一个字节为从节点的地址,后五个字节为任意数据。随后只有私有地址匹配的从节点才会在100ms中应答主节点。

--配置USB以虚拟串口模式工作,这样调用print()函数就会在电脑串口终端打印输出
LIB_UsbConfig("CDC")
--星型网络中的所有模块,无论发送模块还是接收模块,地址Addr必须一样
Addr = {0x01,0x02,0x03,0x04,0x05}
--设置SI24R1 2.4G无线模块占用MOSI,MISO,CLK,cs,以及D5引脚
--通信信道在2480Mhz,速率125K,发射功率为最大的7dB
LIB_24G_Config("D5", Addr, 80, "125Kpbs", "7dB")
--配置D8端口为普通输出(Core电路板上的LED1灯和D8端口是固定连接的)
LIB_GpioOutputConfig("D8","STANDARD")
timer_cnt = 0
--定义10毫秒定时器的回调函数,函数名字必须是LIB_10msTimerCallback
function LIB_10msTimerCallback()
timer_cnt = timer_cnt + 10
end
--使能系统10毫秒定时器开始工作
LIB_10msTimerConfig("ENABLE")
while(GC(1) == true)
do
--主节点每隔100ms轮询一个从节点(从节点地址为1~5)
--注意:即使某些从节点实际上不存在,也不影响下面的轮询过程
for i = 1, 5 do
sdata = {}
sdata[1] = i --节点地址
--下面是随便发的几个字节数据,你也可以发送其他数据,只要个数不超过31个即可
sdata[2] = 0x51
sdata[3] = 0x52
sdata[4] = 0x53
sdata[5] = 0x54
sdata[6] = 0x55 + i
LIB_24G_Send(sdata)
--开始计时,在100ms内等待该节点回复数据,不管有没有回复
timer_cnt = 0
while timer_cnt < 100
do
recv_flag,recv_tab = LIB_24G_Recv()
if recv_flag == 1 then
--判断地址是否匹配
if recv_tab[1] == i then
print(string.format("receive ack from %d", i))
--USB虚拟串口打印出所有接收到的数据
for i, v in ipairs(recv_tab) do
print(i, v)
end
LIB_GpioToggle("D8")--LED1闪烁
end
end
end
end
end

三、从节点(地址为1)参考例程

**代码功能描述:**从节点收到主节点发来的数据后,判断第一个字节是否和自身的私有地址相等,如果相等,才回复数据。这里回复5个字节,第一个字节是从节点自身的私有地址,为了演示方便,后面四个字节也是私有地址吧。

--该从节点私有地址
MyPrivateAddr = 1
--配置USB以虚拟串口模式工作,这样调用print()函数就会在电脑串口终端打印输出
LIB_UsbConfig("CDC")
--发送模块和接收模块的地址Addr必须一样
Addr = {0x01,0x02,0x03,0x04,0x05}
--设置SI24R1 2.4G无线模块占用MOSI,MISO,CLK,cs,以及D5引脚
--通信信道在2480Mhz,速率125K,发射功率为最大的7dB
LIB_24G_Config("D5", Addr, 80, "125Kpbs", "7dB")
--配置D8端口为普通输出(Core电路板上的LED1灯和D8端口是固定连接的)
LIB_GpioOutputConfig("D8","STANDARD")
while(GC(1) == true)
do
--查询是否收到数据,如果收到就print打印收到的数据,固定为32个
recv_flag,recv_tab = LIB_24G_Recv()
if recv_flag == 1 then
--判断地址是否于自身的私有地址 MyPrivateAddr 匹配
if recv_tab[1] == MyPrivateAddr then
--打印所有收到的数据
print(string.format("receive %d bytes", #recv_tab))
for i, v in ipairs(recv_tab) do
print(i, v)
end
--LED1闪烁
LIB_GpioToggle("D8")
--然后回复五个字节,五个字节的值全部为私有地址
sdata = {}
for i = 1 , 5 do
sdata[i] = MyPrivateAddr
end
LIB_24G_Send(sdata)--回传
end
end
end

四、从节点(地址为2~5)参考例程

从节点2至5和上面的从节点1的代码完全一模一样,只需要将代码第一行的 MyPrivateAddr 改成 2至5 即可。

五、实验现象

我们可以看到主节点开发板上的LED1灯每次收到从节点ACK应答数据后会闪烁一次,同时在主节点和从节点的USB虚拟串口打印中也可以看到各自发给对方的数据内容,例如下图是主节点和从节点1各自的通信数据内容:

pic6