在我們使用舵機的過程中,我們需要先對舵機進行配置,設定一下必要的參數,還要設定ID
文章目錄
- 一、配置舵機代碼
- 二、測試
-
- 1.硬體連接配接
- 2.測試
這部分在config_serial_servo檔案裡
一、配置舵機代碼
# 配置序列槽舵機
#!/usr/bin/python3
# encoding: utf-8
# 配置序列槽舵機的參數
# 每次隻能配置一個舵機,且樹莓派擴充闆隻能連接配接一個舵機,既是一個舵機一個舵機配置參數
import sys
if sys.version_info.major == 2:
print('Please run this program with python3!') # 請運作在python3的環境下
sys.exit(0) # 結束程式
from SerialServoCmd import * # 導入序列槽舵機指令庫
# 序列槽舵機設定ID
# oldid 原來的ID newid 要設定的新的ID
def serial_servo_set_id(oldid, newid):
serial_serro_wirte_cmd(oldid, LOBOT_SERVO_ID_WRITE, newid) # 寫入舵機id
# 序列槽舵機讀ID
# id 如果不傳參,預設廣播 此時隻能有一個舵機連接配接,否則會亂碼
def serial_servo_read_id(id=None):
while True:
if id is None: # 如果這個id是空的
#0xfe 為舵機的廣播位址,總線上智能接一個舵機,不然都會傳回資料造成總線沖突
serial_servo_read_cmd(0xfe, LOBOT_SERVO_ID_READ)
else:
serial_servo_read_cmd(id, LOBOT_SERVO_ID_READ) # 讀取舵機的ID
# 擷取内容
msg = serial_servo_get_rmsg(LOBOT_SERVO_ID_READ) # 如果資訊不是空
if msg is not None: # 傳回資訊
return msg
# 序列槽舵機停止
# id: 要停止的舵機
def serial_servo_stop(id=None):
serial_serro_wirte_cmd(id, LOBOT_SERVO_MOVE_STOP) # 發送指令舵機停止運作
# 配置偏差 掉電保護
# id:舵機id d :偏差
def serial_servo_set_deviation(id, d=0):
# 設定偏差 掉電不保護
serial_serro_wirte_cmd(id, LOBOT_SERVO_ANGLE_OFFSET_ADJUST, d) # 角度偏差調整
# 設定為掉電保護
serial_serro_wirte_cmd(id, LOBOT_SERVO_ANGLE_OFFSET_WRITE) # 角度偏差寫
# 序列槽舵機讀取偏內插補點 範圍-125--125 對應角度-30度--30度
# id:要讀取的舵機ID
def serial_servo_read_deviation(id):
# 發送讀取偏差指令
while True:
serial_servo_read_cmd(id, LOBOT_SERVO_ANGLE_OFFSET_READ) # 讀取偏內插補點
# 擷取資料
msg = serial_servo_get_rmsg(LOBOT_SERVO_ANGLE_OFFSET_READ) # 傳回偏內插補點的資訊
if msg is not None: # 消息不為空
return msg # 傳回消息(偏內插補點)
# 設定序列槽舵機轉動範圍
# id: 要設定的舵機 low: 最小角度的範圍0-1000 high:最大角度範圍0-1000
def serial_servo_set_angle_limit(id, low, high):
serial_serro_wirte_cmd(id, LOBOT_SERVO_ANGLE_LIMIT_WRITE, low, high) # 寫入角度的轉動範圍
#讀取舵機轉動範圍
# id: 要讀取的舵機
def serial_servo_read_angle_limit(id):
while True:
serial_servo_read_cmd(id, LOBOT_SERVO_ANGLE_LIMIT_READ) # 讀取角度範圍指令
msg = serial_servo_get_rmsg(LOBOT_SERVO_ANGLE_LIMIT_READ) # 讀取資料
if msg is not None: # 消息不為空
return msg # 傳回舵機的轉動範圍
# 設定序列槽舵機的電壓值範圍 4500-12000mv 4.5V-12V
def serial_servo_set_vin_limit(id, low, high):
serial_serro_wirte_cmd(id, LOBOT_SERVO_VIN_LIMIT_WRITE, low, high)
# 讀取序列槽舵機的電壓值範圍
def serial_servo_read_vin_limit(id):
while True:
serial_servo_read_cmd(id, LOBOT_SERVO_VIN_LIMIT_READ) # 讀舵機電壓值
msg = serial_servo_get_rmsg(LOBOT_SERVO_VIN_LIMIT_READ)
if msg is not None: # 消息不為空
return msg
# 設定舵機最高溫度限制 範圍50-100度 預設值85度
def serial_servo_set_max_temp(id, m_temp):
serial_serro_wirte_cmd(id, LOBOT_SERVO_TEMP_MAX_LIMIT_WRITE, m_temp) # 舵機最高溫度指令
# 讀取舵機最高溫度限制
def serial_servo_read_temp_limit(id):
while True:
serial_servo_read_cmd(id, LOBOT_SERVO_TEMP_MAX_LIMIT_READ) # 讀舵機最高溫度指令
msg = serial_servo_get_rmsg(LOBOT_SERVO_TEMP_MAX_LIMIT_READ) # 讀資料
if msg is not None:
return msg
# 讀取舵機目前的實際角度位置值
def serial_servo_read_pos(id):
while True:
serial_servo_read_cmd(id, LOBOT_SERVO_POS_READ) # 讀目前位置指令
msg = serial_servo_get_rmsg(LOBOT_SERVO_POS_READ) # 讀資料
if msg is not None: # 消息不為空
return msg
#讀取舵機内部實時溫度
def serial_servo_read_temp(id):
while True:
serial_servo_read_cmd(id, LOBOT_SERVO_TEMP_READ) # # 讀舵機溫度指令
msg = serial_servo_get_rmsg(LOBOT_SERVO_TEMP_READ) #讀資料
if msg is not None: #消息不為空
return msg
# 讀取舵機内部目前輸入電壓值
def serial_servo_read_vin(id):
while True:
serial_servo_read_cmd(id, LOBOT_SERVO_VIN_READ) # 讀電壓指令
msg = serial_servo_get_rmsg(LOBOT_SERVO_VIN_READ) #讀資料
if msg is not None: #消息不為空
return msg
# 把舵機複位到中位
def serial_servo_rest_pos(oldid):
# 舵機清零偏差和P值中位(500)
serial_servo_set_deviation(oldid, 0) # 清零偏差
time.sleep(0.1)
serial_serro_wirte_cmd(oldid, LOBOT_SERVO_MOVE_TIME_WRITE, 500, 100) # 設定舵機角度為500,移動時間為100ms
# 顯示舵機目前的狀态
# id:要顯示的舵機 預設廣播,
def show_servo_state(id = None):
oldid = serial_servo_read_id(id) #讀出舵機的id
portRest() # 端口複位
if oldid is not None: # 如果ID是不是空的
print('目前的舵機ID是:%d' % oldid)
pos = serial_servo_read_pos(oldid) # 讀出舵機的位置
print('目前的舵機角度:%d' % pos)
portRest()
now_temp = serial_servo_read_temp(oldid) # 現在舵機的溫度
print('目前的舵機溫度:%d°' % now_temp)
portRest()
now_vin = serial_servo_read_vin(oldid) #讀電壓值
print('目前的舵機電壓:%dmv' % now_vin)
portRest()
d = serial_servo_read_deviation(oldid) #讀偏內插補點
print('目前的舵機偏差:%d' % ctypes.c_int8(d).value)
portRest()
limit = serial_servo_read_angle_limit(oldid) #讀轉動角度範圍
print('目前的舵機可控角度為%d-%d' % (limit[0], limit[1]))
portRest()
vin = serial_servo_read_vin_limit(oldid) #讀電壓值範圍
print('目前的舵機報警電壓為%dmv-%dmv' % (vin[0], vin[1]))
portRest()
temp = serial_servo_read_temp_limit(oldid) #讀溫度範圍
print('目前的舵機報警溫度為50°-%d°' % temp)
portRest()
return oldid # 傳回舵機的id
# 如果是單獨執行這個程式的話
if __name__ == '__main__':
portInit() # 端口複位
oldid = show_servo_state() # 列印舵機的資訊
while True:
print ('*' * 50) # 列印50個*字元
print ('1、設定舵機ID号')
print ('2、設定舵機偏差')
print ('3、設定舵機轉動角度範圍')
print ('4、設定舵機電壓報警範圍')
print ('5、設定舵機溫度報警範圍')
print ('6、顯示舵機狀态')
print ('7、中位舵機')
print ('8、退出')
print ('*' * 50)
num = int(input('請輸入需要配置的數字')) # 輸入一個int型數字
num6_flag = 0
while 1 <= num <= 7: # 這個數字在1-7範圍内
if num == 1:
num6_flag = 0
n_id = int(input('請輸入新的舵機ID号(範圍:0-253)')) # 輸入新舵機ID
if n_id > 253:
print ('超過範圍,請重新輸入')
else:
serial_servo_set_id(oldid, n_id) # 設定新舵機id
portRest()
if serial_servo_read_id() == n_id: # 讀取舵機的ID
# 設定不成功的話繼續設定
oldid = n_id # 設定成功
print ('設定成功')
break
elif num == 2:
num6_flag = 0
n_d = int(input('請輸入舵機偏內插補點(範圍:-125 ~ 125)')) # 輸入舵機的偏內插補點
if n_d < -125 or n_d > 125: # 超出範圍
print ('超過範圍,請重新輸入')
else:
serial_servo_set_deviation(oldid, n_d) # 設定舵機的偏內插補點
time.sleep(0.1)
portRest()
zf_d = serial_servo_read_deviation(oldid) # 讀舵機的偏內插補點
if zf_d > 127: # 負數 最高位是1
zf_d = -(0xff - (zf_d - 1)) # 轉換為正值
if zf_d == n_d:
print ('設定成功')
break # 跳出循環
elif num == 3:
num6_flag = 0
print ('請輸入舵機的轉動範圍(0 ~ 1000)')
low_ang_limit = int(input('請輸入低範圍值'))
high_ang_limit = int(input('請輸入高範圍值'))
# 還需要判斷low_ang_limit >high_ang_limit的情況
if low_ang_limit < 0 or high_ang_limit < 0 or low_ang_limit >= 1000 or high_ang_limit > 1000:
print ('超過範圍,請重新輸入')
else:
serial_servo_set_angle_limit(oldid, low_ang_limit, high_ang_limit)
portRest()
lim = serial_servo_read_angle_limit(oldid) # 讀取舵機的角度範圍
if lim[0] == low_ang_limit and lim[1] == high_ang_limit:
print ('設定成功')
break # 跳出循環
elif num == 4:
num6_flag = 0
print ('請輸入舵機的電壓報警範圍(4500 ~ 12000)mv')
low_vin_limit = int(input('請輸入低範圍值'))
high_vin_limit = int(input('請輸入高範圍值'))
# 還需要判斷low_vin_limit > high_vin_limit的情況
if low_vin_limit < 4500 or high_vin_limit < 4500 or low_vin_limit >= 12000 or high_vin_limit > 12000:
print ('超過範圍,請重新輸入')
else:
serial_servo_set_vin_limit(oldid, low_vin_limit, high_vin_limit)
portRest()
vin = serial_servo_read_vin_limit(oldid) # 讀電壓值範圍
if vin[0] == low_vin_limit and vin[1] == high_vin_limit:
print ('設定成功')
break
elif num == 5:
num6_flag = 0
n_temp = int(input('請輸入舵機的溫度報警範圍(範圍:50-100)度'))
if n_temp > 100 or n_temp < 50:
print ('超過範圍,請重新輸入')
else:
serial_servo_set_max_temp(oldid, n_temp) # 設定舵機的溫度報警上限
portRest()
if serial_servo_read_temp_limit(oldid) == n_temp:
# 不成功繼續
print ('設定成功')
break
elif num == 6: # 顯示舵機狀态
if num6_flag == 0:
oldid = show_servo_state() # 顯示舵機的狀态
num6_flag = 1
break # 跳出循環
elif num == 7: # 中位舵機
num6_flag = 0
serial_servo_rest_pos(oldid) # 設定舵機到中位
print ('中位成功')
break # 跳出循環
# 沒有進入循環
if num == 8:
break # 跳出大循環 退出程式
elif num < 1 or num > 8: # 不在菜單範圍内
print ('輸入有誤,請重新輸入')
二、測試
1.硬體連接配接
我連接配接的是6号舵機
2.測試
輸入對應的編号就可以配置對應的資訊