认真的nrf24l01库 5路接收通道 2月6号_更新用户模式选择
本帖最后由 mylife1213 于 2015-2-6 13:57 编辑更新的库基本重写了,加入软SPI,可以使用任意引脚驱动,也可以选择硬件spi;
加入数据接收是否启用中断;
不再是杂乱无章的测试代码,有规划的一个库;
各个功能实现库分开,下次更新不需要改变函数传入参数;
支持5路通道接收数据;
忘记把uint8_t 改成 byte了,uint8_t = byte; 不改也可以用,有uint8_t 的地方都可以用byte替换
2月6号更新
加入用户界面基于字符串模式选择
通过 int set_reg(String reg, String data);进行操作,例句:nrf.set_reg("Rate","2M");这个是设置nrf24l01为2M速率,如果输入错误的模式与命令会返回"1000"(模式错误) ,"1001"(命令错误)
库已更新-版本号:v1.1
"Mode"-> "Receive" or "Send" //模式 "Power"-> "up" or "Down" //电源模式
"CRC"-> "16bit" or "8bit" //CRC校验模式
"RF_Power"->"0dBm"or"-6dBm"or"-12dBm"or"-18dBm"//功率
"Rate"->"1M"or"2M"or"250k" //速率
"RF_Channel"->数值 //信道
int set_reg(String reg, String data);源代码
int Multiple::set_reg(String reg, String data)
{
uint8_t tmp;
//-------------命令检查模块-------------
boolean cmd_tmp=false;
boolean data_tmp=false;
boolean cmd_RF_Channel=false;
String cmd[]={"Mode","Power","CRC","RF_Power","Rate","RF_Channel","NULL"};
String cmd_data[]={"Receive","Send","up","Down","16bit","8bit","0dBm","-6dBm","-12dBm","-18dBm","1M","2M","250k","NULL"};
for(uint8_t i=0;cmd!="NULL";i++)
{
if(reg==cmd)
{cmd_tmp=true;}
if(reg=="RF_Channel")
{cmd_RF_Channel=true;}
}
if(!cmd_tmp)
{ return 1000;}
for(uint8_t i=0;cmd_data!="NULL";i++)
{
if(data==cmd_data)
{data_tmp=true;}
}
if(!cmd_RF_Channel && !cmd_RF_Channel)
{ return 1001;}
//-------------命令检查模块---------------//
digitalWrite(_CE,LOW);
if(reg=="Mode")
{
tmp=Read(0x00);
if(data=="Receive")
{tmp |=0x01;}
else if(data=="Send")
{tmp &=0xfe;}
RW_Reg(WRITE_REG + 0x00,tmp);
}
if(reg=="Power")
{
tmp=Read(0x00);
if(data=="up")
{ tmp |=0x02;}
else if(data=="Down")
{ tmp &=0xfd;}
RW_Reg(WRITE_REG + 0x00,tmp);
}
if(reg=="CRC")
{
tmp=Read(0x00);
if(data=="16bit")
{tmp |=0x04;}
else if(data=="8bit")
{tmp &=0xfb;}
RW_Reg(WRITE_REG + 0x00,tmp);
}
//-----------------CONFIG--------------
if(reg=="RF_Power")
{
tmp=Read(0x06);
if(data=="0dBm")
{tmp |=0x07;}
else if(data=="-6dBm")
{tmp &=0xf9;
tmp |=0x04; }
else if(data=="-12dBm")
{tmp &=0xf9;
tmp |=0x02; }
else if(data=="-18dBm")
{tmp &=0xf9;
tmp |=0x00; }
RW_Reg(WRITE_REG + 0x06,tmp);
}
if(reg=="Rate")
{
tmp=Read(0x06);
if(data=="1M")
{tmp &=0xd7;
tmp |=0x00; }
else if(data=="2M")
{tmp &=0xd7;
tmp |=0x08; }
else if(data=="250k")
{tmp &=0xd7;
tmp |=0x20; }
RW_Reg(WRITE_REG + 0x06,tmp);
}
if(reg=="RF_Channel")
{
tmp=atof(data.c_str());
RW_Reg(WRITE_REG + 0x05,tmp);
}
digitalWrite(_CE,HIGH);
return tmp;
}
面向用户开放的库头文件函数:
/**
* Copyright (c) 2015 by Mylife1213 <[email protected]>
* Nrf24l01P library for Arduino.
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
* version v1.0
**/
#ifndef Multiple_H_
#define Multiple_H_
#include "nrf_base.h"
#define uint8_t unsigned char
class Multiple : public nrf_base
{
public:
/**
构建函数,使用硬件spi
**/
Multiple(uint8_t ce, uint8_t csn);
/**
构建函数,使用SOFT SPI
**/
Multiple(uint8_t ce, uint8_t csn,uint8_t clk,uint8_t mosi,uint8_t miso);
/**
设置成读取模式,参数: p1接收主地址,p2_p5其余接收地址首位
**/
uint8_t read_mode(uint8_t* p1, uint8_t* p2_p5);
/**
设置使用中断模式
**/
void Interrup(uint8_t pin,void (*func)() );
/**
中断模式下的接收数据读取,channel通道,data读取的数组
**/
uint8_t Interrup_read(uint8_t channel,uint8_t* data);
/**
普通模式下的数据读取,channel通道,data数据数组
返回值 1:收到数据0:没有数据
**/
uint8_t read(uint8_t channel,uint8_t* data);
/**
设置发送模式,参数p0:发送的地址数组
**/
uint8_t send_mode(uint8_t* p0);
/**
发送数据,addr:发送地址data:发送数据数组
**/
uint8_t send(uint8_t* addr, uint8_t* data);
/**
手动修改寄存器,reg:修改的寄存器 data:数值
**/
uint8_t set_reg(uint8_t reg, uint8_t data);
/**
寄存器调试变量,需设置模式前启用
**/
uint8_t _EN_AA;
uint8_t _EN_RXADDR;
uint8_t _SETUP_RETR;
uint8_t _RF_CH;
uint8_t _RF_SETUP;
uint8_t _SETUP_AW;
uint8_t _CONFIG;
uint8_t _RX_PW;
uint8_t _TX_EN_AA;
uint8_t _TX_EN_RXADDR;
uint8_t _TX_SETUP_RETR;
uint8_t _TX_RF_CH;
uint8_t _TX_RF_SETUP;
uint8_t _TX_SETUP_AW;
uint8_t _TX_CONFIG;
uint8_t _TX_PW;
private:
};
#endif
已带不同场景例程,全部有进行测试
例程代码:
Spi_send 使用硬件spi进行发送
/**
* Copyright (c) 2015 by Mylife1213 <[email protected]>
* Nrf24l01P library for Arduino.
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
* version v1.0
**/
/**
nrf24l01 arduino
csk-> csk
mosi-> mosi
miso-> miso
ce-> 用户设置
csn-> 用户设置
**/
#include"Multiple.h"
Multiple nrf(9,8);//构建函数,参数分别为CE,CSN
uint8_t tx_addr[] = { 0x03, 0xFF, 0xFF, 0xFF, 0xFF};//发送地址
uint8_t tx_data={1,2,3,4};//发送的数据,32位
void setup() {
nrf.send_mode(tx_addr);//设置为发送模式,参数为发送地址
}
void loop() {
tx_data++;
nrf.send(tx_addr,tx_data);//发送数据,参数:发送地址,数据
delay(5000);
}
例程Soft_spi_send使用软SPI进行发送
/**
* Copyright (c) 2015 by Mylife1213 <[email protected]>
* Nrf24l01P library for Arduino.
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
* version v1.0
**/
/**
nrf24l01 arduino
csk-> 用户设置
mosi-> 用户设置
miso-> 用户设置
ce-> 用户设置
csn-> 用户设置
**/
#include"Multiple.h"
Multiple nrf(9,8,3,4,5);//构建函数,参数分别为CE,CSN,CLK,MOSI,MISO
uint8_t tx_addr[] = { 0x03, 0xFF, 0xFF, 0xFF, 0xFF};//发送地址
uint8_t tx_data={1,2,3,4};//发送的数据,32位
void setup() {
nrf.send_mode(tx_addr);//设置为发送模式,参数为发送地址
}
void loop() {
tx_data++;
nrf.send(tx_addr,tx_data);//发送数据,参数:发送地址,数据
delay(5000);
}
例程Read_no_interrup_mode不使用中断接收
/**
* Copyright (c) 2015 by Mylife1213 <[email protected]>
* Nrf24l01P library for Arduino.
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
* version v1.0
**/
/**
nrf24l01 arduino
csk-> csk
mosi-> mosi
miso-> miso
ce-> 用户设置
csn-> 用户设置
**/
#include"Multiple.h"
Multiple nrf(9,8);//构建函数,参数分别为CE,CSN
uint8_t rx_addr_p1={ 0x01, 0xFF, 0xFF, 0xFF, 0xFF};//接收地址
uint8_t rx_addr_p2_5={0x02,0x03,0x04,0x05}; /**
通道2至5地址,各地址=各个数
组元素+rx_addr_p1后4位**/
uint8_t rx_data;//接收数据存储
uint8_t channel;//接收通道
uint8_t tmp;
void setup() {
Serial.begin(9600);
nrf.read_mode(rx_addr_p1, rx_addr_p2_5);//设置为接收模式,参数:通道1地址,通道2-5地址
}
void loop() {
tmp=nrf.read(channel,rx_data);//读取接收数据,有数据返回1,参数:通道,数据
if(tmp==1)
{
Serial.print("Channel= ");
Serial.print(channel);
Serial.print(" rx_data= ");
Serial.println(rx_data);
}
}
例程Read_interrup_mode使用中断进行数据接收
/**
* Copyright (c) 2015 by Mylife1213 <[email protected]>
* Nrf24l01P library for Arduino.
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
* version v1.0
**/
/**
nrf24l01 arduino
csk-> csk
mosi-> mosi
miso-> miso
ce-> 用户设置
csn-> 用户设置
isr-> 用户设置中断引脚
**/
#include"Multiple.h"
Multiple nrf(9,8);//构建函数,参数分别为CE,CSN
uint8_t rx_addr_p1={ 0x01, 0xFF, 0xFF, 0xFF, 0xFF};//接收地址
uint8_t rx_addr_p2_5={0x02,0x03,0x04,0x05}; /**
通道2至5地址,各地址=各个数
组元素+rx_addr_p1后4位**/
uint8_t rx_data;//接收数据存储
uint8_t channel;//接收通道
void setup() {
Serial.begin(9600);
nrf.read_mode(rx_addr_p1, rx_addr_p2_5);//设置为接收模式,参数:通道1地址,通道2-5地址
nrf.Interrup(0, r_data);//设置为中断接收,参数:中断号,中断函数
}
void loop() {
}
void r_data()
{
nrf.Interrup_read(channel, rx_data);//中断模式下读取数据,参数:通道,接收数据
Serial.print("Channel: ");
Serial.print(channel);
Serial.print("rx_data=");
Serial.println(rx_data);
}
库文件版本v1.1
转载请注明转载链接 原装nrf24l01+带PA空地测试700米 这个库能否实现多发一收,或者一发多收,或者既能接收也能发送 就这些功能了?能用多块nrf24l01么?一收一发。 LINK~ 发表于 2014-11-6 17:16 static/image/common/back.gif
这个库能否实现多发一收,或者一发多收,或者既能接收也能发送
可以多发一收,库文件有详细说明,配置p2-p5通道地址就行,一发多收也可以实现,但是需要关闭ACK,那样就没有接收状态了,建议你要发几个nrf24l01 ,就顺序发送接收地址 ourutopia 发表于 2014-11-6 17:25 static/image/common/back.gif
就这些功能了?能用多块nrf24l01么?一收一发。
nrf24l01不支持全双工,可以发完以后切换成接收模式,然后接收的那个切换成发送!主要是硬件不允许,只能软件来实现,在下一版可能会加入这个功能,还有nrf24l01+ 独有的ack带数据确认码,原理差不多就是你发一个数据过去,接收端会发回一个已接收ACK和接收端发给你的数据,硬件实现的 mylife1213 发表于 2014-11-6 17:32 static/image/common/back.gif
nrf24l01不支持全双工,可以发完以后切换成接收模式,然后接收的那个切换成发送!主要是硬件不允许,只能软件 ...
我要实现全双工通信,所以要接两块nrf24l01,一块专职发送,一块专职接收~ ourutopia 发表于 2014-11-6 17:35 static/image/common/back.gif
我要实现全双工通信,所以要接两块nrf24l01,一块专职发送,一块专职接收~
你数据量很大吗?切换接收和发送模式在数据发送速度应该可以满足大多数应用啊,下一版库再加入类似硬件全双工,基本和两块板子实现没什么差别 mylife1213 发表于 2014-11-6 17:39 static/image/common/back.gif
你数据量很大吗?切换接收和发送模式在数据发送速度应该可以满足大多数应用啊,下一版库再加入类似硬件全双 ...
数据量不大,但是有一路要求信号不能间断,做控制用啊,所以只能再单独开一路回传数据。 好东西。。。。。。。。 Serial.print(Channel); Channel怎么关联的??不理解啊 原来在库里面定义的啊 lm4766 发表于 2014-11-7 09:17 static/image/common/back.gif
原来在库里面定义的啊
嗯嗯,在.h 头文件定义了全局变量 extern unsigned char Channel; 等到中断启动后读取的都是新数据 :):):):):):):)