arduino与nrf24l01接收端和发送端

文章讲述了作者帮助室友制作航模控制系统时,使用Arduino和nRF24L01进行无线通信,通过A0和A1模拟口读取数据控制两个舵机的示例。重点讲解了数据编码、信道设置以及可能遇到的问题,如数据类型限制和接收端处理大整数的方法。
摘要由CSDN通过智能技术生成

背景:室友要做一个航模,我来给他写控制系统和动力系统,也就是遥控器和电调。

目前进度:几乎完成。

先看代码,代码下面有分析。

发送端(arduino uno):

#include <Arduino.h>
#include <Servo.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(6,7);//CE,CSN
int unsigned sendNumber;
const int analogInPin = A0;
const int analogInPinpin = A1;
int unsigned sensorValue = 0;
int unsigned sensorValuepin = 0;
const byte address[6]="00001";
const byte channel=108;
const int ce=6;
void setup() {
  /**
   * 串口打印初始化
   */
  Serial.begin(9600);
  Serial.println();
  Serial.println("Connecting");
  /**
   * 引脚初始化
   */
  pinMode(analogInPin,INPUT);
  pinMode(analogInPinpin,INPUT);
  /**
   * lora模块初始化
   */
   radio.begin();
   radio.openWritingPipe(address);
    radio.setChannel(channel);
   radio.setPALevel(RF24_PA_HIGH);
   radio.setDataRate(RF24_250KBPS);
   radio.stopListening();
}

void loop() {
  /**
   * 读取模拟口数据并转为0~180之间
   */
  sensorValue = analogRead(analogInPin);
  sensorValuepin = analogRead(analogInPinpin);
  sensorValue=map(sensorValue,0,1023,0,180);
  sensorValuepin=map(sensorValuepin,0,1023,0,180);
  /**
   * 拼接数据
   */
  sendNumber=sensorValue<<8;
  sendNumber=sendNumber+sensorValuepin;
  /**
   * 发送数据
   */
//   digitalWrite(ce,HIGH);
  radio.write(&sendNumber,sizeof(sendNumber));
//  digitalWrite(ce,HIGH);
  delay(100);
//  digitalWrite(ce,LOW);
//  delay(50);
  
}

接收端(arduino nano):

#include <SPI.h>
#include "RF24.h"
#include "printf.h"
#include <Servo.h> 
/**
 * 创建对象
 */
RF24 radio(2,3);//CE,CSN
Servo myservo;
Servo myservo2;
/**
 * 引脚定义
 */
const int pina=9;//舵机
const int pinb=10;//舵机2
/**
 * 对象参数
 */
const byte address[6]="00001";//通信ip
const byte channel=108;//通信信道
int sensorValue = 0;//初始化舵机角度
int sensorValuepin = 0;//初始化舵机2角度
void setup() {
  /**
   * 串口打印初始化
   */
  Serial.begin(9600);
  Serial.println();
  Serial.println("Connecting");
  /**
   * 引脚初始化
   */
  pinMode(pina,OUTPUT);
  pinMode(pinb,OUTPUT);
  /**
   * 模块初始化
   */
  radio.begin();//lora模块初始化
  radio.openReadingPipe(0,address);
  radio.setChannel(channel);
  radio.setPALevel(RF24_PA_HIGH);
  radio.setDataRate(RF24_250KBPS);
  radio.startListening();
  myservo.attach(pina);//舵机1初始化
  myservo2.attach(pinb);//舵机2初始化
}

void loop() {
    while(1){
      /**
      * 判断模块是否可用
      */
      if(radio.available()){
        Serial.println("123");
        /**
        * 接收数据
        */
        int receivedData;
        radio.read(&receivedData,sizeof(receivedData));
        /**
        * 拆分数据
        */
        
        sensorValue=receivedData&0b11111111;
        sensorValuepin=(receivedData>>8)&0b11111111;
        /**
        * 控制舵机
//        */
        Serial.println(sensorValue);
        Serial.println(sensorValuepin);
        myservo.write(sensorValue);
        myservo2.write(sensorValuepin);
        delay(10);
      }
    }
 
  
}

注意:

nrf24l01必须设置信道!!!!

nrf24l01必须设置信道!!!!

nrf24l01必须设置信道!!!!

网上许多教程没写信道,我实测在有多个路由器的室内,1000米的模块5米就没信号了,没设置信道极其容易受到周围2.4G信号干扰!!!

radio.setPALevel(RF24_PA_MAX); // 设置最大功率

radio.setChannel(40); // 设置信道为40

接收端和发送端信道需要一致,上面设置为40信道。

接下来分析代码:现在我的示例代码中只是用摇杆控制了两个舵机(左右控制一个,上下控制另一个)。原理:发送端(arduino uno)读取A0口数据(范围0~1023),用map()函数转化为0~180(因为舵机的角度是0~180)。将转化后的这个数据对应的二进制数左移8位(直接左移也是操作的158对应的二进制数,所以不用来回转化),例如:158度对应二进制数1001,1110,左移八位得到1001,1110,0000,0000;然后读取A1口数据比如是96,和158左移后的数字相加,刚好占据1001,1110,0000,0000的后八位(八位二进制数的取值范围是0-255大于180够用)得到1001,1110,0110,0000,然后发送这个数据。(可以用串口打印一下确认,接收端接受到这个数据右移八位就是左边八位二进制数对应的数据158;0b1111,1111与接受到数据异或操作就是后八位(右边)二进制数对应数据96,然后调用pwm函数(sero.write...(158或者96))控制舵机角度。整个过程结束。

有不会的可以留言讨论!祝大家不踩坑。



上面的程序有个大坑,我现在来说明一下,C语言中int类型最大为16位二进制数,我代码中左移动8位,刚刚好够用,如果你想控制更多的舵机(更多通道),就会不够用,这时候可以用int64_t,但是int64_t发送会失败,因为radio.write()不支持这种数据类型。这时候可以用int64_t来进行移位运算和加减,最后转化为字符串,发动这个字符串,接收端接收字符串,并把它转化为int64_t,然后在去拆分数据。。。我实测直接发送int64_t接收端接受到数字是0也就是接收不到

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值