樹莓派與Arduino Leonardo使用NRF24L01無線模塊通信之基於RF24庫 (四) 樹莓派單子節點查詢
阿新 • • 發佈:2018-02-11
spi listening div num 另一個 control 樹莓派 des gin
考慮到項目的實際需要,樹莓派作為主機,應該只在需要的時候查詢特定節點發送的數據,因此接收到數據後需要根據頭部判斷是否是自己需要的數據,如果不是繼續接收數據,超過一定時間未查詢到特定節點的數據,則退出程序,避免無限等待。
本項目中各個節點和樹莓派的通信不區分信道,因此如果由樹莓派發送給特定節點的數據會被所有節點接收到,因此子節點可以判別該數據是否發給自己的,需要在數據的第二個字節中加入目標節點的編號(第一個字節為源節點的編號)。
樹莓派代碼
如下:
#include <cstdlib> #include <iostream> #include <sstream> #include<string> #include <unistd.h> #include <RF24/RF24.h> using namespace std; RF24 radio(22,0,BCM2835_SPI_SPEED_8MHZ); /********** User Config *********/ // Assign a unique identifier for this node, 0 or 1 bool radioNumber = 1; bool role = 0;//receive mode unsigned long start_time=millis(); unsignedlong count=0; /********************************/ // Radio pipe addresses for the 2 nodes to communicate. const uint64_t pipes = 0xE8E8F0F0E1LL; unsigned long receData; unsigned long respData=0x01; unsigned long srchead=0x00000000; int main(int argc, char** argv){ cout << "RF24/examples/GettingStarted/\n"; // Setup and configure rf radio radio.begin(); // optionally, increase the delay between retries & # of retries radio.setRetries(15,15); // Dump the configuration of the rf unit for debugging radio.printDetails(); radio.openReadingPipe(1,pipes); /***********************************/ // This simple sketch opens two pipes for these two nodes to communicate // back and forth. radio.startListening(); cout << "Listening .... \n"; int node = atoi(argv[1]); cout << "Listening Node is : " <<node<<" \n"; while(1){ unsigned long end_time = millis(); if(radio.available()){ radio.read(&receData,sizeof(unsigned long)); //cout<<"receData is: "<<receData<<"\n"; unsigned int check = (unsigned int) receData>>24; unsigned long data = receData & 0x00001111; //cout<<"check is "<<check<<"\n";
if(check==node && (receData & 0x00110000)==srchead){ cout<<"Get Node Data: "<<data<<",Time consume "<<(end_time-start_time)<<"ms \n"; break; } } cout<<"time out is "<<(end_time-start_time)<<"\n"; if((end_time-start_time)>=5000){ cout<<"Wait Data from Node "<<node<<" time out \n"; break; } } return 0; }
Arduino Leonardo代碼
Arduino Leonardo作為子節點,代碼與前一節一樣,不停發送和接收相互切換。如下:
#include <SPI.h> #include "RF24.h" #include <SPI.h> #include "RF24.h" #include <printf.h> /****************** User Config ***************************/ /*** Set this radio as radio number 0 or 1 ***/ bool radioNumber = 0; /* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */ RF24 radio(9,10); /**********************************************************/ byte addresses[][6] = {"1Node","2Node"}; // Used to control whether this node is sending or receiving bool role = 1;//1表示發送模式,0表示接收模式 unsigned long start_time = millis(); //這個是我們即將建立的傳輸渠道編碼 //!!要和另一個模塊的一致 const uint64_t pipes = 0xE8E8F0F0E1LL; //這個變量會保持我們接受到的信息 //變量類型一定要和傳過來的一樣 //要傳輸的數據 unsigned long sendData = 1; unsigned long srchead = 0x01000000;//高16位為頭標誌,前8位為源節點,後8位為目的節點。根據標誌不同區分不同發送源,00為中心主節點 unsigned long deshead = 0x00000000;//高16位為頭標誌,前8位為源節點,後8位為目的節點。根據標誌不同區分不同發送源,00為中心主節點 unsigned long receData; void setup() { pinMode(13,OUTPUT);//指示燈 Serial.begin(57600); printf_begin(); Serial.println(F("RF24/examples/GettingStarted")); radio.begin(); radio.setPALevel(RF24_PA_MAX); radio.openWritingPipe(pipes); } void loop() { Serial.print("role:"); Serial.println(role); if(role){ unsigned long data = sendData+srchead+deshead; Serial.print("Sending:"); Serial.println(data); digitalWrite(13,HIGH); bool ok = radio.write(&data,sizeof(unsigned long)); role = 0; radio.startListening(); start_time = millis(); } if(!role){ digitalWrite(13,LOW); if(radio.available()){ radio.read(&receData,sizeof(unsigned long)); //根據目標節點,判斷是否是發給自己的,如果是,執行相關操作 unsigned long check = receData & 0x00110000; if(check == srchead){ //接收到來自主機的數據,執行相關操作 Serial.print("Response:"); Serial.println(receData); } role = 1; radio.stopListening(); }else{ unsigned long end_time = millis(); if((end_time-start_time)>=100){ role = 1; radio.stopListening(); } } } } // Loop
樹莓派與Arduino Leonardo使用NRF24L01無線模塊通信之基於RF24庫 (四) 樹莓派單子節點查詢