找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11324|回复: 5
收起左侧

Dynamixel数字舵机驱动

[复制链接]
ID:80436 发表于 2015-5-21 23:17 | 显示全部楼层 |阅读模式
好久没更新技术类日志了,今天更新下,这是一个韩国robotics机器人Dynamixel数字舵机的驱动,采用C语言编写,支持Dynamixel 通信协议 ,案例是AVR单片。实际上可以采用FPGA,例如SOPC系统上,可控制小型机器人。







在这也拆解下CM-5的控制器,是一片atmega128A 哦!哈哈。这PCB做工一般,感觉韩国人是科技领域爆发户,但我们有什么资格嘲笑棒子呢,至少人家都能造CPU了,我们呢?







#include <avr/io.h>
#include <util/delay.h>
void InitUart0(void)
{  
UCSR0A = 0x02; // 设置为倍速模式
UBRR0H = 0;
UBRR0L = 1;
UCSR0B = (1<<RXEN)|(1<<TXEN);// 接收器与发送器使能
UCSR0C = (3<<UCSZ0);
DDRE &= ~_BV(PE0); // 初始化RX 端口默认方向为输入
PORTE &= ~_BV(PE0); // 初始化RX 端口默认状态为高阻
DDRE |= _BV(PE1); // 初始化TX 端口默认方向为输出
PORTE |= _BV(PE1); // 初始化TX 端口默认状态为高电平
DDRA |= _BV(PA0); // 初始化使能端口状态方向为输出
PORTA &= ~_BV(PA0); // 初始化使能端口状态为RX 状态
DDRA |= _BV(PA1); // 初始化使能端口状态方向为输出
PORTA |= _BV(PA1); // 初始化使能端口状态方为TX 状态
}
void SendUart0Byte(unsigned char data)
{   
while ( !( UCSR0A & (1<<UDRE)) );// 等待发送缓冲器为空
UDR0 = data;/* 将数据放入缓冲器,发送数据*/
}
void SetServoLimit(unsigned char id, unsigned short int cw_limit, unsigned short int ccw_limit)
{
unsigned short int temp_ccw = 0; // 临时速度,用于进行方向判别
unsigned short int temp_cw = 0;
unsigned char temp_ccw_h = 0; // 待发送数据h 位
unsigned char temp_ccw_l = 0; // 待发送数据l 位
unsigned char temp_cw_h = 0;
unsigned char temp_cw_l = 0;
unsigned char temp_sum = 0; // 校验和寄存变量


if (ccw_limit > 1023)
{
temp_ccw = 1023; // 限制速度值在可用范围内
}
else
{
temp_ccw = ccw_limit;
}
if (cw_limit > 1023)
{
temp_cw = 1023;
}
else
{
temp_cw = cw_limit;
}
temp_ccw_h = (unsigned char)(temp_ccw >> 8);
temp_ccw_l = (unsigned char)temp_ccw; // 将16bit 数据拆为2个8bit 数据
temp_cw_h = (unsigned char)(temp_cw >> 8);
temp_cw_l = (unsigned char)temp_cw; // 将16bit 数据拆为2个8bit 数据
PORTA &= ~_BV(PA1);
PORTA |= _BV(PA0); // 使总线处于主机发送状态
UCSR0A |= (1<<TXC0); // 清除UART0写完成标志
SendUart0Byte(0xFF); // 发送启动符号0xFF
SendUart0Byte(0xFF); // 发送启动符号0xFF
SendUart0Byte(id); // 发送id
SendUart0Byte(7); // 发送数据长度为参数长度+2,参数长度为3
SendUart0Byte(0x03); // 命令数据为“WRITE DATA”
SendUart0Byte(0x06); // 舵机控制寄存器首地址
SendUart0Byte(temp_cw_l); // 发送顺时针位置限制低位
SendUart0Byte(temp_cw_h); // 发送顺时针位置限制高位
SendUart0Byte(temp_ccw_l); // 发送逆时针位置限制低位
SendUart0Byte(temp_ccw_h); // 发送逆时针位置限制高位
temp_sum = id + 7 + 0x03 + 0x06 + temp_cw_l + temp_cw_h + temp_ccw_l + temp_ccw_h;
temp_sum = ~temp_sum; // 计算校验和
SendUart0Byte(temp_sum); // 发送校验和
while ( !( UCSR0A & (1<<TXC0)) ) // 等待发送完成
{ // (Waiting for finishing sending)
;
}
PORTA |= _BV(PA1);
PORTA &= ~_BV(PA0); // 使总线处于主机接收状态
_delay_ms(2); //送完成后,总线会被从机占用,反馈应答数据,所以进行延时
}
void SetServoPosition(unsigned char id, unsigned short int position, unsigned short int
velocity)
{
unsigned short int temp_velocity = 0; // 临时速度,用于进行方向判别
unsigned short int temp_position = 0;
unsigned char temp_velocity_h = 0; // 待发送数据h 位
unsigned char temp_velocity_l = 0; // 待发送数据l 位
unsigned char temp_position_h = 0;
unsigned char temp_position_l = 0;
unsigned char temp_sum = 0; // 校验和寄存变量
if (velocity > 1023)
{
temp_velocity = 1023; // 限制速度值在可用范围内
}
else
{
temp_velocity = velocity;
}
if (position > 1023)
{
temp_position = 1023;
}
else
{
temp_position = position;
}
temp_velocity_h = (unsigned char)(temp_velocity >> 8);
// 将16bit 数据拆为2个8bit 数据
temp_velocity_l = (unsigned char)temp_velocity;
temp_position_h = (unsigned char)(temp_position >> 8);
// 将16bit 数据拆为2个8bit 数据
temp_position_l = (unsigned char)temp_position;
PORTA &= ~_BV(PA1);
PORTA |= _BV(PA0); // 使总线处于主机发送状态
UCSR0A |= (1<<TXC0); // 清除UART0写完成标志
SendUart0Byte(0xFF); // 发送启动符号0xFF
SendUart0Byte(0xFF);
SendUart0Byte(id); // 发送id
SendUart0Byte(7); // 发送数据长度为参数长度+2,参数长度为3
SendUart0Byte(0x03); // 命令数据为“WRITE DATA”
SendUart0Byte(0x1E); // 舵机控制寄存器首地址
SendUart0Byte(temp_position_l); // 发送速度数据低位
SendUart0Byte(temp_position_h); // 发送速度数据高位
SendUart0Byte(temp_velocity_l); //发送位置低字节
SendUart0Byte(temp_velocity_h); // 发送位置高字节
temp_sum = id + 7 + 0x03 + 0x1E + temp_position_l + temp_position_h + temp_velocity_l +
temp_velocity_h;
temp_sum = ~temp_sum; // 计算校验和
SendUart0Byte(temp_sum); // 发送校验和 (Send the checksum)
while ( !( UCSR0A & (1<<TXC0)) ) // 等待发送完成
{ // (Waiting for finishing sending)
;
}
PORTA |= _BV(PA1);
PORTA &= ~_BV(PA0); // 使总线处于主机接收状态
_delay_ms(2); // 发送完成后,总线会被从机占用,反馈应答数据,所以进行延时
}
void SetServoVelocity(unsigned char id, signed short int velocity)
{
unsigned char temp_sign = 0; // 临时符号,用于进行方向判别
unsigned short int temp_velocity = 0; // 临时速度,用于进行方向判别
unsigned char temp_value_h = 0; // 待发送数据h 位
unsigned char temp_value_l = 0; // 待发送数据l 位
unsigned char temp_sum = 0; // 校验和寄存变量
if (velocity < 0)
{
temp_velocity = -velocity; // 如果为负数,则取绝对值
temp_sign = 1; // 设置负数符号标志
}
else
{
temp_velocity = velocity;
temp_sign = 0; // 设置正数符号标志
}
if (temp_velocity > 1023)
{
temp_velocity = 1023; // 限制速度值在可用范围内
}
temp_velocity |= (temp_sign << 10);
temp_value_h = (unsigned char)(temp_velocity >> 8);
// 将16bit 数据拆为2个8bit 数据
temp_value_l = (unsigned char)temp_velocity;
PORTA &= ~_BV(PA1);
PORTA |= _BV(PA0); // 使总线处于主机发送状态
UCSR0A |= (1<<TXC0); // 清除UART0写完成标志
SendUart0Byte(0xFF); // 发送启动符号0xFF
SendUart0Byte(0xFF); // 发送启动符号0xFF
SendUart0Byte(id); // 发送id
SendUart0Byte(5); // 发送数据长度为参数长度+2,参数长度为3
SendUart0Byte(0x03); // 命令数据为“WRITE DATA”
SendUart0Byte(0x20); // 舵机控制寄存器首地址
SendUart0Byte(temp_value_l); // 发送速度数据低位
SendUart0Byte(temp_value_h); // 发送速度数据高位
temp_sum = id + 5 + 0x03 + 0x20 + temp_value_l + temp_value_h;
temp_sum = ~temp_sum; // 计算校验和
SendUart0Byte(temp_sum); // 发送校验和
while ( !( UCSR0A & (1<<TXC0)) ) // 等待发送完成
{
;
}
PORTA |= _BV(PA1);
PORTA &= ~_BV(PA0); // 使总线处于主机接收状态
_delay_ms(2); // 发送完成后,总线会被从机占用,反馈应答数据,所以进行延时
}
int main(void)
{
InitUart0();
SetServoLimit(2,0,1023);
while(1)
  {
_delay_ms(1000); //延时1s
SetServoPosition(2, 1000, 500); //控制舵机以500的速度运动到1000的位置
_delay_ms(1000); //延时1s
SetServoPosition(2, 200, 100); //控制舵机以100的速度运动到200的位置


  }
}






回复

使用道具 举报

ID:130468 发表于 2016-7-14 17:13 | 显示全部楼层
新手求教: 前辈您好,很冒昧给您消息向您求助,希望能请教一点问题,在此现向您表示感谢。对于使用舵机来说,我是一个新手,现在需要调试一个MX-28R舵机,起初使用RoboPlus连接是识别了舵机的。然后我想修改舵机ID号和波特率,我就根据pdf文档在软件界面操作了,但我发现设置了几次,ID号和波特率并没有改变;然后我就脑残了一下,想着先关闭,重新打开软件连接一下,再看ID号显示是否改变,悲剧的是重启软件,竟然无法搜索到Dynamixel了,真不知道怎么办,十分着急。在此冒昧向您咨询一下,还望您能给予些许指点,不胜感激!
回复

使用道具 举报

ID:149181 发表于 2017-1-21 23:21 来自手机 | 显示全部楼层
FEETECH飞特舵机总线伺服驱动,采用SCS通讯协议,配有上位机操作软件,具备温度,位置,速度,电压,电流反馈。宽电压保护,堵转过载保护,硬件采用自主研发的舵机控制板,进口零配件,性能稳定,每个舵机出厂均一一检测。开发机器人、机械臂、工业、物流等可参考试用。
回复

使用道具 举报

ID:162986 发表于 2017-1-26 21:07 | 显示全部楼层
怎么可以下载啊
回复

使用道具 举报

ID:300001 发表于 2018-3-31 17:27 | 显示全部楼层
是把这段驱动程序放在程序里,就能用arduino控制AX-12A了吗?
回复

使用道具 举报

ID:300001 发表于 2018-3-31 17:28 | 显示全部楼层
火狐free 发表于 2016-7-14 17:13
新手求教: 前辈您好,很冒昧给您消息向您求助,希望能请教一点问题,在此现向您表示感谢。对于使用舵机来 ...

robotplus哪里能弄到
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表