在我们使用舵机的过程中,我们需要先对舵机进行配置,设置一下必要的参数,还要设置ID
这部分在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.测试
输入对应的编号就可以配置对应的信息