1. 项目缘起当工业边缘计算遇上开源自动化最近在折腾一个工业数据采集与可视化的项目手头正好有一台倍福Beckhoff的Edge Box RPi 200。这玩意儿本质上是个基于树莓派CM4模块的工业级边缘控制器接口丰富皮实耐造非常适合放在车间现场。项目需求很明确把产线上几台支持Modbus TCP协议的设备比如温控器、流量计的数据实时采集上来然后做点简单的逻辑处理最后推送到上位机或者Web面板进行监控。要实现这个目标摆在我面前的有几条路用倍福自家的TwinCAT 3写PLC程序那是老本行但开发调试对于快速原型来说有点重用Python写脚本灵活是灵活但数据流管理和可视化又得额外折腾。这时候Node-RED进入了我的视线。它是一个基于流的低代码编程工具用“节点”和“连线”就能构建应用特别适合处理这种设备连接、数据处理和API集成的场景。最关键的是它原生支持Modbus社区节点丰富而且能直接跑在Edge Box RPi 200这个Linux系统上。于是一个“Edge Box RPi 200 Node-RED Modbus TCP”的技术栈组合就成型了。这个组合的魅力在于它用轻量级的开源工具实现了传统工业自动化领域里需要专用软件和控制器才能完成的任务特别适合中小型项目、快速验证和运维人员的自主开发。下面我就把这次从环境搭建、节点配置到实际应用踩过的坑和总结的经验详细分享一下。2. Edge Box RPi 200你的工业级树莓派工作站在开始软件部署之前有必要先了解一下我们的硬件平台——Edge Box RPi 200。它不是一台普通的树莓派而是倍福将其工业化的产物理解它的特点能让后续的配置事半功倍。2.1 硬件规格与接口定位Edge Box RPi 200的核心是树莓派Compute Module 4CM4这意味着它拥有树莓派的基因但形态和接口是针对工业环境设计的。我手头这台配置是CM4带eMMC存储的版本省去了SD卡可靠性更高。其接口堪称豪华双千兆以太网口这是它作为边缘网关的利器。一个口通常eth0可以接入工厂局域网用于连接Modbus TCP设备或与上位机通信另一个口eth1可以配置为独立的网络用于设备直连或实现网络隔离非常符合工业现场的网络规划需求。USB、RS232、RS485接口提供了连接串口设备如Modbus RTU设备的可能扩展性很强。DIO数字输入输出可以直接连接一些开关量传感器或控制指示灯虽然本项目主要用网络通信但这个功能为未来集成更多本地信号留下了伏笔。坚固的金属外壳和DIN导轨安装可以直接卡在配电柜的标准导轨上适应振动、粉尘和电磁干扰相对较差的工业环境。从软件角度看它预装了倍福定制的Linux系统基于Raspberry Pi OS。系统已经做了一些优化比如实时性增强但本质上你可以把它当作一个带有强大工业接口的、运行Linux的迷你电脑。这是我们能安装并运行Node-RED的基础。2.2 系统初始化与网络配置设备上电通过HDMI接口接上显示器或者更常用的通过eth0口用SSH连接首次启动会进行一些初始化。这里有一个关键步骤网络配置。由于我们要用Modbus TCP设备IP地址的稳定性至关重要。我建议为Edge Box RPi 200设置一个静态IP地址而不是依赖DHCP。在工业网络中固定的IP便于管理和寻址。修改网络配置通常通过编辑/etc/dhcpcd.conf文件实现具体方法因镜像版本可能略有不同。例如为eth0设置静态IP# 在 /etc/dhcpcd.conf 文件末尾添加 interface eth0 static ip_address192.168.1.100/24 static routers192.168.1.1 static domain_name_servers8.8.8.8配置完成后重启网络服务或直接重启设备。之后你就可以通过ssh pi192.168.1.100默认用户pi密码请参考倍福文档稳定地连接到设备了这是所有后续操作的起点。注意倍福的镜像可能禁用了默认的pi用户或使用了不同密码请务必查阅设备随附的文档。如果找不到尝试通过显示器和键盘本地登录查看。2.3 环境准备更新系统与安装必要工具在安装Node-RED之前先确保系统是最新的并安装一些常用的工具会让后续过程更顺畅。# 1. 更新软件包列表和系统 sudo apt-get update sudo apt-get upgrade -y # 2. 安装一些常用工具非必须但推荐 sudo apt-get install -y curl wget git vim # 3. 安装Node.js和npm # Node-RED需要Node.js环境。Edge Box RPi 200的官方镜像可能已预装但版本可能较旧。 # 查看当前版本 node --version npm --version # 如果未安装或版本过低建议使用NodeSource的仓库安装LTS版本 curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt-get install -y nodejs确保Node.js版本在14以上Node-RED v3.x推荐使用Node.js 16或18 LTS版本。完成这些我们的硬件和基础软件平台就准备好了。3. Node-RED在边缘盒上的部署与优化有了准备好的Linux系统安装Node-RED本身非常简单。但如何将它配置成一个稳定、自启动的生产级服务并管理好其节点生态这里面有些细节需要注意。3.1 安装Node-RED的推荐方式不推荐直接通过npm install -g node-red进行全局安装因为权限管理和服务化会有点麻烦。官方推荐使用脚本安装它会处理好Node-RED的安装、将其设置为系统服务以及安全更新。# 执行官方安装脚本 bash (curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)这个脚本会做几件事1) 确保Node.js版本合适2) 将Node-RED安装到~/.node-red目录下以当前用户运行3) 询问你是否将其设置为自启动的系统服务。这里一定要选择“是”这样设备重启后Node-RED也会自动运行。安装完成后Node-RED服务就已经启动了。默认情况下它运行在1880端口。你可以在同一局域网的电脑浏览器上访问http://Edge_Box_IP:1880来打开Node-RED的流编辑器界面。3.2 配置为可靠的生产服务安装脚本创建的服务虽然能用但我们可以进行一些优化让它更适应工业边缘环境。首先修改服务配置文件。Node-RED的系统服务文件通常是/lib/systemd/system/nodered.service。我们需要调整运行用户和部分参数。假设我们一直用pi用户操作sudo systemctl stop nodered sudo systemctl disable nodered # 备份原文件 sudo cp /lib/systemd/system/nodered.service /lib/systemd/system/nodered.service.backup # 编辑文件将User和Group改为你的用户名例如 pi sudo vim /lib/systemd/system/nodered.service # 找到 User 和 Group 行进行修改同时可以在[Service]部分添加环境变量例如设置一个更友好的工作目录或调整内存限制对于CM4内存有限需注意EnvironmentNODE_OPTIONS--max-old-space-size256保存后重新加载systemd并启用服务sudo systemctl daemon-reload sudo systemctl enable nodered sudo systemctl start nodered sudo systemctl status nodered # 检查状态应为active (running)其次考虑数据持久化与备份。Node-RED的流Flows和配置默认保存在~/.node-red目录下。其中flows.json文件就是你的所有逻辑。务必定期备份这个文件你可以写一个简单的cron任务将它备份到其他位置。此外settings.js文件包含了运行时配置如安全认证、编辑器主题等根据需求调整。3.3 安装与管理Modbus节点Node-RED的强大在于其节点库。我们需要安装Modbus相关的节点。在Node-RED编辑器中点击右上角的菜单三条横线-“节点管理”-“控制面板”-“安装”然后搜索“modbus”。这里你会看到好几个Modbus节点包。最常用、功能最全的是node-red-contrib-modbus这个包它由biancode维护。它包含了Modbus TCP客户端/服务器、RTU串口、Flex Getter/Setter等多种节点足以满足绝大多数工业协议需求。点击“安装”按钮等待完成。安装完成后在节点面板的左侧你会发现多了一个“modbus”分类里面包含了各种Modbus节点。至此Node-RED的软件和核心节点就绪了。4. Modbus TCP通信原理与节点深度配置在动手连接节点之前我们需要对Modbus TCP协议在Node-RED中的实现方式有个清晰的认识这能帮助我们在配置时避免很多低级错误。4.1 Modbus TCP协议简析与地址映射Modbus TCP可以看作是Modbus RTU协议跑在TCP/IP网络上它使用了标准的502端口。其报文结构在RTU的基础上加了一个MBAP头Modbus Application Protocol header。但对于Node-RED用户来说我们更关心的是数据模型和地址映射。Modbus设备将数据存放在四种不同的“寄存器”区线圈Coils地址0xxxx可读可写的布尔量1位对应开关量输出。例如控制一个继电器的开合。离散输入Discrete Inputs地址1xxxx只读的布尔量1位对应开关量输入。例如读取一个限位开关的状态。保持寄存器Holding Registers地址4xxxx可读可写的16位整数字。这是最常用的区域可以存放各种整型数据也可以通过约定存放浮点数占用两个连续的寄存器。例如PLC中的设定值、运行速度等。输入寄存器Input Registers地址3xxxx只读的16位整数字。通常用于存放模拟量输入值如温度、压力传感器的实时值。这里有一个关键点也是新手最容易混淆的地方Modbus协议地址和Node-RED及很多软件中使用的“数据地址”通常是基于0的偏移量而设备手册上标注的地址常常是基于1的“协议地址”。例如设备手册上说“温度值存放在保持寄存器40001”。那么协议地址40001数据地址偏移量40001 - 40001 0 对于4xxxx区域通常用减去40001的方式得到偏移量在node-red-contrib-modbus的“读保持寄存器”节点中你需要填写的“地址”Address就是0。同理对于线圈0xxxx区域地址00001对应偏移量0对于输入寄存器3xxxx区域地址30001对应偏移量0。务必在配置前仔细查阅你的设备手册并做好这个转换。4.2 Modbus Flex Getter节点的核心配置node-red-contrib-modbus提供了多种节点我最推荐使用Modbus Flex Getter节点进行数据读取。它功能强大配置灵活可以一次读取多个不同地址、不同类型的数据。双击一个Modbus Flex Getter节点其配置主要分为三块Server服务器这里不是指你的Node-RED是服务器而是指你要连接的Modbus TCP设备从站。你需要先配置一个Modbus Client节点作为“服务器”定义。点击笔形图标新建一个关键参数如下Type: TCPHost: 你的Modbus设备IP地址例如192.168.1.50Port: 默认502Unit ID: 从站地址Slave ID。对于很多Modbus TCP设备这个值就是1但也有些设备需要特定的ID请查阅设备手册。Reconnect Timeout: 重连超时建议设置为2000毫秒或更长以适应不太稳定的工业网络。Read/Write Properties读写属性FCFunction Code功能码。例如Read Holding Registers (FC3)就是读保持寄存器。根据你要读的数据类型选择。Address数据地址偏移量如上文所述。例如要读设备手册上的40001这里填0。Quantity要读取的寄存器数量。注意一个16位寄存器是2个字节。如果要读一个32位浮点数占2个寄存器Quantity就是2。Polling轮询这是实现定时采集的关键。Poll Rate轮询频率单位毫秒。例如1000表示每秒读一次。不宜设置过快以免对设备造成过大负载。对于大多数工业场景500ms到2000ms的间隔是合理的。Use Poll Interval务必勾选否则节点不会自动轮询需要外部触发。配置好这些这个节点就会按照设定的频率自动向指定的Modbus设备请求数据并将结果以JavaScript对象的形式输出到msg.payload。4.3 数据处理与消息流构建Modbus Flex Getter节点输出的msg.payload通常是一个Buffer或数组。我们需要将其转换为可读的数据。通常后面会连接一个function节点或change节点进行数据处理。例如读取一个保持寄存器地址0即40001的值它是一个16位无符号整数。在function节点中// msg.payload 可能是一个Buffer如 Buffer 00 0a // 使用Modbus节点自带的解析方法或者直接转换 let rawValue msg.payload.readUInt16BE(0); // 大端序读取 msg.payload { address: 40001, value: rawValue, timestamp: new Date().toISOString() }; return msg;如果要读取一个浮点数占用地址0和1则需要将两个16位寄存器组合let buffer msg.payload; // 假设是4字节Buffer // 假设设备使用大端序Modbus通常是大端序 let intValue (buffer[0] 8) | buffer[1]; // 高字 let fracValue (buffer[2] 8) | buffer[3]; // 低字 // 或者使用DataView进行更标准的解析 let view new DataView(buffer.buffer); let floatValue view.getFloat32(0, false); // false 表示大端序 msg.payload floatValue; return msg;处理后的数据可以连接到debug节点查看也可以发送到dashboard节点组进行可视化或者通过MQTT out节点发布到消息服务器实现数据的上云或跨系统传输。5. 构建一个完整的边缘数据采集与监控流程理论说再多不如一个实际的例子来得直观。假设我们要监控一台工业烤箱它通过一个Modbus TCP网关暴露了以下数据点当前温度只读存放在输入寄存器30001偏移量0数据类型为32位浮点数。设定温度可读写存放在保持寄存器40001偏移量0数据类型为16位整数。加热器状态只读存放在线圈00001偏移量0布尔量。我们的目标是每秒读取一次当前温度和加热器状态在面板上显示并提供一个滑块可以远程修改设定温度。5.1 流程设计与节点连接在Node-RED编辑器中我们拖拽节点构建如下流程Modbus Client配置节点一个即可指向烤箱网关的IP和端口。Modbus Flex Getter (FC4)用于读取当前温度输入寄存器。配置Server为上一步的ClientAddress0, Quantity2因为浮点数占2个寄存器Poll Rate1000ms。Modbus Flex Getter (FC1)用于读取加热器状态线圈。配置相同的ServerAddress0, Quantity1, Poll Rate1000ms。两个Function节点分别接在两个Getter后面用于解析数据。温度解析函数如上节所述将两个寄存器转换为浮点数线圈状态解析则判断msg.payload[0]是否为真。Dashboard UI节点拖入两个gauge仪表节点分别连接温度解析和状态解析的输出用于显示实时值。状态仪表可以设置颜色比如绿色为“运行”红色为“停止”。拖入一个slider滑块节点和一个button按钮节点到画布上它们属于UI输入元件暂时不连线。拖入一个Modbus Flex Setter节点用于写入设定值。配置Server为同一个ClientFC写单个保持寄存器(FC6)Address0。写入逻辑将slider节点和button节点连接到一个function节点。这个函数节点负责在按钮按下时获取滑块的数值并构造给Modbus Flex Setter节点的消息。Setter节点需要msg.payload包含要写入的值。// 当按钮被按下时msg.payload是按钮的配置我们需要取滑块的值 // 这里假设滑块节点的id是“setpoint_slider”我们需要用context或flow变量来传递 // 更简单的方法将滑块和按钮连到同一个function节点判断消息来源 if (msg.topic setpoint_change) { // 来自滑块的消息我们只更新一个临时变量不立即写入 flow.set(targetTemp, msg.payload); return null; // 不向下传递 } if (msg.topic write_trigger) { // 来自按钮的消息执行写入操作 let valueToWrite flow.get(targetTemp) || 150; // 默认值 msg.payload valueToWrite; return msg; // 传递给Modbus Setter }然后配置滑块节点在其“主题Topic”属性中填写setpoint_change按钮节点的主题填写write_trigger。这样滑动滑块只改变内存变量点击按钮才真正下发写入命令避免了网络频繁写操作。5.2 Dashboard的布局与部署点击Node-RED右上角的菜单打开“Dashboard”侧边栏。在这里你可以创建标签页Tabs比如“烤箱监控”。创建分组Groups在标签页下创建分组如“实时数据”、“参数设置”。将UI节点分配到分组编辑每个gauge、slider、button节点在“Group”下拉框中选择刚才创建的分组。你还可以设置它们的尺寸Width/Height以调整布局。布局完成后访问http://Edge_Box_IP:1880/ui就能看到专属的监控面板了。这个面板是响应式的在手机或平板上也能良好显示。5.3 流程的调试与错误处理在实际运行中流程可能会因为网络抖动、设备响应超时等问题出错。Node-RED提供了catch节点来捕获流程中其他节点抛出的错误。你可以将一个catch节点拖入画布它会自动订阅所有节点的错误。将其输出连接到一个debug节点或者一个可以发送警报的节点如email节点或telegram节点这样就能实时知晓系统异常。对于Modbus通信node-red-contrib-modbus节点在出错时通常会在msg.error属性中携带错误信息。你可以在catch节点后面的function节点里分析msg.error区分是连接失败、超时还是非法地址并做出不同的处理比如重试、记录日志或升级报警。6. 进阶应用性能优化、安全与维护当基本流程跑通后我们需要考虑如何让这个边缘系统更健壮、更安全、更易于维护。6.1 性能优化与资源管理Edge Box RPi 200的CM4模块内存和CPU资源有限通常1GB或2GB内存在运行Node-RED并处理多个Modbus轮询时需要注意控制轮询频率不要将所有设备的轮询周期都设为100ms。根据数据变化快慢分级关键数据快如500ms一般数据慢如2s、5s。使用Inject节点配合stoptimer可以实现更复杂的定时逻辑比如只在设备运行时高频采集待机时低频采集。合并请求如果可能使用Modbus Flex Getter的“Read Multiple”功能一次读取多个连续的寄存器而不是为每个数据点建立一个单独的Getter节点。这能大幅减少请求次数和网络开销。流的结构化对于大型项目不要把所有逻辑都放在一个巨大的流里。使用子流程Subflow功能将通用的功能如“解析32位浮点数”、“错误处理模板”封装起来使主流程更清晰也便于复用。监控Node-RED自身安装node-red-dashboard的template节点可以展示系统信息。或者使用node-red-contrib-moment节点定期将内存使用情况、活动连接数等信息通过debug输出或记录到文件。6.2 安全加固措施默认安装的Node-RED编辑器1880端口和Dashboard界面1880/ui是对外开放的这在工业网络中存在风险。启用用户认证这是最重要的步骤。编辑~/.node-red/settings.js文件找到adminAuth部分取消注释并进行配置adminAuth: { type: credentials, users: [{ username: admin, password: $2b$08$YourHashedPasswordHere, // 使用 node-red-admin hash-pw 命令生成 permissions: * }] },使用命令node-red-admin hash-pw生成密码的bcrypt哈希值替换上面注释部分。重启Node-RED后访问编辑器就需要登录了。Dashboard认证在settings.js中同样可以配置ui: { path: ui, middleware: (req, res, next) { ... } }通过中间件来为/ui路径添加认证或者依赖反向代理如Nginx来做HTTP基础认证。使用HTTPS如果数据敏感考虑配置HTTPS。这需要在settings.js中配置https选项并提供证书和私钥。防火墙限制在Edge Box RPi 200上使用ufw或iptables防火墙只允许特定的管理IP地址访问1880端口。例如sudo ufw allow from 192.168.1.10 to any port 1880 proto tcp # 只允许IP为192.168.1.10的电脑访问 sudo ufw enable6.3 备份、版本控制与持续集成将Node-RED的流当作代码来管理是一个好习惯。手动备份定期备份~/.node-red目录尤其是flows.json。可以写一个简单的shell脚本用scp或rsync同步到远程服务器。使用Git将~/.node-red初始化为一个Git仓库每次对流程做重大修改后都进行提交。这样你可以清晰地看到历史变更并且可以轻松地回滚到任何一个版本。cd ~/.node-red git init git add flows.json settings.js package.json git commit -m Initial commit of oven monitoring flow项目化部署对于更复杂的项目可以考虑使用Node-RED的“项目”Project功能。项目将流、依赖的节点、README文件等组织在一起更适合团队协作和版本管理。你可以在编辑器中创建项目并将其与GitHub或GitLab仓库关联。7. 从Modbus TCP出发的生态扩展基于Edge Box RPi 200和Node-RED这个稳固的边缘基座采集到的Modbus数据可以轻松地流向更广阔的信息化系统打破OT运营技术与IT信息技术的壁垒。7.1 数据上行与IT系统集成Node-RED拥有海量的社区节点可以轻松实现数据上行MQTT发布安装node-red-contrib-aedes或使用node-red-node-iot-gateway节点将处理后的数据如{temperature: 25.6, status: true}发布到MQTT Broker如Mosquitto, EMQX。这样任何订阅了该主题的IT系统如数据库、数据分析平台、移动App都能接收到实时数据。写入数据库安装node-red-node-mysql或node-red-contrib-postgresql节点可以将数据直接写入关系型数据库。对于时序数据更推荐使用node-red-contrib-influxdb写入InfluxDB或node-red-contrib-timescale写入TimescaleDB这些数据库对时间序列数据的查询和压缩优化得更好。调用REST API使用内置的http request节点可以将数据以JSON格式发送到任何支持HTTP/HTTPS的云平台或企业内部API例如ThingsBoard、Azure IoT Hub、AWS IoT Core或者自研的数据中台。7.2 横向扩展连接更多工业协议Modbus TCP只是工业协议的冰山一角。Node-RED的生态支持许多其他协议让你能用同一套逻辑处理多种设备OPC UA安装node-red-contrib-opcua节点可以连接更现代、更安全的OPC UA服务器。这对于连接西门子、罗克韦尔等品牌的新型PLC非常有用。西门子S7通过node-red-contrib-s7节点可以直接与西门子S7-1200/1500系列PLC进行通信无需额外的OPC服务器。三菱、欧姆龙等社区也有相应的节点虽然可能不如Modbus和OPC UA成熟但为连接特定品牌设备提供了可能。自定义TCP/UDP对于非标协议可以使用tcp in/tcp out或udp节点配合function节点进行二进制报文的解析和组包灵活性极高。7.3 边缘智能在本地实现轻量级逻辑除了数据转发Edge Box RPi 200完全有能力在边缘侧运行一些轻量级的智能算法或逻辑控制数据预处理在数据上传前进行过滤、清洗、聚合如计算5分钟平均值、单位转换、越限报警判断。这能减少网络传输量和云端计算压力。简单控制逻辑利用Node-RED的function、switch、delay等节点可以实现基于状态的自动控制。例如当温度超过设定值一定范围时自动通过另一个Modbus Write节点关闭加热器实现本地的闭环安全保护。运行机器学习模型虽然CM4算力有限但运行一些训练好的轻量级TensorFlow Lite模型是可行的。你可以使用node-red-contrib-tfjs或node-red-contrib-tflite节点对采集到的图像通过USB摄像头、振动传感器数据等进行实时推理实现缺陷检测、预测性维护的初级功能。通过将Node-RED部署在Edge Box RPi 200这样的工业边缘硬件上我们构建的不仅仅是一个数据采集网关而是一个可编程、可扩展、具备一定智能的边缘计算节点。它成本低廉、开发敏捷、生态丰富非常适合作为工业4.0和物联网项目中连接物理世界与数字世界的那座关键桥梁。从Modbus TCP这个起点出发你能探索的可能性远不止于此。
工业边缘计算实战:基于Node-RED与Modbus TCP的数据采集与监控
1. 项目缘起当工业边缘计算遇上开源自动化最近在折腾一个工业数据采集与可视化的项目手头正好有一台倍福Beckhoff的Edge Box RPi 200。这玩意儿本质上是个基于树莓派CM4模块的工业级边缘控制器接口丰富皮实耐造非常适合放在车间现场。项目需求很明确把产线上几台支持Modbus TCP协议的设备比如温控器、流量计的数据实时采集上来然后做点简单的逻辑处理最后推送到上位机或者Web面板进行监控。要实现这个目标摆在我面前的有几条路用倍福自家的TwinCAT 3写PLC程序那是老本行但开发调试对于快速原型来说有点重用Python写脚本灵活是灵活但数据流管理和可视化又得额外折腾。这时候Node-RED进入了我的视线。它是一个基于流的低代码编程工具用“节点”和“连线”就能构建应用特别适合处理这种设备连接、数据处理和API集成的场景。最关键的是它原生支持Modbus社区节点丰富而且能直接跑在Edge Box RPi 200这个Linux系统上。于是一个“Edge Box RPi 200 Node-RED Modbus TCP”的技术栈组合就成型了。这个组合的魅力在于它用轻量级的开源工具实现了传统工业自动化领域里需要专用软件和控制器才能完成的任务特别适合中小型项目、快速验证和运维人员的自主开发。下面我就把这次从环境搭建、节点配置到实际应用踩过的坑和总结的经验详细分享一下。2. Edge Box RPi 200你的工业级树莓派工作站在开始软件部署之前有必要先了解一下我们的硬件平台——Edge Box RPi 200。它不是一台普通的树莓派而是倍福将其工业化的产物理解它的特点能让后续的配置事半功倍。2.1 硬件规格与接口定位Edge Box RPi 200的核心是树莓派Compute Module 4CM4这意味着它拥有树莓派的基因但形态和接口是针对工业环境设计的。我手头这台配置是CM4带eMMC存储的版本省去了SD卡可靠性更高。其接口堪称豪华双千兆以太网口这是它作为边缘网关的利器。一个口通常eth0可以接入工厂局域网用于连接Modbus TCP设备或与上位机通信另一个口eth1可以配置为独立的网络用于设备直连或实现网络隔离非常符合工业现场的网络规划需求。USB、RS232、RS485接口提供了连接串口设备如Modbus RTU设备的可能扩展性很强。DIO数字输入输出可以直接连接一些开关量传感器或控制指示灯虽然本项目主要用网络通信但这个功能为未来集成更多本地信号留下了伏笔。坚固的金属外壳和DIN导轨安装可以直接卡在配电柜的标准导轨上适应振动、粉尘和电磁干扰相对较差的工业环境。从软件角度看它预装了倍福定制的Linux系统基于Raspberry Pi OS。系统已经做了一些优化比如实时性增强但本质上你可以把它当作一个带有强大工业接口的、运行Linux的迷你电脑。这是我们能安装并运行Node-RED的基础。2.2 系统初始化与网络配置设备上电通过HDMI接口接上显示器或者更常用的通过eth0口用SSH连接首次启动会进行一些初始化。这里有一个关键步骤网络配置。由于我们要用Modbus TCP设备IP地址的稳定性至关重要。我建议为Edge Box RPi 200设置一个静态IP地址而不是依赖DHCP。在工业网络中固定的IP便于管理和寻址。修改网络配置通常通过编辑/etc/dhcpcd.conf文件实现具体方法因镜像版本可能略有不同。例如为eth0设置静态IP# 在 /etc/dhcpcd.conf 文件末尾添加 interface eth0 static ip_address192.168.1.100/24 static routers192.168.1.1 static domain_name_servers8.8.8.8配置完成后重启网络服务或直接重启设备。之后你就可以通过ssh pi192.168.1.100默认用户pi密码请参考倍福文档稳定地连接到设备了这是所有后续操作的起点。注意倍福的镜像可能禁用了默认的pi用户或使用了不同密码请务必查阅设备随附的文档。如果找不到尝试通过显示器和键盘本地登录查看。2.3 环境准备更新系统与安装必要工具在安装Node-RED之前先确保系统是最新的并安装一些常用的工具会让后续过程更顺畅。# 1. 更新软件包列表和系统 sudo apt-get update sudo apt-get upgrade -y # 2. 安装一些常用工具非必须但推荐 sudo apt-get install -y curl wget git vim # 3. 安装Node.js和npm # Node-RED需要Node.js环境。Edge Box RPi 200的官方镜像可能已预装但版本可能较旧。 # 查看当前版本 node --version npm --version # 如果未安装或版本过低建议使用NodeSource的仓库安装LTS版本 curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt-get install -y nodejs确保Node.js版本在14以上Node-RED v3.x推荐使用Node.js 16或18 LTS版本。完成这些我们的硬件和基础软件平台就准备好了。3. Node-RED在边缘盒上的部署与优化有了准备好的Linux系统安装Node-RED本身非常简单。但如何将它配置成一个稳定、自启动的生产级服务并管理好其节点生态这里面有些细节需要注意。3.1 安装Node-RED的推荐方式不推荐直接通过npm install -g node-red进行全局安装因为权限管理和服务化会有点麻烦。官方推荐使用脚本安装它会处理好Node-RED的安装、将其设置为系统服务以及安全更新。# 执行官方安装脚本 bash (curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)这个脚本会做几件事1) 确保Node.js版本合适2) 将Node-RED安装到~/.node-red目录下以当前用户运行3) 询问你是否将其设置为自启动的系统服务。这里一定要选择“是”这样设备重启后Node-RED也会自动运行。安装完成后Node-RED服务就已经启动了。默认情况下它运行在1880端口。你可以在同一局域网的电脑浏览器上访问http://Edge_Box_IP:1880来打开Node-RED的流编辑器界面。3.2 配置为可靠的生产服务安装脚本创建的服务虽然能用但我们可以进行一些优化让它更适应工业边缘环境。首先修改服务配置文件。Node-RED的系统服务文件通常是/lib/systemd/system/nodered.service。我们需要调整运行用户和部分参数。假设我们一直用pi用户操作sudo systemctl stop nodered sudo systemctl disable nodered # 备份原文件 sudo cp /lib/systemd/system/nodered.service /lib/systemd/system/nodered.service.backup # 编辑文件将User和Group改为你的用户名例如 pi sudo vim /lib/systemd/system/nodered.service # 找到 User 和 Group 行进行修改同时可以在[Service]部分添加环境变量例如设置一个更友好的工作目录或调整内存限制对于CM4内存有限需注意EnvironmentNODE_OPTIONS--max-old-space-size256保存后重新加载systemd并启用服务sudo systemctl daemon-reload sudo systemctl enable nodered sudo systemctl start nodered sudo systemctl status nodered # 检查状态应为active (running)其次考虑数据持久化与备份。Node-RED的流Flows和配置默认保存在~/.node-red目录下。其中flows.json文件就是你的所有逻辑。务必定期备份这个文件你可以写一个简单的cron任务将它备份到其他位置。此外settings.js文件包含了运行时配置如安全认证、编辑器主题等根据需求调整。3.3 安装与管理Modbus节点Node-RED的强大在于其节点库。我们需要安装Modbus相关的节点。在Node-RED编辑器中点击右上角的菜单三条横线-“节点管理”-“控制面板”-“安装”然后搜索“modbus”。这里你会看到好几个Modbus节点包。最常用、功能最全的是node-red-contrib-modbus这个包它由biancode维护。它包含了Modbus TCP客户端/服务器、RTU串口、Flex Getter/Setter等多种节点足以满足绝大多数工业协议需求。点击“安装”按钮等待完成。安装完成后在节点面板的左侧你会发现多了一个“modbus”分类里面包含了各种Modbus节点。至此Node-RED的软件和核心节点就绪了。4. Modbus TCP通信原理与节点深度配置在动手连接节点之前我们需要对Modbus TCP协议在Node-RED中的实现方式有个清晰的认识这能帮助我们在配置时避免很多低级错误。4.1 Modbus TCP协议简析与地址映射Modbus TCP可以看作是Modbus RTU协议跑在TCP/IP网络上它使用了标准的502端口。其报文结构在RTU的基础上加了一个MBAP头Modbus Application Protocol header。但对于Node-RED用户来说我们更关心的是数据模型和地址映射。Modbus设备将数据存放在四种不同的“寄存器”区线圈Coils地址0xxxx可读可写的布尔量1位对应开关量输出。例如控制一个继电器的开合。离散输入Discrete Inputs地址1xxxx只读的布尔量1位对应开关量输入。例如读取一个限位开关的状态。保持寄存器Holding Registers地址4xxxx可读可写的16位整数字。这是最常用的区域可以存放各种整型数据也可以通过约定存放浮点数占用两个连续的寄存器。例如PLC中的设定值、运行速度等。输入寄存器Input Registers地址3xxxx只读的16位整数字。通常用于存放模拟量输入值如温度、压力传感器的实时值。这里有一个关键点也是新手最容易混淆的地方Modbus协议地址和Node-RED及很多软件中使用的“数据地址”通常是基于0的偏移量而设备手册上标注的地址常常是基于1的“协议地址”。例如设备手册上说“温度值存放在保持寄存器40001”。那么协议地址40001数据地址偏移量40001 - 40001 0 对于4xxxx区域通常用减去40001的方式得到偏移量在node-red-contrib-modbus的“读保持寄存器”节点中你需要填写的“地址”Address就是0。同理对于线圈0xxxx区域地址00001对应偏移量0对于输入寄存器3xxxx区域地址30001对应偏移量0。务必在配置前仔细查阅你的设备手册并做好这个转换。4.2 Modbus Flex Getter节点的核心配置node-red-contrib-modbus提供了多种节点我最推荐使用Modbus Flex Getter节点进行数据读取。它功能强大配置灵活可以一次读取多个不同地址、不同类型的数据。双击一个Modbus Flex Getter节点其配置主要分为三块Server服务器这里不是指你的Node-RED是服务器而是指你要连接的Modbus TCP设备从站。你需要先配置一个Modbus Client节点作为“服务器”定义。点击笔形图标新建一个关键参数如下Type: TCPHost: 你的Modbus设备IP地址例如192.168.1.50Port: 默认502Unit ID: 从站地址Slave ID。对于很多Modbus TCP设备这个值就是1但也有些设备需要特定的ID请查阅设备手册。Reconnect Timeout: 重连超时建议设置为2000毫秒或更长以适应不太稳定的工业网络。Read/Write Properties读写属性FCFunction Code功能码。例如Read Holding Registers (FC3)就是读保持寄存器。根据你要读的数据类型选择。Address数据地址偏移量如上文所述。例如要读设备手册上的40001这里填0。Quantity要读取的寄存器数量。注意一个16位寄存器是2个字节。如果要读一个32位浮点数占2个寄存器Quantity就是2。Polling轮询这是实现定时采集的关键。Poll Rate轮询频率单位毫秒。例如1000表示每秒读一次。不宜设置过快以免对设备造成过大负载。对于大多数工业场景500ms到2000ms的间隔是合理的。Use Poll Interval务必勾选否则节点不会自动轮询需要外部触发。配置好这些这个节点就会按照设定的频率自动向指定的Modbus设备请求数据并将结果以JavaScript对象的形式输出到msg.payload。4.3 数据处理与消息流构建Modbus Flex Getter节点输出的msg.payload通常是一个Buffer或数组。我们需要将其转换为可读的数据。通常后面会连接一个function节点或change节点进行数据处理。例如读取一个保持寄存器地址0即40001的值它是一个16位无符号整数。在function节点中// msg.payload 可能是一个Buffer如 Buffer 00 0a // 使用Modbus节点自带的解析方法或者直接转换 let rawValue msg.payload.readUInt16BE(0); // 大端序读取 msg.payload { address: 40001, value: rawValue, timestamp: new Date().toISOString() }; return msg;如果要读取一个浮点数占用地址0和1则需要将两个16位寄存器组合let buffer msg.payload; // 假设是4字节Buffer // 假设设备使用大端序Modbus通常是大端序 let intValue (buffer[0] 8) | buffer[1]; // 高字 let fracValue (buffer[2] 8) | buffer[3]; // 低字 // 或者使用DataView进行更标准的解析 let view new DataView(buffer.buffer); let floatValue view.getFloat32(0, false); // false 表示大端序 msg.payload floatValue; return msg;处理后的数据可以连接到debug节点查看也可以发送到dashboard节点组进行可视化或者通过MQTT out节点发布到消息服务器实现数据的上云或跨系统传输。5. 构建一个完整的边缘数据采集与监控流程理论说再多不如一个实际的例子来得直观。假设我们要监控一台工业烤箱它通过一个Modbus TCP网关暴露了以下数据点当前温度只读存放在输入寄存器30001偏移量0数据类型为32位浮点数。设定温度可读写存放在保持寄存器40001偏移量0数据类型为16位整数。加热器状态只读存放在线圈00001偏移量0布尔量。我们的目标是每秒读取一次当前温度和加热器状态在面板上显示并提供一个滑块可以远程修改设定温度。5.1 流程设计与节点连接在Node-RED编辑器中我们拖拽节点构建如下流程Modbus Client配置节点一个即可指向烤箱网关的IP和端口。Modbus Flex Getter (FC4)用于读取当前温度输入寄存器。配置Server为上一步的ClientAddress0, Quantity2因为浮点数占2个寄存器Poll Rate1000ms。Modbus Flex Getter (FC1)用于读取加热器状态线圈。配置相同的ServerAddress0, Quantity1, Poll Rate1000ms。两个Function节点分别接在两个Getter后面用于解析数据。温度解析函数如上节所述将两个寄存器转换为浮点数线圈状态解析则判断msg.payload[0]是否为真。Dashboard UI节点拖入两个gauge仪表节点分别连接温度解析和状态解析的输出用于显示实时值。状态仪表可以设置颜色比如绿色为“运行”红色为“停止”。拖入一个slider滑块节点和一个button按钮节点到画布上它们属于UI输入元件暂时不连线。拖入一个Modbus Flex Setter节点用于写入设定值。配置Server为同一个ClientFC写单个保持寄存器(FC6)Address0。写入逻辑将slider节点和button节点连接到一个function节点。这个函数节点负责在按钮按下时获取滑块的数值并构造给Modbus Flex Setter节点的消息。Setter节点需要msg.payload包含要写入的值。// 当按钮被按下时msg.payload是按钮的配置我们需要取滑块的值 // 这里假设滑块节点的id是“setpoint_slider”我们需要用context或flow变量来传递 // 更简单的方法将滑块和按钮连到同一个function节点判断消息来源 if (msg.topic setpoint_change) { // 来自滑块的消息我们只更新一个临时变量不立即写入 flow.set(targetTemp, msg.payload); return null; // 不向下传递 } if (msg.topic write_trigger) { // 来自按钮的消息执行写入操作 let valueToWrite flow.get(targetTemp) || 150; // 默认值 msg.payload valueToWrite; return msg; // 传递给Modbus Setter }然后配置滑块节点在其“主题Topic”属性中填写setpoint_change按钮节点的主题填写write_trigger。这样滑动滑块只改变内存变量点击按钮才真正下发写入命令避免了网络频繁写操作。5.2 Dashboard的布局与部署点击Node-RED右上角的菜单打开“Dashboard”侧边栏。在这里你可以创建标签页Tabs比如“烤箱监控”。创建分组Groups在标签页下创建分组如“实时数据”、“参数设置”。将UI节点分配到分组编辑每个gauge、slider、button节点在“Group”下拉框中选择刚才创建的分组。你还可以设置它们的尺寸Width/Height以调整布局。布局完成后访问http://Edge_Box_IP:1880/ui就能看到专属的监控面板了。这个面板是响应式的在手机或平板上也能良好显示。5.3 流程的调试与错误处理在实际运行中流程可能会因为网络抖动、设备响应超时等问题出错。Node-RED提供了catch节点来捕获流程中其他节点抛出的错误。你可以将一个catch节点拖入画布它会自动订阅所有节点的错误。将其输出连接到一个debug节点或者一个可以发送警报的节点如email节点或telegram节点这样就能实时知晓系统异常。对于Modbus通信node-red-contrib-modbus节点在出错时通常会在msg.error属性中携带错误信息。你可以在catch节点后面的function节点里分析msg.error区分是连接失败、超时还是非法地址并做出不同的处理比如重试、记录日志或升级报警。6. 进阶应用性能优化、安全与维护当基本流程跑通后我们需要考虑如何让这个边缘系统更健壮、更安全、更易于维护。6.1 性能优化与资源管理Edge Box RPi 200的CM4模块内存和CPU资源有限通常1GB或2GB内存在运行Node-RED并处理多个Modbus轮询时需要注意控制轮询频率不要将所有设备的轮询周期都设为100ms。根据数据变化快慢分级关键数据快如500ms一般数据慢如2s、5s。使用Inject节点配合stoptimer可以实现更复杂的定时逻辑比如只在设备运行时高频采集待机时低频采集。合并请求如果可能使用Modbus Flex Getter的“Read Multiple”功能一次读取多个连续的寄存器而不是为每个数据点建立一个单独的Getter节点。这能大幅减少请求次数和网络开销。流的结构化对于大型项目不要把所有逻辑都放在一个巨大的流里。使用子流程Subflow功能将通用的功能如“解析32位浮点数”、“错误处理模板”封装起来使主流程更清晰也便于复用。监控Node-RED自身安装node-red-dashboard的template节点可以展示系统信息。或者使用node-red-contrib-moment节点定期将内存使用情况、活动连接数等信息通过debug输出或记录到文件。6.2 安全加固措施默认安装的Node-RED编辑器1880端口和Dashboard界面1880/ui是对外开放的这在工业网络中存在风险。启用用户认证这是最重要的步骤。编辑~/.node-red/settings.js文件找到adminAuth部分取消注释并进行配置adminAuth: { type: credentials, users: [{ username: admin, password: $2b$08$YourHashedPasswordHere, // 使用 node-red-admin hash-pw 命令生成 permissions: * }] },使用命令node-red-admin hash-pw生成密码的bcrypt哈希值替换上面注释部分。重启Node-RED后访问编辑器就需要登录了。Dashboard认证在settings.js中同样可以配置ui: { path: ui, middleware: (req, res, next) { ... } }通过中间件来为/ui路径添加认证或者依赖反向代理如Nginx来做HTTP基础认证。使用HTTPS如果数据敏感考虑配置HTTPS。这需要在settings.js中配置https选项并提供证书和私钥。防火墙限制在Edge Box RPi 200上使用ufw或iptables防火墙只允许特定的管理IP地址访问1880端口。例如sudo ufw allow from 192.168.1.10 to any port 1880 proto tcp # 只允许IP为192.168.1.10的电脑访问 sudo ufw enable6.3 备份、版本控制与持续集成将Node-RED的流当作代码来管理是一个好习惯。手动备份定期备份~/.node-red目录尤其是flows.json。可以写一个简单的shell脚本用scp或rsync同步到远程服务器。使用Git将~/.node-red初始化为一个Git仓库每次对流程做重大修改后都进行提交。这样你可以清晰地看到历史变更并且可以轻松地回滚到任何一个版本。cd ~/.node-red git init git add flows.json settings.js package.json git commit -m Initial commit of oven monitoring flow项目化部署对于更复杂的项目可以考虑使用Node-RED的“项目”Project功能。项目将流、依赖的节点、README文件等组织在一起更适合团队协作和版本管理。你可以在编辑器中创建项目并将其与GitHub或GitLab仓库关联。7. 从Modbus TCP出发的生态扩展基于Edge Box RPi 200和Node-RED这个稳固的边缘基座采集到的Modbus数据可以轻松地流向更广阔的信息化系统打破OT运营技术与IT信息技术的壁垒。7.1 数据上行与IT系统集成Node-RED拥有海量的社区节点可以轻松实现数据上行MQTT发布安装node-red-contrib-aedes或使用node-red-node-iot-gateway节点将处理后的数据如{temperature: 25.6, status: true}发布到MQTT Broker如Mosquitto, EMQX。这样任何订阅了该主题的IT系统如数据库、数据分析平台、移动App都能接收到实时数据。写入数据库安装node-red-node-mysql或node-red-contrib-postgresql节点可以将数据直接写入关系型数据库。对于时序数据更推荐使用node-red-contrib-influxdb写入InfluxDB或node-red-contrib-timescale写入TimescaleDB这些数据库对时间序列数据的查询和压缩优化得更好。调用REST API使用内置的http request节点可以将数据以JSON格式发送到任何支持HTTP/HTTPS的云平台或企业内部API例如ThingsBoard、Azure IoT Hub、AWS IoT Core或者自研的数据中台。7.2 横向扩展连接更多工业协议Modbus TCP只是工业协议的冰山一角。Node-RED的生态支持许多其他协议让你能用同一套逻辑处理多种设备OPC UA安装node-red-contrib-opcua节点可以连接更现代、更安全的OPC UA服务器。这对于连接西门子、罗克韦尔等品牌的新型PLC非常有用。西门子S7通过node-red-contrib-s7节点可以直接与西门子S7-1200/1500系列PLC进行通信无需额外的OPC服务器。三菱、欧姆龙等社区也有相应的节点虽然可能不如Modbus和OPC UA成熟但为连接特定品牌设备提供了可能。自定义TCP/UDP对于非标协议可以使用tcp in/tcp out或udp节点配合function节点进行二进制报文的解析和组包灵活性极高。7.3 边缘智能在本地实现轻量级逻辑除了数据转发Edge Box RPi 200完全有能力在边缘侧运行一些轻量级的智能算法或逻辑控制数据预处理在数据上传前进行过滤、清洗、聚合如计算5分钟平均值、单位转换、越限报警判断。这能减少网络传输量和云端计算压力。简单控制逻辑利用Node-RED的function、switch、delay等节点可以实现基于状态的自动控制。例如当温度超过设定值一定范围时自动通过另一个Modbus Write节点关闭加热器实现本地的闭环安全保护。运行机器学习模型虽然CM4算力有限但运行一些训练好的轻量级TensorFlow Lite模型是可行的。你可以使用node-red-contrib-tfjs或node-red-contrib-tflite节点对采集到的图像通过USB摄像头、振动传感器数据等进行实时推理实现缺陷检测、预测性维护的初级功能。通过将Node-RED部署在Edge Box RPi 200这样的工业边缘硬件上我们构建的不仅仅是一个数据采集网关而是一个可编程、可扩展、具备一定智能的边缘计算节点。它成本低廉、开发敏捷、生态丰富非常适合作为工业4.0和物联网项目中连接物理世界与数字世界的那座关键桥梁。从Modbus TCP这个起点出发你能探索的可能性远不止于此。