raspberrypi 與 arduino 使用 nRF24L01+ 通信 -- raspberry pi為發送端
nRF24L01+ 通過gpio與樹梅派鏈接,按著網上能找到的所有方法基本上都不順利,從Python方案到c方案都不行,嘗試了很長時間,終于成功,基本上,每個人都會碰到各種各樣的問題。
arduino 接收端代碼:http://www.rzrgm.cn/hangxin1940/archive/2013/05/01/3048315.html
## 修改系統配置
$ sudo nano /etc/modprobe.d/raspi-blacklist.conf
都注釋掉,修改為:
# blacklist spi and i2c by default (many users don't need them)
#blacklist spi-bcm2708
#blacklist i2c-bcm2708
修改加載模塊
$ sudo nano /etc/modules
改為:
snd-bcm2835
i2c-dev
spidev
主要是增加 `spidev`
重啟之后,`/dev/`中會多出兩個設備 `spidev0.0` 與 `spidev0.1`, 沒有出現的話請google排錯。
## 下載源碼
https://github.com/gnulnulf/RF24
打包下載到樹梅派
## 編譯rf24庫
解壓下載好的源碼,進入目錄`RF24-master/librf24-rpi/librf24`
編譯
$ make
如果出現缺少某些編譯工具的提示,google搜搜然后apt安裝就是了
安裝
$ sudo make install
編譯源碼
$ make
安裝
$ sudo make install
## 連接 nRF24L01+ 模塊

rf24 rasp
3.3v 3.3v (不能使用5v)
GND GND
CE GPIO 18 (右排往下第六個)
CSN GPIO 8 (右排往下倒數第二個)
SCK GPIO 11 (左排往下倒數第二個)
MOSI GPIO 10 (左排往下倒數第四個)
MISO GPIO 9 (左排往下倒數第三個)
## 編寫發送端程序
源碼中已經有豐富的示例程序,我們只需要改改源碼就可以跑通
進入`librf24-rpi/librf24/examples`
更改 `pingtest.cpp` 代碼為:
/**
* Example RF Radio Ping Pair
*
* This is an example of how to use the RF24 class. Write this sketch to two different nodes,
* connect the role_pin to ground on one. The ping node sends the current time to the pong node,
* which responds by sending the value back. The ping node can then see how long the whole cycle
* took.
*/
#include
#include
#include "../RF24.h"
/*
連接方法
rf24 rasp
3.3v 3.3v (不能使用5v)
GND GND
CE GPIO 18 (右排往下第六個)
CSN GPIO 8 (右排往下倒數第二個)
SCK GPIO 11 (左排往下倒數第二個)
MOSI GPIO 10 (左排往下倒數第四個)
MISO GPIO 9 (左排往下倒數第三個)
*/
//
// 硬件配置
// spi設備、CSN速率、CSN引腳 GPIO 8
RF24 radio("/dev/spidev0.0",8000000 , 8);
// 設置數據通道地址
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
// 配置rf24
void setup(void) {
printf("\n\rRF24/examples/pingpair/\n\r");
printf("ROLE: Ping out\n\r");
radio.begin();
// 開啟動態有效信息長度
radio.enableDynamicPayloads();
// 設置重傳次數以及每次重傳的延遲
//radio.setRetries(15,15);
// 設置傳輸速率
radio.setDataRate(RF24_1MBPS);
// 設置功放級別,有四種級別:
// RF24_PA_MIN=-18dBm
// RF24_PA_LOW=-12dBm
// RF24_PA_MED=-6dBM
// RF24_PA_HIGH=0dBm
radio.setPALevel(RF24_PA_HIGH);
// 設置信道(0-127)
radio.setChannel(110);
// 設置crc校驗長度
// 兩種 8位RF24_CRC_8 和 16位RF24_CRC_16
radio.setCRCLength(RF24_CRC_16);
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
//
// 開始監聽
//
radio.startListening();
// 打印配置信息
radio.printDetails();
}
void loop(void) {
// 首先停止監聽
radio.stopListening();
// 獲取時間,并發送時間
unsigned long time = __millis();
printf("Now sending %lu...",time);
// 是否發送成功
bool ok = radio.write( &time, sizeof(unsigned long) );
if (ok)
printf("ok...");
else
printf("failed.\n\r");
// 繼續監聽
radio.startListening();
// 等待對方返回數據,超時時間 250ms
unsigned long started_waiting_at = __millis();
bool timeout = false;
while ( !radio.available() && !timeout ) {
//稍微延遲一下,等待radio.available()檢測有效數據
__msleep(5);
if (__millis() - started_waiting_at > 200 )
timeout = true;
}
// 是否超時
if ( timeout ) {
printf("Failed, response timed out.\n\r");
} else {
// 讀取返回信息,并打印出來
unsigned long got_time;
radio.read( &got_time, sizeof(unsigned long) );
printf("Got response %lu, round-trip delay: %lu\n\r",got_time,__millis()-got_time);
}
//延遲一會兒
sleep(1);
}
int main(int argc, char** argv) {
setup();
while(1)
loop();
return 0;
}
然后編譯:
$ make
之后,這幾個示例都會編譯出來。運行`pingtest`程序
$ sudo ./pingtest
rasp的輸出:
RF24/examples/pingpair/
ROLE: Ping out
SPI device = /dev/spidev0.0
SPI speed = 8000000
CE GPIO = 8
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xf0f0f0f0e1 0xf0f0f0f0d2
RX_ADDR_P2-5 = 0xe2 0xe3 0xf1 0xf2
TX_ADDR = 0xf0f0f0f0e1
RX_PW_P0-6 = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA = 0x3f
EN_RXADDR = 0x3e
RF_CH = 0x6e
RF_SETUP = 0x04
CONFIG = 0x0f
DYNPD/FEATURE = 0x3f 0x04
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_HIGH
Now sending 1607486530...failed.
Got response 1607486430, round-trip delay: 156
Now sending 1607487589...failed.
Got response 1607487489, round-trip delay: 158
Now sending 1607488650...failed.
ps: 本人用arduino uno充當接收端時,發送端總是提示發送失敗`failed`,但是,雙方通信是沒問題的。換成了lilypad就沒有這個情況。
上面的是配置信息,如果大部分數據都是ffffff,那么硬件沒有配置成功,這樣很麻煩,只能求助與google了。
下面的 sending那些東西,是發送給arduino,以及arduino返回的數,arduino會給每個數減去100,并返回。
arduino的輸出:
RF24/examples/pingpair/
ROLE: Pong back
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xf0f0f0f0d2 0xf0f0f0f0e1
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xf0f0f0f0d2
RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x03
RF_CH = 0x6e
RF_SETUP = 0x05
CONFIG = 0x0f
DYNPD/FEATURE = 0x3f 0x04
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = LA_MED
Got payload 1607938782...Sent response.
Got payload 1607939839...Sent response.
Got payload 1607940898...Sent response.
## 補充
http://wenku.baidu.com/view/6c779635eefdc8d376ee3256.html nRF24L01中文手冊
http://maniacbug.github.io/RF24/classRF24.html RF24的api手冊,適用于rasp和arduino
其他 rf24與rasp和arduino相關的資源:
http://www.raspberrypi.org/phpBB3/viewtopic.php?t=17061 官方討論
https://github.com/maniacbug/RF24 rf24庫
https://github.com/gnulnulf/RF24 包含rasp的rf24庫
https://bitbucket.org/Amanoo/rf24rp/wiki/Home BeagleBone的rf24庫移植的rasp庫
http://www.e-risingstar.com/wordpress/?p=543 另一個rasp與arduino的互通指南,基于上面那個BeagleBone移植過來的庫
https://plus.google.com/100198871098258549028/posts/Hn1JpyUWKKo rasp的python rasp庫
http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo arduino的rf24指南
http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/ 另一個arduino的rf24指南
浙公網安備 33010602011771號