# stepper_motor_controller
**Repository Path**: hmsfeng/stepper_motor_controller
## Basic Information
- **Project Name**: stepper_motor_controller
- **Description**: CD-MDRV-STEP Stepper motor controller
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2021-10-20
- **Last Updated**: 2022-11-12
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
CD-MDRV-STEP 簡介
=======================================
下載項目:
```
git clone --recurse-submodules https://github.com/dukelec/stepper_motor_controller.git
```
## 圖形配置工具
CDBUS GUI Tool: https://github.com/dukelec/cdbus_gui
上電後,先往 `state` 寫 1,然後往 `tc_pos` 寫入目標位置 ,步進電機便會轉動。
修改配置後,往 `save_conf` 寫 1 保存配置到 flash。
如果需要恢復默認配置,修改 `magic_code` 爲其它值,保存到 flash,然後重新上電即可。
調試打印窗口:
波形窗口:
波形細節、IAP 升級、數據導入導出(包含寄存器、log、波形):
## 協議
MDRV-STEP 是一個開源步進電機控制器,它使用 RS485 接口,默認波特率爲 115200 bps, 最高 > 10 Mbps,默認地址爲 0xfe.
最底層協議爲 CDBUS,其幀格式爲:
`src, dst, len, [payload], crc_l, crc_h`
由 3 字節頭、數據 和 最後 2 字節的 CRC 結尾(算法同 ModBus RTU 的 CRC)。
CDBUS 協議具體參見: https://github.com/dukelec/cdbus_ip
Payload 部分爲 CDNET 協議,同時支持 CDNET L0 和 L1 兩個版本。
CDNET 協議具體參見: https://github.com/dukelec/cdnet
CDNET 和 TCP/IP 中的 UDP 的概念比較類似,主要參考 UDP 的端口號的概念。
譬如最簡單的 CDNET L0 協議,從主機默認端口發送一個字節數據 0x00 到 MDRV 的 1 號端口的格式:
`01 00`
第一個字節是目標端口號,然後跟數據即可。
以上示範,完整的 CDBUS 協議幀爲(主機地址默認爲 0,MDRV 爲 0xfe):
```
00 fe 02 01 00 crc_l crc_h
```
以上示範,端口 1 是設備信息相關的,端口號可以看做 主命令號,首字節數據約定爲 子命令號,
子命令號 0x00 是讀設備信息。
MDRV 一共有 4 個端口接收指令,分別是:
### 端口 1: 設備信息
唯一一個子命令號 0 是用來查詢信息。
返回 0x80 + 設備信息字符串,譬如 `M: mdrv-step; S: 23ff7660d405535353733034; SW: v1.1`.
### 端口 5: 參數表讀寫
參數表在代碼中是 `csa_t` 類型的全局結構體,csa 爲 Config Status Area 的縮寫,它的前半部分可以寫入 Flash 中,以保存一些用戶設置,
上電時從 flash 中恢復 csa 的前半部分數據。而後部分數據爲運行中的一些變量,通過此接口把這些變量暴露給用戶,讓用戶直接讀寫可以大大簡化代碼。
不過,我們在讀寫前後,可以通過預先定義的 hook 鉤子函數,對寫入數據進行安全檢查,或是定義寫入後需要執行的動作。
而對於讀取命令,可以提前爲用戶準備其所需要的數據格式,譬如格式轉換。
另外,爲了方便用戶整體同步 csa 信息,我們定義了 csa 的哪些區域可寫,不可寫的區域用戶不用小心避開,寫入的數據直接會被忽略。
譬如,我們可以直接把 pid 對象放在 csa 表中,pid 對象中有一些是內部變量,不應該被用戶修改,
有了可寫區域限制,用戶可以非常方便的整塊寫入數據,不用擔心寫到不該寫的數據。
讀寫參數表的子命令爲:
```
read: 0x00, offset_16, len_8 | return [0x80, data]
read_dft: 0x01, offset_16, len_8 | return [0x80, data]
write: 0x20, offset_16 + [data] | return [0x80] on success
```
譬如設置電機鎖舵並進入位置模式。電機狀態 `state` 值爲 0 不鎖舵,爲 1 鎖舵。
`state` 本身的地址是 `0x00b8`,長度 1 個字節,那麼上電後需要鎖舵,發送以下數據到端口 5 即可:
```
20 b8 00 01
```
`20` 是子命令 `write`,`b8 00` 是地址 0x00b8 的小端格式(除非特別說明,否則都是用小端),最後一個 `01` 是寫入數值。
修改 `csa_t` 的定義,可能會影響到很多寄存器的地址,如果每次都是手工計算各寄存器的地址,很麻煩且容易出錯,所以,我們通過 `csa_list_show` 這個函數,
上電時自動打印出所有寄存器的地址、類型,以及說明信息,可以直接拷貝到配置文檔中。
每次修改 `csa_t` 的定義後,請同時修改其中的 `conf_ver` 版本號。
### 端口 6: 快速讀寫
位置模式常用的參數表項有:
```
tc_pos, type: int32_t
tc_speed, type: uint32_t
tc_accel, type: uint32_t
```
我們可以通過端口 5 來寫這些數據,但是,有的時候我們還想去寫非連續的其它 表項,這樣就要拆分多條命令,效率低,且容易導致數據不同步。
而且,我們還想設備同時回覆電機的錯誤碼和一些運行數據,但不同模式下我們關心的運行數據不盡相同,如果寫死會比較不方便。
參數表項內有 快速讀寫 通道的配置:(qxchg 是 quick exchange 的縮寫)
```
regr_t qxchg_set[5];
regr_t qxchg_ret[5];
```
以上數組,首個 size 值爲 0 的元素表示它和後序的未使用,元素的定義:
```
typedef struct {
uint16_t offset;
uint16_t size;
} regr_t; // reg range
```
`qxchg_set` 和 `qxchg_ret` 是 快速讀寫 的 子命令 `20` 所用,
預先設置好寫哪些數據,以及返回哪些數據,然後發送 `20` + 需要寫的數據就可以了,
會返回 `80` + 返回的數據。
`qxchg_set` 默認設定只用了一個元素,指向 `tc_pos`, `tc_speed` 和 `tc_accel` 這 3 個表項所在的區域,
如果需要修改目標位置參數 `tc_pos` 爲 0,向 端口 6 寫數據 `20 00 00 00 00` 即可(`20` 是子命令號)。
如果需要同時修改目標位置和目標速度,譬如位置改爲 0x00001000,速度改爲 0x00000500,則寫入 `20 00 10 00 00 00 05 00 00`.
子命令 `2f` 支持接收包含多個設備數據的廣播或組播包。
### 端口 8: Flash 讀寫
可以通過此接口實現 IAP 升級。
子命令爲:
```
erase: 0x2f, addr_32, len_32 | return [0x80] on success
write: 0x20, addr_32 + [data] | return [0x80] on success
read: 0x00, addr_32, len_8 | return [0x80, data]
cal crc: 0x10, addr_32, len_32 | return [0x80, crc_16] # modbus crc
```
先要把需要寫的區域擦除,然後寫入數據,最後調用 crc 計算所寫數據是否正確即可。
也可以讀回所有數據來判斷,速度會稍慢一點。
Bootloader 上電後,先使用默認波特率 115200,如果收到主機設置 `keep_in_bl` 的命令就保持此波特率,如果一秒鍾內沒有收到該命令,則切換到 Flash 中保存的波特率繼續等待命令,如果再過一秒依然沒收到命令,則跳轉執行 APP 固件。Bootloader 和 APP 共享 csa 配置的開頭部分,其中包含了用戶設置的波特率。
如果不知道 MDRV 當前的 ID 號,可以發送 info 命令到廣播地址 0xff 進行搜尋。
當前 MCU Flash 總共 128K, 每頁大小爲 2K, 前 24K 存放 Bootloader,最後 2K 存放 csa 參數表,其餘爲 APP.
## 波形數據
和 快速讀寫 通道的 `qxchg_XXX` 數組一樣,波形數據用同樣的方式定義需要上報的數據的組成,可以自由配置想要觀察的變量。
和 `qxchg_XXX` 不同的是,一個數據包會存放很多組數據,等數據包滿到一定程度再發送給主機。
如果是固定週期的情況,譬如 FOC 電機,可以在電流環中爲一個變量(譬如 `loop_cnt`)每次加 1,然後只需要把 `loop_cnt` 寫在每個數據包的最前面即可。
但我們這個 stepper motor 控制,週期不固定,所以要把時間信息和其它被觀察的變量,每次都一起記錄。
使用 plot 調試時,建議把設備的波特率設置高一些。
如果數據量很大,MDRV 會把連續的信息保存在 buffer 中,buffer 滿之後,會等待 buffer 完全清空再繼續,能最大程度保證數據的連續性,避免細節丟失。