×

如何用相机制作Wi-Fi坦克

消耗积分:0 | 格式:zip | 大小:0.30 MB | 2023-06-25

欲望都市

分享资料个

描述

你想要自己的遥控坦克吗?我将描述使用智能手机通过 Wi-Fi 控制的相机创建坦克的过程。

我想传达的主要思想是,你不应该重复这个项目,而是根据你在这里阅读的内容,使你自己的项目独一无二。我将向您展示我的坦克示例,但此处概述的原则可应用于创建其他类似的遥控车辆。

有用的信息

我会这样写辅助信息。此信息无需阅读但仍然有用

 

 

 

poYBAGSBohKASSVmAAFxZhtGQJQ570.jpg
我的坦克的主要部件
 

船体和底盘

您可以在车辆上放置什么以及如何放置由车体决定,越野能力和速度取决于底盘。例如,如果你想在街上享受赛车的乐趣,你应该选择一个有很大间隙的底盘,最好有某种悬挂系统,但如果你的设备只在你房子的平坦地板上行驶,并且没有克服这种困难的反抗- 坦克障碍物如毛圈垫,那么你可能不会打扰 - 任何底盘都可以。

在我的坦克中,我使用了一个玩具坦克的船体,将里面所有多余的东西都磨碎了,以增加有用的体积。我用热熔胶填充了所有不必要的孔。变速箱和电机已经安装在玩具坦克上。

为了便于进入,我将船体的上部更换为带铰链的金属舱口,其中包含坦克的主要部件。舱门下方是发动机舱——两个电机+齿轮和一个带有两个电池的电池舱。舱口铰链是家具铰链(可能是一个残酷的解决方案,但这正是我想要的)。

ESP-32-Cam(带天线的白盒子)的外壳是红外运动传感器 (BV-201) 的倒置外壳。它足够宽敞,分为两部分,可以轻松更换其中的东西。

pYYBAGSBohaAc0RhAAOxGjbXglE960.jpg
 

供电系统(车载网络)

您设备的可靠性及其自主运行的持续时间取决于该系统。您必须确保整个设备在任何甚至最恶劣的条件下都能稳定供电。当一切都以最大程度打开时,电压不应下降到会发生故障或重启的水平。

有几种方法可以实现电源稳定性:

  • 创造条件,使得不可能使用超过设备所能提供的能量——例如,软件保护或物理限制。
  • 电源部分的独立电源——电机和强大的消费者与智能部分——微控制器、传感器分开。这样,如果电源部分出现电压骤降,例如,由于电机卡住,您将避免控制器 - 微控制器的电压骤降。
  • 提供某种针对电压骤降的短期保护在大多数情况下会有所帮助并且易于实施。一个例子是微控制器的电力电容器。

主要思想是微控制器的电压骤降非常糟糕,因为这意味着失去对整个机器的控制,以及所有后果......

坦克电池由一对2000mAh锂电池组成。然后电池连接到一个DC-DC升压转换器MT3608,为车载电源网络形成一个稳定的5.1V。需要 0.1V 的余量来减少电压骤降对电线和二极管的影响。

poYBAGSBohiATbZMAABoOrXS668942.jpg
我的坦克的电流消耗
 

从上面的值可以看出,最大的消耗者是发动机,此外,根据坦克行驶的地形,发动机的功耗也不均匀。

坦克上所有连接的设备均由来自稳定器的 5V 供电。那些需要 3.3V 的传感器由于功耗低,由 Arduino Nano 上的稳定器供电。带有 ESP-32 的电路板有一个稳定器,可将输入 5V 转换为 ESP 所需的 3.3V。

在 Arduino 和 ESP 板的电源电压输入附近,有带锁定二极管的电解电容器。由于二极管,电源电压降低,例如,对于 ESP,必须使用肖特基二极管(因为它的电压降很小)。但是,这种小电容容量可确保在电机运行或电池电量耗尽时的短暂功率骤降期间为微控制器供电。没有这个,他们会冻死或重启。这一措施使坦克的电池寿命延长了约 40%。

电机上有 0.1 µF 陶瓷电容器以抑制电刷火花并消除电源中的干扰。阻塞电容器也靠近每个微控制器板上的电源输入,以防止干扰。

微控制器

对于我的坦克,我决定将逻辑分为两部分。一个微控制器将处理来自传感器的数据、移动电机和做其他“简单的事情”。第二个微控制器将处理摄像头并通过 Wi-Fi 与外界通信。

  • ESP-32 是带摄像头的电路板形式——我需要一些便宜的东西,它可以使用 Wi-Fi 并且能够与摄像头一起工作。这是我找到的最佳选择。
  • 作为 Arduino Nano 开发板的 ATmega328p 是尺寸完美的开发板,具有许多空闲引脚和所有必要的接口。传感器读取和电机控制等任务的经典可靠选择。
poYBAGSBohuAGRXvAAFIGST1X08711.jpg
 

为什么我选择了两个微控制器:

  • 我想要 Wi-Fi 连接的最大响应速度,因此 ESP 上的任何额外任务都会给它带来额外的负载,即使它是双核的,这也可能导致额外的延迟,这是不允许的奢侈。
  • 不幸的是,ESP-32-CAM 模块外形中的 ESP-32 板的空闲引脚非常少,其中一些是为其他需要保留的。
  • 某些 Arduino 库在 ESP 上运行不佳。
  • 我喜欢这种职责分离的想法。

ESP-32 和 GPIO0 的有趣错误

在刷入 ESP-32 之前,有必要将其置于启动模式。这是通过将 GPIO0 引脚短接到 GND 来完成的。油箱上有一个开关(红色开关),可以让ESP进入固件模式或普通模式。但是我遇到了一个记录不完整的错误/功能。在正常工作模式下,此引脚上会产生一些特殊的高频信号,违反这些信号会导致整个 ESP 出现各种毛刺。虽然触点有一个内部上拉电源,但它无助于减少通向开关(约 7 厘米)的电线中的干扰,因此偶尔会出现电路板冻结。通过断开引脚上的电线,问题就消失了。我发现这是一个罕见的错误(可能是我的电路板有缺陷)。更换电路板对我有帮助。

软件和固件

我使用了 Arduino 框架,因此您在 Arduino 和 ESP 上获得了一个单一的生态系统,尽管 ESP 有自己的框架和出色的文档。

本项目使用espressif32平台3.2.1版本,因为高于该版本破坏了内存分配算法,会导致ESP重启。这仅适用于我的情况,因为我使用多种协议,例如 HTTP、SSE、Websocket 和频繁的数据传输。在其他情况下,一切正常。

坦克操作算法。这些是一般意义上的工作周期。我的图表不能称为对实际发生的事情的准确描述,因为最好看代码。我只展示主要方面。

pYYBAGSBoh6AfYTXAAF5lVQrxc8506.jpg
 
poYBAGSBoiGAEN2sAAEaXA2Kw7Y292.jpg
 

错误保护。由于错误和崩溃是不可避免的,尤其是在调试期间,我不得不做一些优雅的 hack 并将其称为“错误保护”。

有看门狗之类的东西。看门狗是一个硬件定时器,它一直倒计时,如果计数到零,它会重置微控制器。在正常操作中,微控制器应定期重置看门狗,使其时间恢复到原始状态。如果微控制器突然开始思考并且没有时间复位,看门狗将拉动复位开关 - 简单有效。

Arduino 会很快耗尽 RAM。我决定放一个看门狗来跟踪电路板,如果发生什么事就重新启动它。不幸的是,Arduino Nano 有这样一个本机引导加载程序实现,我的板将进入永久重启(Arduino WDT 引导循环)你可以通过刷新另一个引导加载程序(如optiboot)来解决这个问题,但这个解决方案太无聊了,所以我决定用 ESP-32 来组织看门狗。

pYYBAGSBoiSASU9gAAFmpgzvGDA288.jpg
 

在 ESP 上一切都比在 Arduino 上无聊得多,有两种防止错误的保护措施。第一个通过使用集成看门狗 4 秒来防止在密集数据传输期间发生 RAM 溢出。如果出现死机,电路板将重新启动,并且重新启动的速度甚至让人感觉不到 Wi-Fi 连接中断(不需要重新连接)。

第二个 - 掉电检测器已关闭。这样做是为了在 5V 电压的条件下,可以工作更长时间。现在,万一由于缺电而真正掉电,电路板将冻结,但这可以通过防止电机过载的软件保护(更多内容见下文)和最重要的 - 延长电池寿命来补偿,因为检测器的阈值有点高估。

电机过载保护。尽管名称如此,但这种软件保护并不保护引擎,而是保护车载电源网络免受电压骤降到临界水平的影响。由于发动机是油箱上最大的能量消耗者,我做了一个保护,当电压低于一定水平时 - 停止发动机(从而减少电流消耗),这可以避免大多数重启或挂起电源。

电机过载保护算法在Arduino上实现,电压由其内部ADC测量。这是算法的样子:

  • 在某个时间间隔(5 毫秒)测量电池电压。
  • 如果电压低于阈值,并且在上次测量中没有这种情况,它只会记住这个事实。
  • 如果电压低于阈值,并且在上次测量中也低于阈值,则会触发保护并停止电机。

我试图通过电机的平稳加速来缓和瞬态电压骤降的影响(在改变运动侧的那一刻),但这没有明显的效果(可能在大型电机上它会给出更好的结果),而且由于电机加速时存在延迟,因此失去了动态控制。

声音信号。声音警报是一件很酷的事情,它们会让我知道水箱是否出了什么问题,或者它是否准备好工作了。

我总共有四声哔哔声:

  • “通知” - 最响亮的。这是为了吓唬街上的人(所以他们不会不小心踩到坦克)。可以从控制应用程序手动调用此信号。
  • “警告”——发生了一些事情,但并不严重,例如引擎因电压过低而停止。
  • “错误”——有什么东西坏了,如果不进行干预或重新启动,坦克就无法再工作。
  • “好”——意味着一切都很好。目前用作坦克已准备就绪的指示器。

所有信号都由一组四个部分组成。每个部分存储声音的频率和持续时间,一个特殊的功能在信号发声期间切换频率。该报警系统易于实施且易于扩展。

坦克控制终端(应用程序)

这是一个提供以下功能的应用程序:运动控制、查看来自传感器的数据、进行诊断和调整水箱。该应用程序是使用游戏引擎 Unity 制作的。Unity 不是为此任务而设计的,因为它毕竟是游戏引擎。我选择 Unity 只是为了好玩。

poYBAGSBoieAHFceAAMJnC7Egfo992.jpg
 

  • Wi-Fi 允许通过智能手机进行控制。
  • 我喜欢技术本身。
poYBAGSBoiuAE8GYAAM0VO6CpC4669.jpg
 

与罐体的连接方式有两种:

  • 外部中继器天线 - 这种天线的质量优于智能手机中的天线。
  • 如果您使用 Wi-Fi 标准:802.11n,将带宽从 40 MHz 降低到 20 MHz 是有意义的。据我了解,这种情况很少见,这完全是因为我喜欢廉价组件。网上有贴个防静电袋之类的解决办法,但实际上,这些办法都不是很有效。我花了好几个小时想办法解决这个问题,并将天线换成外置天线,我什至在 ESP 船体周围包裹了箔纸,虽然它更多的是保护它免受街上随机噪音的影响,而且它也很漂亮。

    数据传输协议。储罐和控制终端之间的数据交换通过三种协议进行:

    • HTTP – 只有客户端可以启动通信会话,服务器不能首先向客户端寻址。它传输来自传感器、控制和配置命令的数据。
    • WebSocket (WS) – 允许您从服务器向客户端双向发送数据,反之亦然。它用作建立通信模式并将数据从 ESP 和 Arduino 传输到日志的初始“ping”。
    • Server-Sent Events (SSE) – 根据客户端-服务器订阅的原理工作,但仅以一种方式工作,即从服务器到客户端。将来自传感器的一些数据传输到终端,这些数据会快速更新。
    poYBAGSBoi2AdFgdAADpnBRHl9k778.jpg
     

    使用的主要协议是 HTTP。WebSocket 和 SSE 我选择使用它们来收集经验。所以,用例有点牵强,你可以很容易地没有它们。此外,本机异步 Web 服务器非常快。

    WS和SSE的选择基于两个因素:

    • 它们允许您将数据从服务器直接发送到客户端。使用 HTTP,客户端必须轮询服务器。
    • 理论上,由于数据冗余和不必要的通信会话较少,它们比 HTTP 工作得更快。

    ESP-32 上的数据更新率。ESP 对其可以处理的数据量有一定的限制,大约每秒 15 个数据包。如果超过此限制,数据将被丢弃,并在 UART 中显示“错误:排队的消息太多”条目。请注意,这里每秒的连接数比数据量的影响更大。

    因为我想要更快的传输,所以我决定尝试使用 WS 和 SSE 绕过它。我的流量几乎总是同质的,所以一切都在相同的条件下进行了测试。这是我得到的结果:

    • WebSocket——连接数限制与HTTP服务器类似。除了直接从服务器传输到客户端外,没有其他好处。
    • SSE - 允许您将传输限制稍微增加每秒 3-5 个数据包。
    • 这两种协议都不如 HTTP 服务器稳定。例如,有时,ESP-32 可能会在流量过大时重启或死机,作为提醒:“不要搞乱绕过限制”。如果你不过分,你可以使用它。

    三种协议的响应速度是一样的,传输同样的数据不能说HTTP比WS或者SSE慢。这意味着最终实施比选择任何这些协议进行控制或任何其他需要低延迟的协议更重要。

    数据传输原理。数据以字符串形式传输。有的打包成JSON格式,有的按原样传输。

    ESP-32 托管一个异步 HTTP 服务器。它通过 HTTP GET 请求进行通信。终端通过请求发送控制命令。在参数中有一个数字,它对应于坦克的运动侧。相机或 Arduino 设置以类似方式传输。终端定期轮询来自传感器的数据,从 ESP 接收最后接收到的 JSON 格式的传感器读数作为响应。

    WebSocket - 向终端发送服务消息以记录并确认 Arduino 设置已被接受。

    SSE 用于一个目的:从 Arduino 接收到数据后,立即将更新后的传感器数据快速发送到终端。

    从传感器传输数据。传感器分为两组:

    • 慢速传感器 - 以特定时间间隔更新并从 Arduino 传输到 ESP。控制终端(应用程序)定期请求此数据。更新频率为两秒一次。通过 HTTP GET 请求传输。
    • 快速传感器 - 以一定间隔更新(比慢速传感器快)并由 Arduino 传输到 ESP,然后立即发送到控制终端。更新率为每秒 2.5 次。通过 SSE 传输。

    内部沟通。Arduino-ESP。Arduino开发板和ESP-32-Cam使用UART协议进行通信。起初,我自己制作了数据传输的解决方案,但是当要管理的数据太多时,我意识到使用现成的解决方案要好得多。

    这个解决方案是很棒的库SerialTrasfer,它承担了数据传输的“脏”工作:组织正确的数据包传输、校验和计数并允许您传输简单的数据类型和结构,这正是我所需要的,因为我存储数据来自结构中的传感器。

    ESP-32 有几个板载硬件 UART,与 Arduino 不同,它可以很容易地重新配置为其他引脚。UART_0 保留用于调试和刷新固件,UART_1 用于 Arduino 通信。

    数据传输的 UART 速度设置为 76800 波特/秒。在此速度下,由于 Arduino 微控制器的 16 MHz 时钟频率和 ESP 的 320 MHz 时钟频率,传输错误最少。该解决方案可以在很大程度上保证 ESP 和 Arduino 之间传递正确的数据,而无需检查和复制它们。

    由于 Arduino Nano 微控制器 (ATmega328) - 8 位和 ESP-32 - 32 位的不同架构,您需要使用内存对齐,以便数据(枚举、结构)在两个平台上都能被正确接受。为此,我使用属性“attribute((packed))”。

    鉴于 ESP-32 (3.3V) 和 Arduino (5V) 逻辑电平的不同电压,它们之间的 UART 通过电平转换器连接。

    UART数据传输原理:

    • 数据成对传输:“数据类型”和“有用数据”,最后一个可以不存在,因为有时仅存在传输事实就足够了,例如需要更新的信号看门狗定时器。
    • 共有8种数据类型:“传感器读数”、“控制命令”、“蜂鸣器类型”、“看门狗”、“日志消息”、“快速传感器读数”、“Arduino设置”、“读取Arduino设置”。
    • 在发送方准备一条消息,开头是数据类型,如果需要,后面是有用的数据。
    • 接收方收到消息,根据消息类型,可能有:一些动作或解包数据。
    pYYBAGSBojCAO3L5AAF77O3fpT0928.jpg
     

    这个简单的数据传输系统易于扩展,允许您传输不同类型的数据并引入了一点冗余,因为数据类型只是 Enum,即通常的数字。

    您不仅可以使用 UART,例如 SPI,或 I2C,或其他数据传输协议。我之所以选择 UART,是因为它有很好的文档,易于使用,而且仍然需要它来进行调试。

    传感器

    各种场合都有大量的传感器,它们需要测量所有存在的和不存在的物理量。它们是您设备的“眼睛和耳朵”。有了它们,您的设备就可以感知现实。

    水箱上有许多传感器:

    • DHT-11 模块温度计和湿度计。不是很准确,但便宜且易于使用。我认为在坦克(带遥测)上应该有一个经典的传感器 - 一个温度计。
    • 霍尔传感器 A3144,作为转速计。一个小的钕磁铁安装在左侧轨道的驱动链轮上,一个霍尔传感器放置在船体上靠近它的位置。传感器读取经过它的每个磁铁,并据此计算驱动链轮的转数。知道链轮的直径,您就可以准确地知道油箱以什么速度通过了多远的距离。这种即兴创作的准确性让你希望更好,但效果很酷。
    • 气压计 BMP-280。允许您获得大气压力并基于该气压计算海拔高度。传感器有多种适用于所有场合的工作模式,但设置起来有点复杂。
    • MPU-6050加速度计和陀螺仪模块。一种用于测量空间方向的良好、快速的传感器。使用复杂的数学来工作,但这可以通过许多可用的库来弥补。
    • US-025 超声波测距仪(HC-SR04 的模拟)。用于显示距坦克前方最近障碍物的距离。

    I2C 总线的有趣错误

    一些传感器(MPU-6050、BMP-280)通过 I2C 连接。有时由于这条总线,Arduino Nano 微控制器可能会冻结。我用示波器观察了公共汽车上发生的事情,而不是近似平坦的矩形形状,我看到了可怕的扭曲信号前端,更像是三角形,甚至是随机噪声。我检查了几块木板,没有水箱,但结果是一样的。我一直不知道是什么原因造成的。也许是因为廉价的 Arduino 零件或其他原因。通过 1.3 kOhm 将总线强力上拉到电源有帮助。
    pYYBAGSBojSAUqRcAAX0SjFOHuU153.jpg
     

    •  

      在我的例子中,安装了最便宜的相机版本。对于那些想用第一人称视角 (FPV) 做类似事情的人,我建议购买镜头视角为 120° 的相机版本,因为通常的 66° 会产生非常可悲的结果——它只是缺乏视野。

      执行器

      这就是让您的设备活跃起来的原因。例如,在我的坦克上,它是由两个电机驱动的。它也可能是某种激光和伺服系统来指向​​它。

      执行器通常会消耗很大一部分机载功率。由于微控制器本身只能通过小电流,因此有必要通过特殊的“适配器”——驱动程序来控制这些设备。

      驱动器是连接微控制器、执行器和电源的电路板。这个想法是微控制器只发送诸如“做这个或那个”之类的控制信号,而驱动器本身会弄清楚如何正确地启动执行器。您也可以从微控制器生成信号,但随后必须制作所有电路并实施控制算法。使用现成的专用设备(驱动程序)效率更高、速度更快。

      对于坦克,我使用了 L298N 驱动器。可以使用更新和更高效的驱动程序。但我喜欢使用这样的旧东西,它有一个残酷的外观和一个大的,最重要的是在工作后温暖的散热器 - 它赋予了坦克的精神并且完全适合它的“从桌子上的东西建造”设计。

      一共有9条控制命令:

      • “动”:前进,后退。
      • “转”:左、右。
      • “转身”:前左右、前右、后左、后右。
      • “停止。”

      考虑到坦克的电机略有不同,它们具有不同的直线运动最大 PWM 信号(电机的最大速度)。

      电机控制原理:

      • “停止”命令 - 向驱动器发送信号以停止电机。
      • “移动”命令 - 驱动器向前或向后旋转两个电机。
      • “转弯”命令——转弯一侧的发动机向后旋转,第二个发动机向前旋转。这样就实现了原地快速转弯。
      • “Moving with a turn”命令 - 与转弯相对的轨道电机以 100% 工作,而转弯侧的电机降低转数,例如 70%。这导致平稳地转向制动履带的一侧。

      可以使用更激进的制动策略,例如倒车或锁定电机,但考虑到我的坦克质量小且几乎完全没有惯性,这太过分了。此外,变速箱会阻止自发运动,而且这种制动器会在短时间内消耗大量能量。

      要转弯,您可以关闭(停止)转弯一侧的履带发动机。通过这种方式,您可以在履带制动器周围的位置实现良好的半径转弯。

      如您所见,控制执行器并不复杂。您只需根据电流消耗和您要控制的设备类型选择适合您任务的驱动程序。

      照片展示

       
       
       
      poYBAGSBojiARu6IAARVlcUt-Cc975.jpg
       
      1 / 7坦克 - 前视图
       

      奖金照片

      poYBAGSBojyAKlNuAAVMm_d_PJc617.jpg
       

      结论

      我在 GitHub 上的存储库中发布了 Arduino 固件、ESP-32 和 Unity 应用程序的所有源代码,如果您发现“有趣的解决方案”,请不要感到惊讶。我的目标是向您展示原理本身,最好的方法是自己弄清楚并根据您获得的知识制作自己的东西。

      写这篇文章帮助我列出了我在创建坦克时的所有经验。并记住在此过程中出现的所有错误和缺陷的解决方案,您可以避免这些错误和缺陷,并专注于寻找自己独特的错误并与社区分享。我真的希望我能激励别人创造出这样一件很酷的东西。


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

评论(0)
发评论

下载排行榜

全部0条评论

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