带FPV摄像头的Arduino RC车的制作

电子说

1.2w人已加入

描述

步骤1:硬件概述

汽车由以下硬件组件组成:

-RC 1/10履带式履带底盘

-轴向竞速电子调速器(ESC)

-转向伺服电机

-铝底板和用于安装其他零件的铝角

-Arduino Mega(此项目需要一个Mega)

-Sparkfun Arduino XBee防护板

-XBee Series 1 Pro(60mW)无线模块

-Adafruit ADXL335加速度计

-Adafruit NeoPixel摇杆

-具有云台和红外夜视功能的IP摄像机

-便携式Wi-Fi路由器

-7.2V NiMH电池(用于电调和转向的电源

-11000mAH双USB移动电源(用于Arduino Mega,Wi-Fi路由器,IP摄像机,NeoPixel棒的电源)

A 笔记本电脑需要与汽车进行通信和控制。笔记本电脑必须具有以下内容:

-Windows 7/8

-至少2个USB端口

-Wi-Fi

-可选-以太网端口(但如果笔记本电脑没有以太网端口,则需要访问带有以太网端口的计算机)

在PC端还需要以下硬件组件:

-XBox 360控制器(有线)

-XBee Series 1 Pro(60mW)无线模块

-XBee USB Explorer

完整的零件清单是

步骤2:遥控车的选择和物理改装

我为该平台选择的RC车辆类型为 1/10比例的Electric Rock Crawler 。 RC Rock履带为4x4,具有锁定的差速器,(相对)较高的离地间隙和较大的悬架铰接性,因此在越过障碍物时它们不太可能卡住。但是,它们通常不如普通RC车快(专为高扭矩而不是高速而设计)。我选择的特定型号是HSP穿山甲,因为它很便宜。它也是Axial Racing AX10的仿制品,因此很容易找到兼容的零件:-P。

该车配备了 7.2V NiMH电池,电子速度控制器( ESC)和有刷电机。原始ESC没有关于如何对其进行校准或对其功能进行编程的文档。由于我打算通过Arduino控制ESC,因此我需要可以进行校准和编程的ESC。我发现Axial AE-2 ESC是最合适的替代产品,因为它们有明确的设置和配置说明(请参阅http://www.axialracing.com/blog_posts/787000000)。

要安装所有零件后,我卸下了原来的塑料电池/ESC托盘。然后,我使用了一些铝制角铁和大铝板来创建平坦的安装表面。

各个零件都被拧到铝板上或用电缆绑了起来。对于Arduino等电子组件,将一些塑料放在铝板上进行绝缘。

将大多数组件安装到汽车上后,我发现原来的悬架确实可以不能很好地应对增加的重量-汽车从原始高度掉落了约4cm。为了解决这个问题,我购买并安装了四个超级弹簧。这些弹簧比原始弹簧要好得多(汽车仅下降0.5厘米),但仍然有些过软-踩下油门会使汽车像下沉的船一样晃动!

步骤3:电源和接线配置

摄像头

具有两节电池-7.2V NiMH电池和11000mAh移动电源。 NiMH电池为 ESC和转向伺服器供电。请注意,转向伺服系统由ESC的电池消除器电路(BEC)供电,该电路可提供稳定的5V DC输出。同样,驱动电机由ESC供电/控制。

移动电源为 Arduino,WiFi路由器,IP摄像机和NeoPixel摇杆提供电源。 (所有这些设备都使用5V直流电源工作)。我选择的特定型号是Cygnett 11000mAh Charge Up Pro,因为它具有双USB端口-一个端口可以提供最高 2A ,而另一个端口可以提供最高 1A 。它也是目前可用的最大容量的移动电源之一,因此我不必担心在汽车电池没电之前它会死掉。

由于移动电源只需要用两个USB端口为四个电池供电,我制造了一些 USB电源分配器。这些可以视为USB电源双适配器。 NeoPixel棒的USB电源分配器除USB端口外,还具有一些 0.1“母头母头,以允许使用剥线的22 AWG实芯线将电源连接到NeoPixel棒。 p》

此外,由于涉及两个电池,因此连接到这些电池的设备的接地 应该,因此所有信号电压均基于相同的参考电压为此,我将ESC电池消除器电路(BEC)的接地引脚连接到ArduinoGND。USB电源分配器和Arduino GND之间也存在连接。此公共接地是必需的,以便转向伺服

最后一张图显示了汽车上电线/电缆的完整概览,包括所使用的Arduino Mega引脚。

第4步:软件概述

该项目中的软件包括一个基于PC的C#程序和一个 Arduino草图。该程序是WinForms应用程序,具有图形用户界面(GUI)。 C#程序执行许多功能,并处理各种输入和输出。这些内容的摘要如下:

C#程序

-接收XBox 360控制器输入

-接收鼠标/键盘输入一些功能

-从IP摄像机接收视频数据(通过http)

-从Arduino接收遥测/状态数据(通过串行)

-将指令发送到Arduino(通过串行)

-将指令发送到IP摄像机(通过http)

-将振动指令发送到XBox 360控制器

-GUI-显示状态控制器,串行通信,视频流。

Arduino素描并不像C#程序那么复杂,但是仍然可以做很多事情:

-从C#程序(通过串行)接收指令

-从加速度计模块接收遥测数据(通过模拟输入)

-向电子速度控制器发送控制信号

-向转向伺服器发送控制信号

-将控制数据发送到NeoPixel控制棒(数字输出)

-将状态/遥测数据发送到C#程序(通过串行)

我已已附加 C#项目和下面的Arduino草图。对于接下来的几个步骤,我建议下载文件并保持打开状态,以便您可以在步骤和代码之间进行切换。没有这些步骤,这些步骤就不是很有用,没有这些步骤,代码可能会有些混乱!

注意:如果项目没有,您可能需要从源文件中手动重新创建C#项目。

第5步:软件开发环境和实用程序

C#程序是使用Visual Studio Express 2012开发的。这是Visual Studio的免费版本,但提供了足够的功能来开发复杂的C#应用程序。

不幸的是,在开发C#应用程序时,Microsoft不包括对自己的XBox 360控制器的本机支持。幸运的是,我不是唯一遇到此问题的人,因此有人在“ xinput” 周围做了一个 C#包装器(该API允许开发人员与XBox进行通信360控制器)。我使用的特定版本附在下面。可以从github 下载最新版本的包装器: https://github.com/speps/XInputDotNet。有关详细的安装/配置说明,请参阅github页或自述文件。我的指示摘要是:在C#项目中添加“ XInputDotNetPure.dll”作为参考,并将“ XInputInterface.dll”与.exe文件放在同一文件夹中。

开发了Arduino草图使用Arduino IDE。为了同时使用NeoPixel操纵杆和两个伺服输出(用于转向和油门),还需要两个附加的库。这些库是Adafruit “ TicoServo” 库和Adafruit “ NeoPixel” 库。可以从github 下载这些库:

https://github.com/adafruit/Adafruit_TiCoServo

https://github.com/adafruit/Adafruit_NeoPixel

每个库中均提供了安装说明。有关通用的 Arduino库安装指南,请参阅:https://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use/how-to-install-a-库

注意:由于使用NeoPixel棒,因此无法使用标准的Arduino伺服库。 Adafruit提供了对此不兼容的解释:https://learn.adafruit.com/neopixels-and-servos

步骤6:C#应用程序线程和XBox 360控制器输入

我为此项目编写的第一部分软件是针对XBox 360控制器的(您可能已经注意到原始的Visual Studio项目名称已经沿用了到最后!)。您将在“ Form1.cs”文件的第一部分中找到 XBox控制器代码。如上一步中所述,仅当配置了Xinput dotnet包装器(即,已将“ XInputDotNetPure.dll”添加为C#项目中的引用,并且“ XInputInterface.dll”与该文件位于同一文件夹中)时,此代码才有效。 .exe文件)。

该代码通过重复轮询控制器以检索按钮和模拟控件的状态来工作。由于进行了轮询,我意识到该程序需要多个线程才能正常工作。这是一个挑战,因为在此之前我并没有编写过多线程应用程序。在查看了一些示例和教程之后,我决定将有一个用于图形用户界面(GUI)的主应用程序线程,一个用于处理XBox 360控制器的单独线程以及其他一些用于其他用途的线程。多个线程允许所有这些事情并行运行,而在GUI中没有任何明显的滞后。

在Xbox控制器线程中,控制器状态以大约50Hz的频率轮询,因此它始终具有最新数据。该控制器数据也会在GUI上回显,并且按钮的按下将以橙色突出显示。为此,需要跨线程数据传输。我使用“代理” 的概念允许线程彼此“影响”。您还会注意到在多个线程中使用的许多“ shared _.。..”变量。

此代码段还具有一个计数器,用于跟踪控制器“框架” 即可。在我的代码上下文中,这些框架指的是何时读取了控制器状态。使用计数器“ samplecount”和“ oldsamplecount”,以便正确处理长按按钮。例如,我分配了一些数字按钮,以便一按即可激活一项功能,而下一按则可禁用该功能。如果长按操作不正确,程序将连续打开和关闭该功能。该代码通过将oldsamplecount的值与samplecount进行比较,可以正确地将长按操作作为单按。如果两个变量之间的差异太小,则长按即可检测到。

步骤7:串行通讯(第1部分)

I考虑了几种在笔记本电脑和汽车之间发送控制数据的选项。 Wi-Fi或蓝牙似乎是显而易见的解决方案,但它们都无法提供我想要的范围。大多数无线arduino项目似乎使用依赖串行通信的 XBee模块,所以我决定使用串行接口。

汽车/笔记本电脑通信的工作方式如下:

1。 汽车发送一个串行字符串(具有固定结构),并带有消息字符的开始和结束。

2。 C#程序连续轮询笔记本电脑的串行接口。

3。当C#程序接收到包含预期的开始和结束字符的序列字符串时,将准备自己的序列字符串(具有固定结构),并将其发送到汽车。

3。 汽车接收到串行字符串,进行快速检查(基于消息字符的结尾和消息长度),如果消息“有效”,则提取并处理信息,并等待指定的在准备和发送另一条消息之前延迟-,并且循环重复。

注意:如果在Arduino上收到的消息不被视为“有效”,则Arduino草图将使汽车停下来

通过C#程序发送到汽车的消息的消息结构是:

500,500,F,D00,Z

此字符串的含义是:

第一个字段:油门(以500为中心)

第二个字段:转向(以中心大约500)

第三场:慢速模式-F:快,S:慢(最大油门为半速)

第四场:前大灯

第一个字符:D :暗(熄灭),L:亮

第二个字符:亮度(0-9)

第三个字符:亮灯序列(0-9)

决赛字段:消息结尾字符(Z)

有关某些字段的更多详细信息,将在后续步骤中提供

已发送消息的消息结构从汽车到C#程序,是:

A,500,500,F,D00,R,Z

第一个字段:消息字符的开头(A)

第二个字段:油门(约500个中心)

第三个字段:转向(约500个中心)

第四个字段:慢速模式-F:快,S:慢(最大油门为半速)

第五个字段:前灯

第一个字符:D:黑暗(熄灭),L:亮起

第二个字符:亮度(0-9)

第三个字符:光序列(0-9)

第六场:隆隆声(R-隆隆声,O-关)

最后一个字段:消息结尾字符(Z)

这些字段中的大多数只是呼应 Arduino收到的内容。这是作为串行接口的运行状况的视觉指示器来完成的。如果接口工作正常,则C#程序中显示的输出和输入字符串应该匹配。

此串行通信方法最初是使用有线串行连接(即使用Arduino USB电缆)开发的。我能够将Arduino端的延迟设置为20ms,因此消息频率约为50Hz。使用USB电缆,我的通讯没有问题,并且可以在两端获得稳定的消息接收。波特率设置为 38400 。

步骤8:串行通信(第2部分)-无线串行

为了进行无线串行通信,我最初购买了一些XBee Series 1 1mW模块,只是为了进行尝试。 Arduino需要XBee防护罩,而笔记本电脑一侧则需要XBee USB Explorer(或等效物)。自从我使用Arduino Mega以来,我将XBee防护罩上的相关引脚连接到了第二个硬件串行接口的Arduino Mega引脚上。

我发现使用 XCTU应用程序(请参见Sparkfun指南:https://learn.sparkfun.com/tutorials/exploring-xbees-and-xctu)。但是,我遇到了一些限制。第一个是显而易见的-具有1mW的模块,可用范围非常有限,并且对于没有丢失的消息,我最多只能到达3m!使用长USB电缆可以获得更好的覆盖范围。第二个是更重要的限制,似乎是基于硬件的。我发现即使将XBees配置为38400的波特率,也无法以50Hz的频率进行可靠的通信。我增加了延迟,因此消息速率约为25Hz,并且取得了更好的成功。在25Hz的频率下,我可以在3m内获得稳定的通信。我还发现,当我超出范围时,消息将被丢弃,但是当返回范围时将立即恢复。为了检查串行通讯是否正常工作,我在C#程序GUI上观看了串行输入/输出文本框。串行输入框应显示一个非常稳定的字符串,该字符串与串行输出框匹配。如果串行输入框开始闪烁,显示空白或损坏的数据,则表明消息没有通过。

这些模块正常工作后,我订购了一些功率更高的模块。看到高功率的Series 1和Series 2模块都可用,我选择了价格稍便宜的XBee Series 2 Pro(63mW)模块,而不是XBee Series 1 Pro(60mW)模块。我已经读到它们很难设置,但是可以像系列1模块一样在透明(AT)模式下使用。我配置了这些模块,并让它们以38400波特的价格相互通信(注意:一个模块必须作为“协调器”进行刷新,另一个模块必须作为“路由器”进行通信)。然后,我将一个安装到Arduino防护罩中,立即遇到问题。在25Hz时,我根本无法获得可靠的通信。为了检查发生了什么,我通过Arduino的第一个串行端口(即USB电缆)回应了Arduino收到的消息。使用笔记本电脑上的Arduino串行监视器,我发现Series 2 XBees将消息切成两半或将连续的消息混在一起。因此,Arduino有时会收到固定在下一个字符串前半部分的字符串的后半部分。我必须增加延迟,以使频率降至大约13Hz,然后才能在短距离上获得看似可靠的串行通信。较低频率信息的缺点是,它在控制器输入和汽车运动之间引入了更大的延迟。不幸的是,较低的频率不能完全解决问题。在更长的距离上,串行数据损坏仍然发生,并且当回到近距离时,接口无法恢复。

因此,面对所有这些问题,我最终购买了一对 Series 1个Pro 60mW模块。就串行接口而言,它们的工作原理与1mW Series 1模块一样好-在范围内时,没有数据损坏或奇怪的消息行为。它们的范围也比1mW模块好得多(如预期的那样)。

总之,如果您在项目中使用XBees进行简单的点对点通信,请系列2中的“远离” XBee模块! Series 1模块的性能无限提高,并且没有问题(这可能解释了它们的受欢迎程度和更高的价格)。

(在相关说明中,澳大利亚有谁想要买一些不常用的XBee Series 2 Pro 63mW模块?:-P)

第9步:汽车油门和转向

汽车上的节气门和转向是“模拟” ,这意味着通过使用XBox控制器,汽车可以在一定的速度范围内行驶,并在一定的转向范围内转弯角。 右触发器用于前进,左触发器用于后退,左指杆用于转向(这是XBox赛车游戏的标准控件)。为了将这些“模拟”输入从XBox控制器传输到汽车,数据按如下方式通过程序传播:

油门数据-C#:

1。读取XBox Controller状态。左右触发值保存为浮点数

2。在两个触发值之间进行比较。使用较大的值,而忽略较小的值(例如,如果同时按下向前和向后,则较大的值“获胜”)

3。将该值乘以100,然后对其进行调节,以使0速度等于值500。这意味着反向全速等于值“ 400”,向前全速等于值“ 600”。这样做是为了避免需要使用负数,并且选择500作为中心点是完全任意的。

4。新的油门值将转换为字符串(3位数字)。

5。节流字符串添加到C#输出字符串中,并在需要时发送到Arduino。

节流数据-Arduino:

1。 Arduino接收完整的字符串,然后将油门字符保存到字符数组中。

2。油门字符数组将转换为int

3。使用“映射”功能,将油门值转换为ESC的兼容值。 ESC接受与伺服电动机相同的控制信号,因此使用Servo型将“度”值写入ESC引脚。已对ESC进行校准,以使0度为全速后退,而180度为全速前进。 90度是0速度。

4。该值将被写入ESC。

在C#代码中,您还将看到一些操纵油门的额外功能。这些都是为了改变驾驶特性,但我还没有发现它们有用。这些功能之一涉及线性/平方/立方节气门模式。线性模式在触发位置和速度之间提供1:1关系。因此,将前进触发器按下一半将导致汽车以其最大速度的一半行驶。方形模式涉及对原始值进行平方运算,因此将触发开关按下一半会导致汽车以其最大速度的四分之一移动。这在较低速度下提供了更多的控制范围,而在较高速度下提供了更少的控制范围。可以使用C#程序GUI上的下拉框(使用鼠标)选择这些节气门模式。

另一个功能涉及通过按B上的B按钮来启用/禁用“慢速模式”的功能。 XBox控制器。慢速模式将汽车的最高速度限制为最大速度的一半。因此,您可以使用所有触发器来控制较低的速度。这种模式有时有时会派上用场-非常适合在慢速下进行精确控制。

转向非常类似于油门。数据传输的方式是:

转向数据-C#:

1。读取XBox Controller状态。左指杆的x轴值保存为浮点数

2。该值乘以100,然后相加500。这意味着最左边等于值“ 400”,最右边等于值“ 600”。像油门一样,这样做是为了避免需要使用负数,并且选择500作为中心点是完全任意的。

3。新的转向值将转换为字符串(3位数字)。

4。将操纵字符串添加到C#输出字符串中,并在需要时发送给Arduino。

操纵数据-Arduino:

1。 Arduino接收完整的字符串,并将转向字符保存到字符数组中。

2。转向字符数组将转换为int

3。使用“映射”功能,将转向值转换为转向伺服器的兼容值。请注意,转向伺服器的范围不是0到180。在我的汽车上,左全是133度,右全是60度,中心值约为96度

4。将该值写入转向伺服器。

像油门一样,可以在C#程序中将转向配置为线性/平方/立方模式。我发现对于我的车来说,这是没有意义的,因为转向角的范围相对较小。由于轮子不会转动太远,因此很容易在线性模式下将它们调整到正确的角度。

关于Arduino Servo库的注意事项:

当我开发Arduino草图时,我将标准Arduino伺服库用于ESC和转向伺服器。一旦介绍了NeoPixel荧光棒,就无法再使用Servo库(请参阅https://learn.adafruit.com/neopixels-and-servos)。 TiCoServo库在我的RC车上也能很好地工作,但是有一些限制-只能同时使用两个伺服器,只能使用一小部分引脚(即使在Arduino Mega上也是如此),并且只能使用这些引脚中的特定对一起工作。通过反复试验找出了最后一个。..

步骤10:IP摄像机(第1部分)-硬件

Arduino的视频功能不足,因此我需要一个自包含的视频解决方案。这排除了网络摄像头,这将需要车载计算机来处理视频并将其转发到便携式计算机。而且,GoPro有点贵,模型(当我在2014年中期开始寻找时)在没有明显延迟(3秒)的情况下就没有直播过。我发现可以以最小的延迟传输实时数字视频的摄像机的最佳选择是 IP摄像机。这些通常用作监控摄像机,实际上带来了更多好处,例如红外夜视。然后,我整理了所需/需要的功能列表:

-以太网和/或Wi-Fi接口

-能够设置静态IPv4地址

- MJPEG 视频流(简单地包含在C#程序中)

-如何通过http命令控制相机的文档

-广角镜头

-红外截止滤光片,用于日光(色彩精度更高)

-红外夜视

-5V直流输入

- (可选)云台控制

我能够找到一个符合所有这些条件的模型。我选择的IP摄像机是Foscam FI8910W IP摄像机。这是一个非高清IP摄像机,可以发送MJPEG视频(最大分辨率:640 x 480)。我没有选择HD型号,因为它们通常使用H.264视频,而且我也不知道如何在C#winforms应用程序中显示H.264视频流(是否有可能?

该IP摄像机由 5V DC(需要高达0.7A)供电,使其与USB移动电源兼容。但是,该连接器是桶形连接器,因此我制作了一条定制电缆-一端具有桶形连接器,另一端具有USB连接器。

IP摄像机同时具有Wi-Fi和以太网接口。从理论上讲,我可以在笔记本电脑和IP摄像机之间建立直接的临时Wi-Fi连接,但是我对其Wi-Fi天线的性能存有疑问。因此,我决定在车上添加一个便携式Wi-Fi路由器。我选择的型号是Netgear Trek PR2000。我之所以选择此型号,是因为它很小,可以通过USB电源供电并且具有以太网端口。拥有Wi-Fi路由器还为以后的升级提供了灵活性-可以轻松添加其他基于以太网/Wi-Fi的功能。

IP摄像机配置:

唯一需要设置的是静态IP地址。我选择了地址192.168.1.10(子网掩码255.255.255.0)。要设置相机,我将其插入笔记本电脑的以太网端口,然后首先确保可以自动分配IP地址以进行通信。然后,我打开一个Web浏览器,然后键入摄像机的IP地址以加载其配置页面。然后将静态IP地址设置为192.168.1.10。注意:这将断开与计算机的连接-为了恢复连接,笔记本电脑的IP地址已手动更改为同一子网(例如192.168.1.11,子网掩码255.255.255.0)。

还可以配置用户名和密码,但是由于仅在专用网络上使用摄像机,因此我将这些设置保留为默认设置(user = admin,无密码)。

Wi-Fi路由器配置:

与大多数其他消费级路由器一样,Netgear Trek路由器通过Web浏览器界面进行配置,并且初始设置需要有线以太网连接。为了在汽车上使用,需要将路由器配置为使用子网192.168.1.XXX(子网掩码255.255.255.0)。路由器还需要启用DHCP(默认情况下处于启用状态),并且需要配置基本的Wi-Fi设置(SSID和密码)。此配置只需要完成一次。

初始路由器配置非常轻松,但是不幸的是,常规启动过程并不像我期望的那么简单。只要路由器打开,它就不会进入运行模式,直到它检测到连接到其“ Internet”端口的设备或有线计算机。将IP摄像机连接到黄色端口后,路由器似乎可以进入“边缘”模式。要强制路由器完全启动,必须断开摄像机电缆并将其插入蓝色的“ Internet”端口。几秒钟后,路由器将正常启动,并且Wi-Fi将打开,从而使笔记本电脑可以进行无线连接。 IP摄像机无法在蓝色端口中工作,因此必须拔下电缆,然后将其重新连接到黄色端口。尽可能地邪恶。

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

全部0条评论

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

×
20
完善资料,
赚取积分