某个主控板正在控制从机的时候,可以把 PC 电脑挂到同一条 RS485 总线上,PC 可以读写从机、查看从机打印消息、查看数据波形,完全不干扰现有主板对从机的控制。
项目地址:https://github.com/dukelec/cdbus_gui 跨平台,支持 Linux、Windows、MacOS、树莓派 ……https://github.com/dukelec/stepper_motor_controller
此工具代码架构是 python + web,python 和每个 web 页面通过单个 websocket 管道通讯。 web 端是裸 javascript (vanilla, es6), 不需要瞭解特定的前端框架,就可以参与代码修改。也方便拿此 app 当模板做一些产品的专用上位机软件。
mcu 和 python 之间是 cdnet 协议,目前只用到 level 1 格式的最简版本。 python 和 web 之间的协议也是类似 cdnet,地址和端口用任意字符串代替。
运行 python 程序后,首先打开主页:Available 列出电脑所有串口,只要粘贴其中任意一小段字符串,填到 Serial 第一个输入框就可以了,这样的好处是,如果端口变化,依然可以打开正确的串口。或者是选择插在指定 USB 口的串口。使用过程中,串口掉线会自动重连接,右边是 python 后台打印:插拔之后又成功重接。 Devices 主要是选择调试哪一个从机,支持同时调试多个设备,数量不限。 Logs 是所有设备的打印汇总,每个设备各自的页面只打印各自的调试信息。 打印支持彩色 (ANSI), 和 Linux 下的终端一样,方便在很多 log 中快速定位错误。

下面是具体打开一个设备的调试窗口,首先是数据列表读写(俗称寄存器):鼠标放到寄存器名称和数据上,会分别提示寄存器说明,和默认数据(默认数据也是从设备中读取)。 寄存器的读写是按组进行,可以保证一组数据的原子性。 点某一组的 R 会读该组所有数据,W 则是写一组数据。点最上面的 Read All 和 Write All 则是依次读写每一组。 列表是由不同设备的 json 文件配置,其中寄存器列表是设备上电自动打印出来的,拷贝粘贴到 json 模板中即可。 支持数组和多种数据格式,可以设置是否以 16 进制显示(数据框带 H 标记),或者是 uint8_t 数组(带 B 标记)。 同一个组内部,有一些带一个小凹槽,表示两个寄存器之间有空洞。首次写入前会回读该组数据,避免修改空洞中的数据,空洞可能是空的,也可能是厂商 reserved 寄存器。


这是设备页面的 Log 调试,同样可以随便改变大小:再下面是波形窗口,也支持选择大小。

波形窗口: 可以随便打开、关闭某一条曲线,曲线多的时候不容易乱,图中 tc_speed 是关闭状态,但依然会显示数值。 鼠标滚轮可以配合 shift 或者 ctrl 分别对 x 和 y 轴进行缩放,默认是两个轴一起缩放。 支持触摸屏缩放,同样支持 x 和 y 轴不同比例的缩放。 双击恢复默认示图(最大化显示所有数据)。鼠标中键可拖拽平移(触摸板也可以)。 可以设置数据深度,老数据自动删除。方便动态显示数据(示波器效果)。 波形窗口的个数不限。

上圖下面部分是 IAP 和 寄存器 数据导出和导入: IAP 支持整体回读验证、设备端计算并返回 crc 进行验证、不验证。 會一并导出 log、波形数据,譬如你是做电机控制的,可以让客户把他采集到的波形发给你分析,以此远程协助客户调 PID 等参数。
最后是 json 配置,最上面的 reg 是设备上电打印出来的(mcu 端也是自动生成,不用自己填地址、大小和数据类型,不容易出错): 为了方便阅读,有 16 进制数和注释,所以使用的是 json5 格式。 fmt 字符带 [] 的是数组,在一个编辑框显示所有数据。 带 {} 的也是数组,每组占用一个编辑框,每个框内支持多个数据,方便用于结构体数组。

reg_r 和 reg_w 是默认的寄存器分组读写,写不写无所谓,可以在 UI 上编辑。 plot 的数据的 fmt 比较关键,对应两种数据包格式,x1 a1 b1 a2 b2 ... 和 x1 a1 b1 x2 a2 b2 ... 前者是每个包的多组数据之间共享一个 x 轴数据,fmt 首个字符 I 是 x 的格式,表示 uint32_t, 一般是 mcu 里面一个 cnt, 每个 loop 加 1,loop 周期固定,I 后面的数代表 x1 和 x2 之间的差值,从而恢复出 x2 x3 ... I 后面没有数字的是后者,一个包里面的每一组数据都有一个 x 值,适合 loop 周期变化的场景。

硬件层面普通串口也支持的。 沒有硬件也可以打开上面的所有界面预览,没数据而已(可以導入別人導出的數據)。 用 CDBUS 专用控制器速度更快更方便,带仲裁等特性,兼容传统 RS485,速度最快可以到 50 Mbps,控制器也是 100% 开源:https://github.com/dukelec/cdbus_ip 此工具默認使用的 USB 轉 RS485 的硬件也是开源的:https://github.com/dukelec/cdbus_bridge 最后提一下 CDCAM 开源RS485 摄像头,此工具支持图像预览。CDCAM 开源地址:https://github.com/dukelec/cdcam受限 STM32G071CBT6 的性能,800x600 大小的图片目前是 10 fps,可以发指令触发拍照。一条 RS485 可以挂多个摄像头、电机,非常方便。又譬如:传统需要变焦的场合,直接用 2 个不同焦距的定焦摄像头就好了,反正成本便宜。也不增加接线。

开源 CDCAM 摄像头实物图:


开源步进电机驱动器CD-MDRV-STEP 实物图:

CD-MDRV-FOC 无刷伺服实物图:

再顺便补充一下,cdnet ip 是参考 ipv6 的概念,方便通过字符串来代表不同的地址(为了效率,mcu 用 3 字节 uint8_t 数组),其定义如下:
/* CDNET address format: * * local link unique local multicast * level0: 00:NN:MM * level1: 80:NN:MM a0:NN:MM f0:MH:ML * `-with seq: 88:NN:MM a8:NN:MM f8:MH:ML * level2: c0:NN:MM * `-with seq: c8:NN:MM * * Notes: * NN: net_id, MM: mac_addr, MH+ML: multicast_id */ 广播和组播也可以用 local link 格式,一般没有必要用 multicast 格式。一般用 80 开头的就够了,00 开头的主要是为了人肉敲命令裸数据调试的时候可以少一两个字符而已,机器就不建议用了。unique local 是跨网段的时候才用,譬如有多个网段,每个子网有多个设备。level2 是用来传输框架外的任意数据,一般用来多台电脑之间传输真正的 tcp/ip 协议,组电脑网络。cdnet ip 地址可直接映像为标准的 ipv6 地址,这样电脑上可以通过标准 udp 编程和 mcu 互动,mcu 代码不用变,开销非常小,不用跑 ipv6 协议栈。
|