检测信道占用的需求场景

在使用nRF24L01模块做一对多或多对一的组网通信中,大家都会担心一个问题就是在发送的时候,希望不要有其他的模块也进行发送,因为这样就会使无线信号发生碰撞,信道被堵塞,造成通信失败。

为了避免这种情况发生,就希望在发送前能知道当前信道是否处于空闲,如果空闲就发送,否则就等待一会,直到空闲下来再执行发送。利用这个机制,可以很大程度上规避碰撞的发生。

在nRF24L01+中怎样知道信道被占用了

在nRF24L01+中有个RSSI寄存器,地址是0x09,该寄存器的0号位是代表当前信道信号强度的。当接收信号强度小于-60dBm时0号位为0,大于-60dBm时为1,该寄存器7-1号位是保留位,固定为0。这样我们通过直接读取该寄存器的值是0还是大于0就知道信道是否被占用了。

下面是该寄存器在一些模块厂家官方例程里的定义:

  1. #define RPD 0x09 //接收功率检测寄存器

  1. #define RSSI 0x09 //接收功率检测寄存器

下面是通过读寄存器函数读取该寄存器的状态值的代码:

  1. StatusRPD = nRF24L01P_Read_Reg(RPD); //如果定义的是RSSI,那语句中RPD换成RSSI

通过上面语句得到的StatusRPD值,如果大于0则是信道被占用,在逻辑代码中通过这个判断就可以识别信道是否被占用了。也可以在发送前用循环等待这个值的变化,直到为0时进入发送状态。如下面的代码:

  1. while(nRF24L01P_Read_Reg(RPD));

为什么用循环等待,有时候会死循环(一直返回1)

在实际应用中,使用上述方法的确可以得到当前的信道信号强度,达到判断信道是否占用的目的。但是在循环等待的时候,偶尔会出现死循环的现象。也就是读回来的状态值一直是1,但是的确没有模块在发送,已经将其他模块全部断电了,周围也没有强信号干扰,那么问题出在哪里呢?

仔细查看芯片手册,只找到下面这段话:

在接收模式下,可以通过RSSI寄存器检测接收信号功率。当接收到的信号强度大于-60dBm时,RSSI寄存器的RSSI位的值将被设置为1。否则,RSSI=0。。RSSI寄存器的更新方法有两种:当接收到有效的数据包后,RSSI会自动更新,此外,将芯片从RX模式换到Standby模式时RSSI也会自动更新。RSSI的值会随温度的变化而变化,范围在±5dBm以内

经过仔细分析和反复试验,理解了这段话所描述的具体内涵:

1、这个信号强度检测必须在接收模式下进行,在发送模式下是不准确的。

2、并不是无论什么情况下,这个寄存器都会被更新,只有CE由1变为0时才更新一次;或者在接收到有效数据的时候,会自动更为1。

3、当收到有效数据将该寄存器置1后,只有将接收FIFO寄存器的数据读出后,才会变为0,否则你变化几次CE都无效(这是手册没有提到的,多数会踩到这个坑)。

上面的死循环情况一般发生在执行发送的前夕,刚好收到一个有效数据时,RSSI寄存器被置1,而代码正在处理发送,又没有去读出数据,所以就一直保持着1,所以循环条件一直满足,就成了死循环了。

解决办法建议是在检测到为RSSI为1的时候,判断一下是否收到数据,如果收到数据先读出来,至于读出来的数据要不要处理,根据您自己的业务逻辑决定即可。然后操作一次CE引脚,再次更新检测一下是否有信号占用信道。此方法经过实际应用是有效的。

nRF24L01+如何检测信道被占用-RSSI寄存器实战分享的更多相关文章

  1. nRF24L01+组网方式及防撞(防冲突)机制的实战分享

    利用多个nRF24L01+模块组网通信的实现方式 这里讨论的组网方式,不包含使用6个通道实现的多对1通信方式,因其只限于6个发送端,局限性很大,可以附加其他技术实现更好的组网,暂时这里不讨论.这里分享 ...

  2. Java检测端口的占用情况

    突然间想到这个问题,在网上搜了一下 http://blog.csdn.net/danieluk/article/details/18518175 网上有很多文章都是用上面那个方法来解决这个问题的,总感 ...

  3. nRF24L01+启用自动应答ACK及自动重发的实战分享

    ACK模式(自动应答)功能的官方说明 当用W_TX_PAYLOAD命令对发送端TX FIFO写数据时,将数据打包后,数据包中包控制字段NO_ACK 标志位复位.接收端接收到一帧有效数据后, 产生RX_ ...

  4. nRF24L01+不能接收或接收偶尔异常等问题实战分享

    nRF24L01+接收异常问题综述 在调试nRF24L01+无线收发模块的时候,最具标志性的环节就是在接收端可以收到数据.在实际应用调试中,会出现很多意想不到的情况,造成nRF24L01+模块接收端无 ...

  5. 介质访问控制子层-Medium Access Control Sublayer:多路访问协议、以太网、无线局域网

    第四章 介质访问控制子层-Medium Access Control Sub-layer 4.1介质访问控制子层概述 MAC子层不属于之前提到的OSI或TCP/IP架构的任何一层,这也是为什么这一层被 ...

  6. Flex(flash)检测摄像头的3种状态(是否被占用,没安装摄像头,正常)

    在视频程序的编写过程中,我们经常要使用摄像头,在使用摄像头前有必要对摄像头的现有状态做个检测: 1.被占用 2.没安装摄像头 3.正常 camera=Camera.getCamera();       ...

  7. NRF24L01 射频收发 使用方法

    在干啥 这两天在调nrf24l01,最终还是参考正点原子的例程才调通,看芯片手册太难了 还要说啥废话 废话说到这,接下来上代码 SPI协议 spi.c #include "spi.h&quo ...

  8. 【计算机网络】-介质访问子层-(信道划分介质访问控制&随机访问介质访问控制)

    [计算机网络]-介质访问子层-概述 介质访问控制子层功能 解决信道争用的协议,即用于多路访问信道上确定下一个使用者的协议 是数据链路层协议的一部分 介质访问控制子层位置 位于数据链路层的底部! 信道分 ...

  9. 计算机网络之介质访问控制(静态划分信道、FDM、TDM、STDM、WDM、CDM)、(动态划分信道、ALOHA、CSMA、CSMA/CD、CSMA/CA)、令牌传递协议

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/104935912 学习课程:<2019王道考研计算机网络> 学习目的 ...

随机推荐

  1. Spring Boot 2.2.2.RELEASE 版本中文参考文档

    写在前面 在我初次接触MongoDB的时候,是为了做一个监控系统和日志分析系统.当时在用Java操作MongoDB数据里的数据的时候,都是在网上查找Demo示例然后完成的功能,相信大家也同样的体会,网 ...

  2. JS(TS)中数组常见的方法(未完待续)

    push():向数组末尾添加一个或多个元素 unshift(): 向数组的开头添加一个或多个元素 pop(): 删除数组最后一个元素 shift(): 删除数组第一个元素 sort(): 给数组排序  ...

  3. 简单的jquery表单验证+添加+删除+全选/反选

    //布局 <body> <h4><a href="#">首页</a>><a href="#"> ...

  4. python脚本实现音频m4a格式转成MP3格式

    群里看到有人询问:谁会用python将微信音频文件后缀m4a格式转成mp3格式,毫不犹豫回了句:我会.然后就私下聊起来了 解决方法介绍如下: 工具:windows系统,python2.7,转换库ffm ...

  5. MyBatis中特殊符号的转义

    在MyBatis中遇到特殊符号时有两种转义方式: 第一种 描述 空格 小于 大于 小于等于 大于等于 与 单引号 双引号 原符号 < > <= >= & ' " ...

  6. BERT源码分析

    一.整体 整个代码文件如下: 二.tensorflow基础 1.tf.expand_dims 作用:给定张量“ input”,此操作将在“ input”形状的尺寸索引“ axis”处插入尺寸为1的尺寸 ...

  7. acwing 517. 信息传递

    地址 https://www.acwing.com/problem/content/description/519/ 有 n 个同学(编号为 1 到 n)正在玩一个信息传递的游戏. 在游戏里每人都有一 ...

  8. Go 循环 (for)

    循环类型 for: for a := 0; a < 10; a ++{ fmt.Println(a) } 在执行结束后 a == 10 while: a := 0 for a < 10{ ...

  9. 第04组 Beta冲刺(1/5)

    队名:new game 组长博客:戳 作业博客:戳 组员情况 鲍子涵(队长) 过去两天完成了哪些任务 验收游戏素材 学习Unity 2D Animation系统 接下来的计划 制作游戏需要的人物动画 ...

  10. 【JS】JS校验密码复杂度(必须包含字母、数字、特殊符号)

    #场景一:密码中必须包含大小写 字母.数字.特称字符,至少8个字符,最多30个字符: var pwdRegex = new RegExp('(?=.*[0-9])(?=.*[A-Z])(?=.*[a- ...