今天小编给大家带来的是柴火创客空间骨灰级认证会员-陈子平老师的开源项目-旋币采矿车,一辆可以实现自动化硬币采集、智能硬币储存、摄像头实时监控、手机遥控、一键执行任务的“物联网视频履带车”。项目基于APP Inventor、Web服务器、MQTT协议、物联网、机械自动化等技术,共有1205个零部件,尺寸为670450390mm。
最开始的时候项目命名为“弹币采矿车”,后面觉得弹币容易被想成把硬币弹高,于是就改成了“旋币采矿车”;为什么叫采矿车呢?主要是与红色警戒里面的采矿车很像,功能类似都是获取矿物资源,能够将硬币吸入储存,还能将硬币旋转弹出,同时寓意着:招财进宝,财源滚滚的含义。
说起制作这个项目的初衷最开始是从做了一个简易的旋币装置开始的。
这个简易的旋币装置内部有两个连杆将硬币夹紧,当硬币塞进孔洞后,夹紧力会使硬币产生旋转的力量,跟小时候玩旋转硬币差不多,而装置是将手指弹硬币的过程省去了,实现了半自动化。玩了一段时间于是突发奇想,来了一个灵感,能不能将其做成全自动化的,然后将这个装置增加上全自动收集机构、移动机构、控制机构、摄像头实时监控。这样不就实现了全自动的旋币装置了吗?如果做出来的话一定非常过瘾、非常酷炫。
产生想法后,马上就着手画了一张概念图,这跟完成后的装置有一些偏差,当时就是心中随想画的图,没有考虑太多的技术层面和外观设计的问题。这个概念雏形包含了机械化运作的传送带模块、全自动提升模块、收集和硬币旋转模块、实时摄像模块和履带行走模块。于是有了大致的方向,便一边做一边想,构思这个项目所包含的核心技术难点,通过一个思维导图进行了梳理:
项目思维导图分为四个大块分别是:程序部分、电路部分、机械设计部分、组装过程。程序部分涉及了三个大块,手机端APP、ESP32cam程序、Arduino程序,几个控制器的通讯衔接;电路部分主要是Arduino与ESP32cam的各功能模块连接;机械部分是比较复杂的,为了达到流畅的运行,经过好几次升级改造,有硬币旋转收集机构、硬币提升机构、传送带机构、传送带升降机构、履带运动机构、外壳部分,这几大模块都用了不少时间去进行设计制作,不像编程马上能够立竿见影,需要组装和调试;最后一个部分是组装过程,详细记录了整个装置的机械结构和电路设计。
一、程序部分
整个项目中,依靠机械机构执行,而各个模块相互组合,实现机械自动化,则需要用电路与程序进行控制,程序部分包含的方面比较多,涉及到了ESP32cam与Arduino的配合使用,因为任何单一的控制器都无法保证整个装置的完整性和实时性,所以一个用于顶层通讯,一个用于底层执行,具体的通讯原理图如下:
整个控制系统中,处于指挥层面的是手机APP端,需要开发一款能实时显示摄像头画面和遥控的手机APP软件,APP下达控制指令和显示实时反馈数据。让手机与ESP32cam实现实时控制的是MQTT协议,通过发布和订阅主题的形式来进行通讯,通讯过程是双向的,可以一对一也可以一对多,ESP32cam在整个系统中处于中枢地位,向上连接着手机端,向下连接着Arduino的执行端,为了保证控制的实时性,将运动电机、照明LED、升降电机的控制由ESP32cam完成,同时实时获取摄像头数据,用web服务端进行发送,这样在手机上打开网页就能实时显示视频流数据。ESP32cam往下通过串口连接着Arduino,ESP32cam用串口发送控制指令去指挥Arduino执行实时性不高的指令,比如灯带灯光模式改变、传送带运动、显示屏等,Arduino通过串口反馈底层的数据信息发送给ESP32cam,再由ESP32cam的MQTT协议传到手机端显示,数据包含:入库数、库存数、弹出数、任务数。Arduino同时还处理着各种自动化的任务循环,类似于人类大脑的脑干功能,控制着呼吸与心跳不受外在的影响,如电机提升循环、传感器实时数据变更、电机定位循环等底层部分,如果出现异常会将数据传输到ESP32cam,同时12864进行显示,方便及时处理,这样就打通了从Arduino到ESP32cam再到手机端APP的数据通道,整个系统实时且高效。
下面我着重讲解一下手机端APP是如何编写实现的。
用App inventor设计制作APP,制作的版本是“弹币采矿车V1.0”,这边再次解释一下,因为当时取名比较随意就叫做弹币采矿车,但后来又觉得不合适,弹币与硬币旋转还是差别比较大的,后面把名字改成了“旋币采矿车”。整体APP界面设计如图6,有几个大块,摄像头显示部分是最大的一个窗口,下面是摄像头开启和MQTT开启的开关,中间是数据显示窗口,底部是运动控制窗口,界面的设计过程还是比较简单的,这边就不做过多阐述了,在APP中MQTT协议与服务端视频流是比较关键的,接下来讲一下程序的具体实现。
MQTT原理如上图所示,先由传感器或监测设备先发出主题到Broker,主题的数据会更新,此时终端设备比如手机、电脑或数据存储设备会订阅相应的主题,经过Broker消息中介,将订阅的消息发给终端设备,此流程可以双向或一对多,防止了过程中信息丢失的可能,可以说是非常可靠灵活的。
调用MQTT程序模块,Broker设置为相应服务器名称,端口号1883,心跳周期KeepAlive为60,客户ID(ClientID)为唯一号,可以随机生成也可以指定,调用UrsPahoMqttClient.连接模块,进行服务器连接,连接成功后显示“MQTT连接成功!”。这样就完成了连接MQTT服务器的操作,比较简单。下一步讲解如何发送主题信息:
这边举一个Led点灯的主题发送代码案例,调用UrsPahoMqttClient.Publish模块向主题Topic:Zipng-Maker-Sub-C8:F0:9E:2A:XX:XX-LED,发送Message:“1”。当Broker接收到主题信息改变,则进行消息更新,ESP32cam订阅了相应主题,接收到信息的变更,判断信息值实现Led的点亮,其余按键的编程操作也是一样的。
手机端需要接收来自ESP32cam转来的Arduino数据,由ESP32cam发送主题,手机端APP要订阅相应主题进行显示,接下来讲一下,订阅主题操作,调用UrsPahoMqttClient.Subscribe模块,Topic设置订阅主题,Qos服务质量设置为0一般就行,等级越高越可靠,但传输会变慢,这样就完成了主题的订阅操作。
完成订阅后需要实时接收主题数据,调用UrsPahoMqttClient1.收到消息模块,判断消息主题Topic文本,将对应的文本标签设置为Messsge变量的值,完成数据显示操作。到这一步MQTT的基本操作就已经完成了,是不是很简单。
最后一步设置Web浏览器的页面,在ESP32cam中已经将视频流数据发送给了网页端,所以手机端只需要显示一个对应的网址就能完成摄像头的显示操作,其中的关键代码块是调用Web浏览框.访问网页,设置URL网址,此网址为ESP32cam返回的视频流网址。
这样整个APP关键程序代码就已经编写完成了,测试程序运作是否能够正常运作,修正程序中存在的Bug,操作过程中需要每一步进行调试,遇到的问题也是千奇百怪,要根据实际问题一步一步解决,需要一些耐心。最后检验流畅度,APP整体操作比较丝滑,反应灵敏。
ESP32cam是ESP32系列中带有摄像头的一款主板,搭载的摄像头模块可以很轻松的完成一款网络监控摄像头的项目,实现摄像头的经典例程也比较多,这边主要讲一下关键的MQTT协议是如何实现的。第一步是完成MQTT的服务器连接,新建一个FreeRTOS任务mqtt_task,设置WiFi模式为WIFI_STA,函数mqttClient.setServer设置连接的服务器名称和端口号1883,设置mqttClient.setCallback回调函数,接收订阅主题的信息,调用connectMQTTserver()函数连接MQTT服务器。While(1)是死循环,执行mqttClient.loop()心跳周期,保证连接的稳定。
拼接字符串clientId使其符合连接要求,格式为”esp32-”+”MAC地址”,再将其转化为字符数组形式,赋值给mqttClient.connect函数,执行连接MQTT服务器操作,连接成功后执行subscribeTopic()函数订阅相应主题。
这边举一个LED主题的订阅,其他的都和这个一样,先拼接字符串topicString_LED,这个字符串可以随便自己设计,当然为了主题的唯一性,也可以参考我的命名方法,然后获取字符串的长度,用strcpy将topicString_LED转化为字符串数组subTopic_LED[],再用mqttClient.subscribe函数将字符数组subTopic_LED[]传递过去,订阅成功串口输出相应的订阅主题,方便查看,其他的主题也是同样的操作。
回调函数receiveCallback是接收订阅主题信息的函数,创建字符数组msg[length+1]用于储存字符,然后遍历每个元素将其储存起来,在数组的最后一位添加’\0’字符串结束符。以LED主题为例,先用strcmp函数判断topic与相对应的主题是否相等,相等返回0,如果等于0执行下一步程序。if判断payload[0]信息是否等于1,则执行digitalWrite(LED_BUILTIN, HIGH)亮灯操作,其他的控制单一引脚的可以按照这个一样编写即可,如果是字符串的值则调用msg[]数组赋值即可。
新建一个任务函数receiveSerialDataTask,用于实时接收Arduino发来的串口数据,再将其转发至手机APP。实现过程是这样的,判断是否有串口数据Serial.available() > 0,截取两个指定字符之间的数值赋值给变量,如FS_RuKu_Num为r和K之间的数字,再用sprintf函数将其转化为字符串格式,用mqttClient.publish函数发送数据到Ziping-Maker-Sub-C8:F0:9E:2A:XX:XX-Back-KU主题,APP接收到主题数据,完成Arduino数据的转移与显示操作。
接下来讲解Arduino的程序编写,WS2812与12864的显示这边就略过,主要讲解数据采集和自动化触发任务的编写。导入FreeRTOS操作系统,新建任务用于采集传感器数据,这边要用到一个传感器状态的变量sensor1_temp,先赋值高电平,当传感器接通检测到引脚LOW低电平,延时30ms去除传感器不稳定,判断是否是第一次触发,则执行程序变量自增操作,将sensor1_temp置LOW,只执行一次,当传感器断开,sensor1_temp置HIGH开启下一个循环,这样就避免了传感器一次触发多次自增的情况。
弹币电机模块凸轮上安装有霍尔传感器用于电机定位功能,每次弹币完成后,霍尔传感器都能在相同位置发送信号,检测到信号后,停止电机实现定位功能;当有任务时,执行弹币操作,就不需要电机一刻不停的运行,延长了机构的使用寿命。定位程序是关键的一环,首先新建vTask3任务循环,判断任务数是否<=0,只有当没有任务时才开启程序,电机旋转运动,随后进入while(1)死循环,判断霍尔传感器是否接通,如果接通退出循环,随后关闭电机,定位完成。
要实现硬币采集流程全自动化,还需要提升机的触发循环才行,在传送带的末端安装有4个光电传感器,用来检测是否有硬币通过,当有硬币通过时触发提升机运动,新建vTask1任务循环,整体程序比较简单,四个传感器并行判断,延时函数vTaskDelay来控制电机的运动时间,实现提升机的触发循环。
剩Arduino的串口输出和读取与ESP32cam相同,参照即可完成,就不重复了,把代码写好后还要进行下一步的调试,过程还是比较漫长的,需要不断的修正,直到实现全机械自动化的运作。
现在程序的关键部分已经讲解完成,下面来看一下电路部分的实现。
二、电路部分
电路部分有两个大块,一个是Arduino mega2650部分,一个是ESP32cam部分。
Arduino mega2650 pro负责模块:取料传感器、进料传感器、红外对管模块、WS2812灯带显示、oled12864屏幕显示、PCF8574IO扩展模块(按键)、MOS管模块、霍尔传感器、串口通讯接口。取料传感器由4个红外探头组成,形成并联触发,接收由传送带送入的硬币信号,负责触发提升机;进料传感器负责提升机硬币出口的检测,增加硬币的库存信息;红外对管模块作用是硬币弹出时的检测,减少硬币的库存信息;霍尔传感器控制弹币电机的定位触发信号;PCF8574IO扩展模块连接3个按键控制Arduino断电保护内存的修改,实现掉电数据保持和12Vled的控制;四个MOS管模块分别控制提升电机、弹币电机、震动电机、12vled灯带;串口通讯接口用于与ESP32cam的双向通讯。
ESP32cam是一款性价比很高的控制板,主频可以达到240MHZ,可以传输视频流数据,但由于摄像头所占引脚较多,除去摄像头空闲的引脚并不多,需要用到PCF8574IO扩展模块来增加控制引脚,M1、M2为运动电机实时操作要求较高,M3为传送带升降电机同样也是实时要求高,不能使用Arduino串口去控制,会导致系统通讯延时较高,达不到实时控制的要求。
三、机械部分
机械设计在装置制作中占了很大比例,所有的机械零部件都是自己研发设计,为了实现预想的功能,设计了好几个版本,经常会发生达不到预期效果的情况,这时只能继续修改Bug,继续迭代,过程虽然费时费力,但也乐在其中。
整个装置包含:硬币旋转机构、硬币提升机构、传送带机构、传送带升降模块、履带模块、外壳部分共六大部分,整个装置共有1205个零件,细节部分就不一一展开说了,下面我讲一下这些机构的设计思路。
在整个装置中实现核心功能的是硬币旋转机构,又称为“硬币旋转机”,可以把这个模块单独拿出来使用,也能组合到任何机构中实现相应的功能,独立性比较强。实现硬币旋转要经过几个步骤:第一步硬币的收集与堆叠,第二步将最底层的硬币推出,第三步硬币翻转,第四步下压让硬币旋转。这几个关键步骤,每一步都有相应的机械机构完成,第一步用亚克力管实现堆叠,第二步用齿轮齿条将硬币逐个逐个推出,第三步用机械连杆实现90度的翻转,第四步用凸轮实现缓慢的下压动作,最后将所有的机械机构用齿轮串联起来用一个电机进行驱动。
硬币提升机构的设计中,设想过好几个版本,最后采用的螺旋提升方案,螺旋提升方案有一个好处是当硬币提升到中间时,硬币的各个方向都能挡住实现定位,不会移动,所以在颠簸路段或随时断电也没关系,不会导致硬币在机构中乱跳。在提升机构的设计中螺旋是一个关键,还有一个关键,将硬币一个一个分开并且按顺序放入螺旋提升机构中。运作流程:传送带将硬币输送过来进入分料盘,底部震动电机工作,将硬币散开防止堆叠,两侧边推板工作使硬币一个进入窄道,这时分拨块起作用了,将列队好的硬币一个一个按齿轮转动的时序,依次进入螺杆提升机构。
传送带机构是整个装置的采集机构,负责吸取地面上的硬币,往机器内部输送,整个动作很像采集矿物的车辆,故命名“采矿车”。传送带机构包含了拉紧机构、旋转机构和驱动机构,拉紧机构完成传送带的拉紧与驱动机构密切配合实现了传送带旋转,旋转机构与底座相连,实现了传送带上下旋转运动。运转原理:电机带动传送带旋转,头部的光轮也一并旋转,光轮内部安装磁铁,使硬币吸上传送带,传送带上有磁性橡胶条,使硬币不会掉落,平稳进入机器内部。
传送带升降机构主要用于传送带的升降功能,安装在传送带的下方,将传送带头部支撑起来,形成三角形,类似于千斤顶的原理,当机构伸出时,传送带往上抬高,反之亦然。传送带升降机构内置了一根M3螺杆,末端安装了一个N20减速电机,电机带动螺杆旋转,螺杆推动螺母,螺母连接了顶出杆,实现千斤顶的效果。安装面设计了排孔方便调节伸缩的距离,顶出杆尾部设计了限位柱,当达到限位距离后触发限位开关停止运动。
履带结构比较复杂,使用CAD进行设计,用激光切割加工,外形设计采用了“赛博”风格,底部有4对负重轮,中间有一个驱动轮和一个导向轮,顶部有一个张紧轮,连接部分设计了悬挂结构,可以适应不平的路面,链条齿数共有52个。
外壳部分多采用亚克力覆盖,分为前盖部分、中间部分、后盖部分。前盖和后盖设计成可上翻结构,表面覆盖透明亚克力板,中间部分安装有12864显示屏和按键开关,顶部安装信号天线,3D打印部分采用镂空设计,设计风格沿用“赛博”风格与双侧履带相统一。
四、组装过程
程序、电路、机械都已经讲解完毕,最后是组装过程。在组装过程中,大家可以跟随我的脚步,一起还原整个项目结构和细节。
当然整个装置还处于初代机阶段,在结构设计中,还有很多可以改进的地方。
最开始先组装核心机构的基座,用来固定硬币旋转机和硬币提升机构。
组装硬币旋转机部分,正在安装主动力凸轮轴。
固定硬币旋转机电机座,电机动力输出一拖三,用齿轮分成三路输出驱动齿轮。
左路动力输出用齿轮连接到齿轮齿条,推动硬币往前运动。
装上亚克力管收集器和霍尔传感器,完成了硬币旋转机的组装。
将硬币旋转机与基座固定,整理传感器线,用线卡固定。
组装螺杆提升机构、进料盘的底部齿轮和震动电机,需要注意分拨块的旋转位置要同步。
安装后部连接支架和WS2812灯带。
安装螺杆尾部进料传感器,固定硬币提升机构。
组装好传送带机构,调节好传送带的松紧度。
把传送带机构固定在基座上。
制作传送带升降模块电路,用到了L9110H驱动芯片,控制电机的正反转。
组装传送带升降模块,顶出杆尾部有限位柱,两端各安装有限位开关,当触发开关后相对应的旋转信号断开使运动停止,实现可控距离伸缩。
将传送带升降模块固定在传送的两端,当升降模块伸出时,传送带抬高。
用万用板制作Arduino控制板,所有连接均采用HX接插头形式,主要是为了方便拆卸和调试,其余的电源和MOS管全部集成在控制板上。
安装Arduino控制主板,连接传感器接头。
上篇结束。
由于篇幅有限,小编将这个项目分成上下篇章。有请期待。。。