Python 透過 pyserial 函式庫向 /dev/ttyUSB0 埠發送您指定的 DYNAMIXEL Protocol 2.0 數據包的程式碼範例。
🚨 前置作業
您需要先安裝 pyserial 函式庫:
pip install pyserial
💻 Python 程式碼
這個程式碼會設定串列埠,並以二進位 (byte) 格式發送您提供的數據。
import serial
import time
import binascii
# --- 串列埠設定 ---
SERIAL_PORT = '/dev/ttyUSB0' # Linux 系統下通常是 ttyUSB0
BAUDRATE = 57600
TIMEOUT = 0.1 # 讀取逾時時間 (秒)
# --- 要發送的數據包 (Protocol 2.0 協定) ---
# FF FF FD 00 01 07 00 03 74 00 55 09 00 00 D5 27
# Header ID Len(L/H) Instr Addr(L/H) Data(4 bytes) CRC(L/H)
# 數據包說明:
# ID: 01
# Instruction: 03 (WRITE)
# Address: 0x0074 (Goal Position)
# Data: 0x00000955 (2389, 這是 0x55 0x09 0x00 0x00 的 little-endian 轉換)
# CRC: 0xD5 0x27
HEX_STRING = "FFFFFD0001070003740055090000D527"
# 將十六進制字串轉換為 bytes
try:
# binascii.unhexlify 將十六進制字串轉換為 bytes
PACKET_TO_SEND = binascii.unhexlify(HEX_STRING)
except TypeError as e:
print(f"錯誤:十六進制字串轉換失敗 - {e}")
print("請檢查您的十六進制字串是否有效且長度為偶數。")
exit(1)
def send_dynamixel_packet():
"""
配置串列埠並發送 DYNAMIXEL 數據包。
"""
print(f"嘗試開啟串列埠:{SERIAL_PORT},波特率:{BAUDRATE}")
# 配置串列埠:57600 波特率,無奇偶校驗 (N),8 個數據位 (8),1 個停止位 (1)
# pySerial 預設是 N, 8, 1
try:
ser = serial.Serial(
port=SERIAL_PORT,
baudrate=BAUDRATE,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=TIMEOUT
)
# 確保連接是開啟的
if not ser.isOpen():
ser.open()
print("串列埠開啟成功。")
print(f"準備發送數據包 ({len(PACKET_TO_SEND)} bytes):")
print(f"十六進制:{PACKET_TO_SEND.hex().upper()}")
# --- 發送數據 ---
bytes_written = ser.write(PACKET_TO_SEND)
ser.flush() # 確保數據立即發送
print(f"成功寫入 {bytes_written} 個位元組。")
# --- 嘗試讀取回覆 (Status Packet) ---
# 由於 DYNAMIXEL 會回覆一個狀態包 (Status Packet),我們嘗試讀取它。
# Status Packet 的長度不固定,但通常約為 14-16 bytes 左右。
print("\n等待 DYNAMIXEL 回覆 (Status Packet)...")
time.sleep(0.01) # 短暫延遲,等待馬達處理和回覆
response = ser.read(30) # 嘗試讀取最多 30 個位元組的回覆
if response:
print(f"收到回覆 ({len(response)} bytes):")
print(f"十六進制:{response.hex().upper()}")
else:
print("未收到任何回覆 (逾時)。")
# --- 關閉串列埠 ---
ser.close()
print("\n串列埠已關閉。")
except serial.SerialException as e:
print(f"\n錯誤:無法存取或配置串列埠 {SERIAL_PORT}。")
print("請確認以下事項:")
print(f"* 1. 串列轉接器已連接到 {SERIAL_PORT}。")
print(f"* 2. 您有足夠的權限 (可能需要 'sudo' 或將使用者加入 'dialout' 群組)。")
print(f"* 3. 埠號 ({SERIAL_PORT}) 是否正確。")
print(f"詳細錯誤訊息: {e}")
except Exception as e:
print(f"發生一般錯誤: {e}")
# 執行函式
if __name__ == "__main__":
send_dynamixel_packet()
📋 執行注意事項
使用者權限: 在 Linux 系統中,存取
/dev/ttyUSB0通常需要特定的權限。如果遇到Permission denied錯誤,您可能需要使用sudo執行腳本,或者將您的使用者帳號添加到dialout群組:Bashsudo usermod -a -G dialout $USER # 之後需要登出並重新登入才能生效埠號: 確保您的 USB-to-UART 轉接器或 U2D2 連接到電腦時確實被識別為
/dev/ttyUSB0。如果不是,請修改程式碼中的SERIAL_PORT變數。DYNAMIXEL 連接: DYNAMIXEL 馬達必須正確連接到 UART 轉接器上,且電源開啟,才能收到回覆。