查看: 14321|回复: 13

Arduino nrf24l01 (bluetooth) 模块教程

[复制链接]

该用户从未签到

发表于 2015-10-5 07:25 | 显示全部楼层 |阅读模式
本帖最后由 tmirun 于 2015-10-5 08:09 编辑

第一次发帖子心里好紧张。。。好紧张。。。如果那里不好还请大家多多指教。

(这资料是让大家一起学习的,转载请标明出处,谢谢 O(∩_∩)O~~)

作者:tmirun
转载于 http://blog-tmirun.rhcloud.com/

最近在在做一个 Arduino 的项目用到 nrf24l01 模块, 但是网上找到的资料少的可怜, 而且很多都没有详细的描述,磕磕碰碰了好久,所以决定做一个关于 nrf24l01 模块的教程。这里用的代码你可以在 https://github.com/tmirun/Arduino-nrf24l01-learn 里面找到。
这里我们用到的是maniacbug 的RF24库。

第一步先下载 RF24: https://github.com/maniacbug/RF24

import_library-300x135.png

第二步在arduino IDE里面导入刚刚下载的RF24.zip


下面我们开始连接我们的 arduino 和 nrf24l01模块,这里用到的arduino是 micro 和nano。 如果是其他类型的板子需要找到相对应的 sck, mosi 和 miso 接口, 一般性可以用icsp上的接口 。
nrf24l01 模块和它的接口:

nrf24l01-conection-1024x571.png

nrf24 pins
Arduino Nano
Arduino Micro
GNT
GNT
GNT
Vcc (3.3v)
Vcc (3.3v)
Vcc (3.3v)
CE
D9
D9
CSN
D10
D10
SCK
ICSP SCK
SCK
MOSI
ICSP MOSI
MOSI
MISO
ICSP MISO
MISO
IRQ

图:


然后我们去https://github.com/tmirun/Arduino-nrf24l01-learn 下载测试代码
下载解压后你可以在里面找到一个叫 rf24_hardware_test 的文件夹, 打开里面的 rf24_hardware_test.ino 文件,(不要黏贴下面的代码然后立马烧进去,因为缺少printf.h文件)

[C++] 纯文本查看 复制代码
/*
我们这里用到的库是 maiacbug 的 RF24,下载地址:
https://github.com/maniacbug/RF24
文档:
http://maniacbug.github.io/RF24/classRF24.html
*/

//导入RF24库
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
//这个是maniacbug 做的printf 用来输出文字 *不重要
#include "printf.h"

//初始 RF24(cePin, csnPi)
RF24 radio(9,10);

void setup(void)
{
  //等5s 因为你不可能在第一时间吧串口调试窗口打开。
  delay(5000);
  //开启serial port
  Serial.begin(57600);
  //运作nrf24l01芯片
  radio.begin();
  //开启printf 用来输出下面的测试
  printf_begin();  
  //输出测试
  radio.printDetails();
}

void loop(){
}


烧到arduino里面。然后打开串口调试窗口,在arduino加载完代码后 5 秒后会出现类似下面的内容 证明线全部好了, 如果全部出现 0xff 0x00请重新查看下链接是否正确。*注意 串口要调到 57600否则会出现乱码。

nrf24l01-test-ok.png

上一章描述了arduino如何连接nrf24l01模块。 这一章我们来了解他是怎么样传输的。
Bluetooth传输基本有下面几步
  • 开启Bluetooth设备
  • 建立一个传输渠道,在一个沟通渠道的设备要有同样的编号。
  • 一个设备发送信息,另一个窃听传输渠道里有没有发过的信息。* 每一个设备只能 “听” 或者 “说”,只能在一个状态,这就像我们平时聊天一样, 一个人说另一个人听, 如果两个人同时说会造成信息混乱。

下面我们来说下怎么样才能用RF24这个库实现(这里不懂没事,下面有实例)
  • 初始一个RF24(cePin, csnPin) 对象
  • 用 RF24.begin() 方法开启芯片.
  • 日常生活中有很多不同的bluetooth设备,每一个都有它自己的沟通渠道,每个沟通渠道其实就是一连串的编号, 每个设备都会找另一个和它有一样编号的bluetooth设备。那么 在这里我们也要为我们的模块设定一个编号。例子:uint64_t pipe = 0xE8E8F0F0E1LL
  • 窃听信息:
    • 调用 RF24.openReadingPipe(int num, uint64_t pipe) 来声明窃听的渠道. (*根据文档上说 一个设备科窃听 6 个传输渠道,第一个参数 int num 是用来说明这6只耳朵每一只在听哪个渠道,不懂待会代码上会有讲解)
    • 声明窃听的渠道之后要调用 RF24.startListening() 方法来开始窃听.
    • 调用 RF24.available() 来知道是否有信息传进来, 这个方法会返回 true (有信息) 或 false (没信息) 。
    • 如果有信息可以调用 RF24.read (void *buf, uint8_t len) 来获取着一些传过来的信息。(下面会详细介绍)

  • 调用 RF24.write()
    • 如果你开启了窃听 “RF24.startListening()” ,第一步要做的是调用 RF24.stopListening() 来停止窃听。
    • 调用 RF24.openWritingPipe(uint64_t pipe),这个参数是传输渠道的编号
    • 然后调用 RF24.write(const void *buf, uint8_t len)来发送信息. (下面会详细介绍)



最后我们来进入实战,这里的代码可以在https://github.com/tmirun/Arduino-nrf24l01-learn 的 rf24_simple_transmition 文件夹下面找到。

transmisor(发送信息的模块)这里可以直接黏贴代码

[C++] 纯文本查看 复制代码
//导入RF24库
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

//初始 RF24(cePin, csnPi)
RF24 radio(9,10);

//这个是我们即将建立的传输渠道编码
//!!要和另一个模块的一致
const uint64_t pipe = 0xE8E8F0F0E1LL;

//要传输的数据
int data = 0;

void setup(void){
  Serial.begin(57600);
  //启动芯片
  radio.begin();
  //打开写入通道
  radio.openWritingPipe(pipe);
}

void loop(void)
{
      Serial.print("Sending:");
      Serial.print(data);
      
      //调用radio.write(const void *buf, uint8_t len)传递信息
      //第一个参数是我们要传递的变量指针,第二个参数是要传输的信息大小.
      //如果传输成功会返回true 否则返回false.
      bool ok = radio.write(&data,sizeof(int));
      if(ok)
        Serial.println(".....successed");
      else
        Serial.println(".....failed");

      data++;
      delay(200);
}


receptor(接受信息的模块)

[C++] 纯文本查看 复制代码

//导入RF24库
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

//初始 RF24(cePin, csnPi)
RF24 radio(9,10);

//这个是我们即将建立的传输渠道编码
//!!要和另一个模块的一致
const uint64_t pipe = 0xE8E8F0F0E1LL;

//这个变量会保持我们接受到的信息
//!!变量类型一定要和传过来的一样
int recibeData;

void setup(void){
  Serial.begin(57600);
  //启动芯片
  radio.begin();
  //打开窃听通道
  radio.openReadingPipe(1,pipe);
  //开始窃听
  radio.startListening();
}

void loop(void){
  //用available方法来看是否有信息要接受 
  if (radio.available()){
    Serial.print("recibe:");
    //调用radia.read(const void *buf, uint8_t len)来接受信息
    //第一个参数是我们要保持信息的变量指针, 第二个参数是要接受的信息大小
    radio.read( &recibeData, sizeof(int));     
    Serial.println(recibeData);
  }
}


打开串口调试窗口你可以看见:

nrf24l01-simple-transmition-ok.png

是不是觉得这非常的简单!

如果有什么问题或者想讨论的可以留言或者直接email:tmriun@hotmail.com


  • TA的每日心情
    奋斗
    2016-4-4 16:21
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    发表于 2016-2-27 20:37 | 显示全部楼层
    发送端很好,,但是接收端接收到的数据不对,,为什么???
  • TA的每日心情
    郁闷
    2016-1-11 16:51
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    发表于 2015-12-16 15:14 | 显示全部楼层
    test没问题,但是无法通讯,总是失败,求赐教,两块nano

    该用户从未签到

    发表于 2016-1-2 20:21 | 显示全部楼层
    本帖最后由 lam威风 于 2016-1-2 20:22 编辑

    我用了上面的代码,请问为什么传输距离这么短,模块要连在一起才能传数据,求指教

    该用户从未签到

     楼主| 发表于 2016-2-25 01:33 | 显示全部楼层
    dybie 发表于 2015-12-16 15:14
    test没问题,但是无法通讯,总是失败,求赐教,两块nano

    (抱歉最近工作忙)
    可能是一下问题:
    1-没插好(这是最普遍的错误)
    2-查看传输渠道编码是不是一样
    3-看模块距离(我的两个模块最少间隔距离50cm)

    该用户从未签到

     楼主| 发表于 2016-2-25 01:44 | 显示全部楼层
    lam威风 发表于 2016-1-2 20:21
    我用了上面的代码,请问为什么传输距离这么短,模块要连在一起才能传数据,求指教 ...

    (抱歉最近工作忙,没能及时回答你)
    这个应该是供电不足, 因为arduino 3.3v输出口的 mA 不是很高所以传输距离会小,解决方法就是外加一个mA高一点的电源(!注意要3.3v的否则会烧坏模块)
  • TA的每日心情
    奋斗
    2016-4-4 16:21
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    发表于 2016-2-27 20:26 | 显示全部楼层
    发送端是没有问题的,,但是接收端不对,正反测试都是这样。。
    BJB_N$IQJXAD2{WWPP@{ZQX.png
  • TA的每日心情
    郁闷
    2016-1-26 15:22
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2016-2-27 21:39 | 显示全部楼层
    tmirun 发表于 2016-2-25 01:44
    (抱歉最近工作忙,没能及时回答你)
    这个应该是供电不足, 因为arduino 3.3v输出口的 mA 不是很高所以传 ...

    bluetooth虽然也用的是2.4G,但nrf24l01没法当bluetooth用。

    这种nrf24l01小板的功率就是这么小,通信距离近而且pcb天线有指向性,和arduino输出能力无关,换电源也没用。
  • TA的每日心情
    开心
    2016-3-12 05:35
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2016-3-10 23:25 来自手机 | 显示全部楼层
    谢谢楼主教学,我想问一下,//初始 RF24(cePin, csnPi) RF24 radio(9,10);这里的(9,10)是不是定义CE和CSN两只引脚在arduino上的接口?可不可以换成是其他的,因为我的arduino UNO r3装了l293d的电机驱动板之后这两个接口被舵机占用了,不过模拟输入口没有被占用,可以把被占用的CE和CSN(甚至还有12脚连的MISO,因为我一开始还不需要这么多通道驱动电机,不过可能以后会扩展)插到模拟输入脚上面?要怎么修改程序?
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    Arduino MEGA 与UNO 通过nRF24L模块通讯
    Arduino MEGA 与UNO 通过n
    之前在深水宝很“实惠”的店铺买了一些原件,随手砍了esp8266以及nRF24L*3 因为缺
    原创 drawbot平面关节机械臂 教程直播贴
    原创 drawbot平面关节机械
    这个项目上个月就在做了,结构和代码反反复复改了多次,加上自己又太懒,一直没来得及
    求助大神!
    求助大神!
    我想在函数中返回指针,但不知道为什么系统报错,请问大神们是什么原因呢
    ATMEGA2560板子下载不进去程序
    ATMEGA2560板子下载不进去
    有没有大佬知道,附图
    手机端发送数据通过蓝牙(HC06)给变量赋值的问题探讨
    手机端发送数据通过蓝牙(
    up这两天在弄个程序,具体实现功能为手机端发送一个数据,通过蓝牙串口读取,
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表