mylife1213 发表于 2014-11-6 16:20:37

认真的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








mylife1213 发表于 2014-11-6 16:21:43

转载请注明转载链接

mylife1213 发表于 2014-11-6 16:51:46

原装nrf24l01+带PA空地测试700米

LINK~ 发表于 2014-11-6 17:16:27

这个库能否实现多发一收,或者一发多收,或者既能接收也能发送

ourutopia 发表于 2014-11-6 17:25:26

就这些功能了?能用多块nrf24l01么?一收一发。

mylife1213 发表于 2014-11-6 17:28:34

LINK~ 发表于 2014-11-6 17:16 static/image/common/back.gif
这个库能否实现多发一收,或者一发多收,或者既能接收也能发送

可以多发一收,库文件有详细说明,配置p2-p5通道地址就行,一发多收也可以实现,但是需要关闭ACK,那样就没有接收状态了,建议你要发几个nrf24l01 ,就顺序发送接收地址

mylife1213 发表于 2014-11-6 17:32:06

ourutopia 发表于 2014-11-6 17:25 static/image/common/back.gif
就这些功能了?能用多块nrf24l01么?一收一发。

nrf24l01不支持全双工,可以发完以后切换成接收模式,然后接收的那个切换成发送!主要是硬件不允许,只能软件来实现,在下一版可能会加入这个功能,还有nrf24l01+ 独有的ack带数据确认码,原理差不多就是你发一个数据过去,接收端会发回一个已接收ACK和接收端发给你的数据,硬件实现的

ourutopia 发表于 2014-11-6 17:35:00

mylife1213 发表于 2014-11-6 17:32 static/image/common/back.gif
nrf24l01不支持全双工,可以发完以后切换成接收模式,然后接收的那个切换成发送!主要是硬件不允许,只能软件 ...

我要实现全双工通信,所以要接两块nrf24l01,一块专职发送,一块专职接收~

mylife1213 发表于 2014-11-6 17:39:56

ourutopia 发表于 2014-11-6 17:35 static/image/common/back.gif
我要实现全双工通信,所以要接两块nrf24l01,一块专职发送,一块专职接收~

你数据量很大吗?切换接收和发送模式在数据发送速度应该可以满足大多数应用啊,下一版库再加入类似硬件全双工,基本和两块板子实现没什么差别

ourutopia 发表于 2014-11-6 19:10:04

mylife1213 发表于 2014-11-6 17:39 static/image/common/back.gif
你数据量很大吗?切换接收和发送模式在数据发送速度应该可以满足大多数应用啊,下一版库再加入类似硬件全双 ...

数据量不大,但是有一路要求信号不能间断,做控制用啊,所以只能再单独开一路回传数据。

lm4766 发表于 2014-11-7 08:01:00

好东西。。。。。。。。

lm4766 发表于 2014-11-7 09:15:22

Serial.print(Channel);   Channel怎么关联的??不理解啊

lm4766 发表于 2014-11-7 09:17:17

原来在库里面定义的啊

mylife1213 发表于 2014-11-7 09:20:53

lm4766 发表于 2014-11-7 09:17 static/image/common/back.gif
原来在库里面定义的啊

嗯嗯,在.h 头文件定义了全局变量 extern unsigned char Channel; 等到中断启动后读取的都是新数据

xiwang1314 发表于 2014-11-7 15:39:02

:):):):):):):)
页: [1] 2 3 4 5
查看完整版本: 认真的nrf24l01库 5路接收通道 2月6号_更新用户模式选择