使用无芯直流电机和nRF24L01构建最快Arduino遥控车

描述

  遥控车玩起来总是很有趣,我个人是这些遥控车的忠实粉丝, 并且已经(仍然)广泛地玩过它们。如今,这些汽车中的大多数都提供了巨大的扭矩来应对崎岖的地形,但有些东西总是滞后,它的速度!!。。 所以,在这个项目中,我们将 使用 Arduino 构建一个完全不同类型的 RC 汽车,主要这辆车的目标是达到最高速度,因此我决定为遥控车试用 无芯直流电机。这些电机通常用于无人机,额定转速为 39000 RPM 这应该足以满足我们对速度的渴望。该车将由一块小型锂电池供电,并可使用 nRF24L01 射频模块进行远程控制。

  遥控车用无芯直流电机

  该项目中使用的无芯直流电机如下图所示。您可以轻松找到它们,因为它们广泛用于迷你无人机。只需寻找 8520 磁性微型空心杯电机,您就会找到这些。

nRF24L01

  现在,将直流电机用于遥控车存在某些缺点。首先是它们提供非常低的启动扭矩,因此我们的遥控车应该尽可能轻巧。这就是为什么我决定使用 SMD 组件在 PCB 上构建整个汽车并尽可能减小电路板尺寸的原因。第二个问题是它的高速,39000 RPM(轴的 RPM)很难处理,所以我们需要在 Arduino 端使用 MOSFET 构建的速度控制电路。第三件事是这些电机将由单个锂聚合物电池供电,工作电压在 3.6V 至 4.2V 之间,因此我们必须将电路设计为在 3.3V 上工作。这就是我们使用3.3V Arduino Pro mini的原因作为我们遥控车的大脑。理清了这些问题,我们来看看搭建这个项目所需要的材料。

  所需材料

  3.3V Arduino Pro Mini

  Arduino纳米

  NRF24L01 – 2 个

  操纵杆模块

  SI2302 MOSFET

  1N5819 二极管

  无铁芯 BLDC 电机

  AMS1117-3.3V

  锂聚合物电池

  电阻器、电容器、

  连接线

  使用 Arduino 的遥控车射频操纵杆

  如前所述,遥控车将使用射频操纵杆进行远程控制。该操纵杆也将使用 Arduino 和 nRF24L01 RF 模块构建,我们还使用操纵杆模块在所需方向控制我们的 RC。如果您对这两个模块完全陌生,您可以考虑阅读使用 nRF24L01 连接 Arduino和使用 Arduino 连接操纵杆的文章,以了解它们的工作原理以及如何使用它们。要构建您的Arduino RF 远程操纵杆,您可以按照下面的电路图进行操作。

nRF24L01

  RF 操纵杆电路可以使用纳米板的 USB 端口供电。nRF24L01 模块仅在 3.3V 上运行,因此我们在 Arduino 上使用了 3.3V 引脚。我在面包板上构建了电路,如下所示,如果需要,您也可以为此创建一个 PCB。

nRF24L01

  RF 操纵杆电路的Arduino 代码非常简单,我们必须从操纵杆中读取 X 值和 Y 值并通过 nRF24L01 将其发送到 RC 车。该电路的完整程序可以在本页底部找到。我们不会对此进行解释,因为我们已经在上面共享的接口项目链接中讨论了它。

  Arduino RC 汽车电路图

  我们的遥控 Arduino 汽车的完整电路图如下所示。电路图还包括向我们的汽车添加两个 TCRT5000 IR 模块的选项。这是为了让我们的遥控车能够作为线跟随机器人工作,这样它就可以独立工作而不受外部控制。但是,为了这个项目,我们不会专注于它,请继续关注另一个项目教程,我们将在其中尝试构建“Fastest Line Follower Robot”。为了便于构建,我将两个电路组合在一个 PCB 上,您可以忽略该项目的 IR 传感器和运算放大器部分。

nRF24L01

  遥控车将由连接到终端 P1 的锂电池供电。AMS117-3.3V用于为我们的 nRF24L01 和我们的专业迷你板调节 3.3V。我们也可以直接在原始引脚上为 Arduino 板供电,但 pro mini 上的板载 3.3V 稳压器将无法为我们的射频模块提供足够的电流,因此我们使用了外部稳压器。

nRF24L01

  为了驱动我们的两个 BLDC 电机,我们使用了两个 SI2302 MOSFET。确保这些 MOSFET 可由 3.3V 驱动非常重要。如果您找不到完全相同的部件号,您可以寻找具有以下传输特性的等效 MOSFET

nRF24L01

  电机可以消耗高达 7A 的峰值电流(在负载下连续测试为 3A),因此 MOSFET 漏极电流应为 7A 或更高,并且应在 3.3V 时完全开启。正如您在此处看到的,我们选择的 MOSFET 即使在 2.25V 下也可以提供 10A,因此它是一个理想的选择。

  为 Arduino 遥控车制造 PCB

  构建这个项目的有趣部分是 PCB 开发。这里的 PCB 不仅形成电路,而且还充当我们汽车的底盘,因此我们为它设计了一个看起来像汽车的形状,并且可以选择轻松安装我们的电机。您也可以尝试使用上面的电路设计自己的 PCB,或者您可以使用我的 PCB 设计,完成后如下所示。

nRF24L01

  如您所见,我设计的 PCB 可以轻松安装电池、电机和其他组件。

  组装印刷电路板

  我打开焊条并开始组装电路板。由于脚印、焊盘、通孔和丝网印刷的形状和尺寸都非常完美,因此组装电路板没有问题。从开箱开始,仅用了 10 分钟,电路板就准备好了。

  焊接后的几张电路板图片 如下所示。

nRF24L01

  3D 打印轮子和电机支架

  正如您在上图中可能已经注意到的那样,我们需要对机器人的电机支架和轮子进行 3D 建模。如果您使用了我们上面共享的 PCB Gerber 文件,那么您不妨从这个thingiverse 链接下载它来使用 3D 模型。

nRF24L01

  我使用 Cura 对我的模型进行切片并使用 Tevo Terantuala 打印它们,没有支撑和 0% 填充以减轻重量。您可以更改适合我们打印机的设置。由于电机旋转得非常快,我发现设计一个与电机轴紧密贴合的轮子非常困难。因此,我决定在轮子内使用无人机叶片,如下所示

nRF24L01

  我发现这更可靠和坚固,但是,尝试不同的车轮设计,并在评论部分告诉我什么对你有用。

对 Arduino 进行编程

该项目的完整程序(Arduino nano 和 pro mini)可以在本页底部找到。你的RC程序的解释如下

我们通过包含所需的头文件来启动程序。请注意,nRF24l01 模块需要将库添加到您的 Arduino IDE,您可以使用此链接从 Github 下载 RF24 库。除此之外,我们已经为我们的机器人定义了最小速度和最大速度。最小和最大范围分别为 0 到 1024。

 

#define min_speed 200
#define max_speed 800
#include 
#include "RF24.h"
RF24 myRadio (7, 8);

 

然后在 setup 函数中,我们初始化我们的 nRF24L01 模块。我们使用了 115 个频段,因为它不拥塞,并且已将模块设置为低功耗运行,您也可以使用这些设置。

 

无效设置(){
  串行.开始(9600);
  myRadio.begin();
  myRadio.setChannel(115); //115频段以上WIFI信号
  myRadio.setPALevel(RF24_PA_MIN); //MIN 功率低范围
  myRadio.setDataRate(RF24_250KBPS); //最低速度
}

 

接下来在主循环函数中,我们将只执行 ReadData 函数,我们将使用该函数不断读取从 Transmitter 操纵杆模块发送的值。注意程序中提到的管道地址应该和发射器程序中提到的一样。我们还打印了我们收到的用于调试目的的值。成功读取值后,我们将执行 Control Car 功能,根据从
Rf 模块接收到的值来控制我们的 RC 汽车。

 

无效读取数据()
{
  myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //读取哪个管道,40位地址
  myRadio.startListening(); //停止传输并开始接收
  if (myRadio.available())
  {
    而(myRadio.available())
    {
      myRadio.read( &data, sizeof(data) );
    }
    Serial.print("\n收到:");
    序列号.println(data.msg);
    收到 = data.msg;
    控制车();
  }
}

 

在 Control Car 函数中,我们将使用模拟写入函数控制连接到 PWM 引脚的电机。在我们的发射器程序中,我们将 Nano 的 A0 和 A1 引脚的模拟值转换为 1 到 10、11 到 20、21 到 30 和 31 到 40,分别用于控制汽车的前进、后退、左转和右转。下面的程序用于控制机器人的前进方向

 

if (received>=1 && received <=10) // 前进
  {
    int PWM_Value = map (收到, 1, 10, min_speed, max_speed);
    模拟写入(R_MR,PWM_Value);
    模拟写入(L_MR,PWM_Value);
  }

 

同样的,我们也可以多写三个函数来进行反向、左、右控制,如下图。

 

    if (received>=11 && received <=20) // 中断
  {
    int PWM_Value = map (收到, 11, 20, min_speed, max_speed);
    类比写入(R_MR,0);
    类比写入(L_MR,0);
  }
    if (received>=21 && received <=30) // 左转
  {
    int PWM_Value = map (收到, 21, 30, min_speed, max_speed);
    模拟写入(R_MR,PWM_Value);
    类比写入(L_MR,0);
  }
      if (received>=31 && received <=40) // 右转
  {
    int PWM_Value = map (收到, 31, 40, min_speed, max_speed);
    类比写入(R_MR,0);
    模拟写入(L_MR,PWM_Value);
  }

 

  Arduino 遥控车的工作

  完成代码后,将其上传到您的专业迷你板上。通过 FTDI 模块取出电池和电路板进行测试。启动您的代码,打开串行电池,您应该会收到来自发射器操纵杆模块的值。连接你的电池,你的电机也应该开始旋转。

nRF24L01

射频遥控操纵杆


/*将射频值传输到 Arduino 的代码

*

* 引脚连接

* CE - 7

MISO - 12

MOSI - 11

SCK - 13

CS - 8

A0 - JoyX

A1 - JoyY

*/

#include

#include "RF24.h "

RF24 myRadio (7, 8);

结构包

{

int msg = 0;

};

字节地址[][6] = {"0"};

typedef struct package 封装;

包装资料;

无效设置()

{

序列.开始(9600);

myRadio.begin();

myRadio.setChannel(115); //115频段以上WIFI信号

myRadio.setPALevel(RF24_PA_MAX); //MAX power long 愤怒

myRadio.setDataRate(RF24_250KBPS); //最小速度

延迟(500);

Serial.print("远程初始化");

}

向前诠释;

逆向;

int左;

诠释正确;

无效循环()

{

int xValue = 模拟读取(A0);//读取JoyX值

int yValue = analogRead(A1); //读取JoyY值

//Serial.print(xValue); 序列号.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(转发);

data.msg = 转发;写入数据();延迟(50);

}

if (xValue<500 && xValue > 10) // 过滤 JoyX 的 break

{

reverse = map (xValue, 10, 500, 20, 11); //将JoyX-down转换为11-20

//Serial.print("B="); Serial.println(反向);

data.msg = 反向;写入数据();延迟(50);

}

else if (yValue>600 && yValue<1000) // 为右过滤 JoyY

{

right = map (yValue, 600, 1000, 21, 30); //将 JoyY-right 转换为 21-30

//Serial.print("R="); Serial.println(右);

data.msg = 对;写入数据();延迟(50);

}

else if (yValue<450 && yValue > 10) // 过滤 JoyY 为 left

{

left = map (yValue, 10, 450, 40, 31); //将JoyY-left转换为31-40

//Serial.print("

data.msg = 左;写入数据();延迟(50);

}

/* else

{

Serial.println("Rest");

数据.msg = 0; 写入数据();延迟(50);

}

*/

}

void WriteData()

{

myRadio.stopListening(); //停止接收并开始发送

myRadio.openWritingPipe(0xF0F0F0F0AA); //在这个 40 位地址上发送数据

myRadio.write(&data, sizeof(data));

//Serial.print("\nSent:");

//Serial.println(data.msg);

延迟(50);

}

void ReadData()

{

myRadio.openReadingPipe(1, 0xF0F0F0F066); // 读取哪个管道,40 位地址

myRadio.startListening(); //停止传输并开始接收

if ( myRadio.available())

{

while (myRadio.available())

{

myRadio.read( &data, sizeof(data) );

}

Serial.print("\n收到:");

序列号.println(data.msg);

}

}





无刷直流电机


/*CE - 7

MISO - 12

MOSI - 11

SCK - 13

CS - 8

最近用 nano 测试

*/

/*PIN DEFANITIONS*/

#define R_IR 3

#define L_IR 4

#define L_MR 5

#define R_MR 6

#define min_speed 200

#定义 max_speed 800

#include

#include "RF24.h"

RF24 myRadio (7, 8);

结构包

{

int msg;

};

typedef struct package 封装;

包装资料;

字节地址[][6] = {"0"};

无效设置(){

pinMode(R_IR,输入);

pinMode(L_IR,输入);

pinMode(L_MR,输出);

pinMode(R_MR,输出);

串行.开始(9600);

myRadio.begin();

myRadio.setChannel(115); //115频段以上WIFI信号

myRadio.setPALevel(RF24_PA_MIN); //MIN 功率低

范围 myRadio.setDataRate( RF24_250KBPS ) ; //最低速度

}

int received;

无效循环(){

读取数据();

}

void Control_Car()

{

if (received>=1 && received <=10) // 向前移动

{

int PWM_Value = map (received, 1, 10, min_speed, max_speed);

模拟写入(R_MR,PWM_Value);

模拟写入(L_MR,PWM_Value);

}

if (received>=11 && received <=20) // 中断

{

int PWM_Value = map (收到, 11, 20, min_speed, max_speed);

类比写入(R_MR,0);

类比写入(L_MR,0);

}

if (received>=21 && received <=30) // 右转

{

int PWM_Value = map (received, 21, 30, min_speed, max_speed);

模拟写入(R_MR,PWM_Value);

类比写入(L_MR,0);

}

if (received>=31 && received <=40) // 右转

{

int PWM_Value = map (received, 31, 40, min_speed, max_speed);

类比写入(R_MR,0);

模拟写入(L_MR,PWM_Value);

}

}

void ReadData()

{

myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //读取哪个管道,40位地址

myRadio.startListening(); //停止传输并开始接收

if ( myRadio.available())

{

while (myRadio.available())

{

myRadio.read( &data, sizeof(data) );

}

Serial.print("\n收到:");

序列号.println(data.msg);

收到 = data.msg;

控制车();

}

else //如果不是来自 RF 的数据

{

//analogWrite(R_MR,0);

//analogWrite(L_MR,0);

}

}

void WriteData()

{

myRadio.stopListening(); //停止接收并开始发送

myRadio.openWritingPipe(0xF0F0F0F066);//在这个 40 位地址上发送数据

myRadio.write(&data, sizeof(data));

Serial.print("\n已发送:");

序列号.println(data.msg);

延迟(300);

}
 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分