树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库 树莓派查询子节点温湿度数据

Posted 且听风吟-wuchao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库 树莓派查询子节点温湿度数据相关的知识,希望对你有一定的参考价值。

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库 树莓派查询子节点温湿度数据的主要内容,如果未能解决你的问题,请参考以下文章

树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库 树莓派单子节点查询

树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库全双工通信

树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库 树莓派查询子节点温湿度数据

原创Arduinoarm树莓派与单片机

树莓派网摘树莓派与XBMC及KodiLibreELEC插件

arduino leonardo r3 和 arduino uno r3 有啥区别