串口通信
串口通訊(Serial Communication)是一種接口標准,是指外設和計算機間,通過數據信號線、地線等,按位進行傳輸數據的一種通訊方式。
通訊方式
- 單工模式(Simplex Communication)的數據傳輸是單向的。信息只能沿一個方向傳輸
- 半雙工模式(Half Duplex)既可以發送數據又可以接收數據,但不能同時進行發送和接收
- 全雙工模式(Full Duplex)通信允許數據同時在兩個方向上傳輸
比特率
比特率就是每秒鍾傳輸的數據位數
常見串口通信協議標准
EIA RS232(通常簡稱“RS232”): 1962年由美國電子工業協會(EIA)制定。
EIA RS485(通常簡稱“RS485”): 1983年由美國電子工業協會(EIA)制定。
流程
1. 連接夾爪(串口端口)
2. 進入到`/dev/ttyUSB0`修改權限`chmod 777 ttyUSB0`
3. 發送rs232數據過去
RS232
RS232是計算機與通信工業應用中最廣泛一種串行接口。它以全雙工方式工作,需要地線、發送線和接收線三條線。RS232只能實現點對點的通信方式。
缺點
傳輸速率低,最高波特率19200bps
傳輸距離有限,一般在15m以內
抗干擾能力較差
RS485
具有良好的抗干擾能力,信號能傳輸上千米
可實現真正的多點通訊
串口調試工具cutecom
sudo apt install cutecom
因時機械人有一款基於LA16-021D 的直線伺服驅動器的電動夾爪,通訊方式有can/rs232/rs485三種通訊方式,此處記錄基於rs232控制機械夾爪的代碼和相關文件。
以下內容摘錄與因時機器人官網:
2 通信協議
2.1 通信協議概要
主控單元與夾爪之間采用問答方式通信,主控單元主動發送指令幀,夾爪收到指令幀,解
析並執行后返回應答幀。
同一控制網絡中允許一個主控單元同時連接控制多個夾爪,因此每個夾爪需用戶分配不同
的 ID 號作為唯一標識(夾爪出廠時默認的 ID 號為 1)。主控單元發出的指令幀數據體中包括
有 ID 號信息,只有與之匹配的 ID 號對應的夾爪才能完整接收指令幀信息,並在執行指令后返
回相應的應答幀。
通信方式為 RS232 異步串口,每個指令幀以字節為最小單位,單一字節由 1 位起始位、8
位數據位以及 1 位停止位組成,無奇偶校驗,共 10 比特。
2.2 指令幀
基礎指令幀格式:
幀頭:連續收到0xEB和0x90 ,表示有指令幀到達。
ID號: 每個夾爪都有一個ID號。ID號范圍為1~254,轉換為十六進制為0x01~0xFE。廣播ID號255(0xFF),若控制器發出的ID號為255(0xFF),所有的夾爪均接收指令幀,但都不返回應答信息。
數據體長度:等於待發送的數據段長度,包括指令號與數據,即“ Len ”,總指令幀的長度為“ Len +5”。
補充基礎知識:
0X代表16進制,這里的幀頭是2個字節,其中第一個0xEB,是指16進制的14*16 + 11 = 235(十進制),轉換為2進制是1110 1011。其實不需要知道這么詳細,只需要知道,16進制2個字母(或數字)代表2進制(計算機中的)8個位即可。即,1個字節代表8位。
數據體1/2——指令號:指定該指令幀的類型。
CMD_MC_PARA_SAVE(0x01):參數保存到內部閃存,掉電不丟失
CMD_MC_PARA_ID_SET(0x04):設置夾爪ID
CMD_MC_MOVE_CATCH_XG(0x10):以設置的速度和力控閾值去夾取
CMD_MC_MOVE_HOLD_CATCH_XG(0x18):以設置的速度和力控閾值持續夾取
CMD_MC_MOVE_RELEASE(0x11):以設置的速度松開
CMD_MC_MOVE_STOPHERE(0x16):急停
CMD_MC_SET_EG_PARA(0x12):設置夾爪開口的最大最小值
MD_MC_READ_EG_PARA(0x13):讀取夾爪開口的最大最小值
CMD_MC_READ_EG_STATE(0x14):讀取當前夾爪的狀態
CMD_MC_READ_EG_RUNSTATE(0x41);讀取當前夾爪運行狀態
數據體2/2——數據:隨指令幀一起發送的數據內容。其中,讀指令時該數據體無字節;
寫指令時即為需要寫入的內容。
校驗和:校驗和 Check_Sum,定義為校驗和之前的除幀頭兩字節外其余所有數據累加和的低字節。
抓取:
釋放:
from serial import Serial # 夾爪驅動類 class Gripper: def __init__(self, port, baudrate): self.serial = Serial(port, baudrate) def catch(self, speed=500, power=100): # 夾取邏輯 # 1.創建串口通訊的對象 # 2.發送數據 注意傳的是字節數據 # data = b'\xEB\x90\x01\x05\x10\xF4\x01\x64\x00\x6F' b0b1 = b'\xEB\x90' b2 = b'\x01' b3 = b'\x05' b4 = b'\x10' # 數據轉換成字節數組 b5 = bytearray([speed & 0x00ff]) # 取低字節 b6 = bytearray([speed >> 8]) # 取高字節 b7 = bytearray([power & 0x00ff]) # 取低字節 b8 = bytearray([power >> 8]) # 取高字節 # 將字節轉成int數據 b9 = bytearray([(ord(b2)+ord(b3)+ord(b4)+ord(b5)+ord(b6)+ord(b7)+ord(b8)) & 0x00ff]) data = b0b1+b2+b3+b4+b5+b6+b7+b8+b9 # 3.寫入數據(字節數據) self.serial.write(data) # 讀取返回值 # read_data = self.serial.read(7) # print(read_data[0]) # 4.關閉串口通訊對象 self.serial.close() def release(self, speed=500): # 釋放邏輯 # 1.創建串口通訊的對象 # 2.發送數據 注意傳的是字節數據 # data = b'\xEB\x90\x01\x05\x10\xF4\x01\x64\x00\x6F' b0b1 = b'\xEB\x90' b2 = b'\x01' b3 = b'\x03' b4 = b'\x11' # 數據轉換成字節數組 b5 = bytearray([speed & 0x00ff]) # 取低字節 b6 = bytearray([speed >> 8]) # 取高字節 # 將字節轉成int數據 b7 = bytearray([(ord(b2) + ord(b3) + ord(b4) + ord(b5) + ord(b6)) & 0x00ff]) data = b0b1 + b2 + b3 + b4 + b5 + b6 + b7 # 3.寫入數據(字節數據) self.serial.write(data) # 4.關閉串口通訊對象 self.serial.close() if __name__ == '__main__': # 注意運行前,要先給 /dev/ttyUSB0 這個端口 chmod+權限 gripper = Gripper('/dev/ttyUSB0', 115200) # 夾取 gripper.catch() # 等待夾取完成 ... # 釋放 gripper.release()