久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: Arduino學習16-連接nRF24L01無線收發模塊 [打印本頁]

作者: 51黑學者    時間: 2016-4-18 03:33
標題: Arduino學習16-連接nRF24L01無線收發模塊
nRF24L01是一款工作在 2.4~2.5GHz 世界通用ISM頻段的單片無線收發器芯片,輸出功率、頻道選擇和協議的設置可以通過SPI接口進行設置。有極低的電流消耗,當工作在發射模式下發射功率為-6dBm時電流消耗為9.0mA,接收模式時為12.3mA。掉電模式和待機模式下電流消耗更低。
nRF24L01參考數據:供電電壓:1.9 V~3.6V;最大發射功率:0 dBm;最大數據傳輸率:2000 kbps;發射模式下電流消耗(0dBm時):11.3 mA;接收模式下電流消耗(2000kbps):12.3 mA;接收模式數據傳輸率為1000kbps下的靈敏度:-85 dBm;掉電模式下電流消耗:900 nA。

淘寶上面有兩種nRF24L01模塊,一種是單純的nRF24L01模塊,號稱傳輸距離250m的,幾塊錢就有交易;另外一種是NRF24L01+PA+LNA模塊,包含放大,號稱可以傳輸1000m,價格幾十塊。實際距離視地形和障礙物而定,是否夠遠只能通過試用確定。

下面用廉價的第一種單純nRF24L01模塊做示例:




一、nRF24L01硬件連接:
此模塊是使用SPI方式連接,在標準SPI口基礎增加CE和CSN引腳:
nRF24L01 Arduino UNO
VCC <-> 3.3V
GND <-> GND
CE <-> D9
CSN <-> D10
MOSI<-> D11
MISO<-> D12
SCK <-> D13
IRQ <-> 不接

還有就是nRF24L01屬于對傳模塊。每塊芯片既是發射器,也是接收器。所以一般來說,要使用兩塊nRF24L01+兩塊Arduino才能進行測試。

二、應用例子
實驗1:

將Sender機A0的AD轉換值無線發送到Receiver機

原理圖:

Sender機(A0端與電源兩端接一個電位器,阻值隨意,一般1k~100k均可):


Receiver機:


代碼:

首先需要安裝Mirf庫,可以在http://playground.arduino.cc/InterfacingWithHardware/Nrf24L01下載或者本文附件下載。

Sender機:
  1.     /*
  2.     nRF24L01 Arduino發送端
  3.      
  4.     Ansifa
  5.     2015/3/7
  6.      
  7.     引腳接法:
  8.     nRF24L01   Arduino UNO
  9.     VCC        <->        3.3V
  10.     GND        <->        GND
  11.     CE        <->        D9
  12.     CSN        <->        D10
  13.     MOSI<->        D11
  14.     MISO<->        D12
  15.     SCK        <->        D13
  16.     IRQ        <->        不接
  17.     */
  18.      
  19.     #include
  20.     #include
  21.     #include
  22.     #include
  23.     void setup()
  24.     {
  25.         Serial.begin(9600);
  26.      
  27.         Mirf.cePin = 9;                //設置CE引腳為D9
  28.         Mirf.csnPin = 10;        //設置CE引腳為D10
  29.         Mirf.spi = &MirfHardwareSpi;
  30.         Mirf.init();  //初始化nRF24L01               
  31.      
  32.             //設置接收標識符"Sen01"
  33.         Mirf.setRADDR((byte *)"Sen01");
  34.         //設置一次收發的字節數,這里發一個整數,寫sizeof(unsigned int),實際等于2字節
  35.         Mirf.payload = sizeof(unsigned int);
  36.         //發送通道,可以填0~128,收發必須一致。
  37.         Mirf.channel = 3;
  38.         Mirf.config();
  39.      
  40.             //注意一個Arduino寫Sender.ino,另一個寫Receiver.ino。
  41.             //這里標識寫入了Sender.ino
  42.         Serial.println("I'm Sender...");
  43.     }
  44.     unsigned int adata = 0;
  45.     void loop()
  46.     {
  47.             //讀取A0值到adata
  48.         adata = analogRead(A0);
  49.      
  50.         //由于nRF24L01只能以byte單字節數組形式發送Mirf.payload個數據,
  51.         //所以必須將所有需要傳輸的數據拆成byte。
  52.         //下面定義byte數組,存放待發數據,因為Mirf.payload = sizeof(unsigned int);
  53.         //實際下面等于byte data[2];
  54.         byte data[Mirf.payload];
  55.      
  56.         //adata是unsigned int雙字節數據,必須拆開。
  57.         //將adata高低八位拆分:
  58.         data[0] = adata & 0xFF;                //低八位給data[0],
  59.         data[1] = adata >> 8;                //高八位給data[1]。
  60.      
  61.         //設置向"serv1"發送數據
  62.         Mirf.setTADDR((byte *)"Rec01");
  63.         Mirf.send(data);
  64.         //while死循環等待發送完畢,才能進行下一步操作。
  65.         while(Mirf.isSending()) {}
  66.         delay(20);
  67.     }
復制代碼

Receiver機:
  1.     /*
  2.     nRF24L01 Arduino Receiver接收端
  3.      
  4.     Ansifa
  5.     2015/3/7
  6.      
  7.     引腳接法:
  8.     nRF24L01   Arduino UNO
  9.     VCC <-> 3.3V
  10.     GND <-> GND
  11.     CE  <-> D9
  12.     CSN <-> D10
  13.     MOSI<-> D11
  14.     MISO<-> D12
  15.     SCK <-> D13
  16.     IRQ <-> 不接
  17.     */
  18.      
  19.     #include
  20.     #include
  21.     #include
  22.     #include
  23.      
  24.         //定義一個變量adata存儲最終結果,oldadata存儲舊結果,防止相同結果刷屏。
  25.         unsigned int adata = 0, oldadata = 0;
  26.      
  27.     void setup()
  28.     {
  29.         Serial.begin(9600);
  30.      
  31.         //---------初始化部分,不可隨時修改---------
  32.         Mirf.cePin = 9;     //設置CE引腳為D9
  33.         Mirf.csnPin = 10;   //設置CE引腳為D10
  34.         Mirf.spi = &MirfHardwareSpi;
  35.         Mirf.init();  //初始化nRF24L01
  36.      
  37.         //---------配置部分,可以隨時修改---------
  38.         //設置接收標識符"Rev01"
  39.         Mirf.setRADDR((byte *)"Rec01");
  40.         //設置一次收發的字節數,這里發一個整數,
  41.         //寫sizeof(unsigned int),實際等于2字節
  42.         Mirf.payload = sizeof(unsigned int);
  43.         //發送通道,可以填0~128,收發必須一致。
  44.         Mirf.channel = 3;
  45.         Mirf.config();
  46.      
  47.         //注意一個Arduino寫Sender.ino,另一個寫Receiver.ino。
  48.         //這里用來辨別寫入了Receiver.ino程序
  49.         Serial.println("I'm Receiver...");
  50.     }
  51.      
  52.     void loop()
  53.     {
  54.         //定義一個暫存數組,大小為Mirf.payload。
  55.         byte data[Mirf.payload];
  56.         if(Mirf.dataReady())    //等待接收數據準備好
  57.         {
  58.             Mirf.getData(data);    //接收數據到data數組
  59.             //data[1]<左移8位與data[0]并,重組數據。
  60.             adata = (unsigned int)((data[1] << 8) | data[0]);
  61.      
  62.             //與上一次結果比較,避免相同結果刷屏,降低串口流量
  63.             if(adata != oldadata)
  64.             {
  65.                 oldadata = adata; //本次結果作為歷史結果。
  66.                 //Serial.print輸出數據
  67.                 Serial.print("A0=");
  68.                 Serial.println(adata);
  69.                 //也可以輸出雙字節數據
  70.                 //Serial.write(data[1]);
  71.                 //Serial.write(data[0]);
  72.             }
  73.      
  74.         }
  75.     }
復制代碼

實驗2:

將上述的數據繪圖表。

修改一下輸出格式,然后用現成的串口圖表軟件顯示出來。

原理圖:
與實驗1一樣。
代碼:
發射端代碼與原來一樣。
接收端新代碼:
  1.     /*
  2.     nRF24L01 Arduino Receiver接收端
  3.     圖表輸出版本
  4.      
  5.     Ansifa
  6.     2015/3/7
  7.      
  8.     引腳接法:
  9.     nRF24L01   Arduino UNO
  10.     VCC <-> 3.3V
  11.     GND <-> GND
  12.     CE  <-> D9
  13.     CSN <-> D10
  14.     MOSI<-> D11
  15.     MISO<-> D12
  16.     SCK <-> D13
  17.     IRQ <-> 不接
  18.     */
  19.      
  20.     #include
  21.     #include
  22.     #include
  23.     #include
  24.      
  25.     //定義一個變量adata存儲最終結果。
  26.     unsigned int adata = 0;
  27.      
  28.     void setup()
  29.     {
  30.         Serial.begin(9600);
  31.      
  32.         //---------初始化部分,不可隨時修改---------
  33.         Mirf.cePin = 9;     //設置CE引腳為D9
  34.         Mirf.csnPin = 10;   //設置CE引腳為D10
  35.         Mirf.spi = &MirfHardwareSpi;
  36.         Mirf.init();  //初始化nRF24L01
  37.      
  38.         //---------配置部分,可以隨時修改---------
  39.         //設置接收標識符"Rev01"
  40.         Mirf.setRADDR((byte *)"Rec01");
  41.         //設置一次收發的字節數,這里發一個整數,
  42.         //寫sizeof(unsigned int),實際等于2字節
  43.         Mirf.payload = sizeof(unsigned int);
  44.         //發送通道,可以填0~128,收發必須一致。
  45.         Mirf.channel = 3;
  46.         Mirf.config();
  47.      
  48.         //注意一個Arduino寫Sender.ino,另一個寫Receiver.ino。
  49.         //這里用來辨別寫入了Receiver.ino程序
  50.         Serial.println("I'm Receiver...");
  51.     }
  52.      
  53.     void loop()
  54.     {
  55.         //定義一個暫存數組,大小為Mirf.payload。
  56.         byte data[Mirf.payload];
  57.         if(Mirf.dataReady())    //等待接收數據準備好
  58.         {
  59.             Mirf.getData(data);    //接收數據到data數組
  60.             //data[1]<左移8位與data[0]并,重組數據。
  61.             adata = (unsigned int)((data[1] << 8) | data[0]);
  62.      
  63.             //輸出雙字節數據
  64.             Serial.write(data[0]);
  65.             Serial.write(data[1]);
  66.         }
  67.     }
復制代碼

上位機:
直接用現成軟件比如這個串口獵人。
配置如圖。依照圖片順序配置成截圖一樣即可。





特意測試了一下可以,這個說是+7dB的,比wifi的+5dB高一點,感覺會比wifi好一些。

下面是PDF版本文章與源代碼:

Arduino連接NRF24L01無線收發模塊.zip (3.25 MB, 下載次數: 177)

作者: 51黑學者    時間: 2016-4-18 03:41
問題解答:
樓主你好,我想請教下,如果一次發送多個傳感器的數據該怎么改呢?我試著改了一下你的程序,但是只能接收到第一個傳感器的數據,第二個傳感器的數據一直不對,能幫我看下嗎?謝謝了
發送端程序
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
void setup()
{
    Serial.begin(9600);

    Mirf.cePin = 8;                //設置CE引腳為D9
    Mirf.csnPin = 7;        //設置CE引腳為D10
    Mirf.spi = &MirfHardwareSpi;
    Mirf.init();  //初始化nRF24L01               

        //設置接收標識符"Sen01"
    Mirf.setRADDR((byte *)"Sen01");
    Mirf.payload = sizeof(unsigned int);
    Mirf.channel = 3;
    Mirf.config();

        //注意一個Arduino寫Sender.ino,另一個寫Receiver.ino。
        //這里標識寫入了Sender.ino
    Serial.println("I'm Sender...");
}
unsigned int adata = 0;
unsigned int bdata = 0;
void loop()
{
        //讀取A0值到adata
    adata = analogRead(A0);
    bdata = analogRead(A1);

    //由于nRF24L01只能以byte單字節數組形式發送Mirf.payload個數據,
    //所以必須將所有需要傳輸的數據拆成byte。
    //下面定義byte數組,存放待發數據,因為Mirf.payload = sizeof(unsigned int);
    //實際下面等于byte data[2];
    byte data[Mirf.payload];

    //adata是unsigned int雙字節數據,必須拆開。
    //將adata高低八位拆分:
    data[0] = adata & 0xFF;                //低八位給data[0],
    data[1] = adata >> 8;    //高八位給data[1]。
  data[2] = bdata & 0xFF;                //低八位給data[0],
    data[3] = bdata >> 8;
    //設置向"serv1"發送數據
    Mirf.setTADDR((byte *)"Rec01");
    Mirf.send(data);
    //while死循環等待發送完畢,才能進行下一步操作。
    while(Mirf.isSending()) {}
    Serial.println(adata);
    Serial.print("*****");
    Serial.println(bdata,DEC);
    delay(3000);
}

接收端程序:

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

    //定義一個變量adata存儲最終結果,oldadata存儲舊結果,防止相同結果刷屏。
    unsigned int adata = 0, bdata = 0;

void setup()
{
    Serial.begin(9600);

    //---------初始化部分,不可隨時修改---------
    Mirf.cePin = 8;     //設置CE引腳為D9
    Mirf.csnPin = 7;   //設置CE引腳為D10
    Mirf.spi = &MirfHardwareSpi;
    Mirf.init();  //初始化nRF24L01

    //---------配置部分,可以隨時修改---------
    //設置接收標識符"Rev01"
    Mirf.setRADDR((byte *)"Rec01");
    //設置一次收發的字節數,這里發一個整數,
    //寫sizeof(unsigned int),實際等于2字節
    Mirf.payload = sizeof(unsigned int);
    //發送通道,可以填0~128,收發必須一致。
    Mirf.channel = 3;
    Mirf.config();

    //注意一個Arduino寫Sender.ino,另一個寫Receiver.ino。
    //這里用來辨別寫入了Receiver.ino程序
    Serial.println("I'm Receiver...");
}

void loop()
{
    //定義一個暫存數組,大小為Mirf.payload。
    byte data[Mirf.payload];
    if(Mirf.dataReady())    //等待接收數據準備好
    {
        Mirf.getData(data);    //接收數據到data數組
        //data[1]<左移8位與data[0]并,重組數據。
        adata = (unsigned int)((data[1] << 8) | data[0]);
  bdata = (unsigned int)((data[3] << 8) | data[2]);



          Serial.println(adata);
    Serial.print("*****");
    Serial.println(bdata,DEC);
    }
}

求指教,十分感謝!

-----------------------------------------------

答:
你在可以這樣修改:

發送端程序
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
void setup()
{
    Serial.begin(9600);

    Mirf.cePin = 8;                //設置CE引腳為D9
    Mirf.csnPin = 7;        //設置CE引腳為D10
    Mirf.spi = &MirfHardwareSpi;
    Mirf.init();  //初始化nRF24L01               

        //設置接收標識符"Sen01"
    Mirf.setRADDR((byte *)"Sen01");
    Mirf.payload = sizeof(unsigned int);//在這把2 修改成4
    Mirf.channel = 3;
    Mirf.config();

        //注意一個Arduino寫Sender.ino,另一個寫Receiver.ino。
        //這里標識寫入了Sender.ino
    Serial.println("I'm Sender...");
}
unsigned int adata = 0,bdata = 0;

void loop()
{
        //讀取A0值到adata
    adata = analogRead(A0);
    bdata = analogRead(A1);

    //由于nRF24L01只能以byte單字節數組形式發送Mirf.payload個數據,
    //所以必須將所有需要傳輸的數據拆成byte。
    //下面定義byte數組,存放待發數據,因為Mirf.payload = sizeof(unsigned int);
    //實際下面等于byte data[2];
    byte data[Mirf.payload];

    //adata是unsigned int雙字節數據,必須拆開。
    //將adata高低八位拆分:
    data[0] = adata & 0xFF;                //低八位給data[0],
    data[1] = adata >> 8;    //高八位給data[1]。
    data[2] = bdata & 0xFF;                //低八位給data[0],
    data[3] = bdata >> 8;
    //設置向"serv1"發送數據
    Mirf.setTADDR((byte *)"Rec01");
    Mirf.send(data);
    //while死循環等待發送完畢,才能進行下一步操作。
    while(Mirf.isSending()) {}
    Serial.println(adata);
    Serial.print("*****");
    Serial.println(bdata,DEC);
    delay(3000);
}

接收端程序:

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

    //定義一個變量adata存儲最終結果,oldadata存儲舊結果,防止相同結果刷屏。
    unsigned int adata = 0, bdata = 0;

void setup()
{
    Serial.begin(9600);

    //---------初始化部分,不可隨時修改---------
    Mirf.cePin = 8;     //設置CE引腳為D9
    Mirf.csnPin = 7;   //設置CE引腳為D10
    Mirf.spi = &MirfHardwareSpi;
    Mirf.init();  //初始化nRF24L01

    //---------配置部分,可以隨時修改---------
    //設置接收標識符"Rev01"
    Mirf.setRADDR((byte *)"Rec01");
    //設置一次收發的字節數,這里發一個整數,
    //寫sizeof(unsigned int),實際等于2字節
    Mirf.payload = sizeof(unsigned int);//在這把2 修改成4
    //發送通道,可以填0~128,收發必須一致。
    Mirf.channel = 3;
    Mirf.config();

    //注意一個Arduino寫Sender.ino,另一個寫Receiver.ino。
    //這里用來辨別寫入了Receiver.ino程序
    Serial.println("I'm Receiver...");
}

void loop()
{
    //定義一個暫存數組,大小為Mirf.payload。
    byte data[Mirf.payload];
    if(Mirf.dataReady())    //等待接收數據準備好
    {
        Mirf.getData(data);    //接收數據到data數組
        //data[1]<左移8位與data[0]并,重組數據。
        adata = (unsigned int)((data[1] << 8) | data[0]);
        bdata = (unsigned int)((data[3] << 8) | data[2]);
   
      
            
          Serial.println(adata);
    Serial.print("*****");
    Serial.println(bdata,DEC);
    }
}


作者: kongkongzxc    時間: 2016-12-22 01:11
教程真的不錯。
作者: kongkongzxc    時間: 2016-12-22 01:13
相當不錯的教程
作者: oilstick    時間: 2017-2-22 01:05
1) 終于成功測試成功。  不過網上的MIRF 庫有多個版本的,我用上老的版本·
https://github.com/aaronds/arduino-nrf24l01

2)  設置CE CSN引腳也很方便可以用以下指令
Mirf.cePin = 9;   
Mirf.csnPin = 10

3) 范例開始的這段漏了  
#include
#include
#include
#include ,  
后來查了一下應該是
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
作者: 姚姚的追求者    時間: 2017-4-13 14:42
參照了您的寫法,一對一成功了,請問一對多如何改寫
作者: yzy7103    時間: 2017-4-17 09:06
很不錯的教程,學習了
作者: yzy710308    時間: 2017-4-17 13:00
有一對多的代碼嗎?
作者: 姚姚的追求者    時間: 2017-4-18 09:40
這個是別人寫的多通道發送端程序,更改地址,但是只有03號地址才能用為啥?
  1. /*
  2.     nRF24L01 Arduino Receiver接收端
  3.     圖表輸出版本
  4.      
  5.     Ansifa
  6.     2015/3/7
  7.      
  8.     引腳接法:
  9.     nRF24L01   Arduino UNO
  10.     VCC <-> 3.3V
  11.     GND <-> GND
  12.     CE  <-> D9
  13.     CSN <-> D10
  14.     MOSI<-> D11
  15.     MISO<-> D12
  16.     SCK <-> D13
  17.     IRQ <-> 不接
  18.     */
  19. #include"Multiple.h"

  20. Multiple nrf(9,10,13,11,12);//構建函數,參數分別為CE,CSN,CLK,MOSI,MISO

  21. uint8_t tx_addr[] = { 0x03, 0xFF, 0xFF, 0xFF, 0xFF};//發送地址
  22. uint8_t tx_data[32]={3,0,2,5,8};//發送的數據,32位
  23. //uint8_t channel;//接收通道
  24. //uint8_t tmp;

  25. void setup() {
  26.   nrf.send_mode(tx_addr);//設置為發送模式,參數為發送地址
  27. }

  28. void loop() {
  29.    
  30.   tx_data[2]++;
  31.   nrf.send(tx_addr,tx_data);//發送數據,參數:發送地址,數據
  32.   delay(1000);

  33. }
復制代碼

作者: savantor    時間: 2017-5-17 00:53
支持一個,我用RF24丟包好嚴重,不懂是什么問題
作者: zxy2266    時間: 2017-5-28 19:33
丟包多數是信號強度不夠,你看設置有問題沒,簡單辦法可以試試降低速率,如果可以就是這樣的問題
作者: gdgzwqz    時間: 2017-8-1 22:52
不小心重復了下載,怎么又扣分哪!!!!!!!

作者: gdgzwqz    時間: 2017-8-1 22:53
我下載了再次,扣了我再次5分!!!!!!冤枉啊!!!!!!!!!

作者: klklkl    時間: 2017-10-11 16:52
請問下怎樣實現兩個邊發送 邊接收
作者: nl604623967    時間: 2017-12-15 23:18
用的庫里帶的事例,一直這樣
Beginning ...
Finished sending
Timeout on response from server!
Finished sending
Timeout on response from server!
Finished sending
Timeout on response from server!
Finished sending
Timeout on response from server!
Finished sending
Timeout on response from server!
Finished sending
作者: nl604623967    時間: 2017-12-15 23:28
I'm Receiver...
沒有然后了
作者: midrich    時間: 2018-8-27 10:10
我也點“后退”結果造成重復下載被重復扣了5分!!!
作者: 猶豫的流星    時間: 2018-12-9 10:35
學習一下           
作者: 猶豫的流星    時間: 2018-12-27 09:03
下載一個看看
作者: Kinarmy    時間: 2019-1-19 20:05
樓主您好!我今天也碰巧搞這個模塊,不過好像存在些問題,接線沒有問題。C:\Users\Administrator\DesktopC:\Users\Administrator\Desktop
作者: 賈濡    時間: 2019-8-3 11:11
gdgzwqz 發表于 2017-8-1 22:53
我下載了再次,扣了我再次5分!!!!!!冤枉啊!!!!!!!!!

下載好的能不能分享一下





歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 日韩欧美视频免费在线观看 | 国产亚洲一区二区三区 | 久色视频在线 | 欧美日韩精品一区二区天天拍 | 国产一级视频免费播放 | 国产一区二区三区四区 | 99久久国产综合精品麻豆 | 免费观看一级特黄欧美大片 | 在线观看av网站 | 成人中文字幕在线观看 | 操人网站 | 欧美在线一区二区三区四区 | 99精品国产成人一区二区 | 欧美一区2区三区3区公司 | 日韩一区二区av | 欧美男人天堂 | 日韩av免费在线观看 | 亚洲免费人成在线视频观看 | 欧美精品福利视频 | 久久久久久久久久久国产 | 伊人手机在线视频 | pacopacomama在线| 中文字幕 在线观看 | 欧美国产日韩在线 | 搞黄视频免费看 | 久久久精品影院 | 国产高清在线观看 | 成人在线视频观看 | 久久综合av| 欧美福利影院 | 国产精品无码专区在线观看 | 欧美一区二区三区视频在线 | www精品| 成人在线视频免费观看 | 97久久久 | 久久久久国产精品人 | 一区二区在线看 | 亚洲欧美综合精品久久成人 | 99久久国产精 | 成人高潮片免费视频欧美 | 农夫在线精品视频免费观看 |