赞
踩
萌新第一次发文,多多关照~
玩航模估计有七八年了,玩arduino和各类单片机也有一两年啦,今年回家以后因为疫情被困在家里回不去,就寻思着用arduino做个2.4g的遥控和接收。闲话不多说,开始正文。
接线还有其他的基础介绍可以参考凌顺实验室的介绍和示意,我感觉很不错
Arduino 2.4G通信实验 nRF24L01模块的简单例子
我用的是两块Nano来做主板,接线与Uno基本相同。
库下载地址: https://github.com/nRF24/RF24
或者在Arduino IDE 的库管理器中搜索nrf24,作者为TMRh20
接线大致如下
然后就是上程序。
#include "SPI.h" //24L01库文件 #include "Mirf.h" #include "nRF24L01.h" #include "MirfHardwareSpiDriver.h" int a; //定义一个变量储存前一次通道参数; int aa; //改变后的通道参数; int b; int bb; int c; int cc; int d; int dd; int e; int ee; int x=2; //开关通道; int y=3; int z=4; int f=4001; int g=4002; int h=4003; int i = 4005; int data; void setup(){ Mirf.spi = &MirfHardwareSpi; //加载24L01 SPI Mirf.init(); //开始 Mirf.setTADDR((byte *)"serv1");//发送到"接收地址" Mirf.payload = sizeof(int); //将数据类型定义为整型; Mirf.config(); Serial.begin(9600); pinMode(x,INPUT); pinMode(y,INPUT); pinMode(z,INPUT); } void loop(){ a=analogRead(A7); //读取电位器电平(0至1023),一定要是模拟接口才可以。 b=analogRead(A6); c=analogRead(A2); d=analogRead(A3); e=analogRead(A1); a=map(a,0,1023,0,999) ; //map函数将读取到的数据转换成不同区间的数,加以区分; b=map(b,0,1023,1000,1999) ; c=map(c,0,1023,2000,2999) ; d=map(d,0,1023,3000,3999) ; e=map(e,0,1023,5000,5999) ; Mirf.send((byte *)&a); //向接收机发送数据; while(Mirf.isSending()){ //等待发送完毕; } Mirf.send((byte *)&b); while(Mirf.isSending()){ } Mirf.send((byte *)&c); while(Mirf.isSending()){ } Mirf.send((byte *)&d); while(Mirf.isSending()){ } Mirf.send((byte *)&e); while(Mirf.isSending()){ } if (a !=aa) { //如果数值改变,则参数发生改变,aa是一个中间变量; aa=a; } if (b !=bb) { bb=b; } if (c !=cc) { cc=c;} if (d !=dd) { dd=d;} if (e !=ee) { ee=e; } int x_1 = digitalRead(x); //读取开关通道的电平; if (x_1==0) { Mirf.send((byte *)&f); //若开关通道为低电平,则发送数据;开关通道我接了个1k的上拉电阻(连接5v),不接有干扰; while(Mirf.isSending()){ } } int y_1 = digitalRead(y); Serial.println(y_1); if (y_1==0) { Mirf.send((byte *)&g); while(Mirf.isSending()){ } } if (y_1==1) { Mirf.send((byte *)&i); while(Mirf.isSending()){ } } int z_1 = digitalRead(z); if (z_1==0) { Mirf.send((byte *)&h); while(Mirf.isSending()){ } } delay(10); // 等待0.01秒,等待接收部分清理缓存; }
#include "SPI.h" //24L01库文件 #include "Mirf.h" #include "nRF24L01.h" #include "MirfHardwareSpiDriver.h" #include <Servo.h> Servo myservo1; // 定义舵机,使用舵机库; Servo myservo2; Servo myservo3; Servo myservo4; Servo myservo5; Servo myservo6; int data; int a; int b; int c; int d; int e; int h = 1000; int pin3=3; int pin4=4; int pin5=5; int pin6=6; int pin10=10; int pin2=2; int pin9=9; void setup(){ myservo1.attach(pin3,1000,2000); // 定义舵机通道,还有转动角度; myservo2.attach(pin4,1000,2000); myservo3.attach(pin5,1000,2000); myservo4.attach(pin6,1000,2000); myservo5.attach(pin9,1000,2000); myservo6.attach(pin2,1000,2000); Mirf.spi = &MirfHardwareSpi; //加载24L01 SPI Mirf.init(); Mirf.setRADDR((byte *)"serv1"); //接收地址" ",一定要与发送端地址相同; Mirf.payload = sizeof(int); //定义数据类型为整型; Mirf.config(); Serial.begin(9600); pinMode(pin10,OUTPUT); //开关通道定为输出通道,要接一个继电器用于点燃拉烟器。 } void loop(){ digitalWrite(pin10,LOW); analogWrite(A1,0); //数字IO口不足,用模拟接口代替; analogWrite(A2,0); analogWrite(A3,0); if(Mirf.dataReady()){ //如果接收到数据则执行 Mirf.getData((byte *)&data); //接收数据 if (data>=0&&data<=999) //如果数据处于此区间,则说明数据是发送部分的a; { a=map(data,0,999,2000,1000); //将a的数据转变为舵机转动的角度; myservo1.writeMicroseconds(a); //舵机转动;因为输出的是pwm信号,所以也可以直接接电调; } if (data>=1000&&data<=1999) { b=map(data,1000,1999,1000,2000); myservo2.writeMicroseconds(b); } if (data>=2000&&data<=2999) { c=map(data,2000,2999,1200,1800); //这个通道被我拿来当升降舵通道,我觉得舵量太高就改小了,方法是将1000,2000同时减去一个数,如果要通道反向就将两个数位置调换即可; myservo3.writeMicroseconds(c); } if (data>=3000&&data<=3999) { d=map(data,3000,3999,1200,1800); myservo4.writeMicroseconds(d); } if (data>=5000&&data<=5999) { e=map(data,5000,5999,1314,1800); myservo5.writeMicroseconds(e); } if(data==4001) { digitalWrite(pin10,HIGH); //开关通道为高电平; } if(data==4002) { myservo6.writeMicroseconds(1000); } if(data==4005) { myservo6.writeMicroseconds(1500); } if(data==4006) { myservo6.writeMicroseconds(2000); //我做的三段开关; } if(data==4003) { analogWrite(A1,1023); //模拟通道高电平; } if(data==4004) { analogWrite(A2,1023); } Mirf.rxFifoEmpty(); //清理24L01援存 } }
这样做出来的遥控器大概是八通道,对于航模来说已经绰绰有余了,因为我买的是半双工的2.4g,所以无法实现数据回传,或者说数据回传会造成很高的数据延迟,就没有加到程序里。如果要拓展通道的话直接增加区间减小区间就可以了,理论上可以做无数个通道只要io口足够,不过并不推荐,够用就行,否则延迟增高。前几天买了个曼塔K3的遥控器,看着挺高级的才花了八十,上面有一个大功率的2.4g和5.8g模块,接下来准备写几块板子做个好点的遥控器,就酱。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。