nRF24L01 一傳多問題
大家好小弟用3個nRF24L01組成系統, 1個當master, 2個當slave
master定時輪流詢問slave(step 1,3), slave收到後回應master(step 2,4)
但是slave總會規律低收不到來自master訊息
有人有成功經驗嗎
研究好久都沒結果
附上程式碼
謝謝
master 程式碼
#include <SPI.h>
#include "RF24.h"
RF24 rf24(7, 8); // CE腳, CSN腳
byte pipe = 1;// 指定通道編號
const byte addr[] = {"1Node","2Node"};
const byte addr_m_tx[] = {"1MOSI", "2MOSI"};
const byte addr_s_tx[] = {"1MISO", "2MISO"};
const char msg1[] = "1 Happy Hacking!";
const char msg2[] = "2 Happy Hacking!";
unsigned long started_waiting_at;
void setup() {
Serial.begin(9600);
rf24.begin();
rf24.setChannel(83); // 設定頻道編號
rf24.openWritingPipe(addr_m_tx); // 設定1Node通道位址
rf24.openReadingPipe(pipe, addr_s_tx); // 設定1Node通道位址
rf24.setPALevel(RF24_PA_MIN); // 設定廣播功率
rf24.setDataRate(RF24_2MBPS); // 設定傳輸速率
rf24.stopListening(); // 停止偵聽;設定成發射模式
Serial.println("nRF24L01 master ready!");
}
void loop() {
rf24.openWritingPipe(addr_m_tx); // 設定1Node通道位址
rf24.openReadingPipe(pipe, addr_s_tx); // 設定1Node通道位址
rf24.write(&msg1, sizeof(msg1));// 傳送資料
#if 1
rf24.startListening();
started_waiting_at = micros();
while(1)
{
//if(rf24.available(&pipe))
if(rf24.available())
{
char msg = "";
rf24.read(&msg, sizeof(msg));
Serial.println(msg); // 顯示訊息內容
break;
}
if(micros() - started_waiting_at > 100000) //If waited longer than 100ms, indicate timeout and exit while loop
{
Serial.println("Timeout");
break;
}
}
rf24.stopListening();
#endif
delay(1000);
rf24.openWritingPipe(addr_m_tx); // 設定2Node通道位址
rf24.openReadingPipe(pipe, addr_s_tx); // 設定2Node通道位址
rf24.write(&msg2, sizeof(msg2));// 傳送資料
#if 1
rf24.startListening();
started_waiting_at = micros();
while(1)
{
//if(rf24.available(&pipe))
if(rf24.available())
{
char msg = "";
rf24.read(&msg, sizeof(msg));
Serial.println(msg); // 顯示訊息內容
break;
}
if(micros() - started_waiting_at > 100000) //If waited longer than 100ms, indicate timeout and exit while loop
{
Serial.println("Timeout");
break;
}
}
#endif
rf24.stopListening();
delay(1000);
}
slave1 程式碼
#include <SPI.h>
#include "RF24.h"
RF24 rf24(7, 8); // CE腳, CSN腳
byte pipe = 1;// 指定通道編號
const byte addr_m_tx = "1MOSI";
const byte addr_s_tx = "1MISO";
const char ack_msg[] = "Slave1 ack";
void setup() {
Serial.begin(9600);
rf24.begin();
rf24.setChannel(83);// 設定頻道編號
rf24.setPALevel(RF24_PA_MIN);
rf24.setDataRate(RF24_2MBPS);
rf24.openWritingPipe(addr_s_tx); // 設定1Node通道位址
rf24.openReadingPipe(pipe,addr_m_tx); // 設定1Node通道位址
rf24.startListening();// 開始監聽無線廣播
Serial.println("nRF24L01 slave1 ready!");
}
void loop() {
if (rf24.available(&pipe)) {
char msg = "";
rf24.read(&msg, sizeof(msg));
Serial.println(msg); // 顯示訊息內容
rf24.stopListening();
rf24.write( &ack_msg, sizeof(ack_msg) );
rf24.startListening();
}
}
slave2 程式碼
#include <SPI.h>
#include "RF24.h"
RF24 rf24(7, 8); // CE腳, CSN腳
byte pipe = 1;// 指定通道編號
const byte addr_m_tx = "2MOSI";
const byte addr_s_tx = "2MISO";
const char ack_msg[] = "Slave2 ack";
void setup() {
Serial.begin(9600);
rf24.begin();
rf24.setChannel(83);// 設定頻道編號
rf24.setPALevel(RF24_PA_MIN);
rf24.setDataRate(RF24_2MBPS);
rf24.openWritingPipe(addr_s_tx); // 設定2Node通道位址
rf24.openReadingPipe(pipe,addr_m_tx); // 設定2Node通道位址
rf24.startListening();// 開始監聽無線廣播
Serial.println("nRF24L01 slave ready!");
}
void loop() {
if (rf24.available(&pipe)) {
char msg = "";
rf24.read(&msg, sizeof(msg));
Serial.println(msg); // 顯示訊息內容
rf24.stopListening();
rf24.write( &ack_msg, sizeof(ack_msg) );
rf24.startListening();
}
} 把 程式 TIMEOUT 時間加長
或是
SLAVE 端 調過來看
原來
Serial.println(msg); // 顯示訊息內容
rf24.stopListening();
rf24.write( &ack_msg, sizeof(ack_msg) );
rf24.startListening();
改成
rf24.stopListening();
rf24.write( &ack_msg, sizeof(ack_msg) );
rf24.startListening();
Serial.println(msg); // 顯示訊息內容
嗨,更新一下狀況
我後來排除timeout值太短或serial.println造成延遲的關係
後來方法是master在timeout的時候再重傳一次資料
這樣就能收到slave回應
master 程式碼
#include <SPI.h>
#include "RF24.h"
RF24 rf24(7, 8); // CE腳, CSN腳
byte pipe = 1;// 指定通道編號
const byte addr[] = {"1Node","2Node"};
const byte addr_m_tx[] = {"1MOSI", "2MOSI"};
const byte addr_s_tx[] = {"1MISO", "2MISO"};
const char msg1[] = "1 Happy Hacking!";
const char msg2[] = "2 Happy Hacking!";
unsigned long started_waiting_at;
void setup() {
Serial.begin(115200);
rf24.begin();
rf24.setChannel(83); // 設定頻道編號
//rf24.openWritingPipe(addr_m_tx); // 設定1Node通道位址
//rf24.openReadingPipe(pipe, addr_s_tx); // 設定1Node通道位址
rf24.setPALevel(RF24_PA_MIN); // 設定廣播功率
rf24.setDataRate(RF24_2MBPS); // 設定傳輸速率
rf24.stopListening(); // 停止偵聽;設定成發射模式
Serial.println("nRF24L01 master ready!");
}
void loop() {
delay(1000);
rf24.openWritingPipe(addr_m_tx); // 設定1Node通道位址
rf24.openReadingPipe(pipe, addr_s_tx); // 設定1Node通道位址
rf24.write(&msg1, sizeof(msg1));// 傳送資料
#if 1
rf24.startListening();
started_waiting_at = micros();
while(1)
{
//if(rf24.available(&pipe))
if(rf24.available())
{
char msg = "";
rf24.read(&msg, sizeof(msg));
Serial.println(msg); // 顯示訊息內容
break;
}
if(micros() - started_waiting_at > 300000) //If waited longer than 100ms, indicate timeout and exit while loop
{
rf24.stopListening();
rf24.write(&msg1, sizeof(msg1));// 重傳資料
rf24.startListening();
started_waiting_at = micros();
Serial.println("Resend 1");
}
}
rf24.stopListening();
#endif
delay(1000);
rf24.openWritingPipe(addr_m_tx); // 設定2Node通道位址
rf24.openReadingPipe(pipe, addr_s_tx); // 設定2Node通道位址
rf24.write(&msg2, sizeof(msg2));// 傳送資料
#if 1
rf24.startListening();
started_waiting_at = micros();
while(1)
{
//if(rf24.available(&pipe))
if(rf24.available())
{
char msg = "";
rf24.read(&msg, sizeof(msg));
Serial.println(msg); // 顯示訊息內容
break;
}
if(micros() - started_waiting_at > 300000) //If waited longer than 100ms, indicate timeout and exit while loop
{
rf24.stopListening();
rf24.write(&msg2, sizeof(msg2));// 重傳資料
rf24.startListening();
started_waiting_at = micros();
Serial.println("Resend 2");
}
}
#endif
rf24.stopListening();
}
不過不清楚為什麼一定要重傳一次
印像中SPI需要dummy data,會不會有關呢
還請熟悉SPI高手解惑
頁:
[1]