1. 程式人生 > >樹莓派與Arduino Leonardo使用NRF24L01無線模塊通信之基於RF24庫 (六) 樹莓派查詢子節點溫濕度數據

樹莓派與Arduino Leonardo使用NRF24L01無線模塊通信之基於RF24庫 (六) 樹莓派查詢子節點溫濕度數據

put fort 自己 include signed 區分 hardware atoi ace

nrl24l01每次只能發送4個字節,前面說到,第一個字節用於源節點,第二個字節用於目的節點。因此只剩下兩個字節用於溫度和濕度,一個字節只有八位,需要表示溫濕度的正負數,因此每個字節的第一位表示正負符號,後七位表示數據,最大能表示+-127。

樹莓派代碼

如下:

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>
#include <RF24/RF24.h>

using
namespace std; // RPi generic: 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(); unsigned long 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 & 0x0000ffff; //cout<<"check is "<<check<<"\n"; if(check==node && (receData & 0x00ff0000)==srchead){ //cout<<"Get Node oriData: "<<receData<<",data:"<<data<<",Time consume "<<(end_time-start_time)<<"ms \n"; int temperature = (data & 0x00007f00)>>8; int humidity = data & 0x0000007f; if((0x00008000& data)==0){ temperature = -temperature; } if((0x00000080&data)==0){ humidity = -humidity; } cout<<temperature<<"-"<<humidity<<"\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代碼

如下:

#include <SPI.h>
#include "RF24.h"
#include <SPI.h>
#include "RF24.h"
#include <printf.h>
#include <dht.h>

dht DHT;
#define DHT22_PIN 7

/****************** 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 = 15;
unsigned long srchead = 0x01;//高16位為頭標誌,前8位為源節點,後8位為目的節點。根據標誌不同區分不同發送源,00為中心主節點
unsigned long deshead = 0x00;//高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){
     int chk = DHT.read22(DHT22_PIN);  //讀取數據
     if(chk==DHTLIB_OK){
        int  humidity = (int)(DHT.humidity+0.5);
        int  temperature = (int)(DHT.temperature+0.5);
         Serial.print("data:temperature=");
         Serial.print(temperature);
         Serial.print(",humidity=");
         Serial.println(humidity);
        //第三個字節存放溫度,第四個字節存放濕度,目前只能表示
        unsigned long data = (temperature<<8)+(humidity)+(srchead<<24)+(deshead<<16);
        if(temperature>0){
           data = data+0x00008000;   
        }
        if(humidity>0){
           data = data+0x00000080;  
        }
         Serial.print("Sending:");
         Serial.println(data);
         digitalWrite(13,HIGH);
         bool ok = radio.write(&data,sizeof(unsigned long));

     
         role = 0; 
         radio.openReadingPipe(1,pipes);
         radio.startListening();
         start_time = millis();      
     }
     
  }
  if(!role){
     digitalWrite(13,LOW);
     if(radio.available()){
         radio.read(&receData,sizeof(unsigned long));
        
         //根據目標節點,判斷是否是發給自己的,如果是,執行相關操作
         unsigned long check = (receData & 0x00ff0000)>>16;

         if(check == srchead){
            //接收到來自主機的數據,執行相關操作
             Serial.print("Response:");
             Serial.println(receData&0x0000ffff);
             Serial.println("=======================");
             sendData++;
         }
         role = 1;
         radio.stopListening();
     }else{
        unsigned long end_time = millis();
        if((end_time-start_time)>=100){
          role = 1;
          radio.stopListening();
          radio.openWritingPipe(pipes);
        }
     }
  }
  
} // Loop

樹莓派與Arduino Leonardo使用NRF24L01無線模塊通信之基於RF24庫 (六) 樹莓派查詢子節點溫濕度數據