(由于服务器故障导致很久没有上传文章,阿里云还是有点坑。)
在之前的文章中,我们介绍了如何使用joystick模块通过Arduino控制舵机,详见:如何使用Arduino和joystick模块控制舵机。文章中介绍的方法是通过单片Arduino和joystick模块来控制舵机,今天我们将这个项目延伸一下,引入NRF24L01模块,采用两块Arduino通过无线的方式控制舵机。Arduino控制舵机的文章前期发了好几篇,可延伸阅读:
项目用到的材料
- Arduino UNO 两块;
- NRF24L01模块 两块;
- joystick模块一块;
- 舵机一个。
控制原理
在这个项目中,我们将使用NRF24L01模块和Arduino来控制伺服电机。我们将在发射端操作joystick操纵杆,使用NRF24L01将操纵杆的移动值发送到接收端,接收端接收到该值,并通过该值来控制舵机的移动。
当我们在水平方向移动操纵杆时,操纵杆模块会向Arduino发送一个模拟值。我们将NRF24L01模块设置为发射机模式,将操纵杆的运动值发送到指定地址。在接收端,我们将NRF24L01模块设置为接收模式。我们在接收端给另一个NRF24L01模块设置了相同的地址。所以无论何时模块接收到数据,Arduino都会读取数据,并根据数据移动舵机。
NRF24L01模块的接口定义
NRF24L01是射频收发器件,工作于2.4 GHz~2.5 GHz ISM频段。内置频率合成器、功率放大器、晶体振荡器、调制器等功能模块,并融合了增强型ShockBurst技术,其中输出功率和通信频道可通过程序进行配置。
NRF24L01功耗低,在以-6 dBm的功率发射时,工作电流也只有9 mA;接收时,工作电流只有12.3 mA,比普通LED的功耗还低。模块工作电压为3.3V,请勿直接连接Arduino的5V,否则可能会损坏。NRF24L01模块的其他引脚具有5V的耐受性,因此我们可以直接将这些引脚连接到Arduino。SCK、MOSI和MISO引脚用于SPI通信,CSN和CE引脚用于设置备用或活动模式,以及设置传输或命令模式。
电路连接
发射机端连接如下:
一、NRF24L01连接
- NRF24L01 3.3V –> Arduino 3.3V
- NRF24L01 GND –> Arduino GND
- NRF24L01 CSN –> Arduino pin 8
- NRF24L01 CE –> Arduino Pin 7
- NRF24L01 SCK –> Arduino pin 13
- NRF24L01 MOSI –> Arduino pin 11
- NRF24L01 MISO –> Arduino pin 12
二、Joystick操纵杆连接
- VCC joystick –> 5V Arduino
- GND joystick –> GND Arduino
- VER joystick –> A1 Arduino
- HOR joystick –> A0 Arduino
接收端连接如下:
在接收端,NRF24L01与Arduino的连接与发送端相同。Arduino连接舵机的方法如下:
- 舵机红线连至 5V Arduino
- 舵机棕线连至 GND Arduino
- 舵机黄线连至 Pin 6 Arduino
代码部分
一、发射端代码
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> RF24 radio(7, 8); // CSN, CE const byte address[6] = "00001"; int x_key = A1; int y_key = A0; int x_pos; int y_pos; void setup() { radio.begin(); radio.openWritingPipe(address); radio.setPALevel(RF24_PA_MIN); radio.stopListening(); pinMode (x_key, INPUT) ; pinMode (y_key, INPUT) ; } void loop() { x_pos = analogRead (x_key) ; y_pos = analogRead (y_key) ; radio.write(&x_pos, sizeof(x_pos)); delay(100); }
二、接收端代码
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <Servo.h> Servo servo; RF24 radio(7, 8); // CSN, CE const byte address[6] = "00001"; int servo_pin = 6; void setup() { Serial.begin(9600); radio.begin(); servo.attach (servo_pin ) ; radio.openReadingPipe(0, address); radio.setPALevel(RF24_PA_MIN); radio.startListening(); } void loop() { if (radio.available()) { int x_pos ; radio.read(&x_pos, sizeof(x_pos)); Serial.println(x_pos); x_pos = map(x_pos, 0, 1023, 0, 180); if (x_pos>400 && x_pos<600) { } else{ servo.write (x_pos) ; } } }
三、代码解释
首先,包含NRF24L01和舵机的库文件。
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <Servo.h>
然后,定义连接NRF24L01的CSN和CE引脚的引脚。然后,我们初始化发送和接收数据的地址。这个地址在发送端和接收端应该是相同的。这个地址可以是任何五个字母的字符串。
RF24 radio(7, 8); // CSN, CE const byte address[6] = "00001";
在发射器的setup函数中,我们设置了发送数据的地址。然后我们将功率放大范围设置为最小,因为我们的两个模块彼此更接近。
radio.openWritingPipe(address); radio.setPALevel(RF24_PA_MIN);
对于接收端,我们使用以下命令并设置模块从这个地址接收数据。
radio.openReadingPipe(0, address);
在发送器的loop函数中,我们从操纵杆模块读取数据并将其发送到我们之前设置的地址。
radio.write(&x_pos, sizeof(x_pos));
接收端通过如下命令从发送端获取数据,将数据映射到0-180后,移动舵机。
radio.read(&x_pos, sizeof(x_pos));
至此,使用joystick模块和NRF24L01模块控制舵机的项目节完成了。