大家好,去年,一位客户在其工业设施的出入口安装了安全路桩,并要求我设计一个电子系统,以便通过控制塔经由 TCP/IP 控制这些路桩。
本教程描述了我所遵循的过程,从初步构思、制作原型,到最终交付给客户的版本。
为工业用途设计设备需要精心准备,并且必须使用经批准用于工业用途的材料和组件进行构建。
在本教程中,我将重点介绍使原型与具有商业或工业质量的产品之间产生差异的关键点。
虽然从技术角度来看,问题的解决方案简化为控制一对继电器,而且我们在市场上可以找到无数现成的此类产品。但制作定制产品和满足客户需求是一个稍微复杂的过程。
对我来说,区分原型和商业版本质量的关键在于图形用户界面(GUI)的设计,这也是本教程中将详细介绍的部分。
这里展示的想法可以修改并适应任何可以通过继电器控制的机电设备:水泵、车库门、百叶窗、电动门等。
如果您有改进建议,请告诉我。
让我们开始吧。
第一步:背景
“路桩是一种短柱,用于创建防护或建筑围栏。当主要作为视觉引导安装时,路桩可以引导交通并标记边界。它们有各种各样的形状和风格,以突出或在其环境中视觉上脱颖而出。路桩也可以设计成物理上阻止车辆入侵,保护人员和财产。这些安全路桩可能具有装饰元素,或被选择以与景观相协调,但其主要考虑因素是抗冲击力。路桩可以由几乎任何材料制成,具体取决于其所需功能,但最常见的路桩材料是金属、石头、水泥或塑料。”
“自动路桩”
“这种类型的路桩也称为上升式或伸缩式路桩。这些是可伸缩的安全岛护柱,它们可以升出地面以阻挡交通,或者收回地面以让交通通过。大多数能在几秒钟内伸展到最大高度,是管理交通和保护行人安全的一种有效、灵活的方式。自动系船柱可由气动、液压或电动控制。这种选择通常取决于特定地点的应用和用途。这些护柱由碳钢或不锈钢制成,通常有多种不同的表面。自动路桩永久安装在地下,需要定期维护。自动安全岛路桩的主要用途自动安全岛路桩非常适合交通流量不断变化的情况,入口和出口可能会随时发生变化。自动路桩的实际应用的一个例子可能是停车库或停车场。它们也非常适合用在博物馆、动物园或其他公共设施的入口处,这些地方在特定时间后禁止进入。”
第二步:客户访谈
在研究了所有关于路桩的信息后,我要求与客户进行第一次访谈,以收集能让我了解客户需求的信息。
在与客户会面前,准备一份简要的技术规格书,说明项目构想,以便客户对他将要接收的产品有一个大致的了解。
接下来,向客户询问以下信息:
路桩的品牌和型号
路桩安装手册的副本
要安装的路桩数量
路桩的安装位置
如何以及由谁控制设施的出入口
设施和设备的标识或名称
所需控制系统的要求
系统交付时间
第三步:分析客户信息 - (内容)
客户向我提供了要安装的路桩的品牌和型号及其手册。
客户型号是带有液压驱动的 Access PRO Bollard XB220H06K。该路桩有一个控制箱,用于处理液压泵和一个执行上下移动的活塞。活塞有两个限位开关,一个位于完全缩回位置,另一个位于完全伸出位置,用于向控制系统指示其位置。它还有两个连接口,用于放置手动操作键盘。阅读手册后,确定了手动键盘的连接点,以及缩回位置的限位开关。
第四步:分析客户信息 - (位置)
客户场所的两个出入口控制区将安装 7 个路桩。主出入口控制区(ACCESS AREA “A”)由三条车辆通行路线组成:一条入口路线和一条出口路线,每条路线各有三个出入口车道。该区域将安装 4 个路桩:入口区 2 个,出口区 2 个。
第二个出入口控制区(ACCESS AREA “B”)由三条单车道通行路线组成:一条入口、一条出口和一条双向路线。该区域将安装 3 个路桩。
出入口控制亭之间的距离为一公里。
根据这些数据,为每个路桩分配了一个 ID。该标识由客户制定:
ACCESS AREA "A"
入口区:
路桩1 ID: CAS01-B01-EA
路桩2 ID: CAS01-B02-ET
出口区:
路桩3 ID: CAS01-B03-ST
路桩4 ID: CAS01-B04-SA
ACCESS AREA “B”
入口区:
路桩5 ID: CAS02-B01-SA
出口区:
路桩6 ID: CAS02-B02-ST
双向区:
路桩7 ID: CAS02-B03-E/S-AT
第五步:分析客户信息 - 具体要求
客户需要一个通过以太网通信网络使用 TCP/IP 通信协议操作路桩的控制系统。该控制系统必须有一个手动键盘,以便在控制系统或通信网络出现故障时能够本地操作系统。图形用户界面(GUI)必须友好且易于使用,并且必须能够监控每个路桩的状态,以及指示温度、可用内存和所提供控制系统的状态。
控制系统必须有一个触摸屏,以便能够本地操作系统。
设备将放置在出入口控制亭内。
完成项目的时间为 40 天。
为了下订单,客户需要评估一个原型。
第六步:构思
在分析了客户数据后,下一步是选择一个能够高效、快速且优雅地执行所有所需任务的微控制器。我选择使用树莓派 3B+,因为我之前曾使用该微控制器和 NODE RED 编程过一个移动机器人。因此,下一步是确定系统架构。是使用一个树莓派控制所有路桩,还是为每个路桩使用一个树莓派。我决定采用一个中间点,即为每 3 个路桩设计一个控制箱。
考虑到这些因素,基本设计如下:
一个带有 3.5” LCD 触摸屏的树莓派、一个 8 通道 5V 继电器模块、一个 5 VDC 电源和用于电气连接的接线端子,所有这些都放置在一个具有 IP65 防护等级的 ABS 塑料外壳中。
基本想法确定后,是时候规划接下来的步骤了:
采购材料
在树莓派上安装软件
编写路桩控制程序
构建客户评估原型
第七步:原型部件和工具
部件:
树莓派 3B+
树莓派 3.5" LCD 触摸屏
8 通道 5V 继电器模块
5 VDC / 3 AMP 墙插电源
DIN 导轨
接线端子(Weidmuller 1020100000 WDU 4)
表面式双孔插头 EG78V
ABS NEMA IP66 外壳
AWG 14 电缆
工具:
电烙铁
螺丝刀
第八步:软件:RASPBIAN 安装
在本节中,我将向您展示如何为树莓派安装操作系统。不过,我不知道您是树莓派专家还是初学者。
如果您是专家,本节可能对您没有太大帮助,您可以直接跳到 GUI 设计部分。但如果您是初学者,那么最好与专家一起学习。因此,我建议您下载《官方树莓派初学者指南》杂志。
杂志的“附录 A”介绍了如何在 micro SD 存储卡上安装操作系统。
第九步:软件:NODE RED 安装
Node-RED 是一种编程工具,用于以新颖有趣的方式将硬件设备、API 和在线服务连接在一起。
它提供了一个基于浏览器的编辑器,可以轻松使用调色板中的各种节点连接流程,并可以一键部署到运行时。
Node-RED 提供了一个基于浏览器的流程编辑器,可以轻松使用调色板中的各种节点连接流程。流程可以一键部署到运行时。
可以在编辑器中使用富文本编辑器创建 JavaScript 函数。内置库允许您保存有用的函数、模板或流程以供重用。
NODE RED 安装:
我们希望 Node-RED 在树莓派启动或重启时运行。通过运行以下命令启用服务自动启动:
sudo systemctlenablenodered.service
为了在树莓派启动时在浏览器中运行程序,请在终端中输入:
$sudo nano .bashrc
并在文件末尾添加以下内容:
chromium-browser —kiosk127.0.0.1:1880/ui/#!/1
第十步:FRED:Node Red 的字体编辑器
我们已经完成了树莓派和 Node-RED 的安装。
我们可以继续在树莓派上工作,但出于重要原因,我们建议在外部计算机上继续开发程序,并在程序准备好并调试完成后,再将其迁移到树莓派上。使用独立开发计算机的原因包括:
1.这是我们正在开发的商业产品,因此我们希望树莓派上只有客户端程序代码,没有其他内容。
2.在程序开发过程中,我们通常会下载大量额外的软件来开发程序和测试代码,我们不希望这些程序出现在客户端的树莓派上。
3.在开发阶段,我们会进行大量在线查询,我们不希望所有这些数据流、cookie、下载等出现在树莓派上。
我在 Node-RED 中使用的开发工具是 FRED。
如果您还没有 FRED(Cloud Node-RED)账户,请立即注册一个。演示账户是免费的,可用于本教程和您可能进行的任何其他实验。在http://fred.sensetecnic.com注册免费账户。
注册后,请务必通过电子邮件激活您的账户。在验证账户之前,您将无法登录。
虽然 FRED 没有树莓派的 GPIO 组件,但这些组件可以模拟:rpi-gpio in 节点可以用 inject 输入节点模拟,rpi-gpio out 节点可以用 debug 输出节点模拟。
不过,您无需安装 FRED,也可以继续在树莓派的 Node-RED 上工作。
第十一步:软件:图形用户界面(GUI)
我们已经安装了操作系统和 NODE RED 编程软件,现在可以开始编写构成程序的代码行了。但想法是什么?我们从哪里开始?虽然从硬件角度来看,系统非常简单:一个控制继电器的树莓派,但项目中最长且最复杂的部分是图形界面设计。
通过 TCP/IP 控制路桩的最简单方法是使用 NODE RED 的开关组件。然而,这并不是交付 GUI 设计的专业和商业方式。我决定以最真实的方式进行图形控制,因此设计了一个可以动画显示的路桩图像,模拟其升降,并用颜色指示路桩状态:
红色:表示路桩正在升起或处于完全伸出位置。
绿色:表示路桩已完全缩回。
动画通过位于界面顶部和底部的两个按钮激活。顶部按钮为红色,标有“UP”(升起),底部按钮为绿色,标有“DOWN”(降下)。我使用了 NODE RED 的 TEMPLATE 节点,其中嵌入了 CSS 和 HTML 程序源代码。为了更好地理解这部分代码,让我们看看它的三个主要部分:“style”(CSS)、“body”和“script”。
第十二步:GUI - “style” 部分
CSS 是一种描述 HTML 文档样式的语言。
CSS 描述了 HTML 元素应如何显示。
CSS 可以通过三种方式添加到 HTML 元素中:
内联:通过在 HTML 元素中使用 style 属性。
内部:通过在 “head” 部分使用 “style” 元素。
外部:通过使用外部 CSS 文件。
我们将使用内部方式:
查看此 CSS 教程,您将找到所有属性和选择器的完整 CSS 参考,包括语法、示例、浏览器支持等。
https://www.w3schools.com/html/html_css.asp
查看此教程,了解如何一劳永逸地理解 CSS 绝对定位。
https://www.freecodecamp.org/news/how-to-understand-css-position-absolute-once-and-for-all-b71ca10cd3fd/
要更好地了解在 “style” 部分中可以定义的图形,请查看以下链接。
https://css-tricks.com/the-shapes-of-css/
分析组件
仔细观察图形,绘制了构成图形界面的组件,然后我将详细介绍每个组件的代码。
要定义绿色按钮(降下按钮),我们使用以下代码:
.buttonGreen_B1{ background-color:#4CAF50;/* Green */ border: none; color: white; padding:15px32px; text-align: center; text-decoration: none; display: inline-block; font-size:16px; margin:4px2px; cursor: pointer;}
要定义红色按钮(升起按钮),我们使用以下代码:
.buttonRed_B1{ background-color:#f44336;}/* Red */
要定义包含所有元素的主矩形,我们使用以下代码:
#container_B1{ top:0px; left:0px; width:120px; height:460px; position: relative; background-color:#333333;}
要定义路桩的形状,我们使用三个矩形(# r1_B1、# r2_B1 和 # r3_B1)。
要定义矩形 # r1_B1,我们使用以下代码:
#r1_B1{ display: inline-block; top:10px; left:25px; width:72px; height:10px; position: absolute; border:1pxsolid black; background-color:#f44336;}
要定义矩形 # r2_B1,我们使用以下代码:
#r2_B1{ top:10px; left:2px; width:66px; height:10px; position: absolute; border:1pxsolid black; background-color:#aaaa44;}
要定义矩形 # r3_B1,我们使用以下代码:
#r3_B1{ display: inline-block; top:10px; left: -2px; width:70px; height:200px; position: absolute; border:1pxsolid black; background-color:#f44336;}
要模拟路桩的 LED 灯,我们使用六个点(#dot1_B1 到 #dot6_B1),我使用以下代码:
#dot1_B1{ display: inline-block; top:2px; left: 5px; height:3px; width:3px; position: absolute; border-radius:100%; border:2pxsolid yellow; background-color:#ff0000;}#dot2_B1{ display: inline-block; top:2px; left: 15px; height:3px; width:3px; position: absolute; border-radius:100%; border:2pxsolid yellow; background-color:#ff0000;}#dot3_B1{ display: inline-block; top:2px; left: 25px; height:3px; width:3px; position: absolute; border-radius:100%; border:2pxsolid yellow; background-color:#ff0000;}#dot4_B1{ display: inline-block; top:2px; left: 35px; height:3px; width:3px; position: absolute; border-radius:100%; border:2pxsolid yellow; background-color:#ff0000;}#dot5_B1{ display: inline-block; top:2px; left: 45px; height:3px; width:3px; position: absolute; border-radius:100%; border:2pxsolid yellow; background-color:#ff0000;}#dot6_B1{ display: inline-block; top:2px; left: 55px; height:3px; width:3px; position: absolute; border-radius:100%; border:2pxsolid yellow; background-color:#ff0000;}
要定义路桩外壳,我们使用两个矩形(# r4_B1 和 # r5_B1)。
要定义矩形 # r4_B1,我们使用以下代码:
#r4_B1{ top:214px; left:5px; width:110px; height:10px; position: absolute; border:1pxsolid black; background-color:#666666;}
要定义矩形 # r5_B1,我们使用以下代码:
#r5_B1{ display: inline-block; top:225px; left:22px; width:82px; height:218px; position: absolute; border:1pxsolid black; background-color:#443333; }
我们已经完成了 CSS 部分的编写,现在让我们进入 body 部分...
第十三步:GUI - "body" 部分
body 部分包含三个重要部分:
1.UP 和 DOWN 按钮的定义。
UP 按钮具有以下源代码:
class="buttonGreen_B3 buttonRed_B3"onclick="myMoveUp_B3()"ng-click="send({payload: 2})”>__UP__
DOWN 按钮具有以下源代码:
2.div 标签:在 HTML 文档中定义一个分区或部分。
div 元素通常用作其他 HTML 元素的容器,以便使用 CSS 对其进行样式设置,或使用 JavaScript 执行某些任务。
然后,此标签用于包含路桩的所有元素:
3.script 部分,我们将在下一步中看到。
第十四步:GUI - "script" 部分
此部分有三个重要函数:负责获取外部输入值(GPIO IN)的 function(scope) 函数:
(function(scope) {scope.$watch('msg.payload',function(newValue1,oldValue1) { console.log('BOLLARD 1'); console.dir(newValue1); if(newValue1===oldValue1) { dos1(oldValue1); }else{ uno1(newValue1); } }); })(scope); functionuno1(bale1){ if(bale1 ==true){ console.dir('TRUE b1:'+bale1); myMoveUp_B1(); }else { console.dir('FALSE b1:'+bale1); myMoveDown_B1(); } } functiondos1(gale1){ console.dir('DOS b1:'+gale1); }
myMoveDown_B1() 函数,用于降下路桩:
varaltura_B1 =0;functionmyMoveDown_B1() { varelem =document.getElementById("r1_B1"); varpos =0; varid =setInterval(frame,5); functionframe() { if(altura_B1 >=214) { clearInterval(id); elem.style.backgroundColor="#4CAF50"; varelem1 =document.getElementById("r1_B1"); elem1.style.backgroundColor="#4CAF50"; }else{ altura_B1++; elem.style.top= altura_B1 +'px'; elem.style.left=10; elem.style.backgroundColor="#f44116"; } }}
myMoveUp_B1() 函数,用于升起路桩:
functionmyMoveUp_B1() { varelem1 =document.getElementById("r1_B1"); elem1.style.backgroundColor="#f44116"; varelem =document.getElementById("r1_B1"); varpos =220; varid =setInterval(frame,5); functionframe() { if(altura_B1 ==0) { clearInterval(id); }else{ altura_B1--; elem.style.top= altura_B1 +'px'; elem.style.left=10; elem.style.backgroundColor="#f44116"; } }}
第十五步:整合所有部分 - TEMPLATE 节点
现在是时候将所有代码整合在一起了。在一个 TEMPLATE 节点中,放置以下代码: