博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
arduino 串口读取字符串_Arduino传感器教程 第24章NRF24L01 控制电舵机
阅读量:7002 次
发布时间:2019-06-27

本文共 8461 字,大约阅读时间需要 28 分钟。

NRF24L01 控制电舵机

目录

一、控制舵机

二、控制步进舵机

(一)控制舵机

下面,我们主要介绍如何使用 NRF24L01 和 Arduino 控制伺服电机。我们在发送端移动操纵杆,使用 NRF24L01,将操纵杆移动的值发送到接收侧,然后在接收侧接收该值,使用此值移动伺服电机。

模块简介

 1 

材料准备

Arduino UNO 开发板NRF24L01 模块操纵杆模块伺服电机杜邦线
a64c0cdc35bdaa9b04b2bc099c9df096.png

 2 

NRF24L01引脚说明

该模块的
功耗非常低。它在传输过程中消耗大约 12mA 的功率,甚至低于 LED。该模块工作在 3.3V,因此不要将其直接连接到 5V 的 Arduino,因为它可能会损坏。NRF24L01 模块的其他引脚具有 5V 容限,因此您可以将它们直接连接到Arduino。SCK、MOSI 和 MISO 引脚用于 SPI 通信,CSN 和 CE 引脚用于设置待机或活动模式以及设置发送或命令模式。
3649f773fe869b5f67d9d9dc61891500.png

 3 

RF遥感模块

RF 摇杆模块非常简单,我们需要从摇杆读取 X 值和 Y 值,然后通过 nRF24L01 将其发送到接收模块。
2a629b7a0f50694605fc145ecac1338e.png

工作原理

伺服电机控制工作在发送侧,我们有一个操纵杆模块、Arduino 和 NRF24L01,而在接收侧,我们有一个 NRF24L01、Arduino 和一个伺服电机。当我们在水平方向上移动操纵杆时,操纵杆模块将向 Arduino 发送模拟值。我们已将 NRF24L01 模块设置为发送模式,并将操纵杆移动值发送到特定地址。在接收侧,将 NRF24L01 模块设置为接收模式。我们在接收端给出了相同的地址,其他 NRF24L01 模块正在传输数据。因此,只要模块接收到数据,Arduino就会读取数据并根据它移动伺服电机。
080f69f8b74b0ab976ba231b4a0e95ad.png

用法用例

 1 

硬件原理图

d0107284546e3ca39b14cfdd4393ad71.png连接有点冗长,因此我将分别介绍发送器和接收器的连接。在发送器侧,NRF24L01 与 Arduino 的连接如下:将 NRF24L01 的 3.3V 引脚与 Arduino 的 3.3V 连接
将 NRF24L01 的 GND 引脚与 Arduino 的 GND 连接将 NRF24L01 的 CSN 引脚与 Arduino 的引脚 8 连接 将 NRF24L01 的 CE 引脚与 Arduino 的引脚 7 连接 将 NRF24L01 的 SCK 引脚与 Arduino 的引脚 13 连接将 NRF24L01 的 MOSI 引脚与 Arduino 的引脚 11 连接 将 NRF24L01 的 MISO 引脚与 Arduino 的引脚 12 连接然后将操纵杆模块与 Arduino 连接如下:操纵杆模块的 VCC 到 Arduino 的 5V操纵杆模块的 GND 到 Arduino 的 GND操纵杆模块的 VER 到 Arduino 的 A1操纵杆模块的 HOR 到 Arduino 的 A0在接收器侧,NRF24L01 与 Arduino 的连接与发送器侧的连接相同。使用Arduino 连接伺服电机如下:红线到 Arduino 的 5V棕色线到 Arduino 的 GND黄色线到 Arduino 的引脚 6

 2 

示例代码

 
//reciver#include //包含头文件#include  #include #include  Servo servo;//创建一个舵机对象RF24 radio(7, 8);//两个参数分别为 Arduino 连接 CE 和 CSN 的引脚const byte address[6] = "00001"; //定义发送数据的地址int servo_pin = 6;//将舵机控制引脚连接到 Arduino 的数字引脚 6void setup() {      Serial.begin(9600); //初始化串口,设定串口通信速率为 9600(波特)     radio.begin(); //初始化 NRF24L01     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);//遥感映射函数          servo.write (x_pos) ;     }  }//Transimitter#include  //包含头文件#include #include  RF24 radio(7, 8);//两个参数分别为 Arduino 连接 CE 和 CSN 的引脚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); }
首先,包括
NRF24L01和伺服电机的库
#include #include #include #include 
然后,定义我们连接 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));

(二)控制步进电机

下面,我们将使用 Arduino 和 nRF24L01 RF 模块进行远程控制驱动无芯直流电机。这些电机通常用于无人机,额定功率为 39000 RPM,足以满足速度要求。该小车将使用小型锂电池供电。

模块简介

无芯直流电机

直流电机存在一些不足。它的速度,难以处理 39000 RPM,因此我们需要在 Arduino 端使用MOSFET 构建的速度控制电路。这些电动机将由工作电压在3.6V 至 4.2V 之间的单个锂聚合物电池供电,因此我们必须将电路设计为在 3.3V 电压下工作。这就是为什么我们将 3.3V Arduino Promini 用来控制电机的原因。
ae2a1701766d59ff551a5a9e6a440dda.png
94702dfd402f6713800de85e55bde8ba.png
4a360700cb7c0d6738d5f9dd983ddf5f.png

 1 

材料准备

Arduino nano 开发板3.3V Arduino Pro Mini 开发板NRF24L01 模块操纵杆模块无芯无刷直流电机杜邦线锂聚合物电池

 2 

硬件原理图

发射模块

9b6faa330e9adb029d74ea31c08b1ffb.png

 3 

引脚说明

27a98b39077e2fe056ee842c558d6ac7.pngnRF24L01 模块在 3.3V 电压下运行,因此我们在 Arduino 上使用了 3.3V 引脚。

驱动模块

4e3c58a3dd3dd7f23874cadb20efa1e3.png
1e03457dcde40de201a24076a56c4346.png
6d112326696ecec576698ffc7cafc246.png

 4 

实物链截图

ea04216781c5fe5d6c3c39c2a5ce8bd3.png直流电机由连接到 P1 的锂电池供电。AMS117-3.3V 用于为我们的 nRF24L01 和 Mini开发板调节 3.3V。我们还可以直接在插针上为 Arduino 开发板供电,但是 pro mini 上的板载 3.3V 稳压器将无法为我们的 RF 模块提供足够的电流,因此我们使用了外部电源。

示例代码

RF驱动代码

 
#include  //包含头文件#include "RF24.h" RF24  myRadio (7, 8); //两个参数分别为 Arduino 连接 CE 和 CSN 的引脚struct package {
 intmsg=0; }; byte addresses[6] = {
"00001"}; //定义发送数据的地址typedef struct package Package; //定义结构体 Package data;void setup() {
    Serial.begin(9600);//初始化串口,设定串口通信速率为 9600(波特)     myRadio.begin(); //初始化 NRF     myRadio.setChannel(115); //WIFI 信号上方 115 频段     myRadio.setPALevel(RF24_PA_MAX);//最大功率远射      myRadio.setDataRate( RF24_250KBPS ) ; //最低速度      delay(500);     Serial.print("Remote Initialized");//初始化成功int forward;int reverse; }void loop() {
int xValue = analogRead(A0);//读取 JoyX 值int yValue = analogRead(A1); //读取 JoyY 值      Serial.print(xValue);     Serial.print(" , ");     Serial.println(yValue);if (xValue>560 && xValue<1000) //筛选 JoyX     {
        forward = map (xValue, 560, 1000, 1, 10); //将 Joyx-up 转换为 0-10         Serial.print("F=");         Serial.println(forward);         data.msg = forward; //保存数据         WriteData();          delay(50);  }if (xValue<500 && xValue > 10) //筛选 JoyX     {
        reverse = map (xValue, 10, 500, 20, 11); //将 JoyX-down 转换为 11-20         Serial.print("B=");        Serial.println(reverse);        data.msg = reverse;         WriteData();         delay(50);     }else     {         Serial.println("Rest");         data.msg = 0;//更新数据        WriteData();         delay(50);     }  }void WriteData() //输入函数{
    myRadio.stopListening(); //停止接收并开始传送      myRadio.openWritingPipe( 0xF0F0F0F0AA);//在此 20 位地址上发送数据     myRadio.write(&data, sizeof(data));     delay(50); }void ReadData() //读取函数{
    myRadio.openReadingPipe(1, 0xF0F0F0F066);//读取哪个管道,20 位地址     myRadio.startListening(); //停止发送并开始接收 if (myRadio.available())     {
while (myRadio.available())          {
            myRadio.read( &data, sizeof(data) );          }         Serial.print("\nReceived:");         Serial.println(data.msg);      } }

电机驱动代码

/*CE-7 MISO-12 MOSI-11 SCK-13 CS-8*/#define R_IR 3//定义输入输出引脚#define L_IR 4#define L_MR 5 #define R_MR 6 #define min_speed 200 //定义速度#define max_speed 800 #include  #include "RF24.h"RF24 myRadio (7, 8);struct package {
 intmsg; };typedef struct package Package;  Package data; byte addresses[6] = {
"00001"}; void setup() {
    pinMode(R_IR, INPUT);//将电机引脚设置为输入状态     pinMode(L_IR, INPUT);     pinMode(L_MR, OUTPUT);//将电机引脚设置为输出状态     pinMode(R_MR, OUTPUT);     Serial.begin (9600);     myRadio.begin();     myRadio.setChannel(115); //WIFI 信号上方 115 频段     myRadio.setPALevel(RF24_PA_MIN); //最小功率     myRadio.setDataRate( RF24_250KBPS ) ; //最低速度int received; }void loop(){
    ReadData(); }void Control() //前进后退控制{
if (received>=1 && received <=10) // 向前      {
int PWM_Value = map (received, 1, 10, min_speed, max_speed);         analogWrite(R_MR,PWM_Value);        analogWrite(L_MR,PWM_Value);     }else if (received>=11 && received <=20) //向后      {
int PWM_Value = map (received, 11, 20, min_speed, max_speed);         analogWrite(R_MR,0);        analogWrite(L_MR,0);     }  }void ReadData(){
    myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //读取哪个管道,20 位地址     myRadio.startListening(); //停止发送并开始接收if ( myRadio.available()) //有来自 RF 的数据     {
while (myRadio.available())         {
           myRadio.read( &data, sizeof(data) );          }         Serial.print("\nReceived:");          Serial.println(data.msg);         received = data.msg;          Control_Car();     }  }void WriteData() {
//向电机输入转动方向     myRadio.stopListening(); //停止接收并开始传送      myRadio.openWritingPipe(0xF0F0F0F066);//在此 20 位地址上发送数据      myRadio.write(&data, sizeof(data));     Serial.print("\nSent:");     Serial.println(data.msg);     delay(300); }
 接下来,在 loop 函数中,我们将仅执行 
ReadData 函数,通过该函数我们将不断读取从发送器摇杆模块发送的值。请注意,程序中提到的管道地址应与发送器程序中提到的管道地址相同。我们还打印了我们收到的用于调试的值。成功读取该值后,我们将执行 Control 函数,根据从 RF 模块接收到的值来控制直流电机。
 
void ReadData() {
    myRadio.openReadingPipe(1,0xF0F0F0F0AA);     myRadio.startListening();if ( myRadio.available())     {
while (myRadio.available())          {
            myRadio.read( &data, sizeof(data) );          }     Serial.print("\nReceived:");      Serial.println(data.msg);      received = data.msg;      Control_Car();     }  }
在 Control 函数内,我们将使用模拟写入功能来控制连接到 PWM 引脚的电机。在我们的发送器程序中,我们已将 Nano 的 A0 和 A1 引脚的模拟值转换为 1 到 10、11 到 20,以分别控制电机向前、向后。以下程序用于控制向前
if (received>=1 && received <=10) // Move Forward  {
int PWM_Value = map (received, 1, 10, min_speed, max_speed);      analogWrite(R_MR,PWM_Value);analogWrite(L_MR,PWM_Value); }
完成代码后,将其上传到 pro mini 开发板。通过 FTDI 模块取出电池和电路板进行测试。启动代码,打开串口监视器,您应该从发送器的摇杆模块接收到该值。连接电池,电动机也应开始旋转。

以上代码文件及使用的库可以到以下QQ群统一下载

机甲学院技术交流QQ群

931630584

8c008b4e0afcf69f5908399183c96327.gif
90ad3a4470a0247df8fc91ed28202798.png

转载地址:http://sfevl.baihongyu.com/

你可能感兴趣的文章