极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 27649|回复: 13

从零开始 NRF24L01通信模块

[复制链接]
发表于 2015-4-1 23:24:59 | 显示全部楼层 |阅读模式
本帖最后由 hxf 于 2015-4-5 22:22 编辑

       好久没有发帖了,楼主这次尝试挑战了一下NRF24L01通信模块,计划是做成一个遥控器。先上初步成果,后续还有会更新。
       楼主翻遍了各大论坛和此类有关的文章,发现大部分按照原文介绍都调试不太成功,不是版本不兼容就是步奏介绍的不够详细,好在最后总算让楼主摸索出来了。所以楼主决心自己整理一篇详尽的调试过程与大家分享。
       (1)首先是连续问题
  这是楼主使用的NRF24L01芯片,标注了各引脚的名称
  

  以下是与arduino的具体连接方式
  NRF24L01 -------------- Arduino
  IRQ          -------------- 悬空不接
  MISO       --------------  D12
  MOSI       --------------  D11
  SCK         --------------  D13
  CSN         --------------  D7
  CE          --------------   D8
  VCC        --------------   3.3V
  GND        --------------  GND

        (2)其次是软件问题
因为要用到ASK码表,直接给大家贴上来:

bin             dec  hex  对应字符
01100000   48   30   0
 
00110001   49   31   1
          
00110010   50   32   2
          
00110011   51   33   3
          
00110100   52   34   4
          
00110101   53   35   5
          
00110110   54   36   6
          
00110111   55   37   7
          
00111000   56   38   8
          
00111001   57   39   9

发送端内容如下:
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

char tempx[6]="00000";
int x=0;

void setup(){
Serial.begin(9600);
Mirf.spi = &MirfHardwareSpi;
Mirf.init();

Mirf.setRADDR((byte *)"clie1"); // 标记本地名,用于接收
Mirf.payload = 5; //对话的长度,用于约定双方对话的缓冲窗口大小,这个代表5个字节
Mirf.channel = 3; // 通信信道

Mirf.config();
}
void loop(){
unsigned long time = millis();

Mirf.setTADDR((byte *)"serv1"); // 标记对方的地址
  
if(x<10)tempx[4]=x+48;//当x小于10时,只需要显示个位,+48正好对应ASK码数值
else if(x>9 && x<100){
  tempx[4]=x%10+48;
  tempx[3]=x/10+48;//当x大于10小于100时,需要显示个位和十位
}  

Sends(tempx);
x++;
if(x==100){
  x=0;
  tempx[4]=x%10+48;
  tempx[3]=x/10+48;
}

delay(500);
}


void Sends(char *str)
{
int lens;
lens=strlen(str);

char msg[lens];
int i;
for (i=0;i<lens;i++)
{
msg= int(str);
}
Mirf.send((byte *)&msg);

while(Mirf.isSending()){}
   
}

接收内容如下:
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
void setup(){
Serial.begin(9600);

Mirf.spi = &MirfHardwareSpi;
Mirf.init();

Mirf.setRADDR((byte *)"serv1"); // 本地名
Mirf.payload = 5; // 长度
Mirf.channel = 3; // 信道

Mirf.config();

}
void loop(){

byte data[Mirf.payload];
if(!Mirf.isSending() && Mirf.dataReady()){ //存在数据

Mirf.getData(data);
  
int i;
String Temp;
for (i = 0; i < Mirf.payload; i++) //把收到的信息拼起来,到一个串里面
{
Temp += char(data);
}
Serial.print("Get:");
Serial.print(Mirf.payload);
Serial.print(" ");
Serial.println(Temp);

  }
}


最后送上用到的库文件




完成了第一步调试的朋友还可以尝试一下通过修改tempx值和增加一个输入口实现无线开关控制LED灯的点亮
(1)还是先来说连接方法
        作为发送信号端的arudino的D5端口接一个拨动开关(注;拨动开关一头接5v,另一头记得接地)
        作为接收信号端的arduino的D5端口接一个LED灯
(2)软件方面改动部分也给出了注释
传动内容如下:
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
char tempx[6]="00000";
int x=0;
int y=0;
void setup(){
Serial.begin(9600);
Mirf.spi = &MirfHardwareSpi;
Mirf.init();
Mirf.setRADDR((byte *)"clie1"); // 标记本地名,用于接收
Mirf.payload = 5; //对话的长度,用于约定双方对话的缓冲窗口大小,这个代表5个字节
Mirf.channel = 3; // 通信信道
Mirf.config();
pinMode(5,INPUT);//D五端口作为输入端
}
void loop(){
unsigned long time = millis();
Mirf.setTADDR((byte *)"serv1"); // 标记对方的地址
y=digitalRead(5);    //读取D5端口的状态
if(y==HIGH)           
{tempx[4]=48;}//如果端口状态为高电平传送数据48
else
{tempx[4]=49;}   //如果端口状态为低电平传送数据49
Sends(tempx);
delay(1000);
}
void Sends(char *str)
{
int lens;
lens=strlen(str);
char msg[lens];
int i;
for (i=0;i<lens;i++)
{
msg= int(str);
}
Mirf.send((byte *)&msg);

while(Mirf.isSending()){}   
}




接收内容如下:
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
int y=0;
void setup(){
Serial.begin(9600);

Mirf.spi = &MirfHardwareSpi;
Mirf.init();

Mirf.setRADDR((byte *)"serv1"); // 本地名
Mirf.payload = 5; // 长度
Mirf.channel = 3; // 信道
Mirf.config();
}
void loop(){
byte data[Mirf.payload];
if(!Mirf.isSending() && Mirf.dataReady()){ //存在数据
Mirf.getData(data);
int i;
String Temp;
for (i = 0; i < Mirf.payload; i++) //把收到的信息拼起来,到一个串里面
{
Temp += char(data);
}
Serial.print("Get:");
Serial.print(Mirf.payload);
Serial.print(" ");
Serial.println(Temp);
y=data[4];
Serial.println(y);
if(y==48)                          
{digitalWrite(5,HIGH);}     //接收到的数据为48,D5端口输出高电平
else if(y==49)
{digitalWrite(5,LOW);}    //接收到的数据为49,D5端口输出低电平
  }
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2015-4-2 07:52:53 | 显示全部楼层
呵呵……弱爆啦~
回复 支持 反对

使用道具 举报

发表于 2015-4-2 08:25:39 | 显示全部楼层
你說的應該是ASCII碼吧
回复 支持 反对

使用道具 举报

发表于 2015-4-2 09:14:52 | 显示全部楼层
        是用了两个NRF24?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-4-2 14:30:31 | 显示全部楼层
suoma 发表于 2015-4-2 09:14
是用了两个NRF24?

是的,接法都一样
回复 支持 反对

使用道具 举报

发表于 2015-4-2 15:57:24 | 显示全部楼层
RF24库很好用,2小时搞定。测试发现穿一面墙后10米OK,掉包率10%。穿两面墙失败!
回复 支持 反对

使用道具 举报

发表于 2015-5-31 11:30:17 | 显示全部楼层
怎么在发送端接DHT11采集温湿度信号,接收端在TFT屏上显示?
回复 支持 反对

使用道具 举报

发表于 2015-5-31 11:43:48 | 显示全部楼层
报错了在Arduino:1.5.6-r2 (Windows 7), 板:"Arduino Nano, ATmega328"

sketch_may31a.ino: In function 'void Sends(char*)':
sketch_may31a:37: error: incompatible types in assignment of 'int' to 'char [(((unsigned int)(((int)lens) + -0x000000001)) + 1)]'

  报告将会包含更多的信息
  "Show verbose output during compilation"
  在 文件>首选项 中启用
回复 支持 反对

使用道具 举报

发表于 2015-6-22 15:36:37 | 显示全部楼层
LZ,

for (i=0;i<lens;i++)
{
msg= int(str);
}

第一个程序里的,没看懂啊。
回复 支持 反对

使用道具 举报

发表于 2015-6-27 21:16:56 | 显示全部楼层
hxf 发表于 2015-4-2 14:30
是的,接法都一样

为什么我加载库后编译不了
回复 支持 反对

使用道具 举报

发表于 2015-6-29 07:17:01 | 显示全部楼层
还是自己写库吧,自己装成方便自己用的比较好
回复 支持 反对

使用道具 举报

发表于 2018-4-28 19:58:00 | 显示全部楼层
示范岗的的是短发短发阿哥
回复 支持 反对

使用道具 举报

发表于 2018-4-28 21:58:00 | 显示全部楼层
for (i=0;i<lens;i++)             msg= int(str);楼主这句显示复制错信息求赐教
{
msg= int(str);
}
回复 支持 反对

使用道具 举报

发表于 2018-4-30 12:50:30 | 显示全部楼层

请问现在研究出来了吗,求赐教
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-26 21:01 , Processed in 0.069367 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表