一.简介 因平时都太忙了,受技术网友的多次催促,今天抽点休息时间来给大家分享一个技术帖,看到标题有的人可能会惊的一声,这有什么好奇的嘛,不就是一个串口通信嘛,这有什么技术含量呢? 好的,接下来我为大家揭晓答案, 请大家再仔细看一看标题,是否有注意到浏览器和Node-RED技术等关键字,我相信有一部分人肯定拿串口做过各种花式应用,那它的分布方式无非就是如下几种: 1)T5L迪文屏串口和硬件外设模块通信 2)T5L迪文屏串口和单片机, PLC, Arduino等微处理器通信 3)T5L迪文屏串口和PC电脑上位机通信 而本帖要讲的是第4种方式,即T5L迪文屏串口和浏览器网页串口通信,是利用Node-RED技术为通道,可以把迪文屏带入到一种新的领域,只需要一个串口,迪文屏就可以进行非常广的技术拓展.可能这样讲,大家还是不能理解 它的强大,我再举如下2个例子: 1.以往迪文屏是不是需要借助wifi模块才能接入到互联网或者物联网,而通过Node-RED技术,就不需要了,只需迪文屏的一个串口即可,迪文屏就可以接入到互联网,相当于把串口变成了网口的功能 2.大多数人可能用迪文屏跟PLC做有线通信,而通过Node-RED技术,可以实现无线通信,重点的是不需要开发者去弄懂太多的PLC协议,因为它封装了内部,这对初学者来说是非常友好的,降低难度的同时也加快了开发进度
那Node-RED是什么呢?它是一个”基于事件驱动的低代码编程物联网平台”,通过浏览器为交互入口,让用户以拖拽拉控件的方式进行编程,它可以运行在树莓派, arduino, Mac os, windows, Android等多种平台上,它的官网地址是:https://nodered.org/ ,下面是官网主页截图:
<span]
二.Node-RED网页设计 1.如何安装Node-RED开发环境 打开cmd命令窗口,执行如下命令:
npm install -g --unsafe-perm node-red
2.如何进入Node-RED编程界面 打开cmd命令窗口,直接输入node-red命令运行,然后打开浏览器输入
3.本开源项目的节点流程代码如下
就这样一幅简单的节点流程代码图它却描述了一个丰富的功能页面
其中节点的配置信息如下:
页面布局如下:
4.如何把Node-RED流程设计给运行起来看效果呢? 先点击右上角的部署按钮,如下所示
5.网页运行效果展示
数据收发Tab页面效果如下:
图表交互Tab页面效果如下:
基本信息Tab页面效果如下:
6.Node-RED网页示意代码如下 [ { "id": "09e0777eaff7fdea", "type": "tab", "label": "main_flow", "disabled": false, "info": "", "env": [] }, { "id": "c1661722c7db00f9", "type": "group", "z": "09e0777eaff7fdea", "name": "数据收发页面", "style": { "label": true, "label-position": "n", "color": "#ff0000" }, "x": 294, "y": 39, "w": 672, "h": 322 }, { "id": "7afc705aac2feb4b", "type": "group", "z": "09e0777eaff7fdea", "name": "基本信息页面", "style": { "label": true, "color": "#ff0000", "label-position": "n" }, "nodes": [ "a944cadcb2b4632a", "b3d256b04fc627cc", "922612b9445f2535", "fa7c6de2d7cfee3d", "b902ed643e396df2" ], "x": 294, "y": 399, "w": 592, "h": 142 }, { "id": "19a36681d87b7de2", "type": "group", "z": "09e0777eaff7fdea", "name": "图表交互页面", "style": { "label": true, "label-position": "n", "color": "#ff0000" }, "x": 294, "y": 579, "w": 792, "h": 322 }, { "id": "a944cadcb2b4632a", "type": "ui_text", "z": "09e0777eaff7fdea", "g": "7afc705aac2feb4b", "group": "0f7fa91d4ff14c6e", "order": 1, "width": 0, "height": 0, "name": "", "label": "波特率:", "format": "115200", "layout": "row-spread", "className": "", "style": false, "font": "", "fontSize": 16, "color": "#000000", "x": 380, "y": 440, "wires": [] }, { "id": "fbb314a16ea00889", "type": "serial in", "z": "09e0777eaff7fdea", "g": "c1661722c7db00f9", "name": "串口接受数据", "serial": "83fb45b5f4b51d61", "x": 390, "y": 140, "wires": [ [ "685a2fb2c2dc8fba" }, { "id": "1ba3c6e812e03e27", "type": "serial out", "z": "09e0777eaff7fdea", "g": "c1661722c7db00f9", "name": "串口发送", "serial": "83fb45b5f4b51d61", "x": 860, "y": 260, "wires": [] }, { "id": "5fb7f1d3d7425133", "type": "status", "z": "09e0777eaff7fdea", "g": "c1661722c7db00f9", "name": "监听串口状态", "scope": [ "fbb314a16ea00889" ], "x": 390, "y": 200, "wires": [ [ "3f18d1fdea398d35" }, { "id": "3f18d1fdea398d35", "type": "function", "z": "09e0777eaff7fdea", "g": "c1661722c7db00f9", "name": "提取串口状态", "func": "let sta = msg.status.text;\nlet color = 'red';\nif (sta.indexOf('not-connected') >= 0) \n sta = '未连接';\nelse if (sta.indexOf('connected') >= 0)\n{\n sta = '连接成功';\n color = 'green';\n}else\n sta = '出现错误';\nmsg['payload'] = sta;\nmsg['color'] = color;\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 620, "y": 200, "wires": [ [ "2ec78ff0b0b9a56f" }, { "id": "2ec78ff0b0b9a56f", "type": "ui_template", "z": "09e0777eaff7fdea", "g": "c1661722c7db00f9", "group": "4e4db779a7b91019", "name": "显示串口状态", "order": 1, "width": 0, "height": 0, "format": "<div style=\"font-size:19px;color:#444;margin:10px;\">\n 串口状态:<span style=\"margin-left:5px;font-weight:bold;color:{{msg.color}};\">{{msg.payload}}<span>\n</div>", "storeOutMessages": true, "fwdInMessages": true, "resendOnRefresh": true, "templateScope": "local", "className": "", "x": 860, "y": 200, "wires": [ [] }, { "id": "685a2fb2c2dc8fba", "type": "ui_template", "z": "09e0777eaff7fdea", "g": "c1661722c7db00f9", "group": "4e4db779a7b91019", "name": "显示接收到的串口数据", "order": 2, "width": 0, "height": 0, "format": "<div style=\"font-size:19px;padding:10px;color:#444;\">\n 数据接受区:\n <div style=\"border: 2px solid #aaa;margin-top:10px;padding:10px;min-height:120px;color:#000;\">{{msg.payload}}</div>\n</div>\n\n", "storeOutMessages": true, "fwdInMessages": true, "resendOnRefresh": true, "templateScope": "local", "className": "", "x": 720, "y": 140, "wires": [ [] }, { "id": "e87a9ff87737f4aa", "type": "ui_form", "z": "09e0777eaff7fdea", "g": "c1661722c7db00f9", "name": "", "label": "数据发送区:", "group": "4e4db779a7b91019", "order": 7, "width": 0, "height": 0, "options": [ { "label": "请输入要发送的数据", "value": "payload", "type": "multiline", "required": true, "rows": 1 } ], "formValue": { "payload": "" }, "payload": "", "submit": "发送", "cancel": "清空", "topic": "topic", "topicType": "msg", "splitLayout": false, "className": "", "x": 390, "y": 300, "wires": [ [ "4e147ffdadc671a1" }, //... { "id": "b902ed643e396df2", "type": "ui_template", "z": "09e0777eaff7fdea", "g": "7afc705aac2feb4b", "group": "0f7fa91d4ff14c6e", "name": "", "order": 4, "width": 0, "height": 0, "format": "<div style=\"text-align:center;margin-top:80px;\">\n <img src=\"https://dwin.com.cn/img/logo.png?1699842946\"/>\n</div>\n", "storeOutMessages": true, "fwdInMessages": true, "resendOnRefresh": true, "templateScope": "local", "className": "", "x": 540, "y": 500, "wires": [ [] }, { "id": "ae56c4786d0a807e", "type": "ui_dropdown", "z": "09e0777eaff7fdea", "g": "19a36681d87b7de2", "name": "", "label": "城市:", "tooltip": "", "place": "请选择城市", "group": "293748cd26b96ad4", "order": 2, "width": 0, "height": 0, "passthru": true, "multiple": false, "options": [ { "label": "北京", "value": "cmd0", "type": "str" }, { "label": "上海", "value": "cmd1", "type": "str" }, { "label": "广州", "value": "cmd2", "type": "str" } ], "payload": "", "topic": "topic", "topicType": "msg", "className": "", "x": 370, "y": 620, "wires": [ [ "5a4d7b59a0b6414f" }, { "id": "bc5c4d6a9a34ac89", "type": "link in", "z": "09e0777eaff7fdea", "g": "c1661722c7db00f9", "name": "link in 1", "links": [ "5a4d7b59a0b6414f" ], "x": 555, "y": 260, "wires": [ [ "1ba3c6e812e03e27" }, { "id": "5a4d7b59a0b6414f", "type": "link out", "z": "09e0777eaff7fdea", "g": "19a36681d87b7de2", "name": "link out 1", "mode": "link", "links": [ "bc5c4d6a9a34ac89" ], "x": 525, "y": 700, "wires": [] }, { "id": "2817f237bcdb1814", "type": "ui_switch", "z": "09e0777eaff7fdea", "g": "19a36681d87b7de2", "name": "", "label": "开关:", "tooltip": "", "group": "293748cd26b96ad4", "order": 1, "width": 0, "height": 0, "passthru": true, "decouple": "false", "topic": "topic", "topicType": "msg", "style": "", "onvalue": "cmd3", "onvalueType": "str", "onicon": "", "oncolor": "", "offvalue": "cmd4", "offvalueType": "str", "officon": "", "offcolor": "", "animate": false, "className": "", "x": 370, "y": 680, "wires": [ [ "5a4d7b59a0b6414f" }, { "id": "320c4fbe35464796", "type": "ui_slider", "z": "09e0777eaff7fdea", "g": "19a36681d87b7de2", "name": "", "label": "滑块:", "tooltip": "", "group": "293748cd26b96ad4", "order": 8, "width": 0, "height": 0, "passthru": true, "outs": "end", "topic": "topic", "topicType": "msg", "min": 0, "max": "100", "step": 1, "className": "", "x": 370, "y": 740, "wires": [ [ "5a4d7b59a0b6414f" }, { "id": "150c757128315052", "type": "ui_gauge", "z": "09e0777eaff7fdea", "g": "19a36681d87b7de2", "name": "", "group": "293748cd26b96ad4", "order": 8, "width": "4", "height": "5", "gtype": "donut", "title": "汽车仪表盘(类型2)", "label": "km/h", "format": "{{value}}", "min": 0, "max": "260", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "80", "seg2": "120", "diff": false, "className": "", "x": 970, "y": 700, "wires": [] }, { "id": "4e4db779a7b91019", "type": "ui_group", "name": "数据收发", "tab": "34d769912ecacd01", "order": 2, "disp": true, "width": "12", "collapse": false, "className": "" }, { "id": "293748cd26b96ad4", "type": "ui_group", "name": "图表交互", "tab": "20aef80442d92012", "order": 1, "disp": true, "width": "12", "collapse": false, "className": "" }, { "id": "2a9f33344a20e68d", "type": "ui_tab", "name": "基本信息", "icon": "fa-info-circle", "order": 3, "disabled": false, "hidden": false }, { "id": "34d769912ecacd01", "type": "ui_tab", "name": "数据收发", "icon": "fa-comments-o", "order": 1, "disabled": false, "hidden": false }, { "id": "20aef80442d92012", "type": "ui_tab", "name": "图表交互", "icon": "fa-line-chart", "order": 2, "disabled": false, "hidden": false }
三.GUI工程设计 素材如下:
DGUS Tool界面设计如下:
四.C51工程设计 用的是T5L迪文屏的串口2来和Node-RED网页通信的,下面给出主函数代码如下:
#include "sys.h" #include "uart2.h" #include <string.h> #include <stdio.h>
u8 buff[200];
void main(void) { u16num; u16val; u16old; u8i;
sys_init(); uart2_init(115200); old= 0;
while(1) { if(is_recv_complete) { uart2_buf[recv_len++]= 0; uart2_buf[recv_len++]= 0;
if(strstr((char*)uart2_buf,"cmd")) { num= uart2_buf[3]-'0'; if(num<3) { for(i=0;i<3;i++) { val= (num==i); sys_write_vp(0x2300+i,(u8*)&val, 1); } }elseif(num<5) { val= (num==3); sys_write_vp(0x2200,(u8*)&val, 1); } }else { sys_write_vp(0x2000,uart2_buf, recv_len/2+2); }
recv_len= 0; is_recv_complete= 0; }
sys_read_vp(0x1000,(u8*)&val, 1); if(val==1) { sys_read_vp(0x2100,buff, 50); for(i=0;i<100;i++) { if(buff==0xff) { buff= 0x00; buff[i+1]= 0x00; break; } } u2_send_bytes(buff,strlen(buff)); val= 0; sys_write_vp(0x1000,(u8*)&val, 1); } sys_read_vp(0x2400,(u8*)&val, 1); if(val!=old) { sprintf(buff,"%d", val); u2_send_bytes(buff,strlen(buff)); old= val; } }
}
五.视频演示效果
|