硬汉嵌入式论坛

 找回密码
 立即注册
查看: 548|回复: 3
收起左侧

[串口助手] CDBUS GUI 工具 - 开源跨平台 波形显示、调试打印、IAP 升级

[复制链接]

1

主题

80

回帖

83

积分

初级会员

积分
83
发表于 2025-10-29 17:28:27 | 显示全部楼层 |阅读模式
本帖最后由 dukelec 于 2025-10-29 17:59 编辑

最近看大家关注某个开源波形显示工具,开源版本功能不全,编译很麻烦,我这个是免编译的,会网页编程的话,想加什么控件自己加很方便

如果只用波形功能,可以忽略其它功能,mcu 直接发波形数据包给电脑即可,文末有数据包定义。

使用方法是,安装 python,运行 `main.py`, 然后浏览器打开连接: http://localhost:8910

工具开源和下载地址:https://github.com/dukelec/cdbus_gui


### Index 首页
- "Serial":第一个输入框可填写串口号或匹配字符串(例如 COM2、ACM0、Bridge、2E3C:5740),支持通配符。  
   第二个输入框为波特率。
- "Available":列出电脑上所有串口。
- "Devices":可快速打开对应设备的调试页面(列表会自动扩展)。
- "Logs":汇总所有设备的日志。  
   (按 Enter 插入空行;按住 Alt 或 Ctrl + Alt 可进行块选择。)
- 串口支持自动重连。
- 修改的设置会自动保存。
- 支持 ANSI 彩色字符显示。


00 index.png


### Device 页面
- 显示用于读写的寄存器。
- 鼠标悬停在寄存器上可查看其描述、类型和默认值。
- 寄存器按组组织,以保证读写一致性;组可以自由编辑。
- 按 `R` 读取一组,按 `W` 写入一组。`Read All` / `Write All` 对所有组执行相应操作。
- 支持数组和多种数据格式,可显示为十六进制(`H`)或字节数组(`B`)。
- `R`/`W` 按钮上的小缺口表示寄存器间的空隙;写入前会先读取整组数据,以保持空隙中的数据不被修改。


01 reg.png

02 reg edit.png


#### 波形显示:
- 支持实时显示与长时间数据记录,包括 FFT 可视化。
- 支持多窗口显示,窗口大小可自由调整。
- 若串口数据包丢失,会自动插入占位符,防止后续波形与前一段错误连接。
- 鼠标滚轮配合 `Shift` 或 `Ctrl` 可分别缩放 `X` 或 `Y` 轴;默认同时缩放两轴。
- 支持触屏缩放与独立的 `X`/`Y` 轴缩放。
- 双击可重置视图(自动适配缩放);按住鼠标左键或中键可平移。
- 可独立开关各通道,便于观察。
- 可通过 `dbg_raw_msk` 寄存器同时启动或停止多个波形。
- 支持基于公式的波形(如下图 `u_cal` 所示);修改或新增公式后,点击 `更新计算` 即可刷新波形。


03 log plot iap.png

04 fft.png


#### 图片显示:
- 预览来自设备发送的图像(如 JPEG 文件)。


p8.png


#### IAP 升级 和 数据导入/导出:
- IAP 支持回读校验、设备端 CRC 校验或无校验模式。
- IAP 支持包含多段的 Intel HEX 文件。
- 寄存器数据、日志输出和波形数据可一同导出与导入(MessagePack 格式)。

### JSON 格式
- 寄存器列表可由 MCU 自动生成(上电时打印)。
- 使用 JSON5 格式,支持十六进制数值和注释。
- "fmt" 字符串中带 "[]" 的表示数组,所有数据显示在同一个文本框中。
- "{}" 表示结构体数组,每个数组元素对应一个文本框,文本框中包含该结构体的多个成员。


**E.g.** `cdstep-v6.json`
[Python] 纯文本查看 复制代码

{
    "reg": {
        // fmt: [c]: string, b: int8_t, B: uint8_t, h: int16_t, H: uint16_t, i: int32_t, I: uint32_t
        //       q: int64_t, Q: uint64_t, f: float, d: double
        // show: 0: normal, 1: hex, 2: bytes
        "list": [
            [ 0x0000, 2, "H", 1, "magic_code", "Magic code: 0xcdcd" ],
            [ 0x0002, 2, "H", 1, "conf_ver", "Config version" ],
            [ 0x0004, 1, "B", 0, "conf_from", "0: default config, 1: all from flash, 2: partly from flash" ],
            [ 0x0005, 1, "B", 0, "do_reboot", "1: reboot to bl, 2: reboot to app" ],
            [ 0x0007, 1, "b", 0, "save_conf", "Write 1 to save current config to flash" ],

            [ 0x000c, 1, "B", 1, "bus_cfg_mac", "RS-485 port id, range: 0~254" ],
            [ 0x0010, 4, "I", 0, "bus_cfg_baud_l", "RS-485 baud rate for first byte" ],
            [ 0x0014, 4, "I", 0, "bus_cfg_baud_h", "RS-485 baud rate for follow bytes" ],
            // ...

            [ 0x00bc, 4, "i", 0, "tc_pos", "Set target position" ],
            [ 0x00c0, 4, "I", 0, "tc_speed", "Set target speed" ],
            [ 0x00c4, 4, "I", 0, "tc_accel", "Set target accel" ],
            [ 0x00c8, 4, "I", 0, "tc_accel_emg", "Set emergency accel" ],

            [ 0x00d4, 4, "f", 0, "pid_pos_kp", "" ],
            [ 0x00d8, 4, "f", 0, "pid_pos_ki", "" ],
            [ 0x00dc, 4, "f", 0, "pid_pos_kd", "" ],
            [ 0x0100, 4, "i", 0, "cal_pos", "PID input position" ],
            [ 0x0104, 4, "f", 0, "cal_speed", "PID output speed" ],

            [ 0x0108, 1, "B", 0, "state", "0: disable drive, 1: enable drive" ],

            // --------------- Follows are not writable: -------------------
            [ 0x0109, 1, "B", 0, "tc_state", "t_curve: 0: stop, 1: run" ],
            [ 0x010c, 4, "i", 0, "cur_pos", "Motor current position" ],
            [ 0x0110, 4, "f", 0, "tc_vc", "Motor current speed" ],
            [ 0x0114, 4, "f", 0, "tc_ac", "Motor current accel" ],

            [ 0x0124, 4, "I", 0, "loop_cnt", "Count for plot" ],
            [ 0x0128, 10, "[c]", 0, "string_test", "String test" ]
        ],
        
        // button groups
        "reg_r": [["magic_code","save_conf"],["bus_cfg_mac","bus_cfg_tx_pre_len"],["dbg_en"],["qxchg_mcast"],
                  ["qxchg_set","qxchg_ret"],["dbg_raw_msk"],["dbg_raw[0]","dbg_raw[1]"],["ref_volt","lim_en"],
                  ["tc_pos","tc_accel"],["tc_accel_emg"],["pid_pos_kp","pid_pos_kd"],["cal_pos","cal_speed"],
                  ["state"],["tc_state","cur_pos"],["tc_vc","tc_ac"],["loop_cnt"],["string_test"]],
        "reg_w": [["magic_code","conf_ver"],["do_reboot"],["save_conf"],["bus_cfg_mac"],["bus_cfg_baud_l","bus_cfg_baud_h"],
                  ["bus_cfg_filter_m"],["bus_cfg_mode"],["bus_cfg_tx_permit_len","bus_cfg_tx_pre_len"],["dbg_en"],
                  ["qxchg_mcast"],["qxchg_set","qxchg_ret"],["dbg_raw_msk"],["dbg_raw[0]","dbg_raw[1]"],
                  ["ref_volt","md_val"],["set_home"],["lim_en"],["tc_pos"],["tc_speed","tc_accel"],["tc_accel_emg"],
                  ["pid_pos_kp","pid_pos_kd"],["state"],["string_test"]],
        "less_r": [["tc_pos","tc_accel"],["state","loop_cnt"]],
        "less_w": [["tc_pos"],["tc_speed","tc_accel"],["state"]]
    },
    
    "plot": {
        "mask": "dbg_raw_msk",
        "plots": [
            {
                // "color": ["black", "red", "green", ...]
                "fmt": "I1.iBiiff",
                "label": ["N", "tc_pos", "tc_state", "cal_pos", "cur_pos", "tc_vc", "tc_va"],
                "cal": {
                    "pos_err": "_d[4].at(-1) - _d[3].at(-1)" // data4 - data3
                },
                "fft": {
                    "sample_rate": 5000,
                    "size": 4096
                }
            }, {
                "fmt": "I1.ifif",
                "label": ["N", "pid target", "i_term", "last_in", "cal_speed"]
            }
        ]
    },
    
    "iap": { "reboot": 0x0005, "keep_bl": 0x0006 }
}




- "reg_r" 和 "reg_w" 是默认的寄存器分组配置;可留空并在界面上编辑(编辑后浏览器调试窗口会打印出来;"less_r" 和 "less_w" 同样如此)。
- "plot" 数据的 "fmt" 对应两种数据包格式:
   * "x1 a1 b1 a2 b2 …" —— x 轴数据在各组间共享。"I" 表示一个 uint32_t 计数器,每次循环递增;I 后的数字表示增量,用于还原后续 x 值。
   * "x1 a1 b1 x2 a2 b2 …" —— 每组数据都有独立的 x 值,适用于循环周期不固定的场景。


### 更多
顺便提一下,CDNET Address 参考的是 IPv6 的概念,允许用字符串表示不同地址,定义如下。

```
/* CDNET Address string formats:
*
*            localhost      local link     unique local    multicast
*             10:00:00
* level0:                    00:NN:MM
* level1:                    80:NN:MM        a0:NN:MM       f0:MH:ML
*
* Notes:
*   NN: net_id, MM: mac_addr, MH/ML: multicast_id (H: high byte, L: low byte)
*/
```

- 广播和组播也可以使用 "link-local" 格式;在简单场景下通常不需要使用 "multicast" 格式。
- "Unique local" 仅用于跨网络段,例如多个子网中每个子网包含多个设备。

串口 CDNET 数据包可以直接映射为 UDP 数据包,从而允许多个软件同时访问同一串口设备。详情请参见:
https://github.com/dukelec/cdnet_tun

通过 UDP 访问串口设备时,请运行 `main_udp.py` 程序。


附上 MCU 发送波形数据的格式:

data.png



Python 安装和运行程序的 windows 版教程:

Windows 用户运行软件的方法 · dukelec_cdbus_gui Wiki.pdf (740.63 KB, 下载次数: 13)

协议文档:
CDNET 协议简介及示范 · dukelec_cdnet Wiki.pdf (944.84 KB, 下载次数: 11)
CDNET 协议中文版 · dukelec_cdnet Wiki.pdf (524.42 KB, 下载次数: 13)


评分

参与人数 1金币 +100 收起 理由
eric2013 + 100 很给力!

查看全部评分

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
发表于 2025-10-30 12:49:33 | 显示全部楼层
谢谢楼主分享。
回复

使用道具 举报

2

主题

114

回帖

120

积分

初级会员

积分
120
发表于 2025-10-31 18:47:21 | 显示全部楼层
真牛!感谢分享~
回复

使用道具 举报

1

主题

31

回帖

34

积分

新手上路

积分
34
发表于 2025-11-1 00:07:57 | 显示全部楼层
感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-11-21 20:02 , Processed in 0.045019 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表