一、
无线通信模块nrf24l01采用2.4G技术,同样,蓝牙和wifi模块也是采用的2.4G技术,只是后者在技术的基础之上做了扩展,封装更高,那么我们在做通信的时候,如果只是单纯想完成两个设备之间的通信,我的建议是使用nrf24l01模块*2。之前做过蓝牙模块之间的通信,其优点在于有指定的指令集,集成度高,操作起来十分方便,但是传输速度不快,质量不可靠,实时性不高,所以需要nrf24l01。
二、
在openmv上编写nrf24l01的发送代码,Python。
openmv是用于做图像处理的一个开源项目,将摄像头和一块stm32芯片集成在一起,通过python语言来完成对单片机的控制,以及调用内部的库函数来完成图像处理的部分内容。
首先得知道nrf24l01是如何完成通信的。
1、nrf24l01需要与单片机正常通信,这是通过spi总线来完成的,四根信号线,mosi、miso、sck、cs,注意,并不是nrf24l01上的mosi与单片机的miso连接,这里我在连线的时候是有过犹豫的,之后通过实践证明以及百度,证实了mosi与mosi相连,miso与miso相连。
nrf24l01与单片机是通过spi串行通信,但具体如何完成通信,这涉及到spi协议,网上资料还是很多的,在此是调用了openmv的库内的spi相关函数。调用方法点击跳转:
http://docs.openmv.io/library/pyb.SPI.html#pyb-spi
在此我想说的是,即使调用了spi的库,仍然被一个地方卡住了,正确的使用是这样的:
CS.value(0)
NRF_SPI.send_recv(buff, buff, timeout=500)
CS.value(1)
可以看到,需要经过一次片选的完成才能正确的完成数据的通信,而不是一直片选中该模块就可以完成通信的。
2、nrf24l01的通信,上面说到,四根信号线用在了spi上,还有两个CE、IRQ来完成模块的自身需求,通过配置模块内部的寄存器来完成数据的发送,此处应有代码。
(如需详细了解模块内部的寄存器可以仔细阅读数据手册,那上面说的很清楚,另外,此处只将nrf24l01作为发送端,接收端同理)
def nrf_writereg(reg, dat): # NRF24L01+写寄存器
…
def nrf_readreg(reg):
…
def nrf_writebuf(reg, pBuf, datalen): #pBuf为TX的地址
…
上面这三个函数是对nrf24l01的寄存器进行的基本操作,下面上全部的代码,表示在我的设备上已正常测试通过
import sensor, image, time
import pyb
from pyb import Pin, SPI, ExtInt
# 用户配置 发送和 接收地址,频道
TX_ADDRESS = (0x34, 0x43, 0x10, 0x10, 0x01) # 定义一个静态发送地址
RX_ADDRESS = (0x34, 0x43, 0x10, 0x10, 0x01)
CHANAL = 40 #频道选择
buff = bytearray(2)
def callback(line): #中断服务函数
state = nrf_readreg(FIFO_STATUS) #读取FIFO_STATUS寄存器的值,正常为17
#print("FIFO_STATUS = ", state)
state = nrf_readreg(STATUS) #读取status寄存器的值,state为发送状态,数值46: 正常发送完成, 30:重发超过次数
#print("state = ", state)
nrf_writereg(NRF_WRITE_REG + STATUS, state) #清除中断标志
global nrf_irq_tx_flag
#if(state & RX_DR) #接收到数据
#不会接受到数据的,忽略该种情况
if(state & TX_DS): #发送完数据
nrf_irq_tx_flag = 0
nrf_writereg(FLUSH_TX, NOP) #清除TX FIFO寄存器
print("\nTX_DS")
if(state & MAX_RT): #发送超时,达到最多重发次数标志位
nrf_irq_tx_flag = 0 #标记发送失败
nrf_writereg(FLUSH_TX, NOP) #清除TX FIFO寄存器
#有可能是 对方也处于 发送状态