|
分享点有意思的东西,就是六轴机械手,采用的是DMG10600C101_03WTC迪文屏,即T5L芯片为主控,和六轴机械手之间采用的是modbus tcp协议,这里是tcp协议哦,不是rtu协议,也不是ascii协议
机械臂长如下这样的,不过市面上外观很多种,本质基本是一样的,有四轴的,有六轴的,然后很多机械手都是带有急刹停功能和碰撞检测功能的,主要是为了安全考虑,然后程序是可以全部抓取这些信息的
然后modbus tcp协议具有它自己独特的MBAP报文头,如下所示
1.事务元标识符:其取值为0x00,0x00,一般也理解为包序列号,依次递增的,如果从机验证不严格的话,也可以保持不变的
2.协议标识符:其取值为0x00,0x00,这是协议的固定标识。该标识符用于明确所使用的协议类型
3.长度:其取值需经过计算得出。长度域指明了后续字节的数量,涵盖单元标识符及数据域
4.单元标识符:其取值为0x01。该域主要作为设备站号,即远程从站的唯一识别码,但是在tcp协议中,此字段意义不大
然后主界面的布局效果如下:
左侧是获取六轴机械手的关节信息和空间坐标信息的,右侧是控制操作区,机械手是支持移动速度随意调节的
1.实时获取关节信息和空间坐标信息
if(is_inited&&(get_info_period==GET_INFO_PERIOD))
{
get_info_period = 0;
//关节信息
packet.slave_addr = 0x01;
packet.func_code = MODBUS_FUNC_CODE_03;
packet.start_addr = 202;
packet.data_len = 8;
modbus_tcp_packet((u8*)&packet);
is_modbus_recv_complete = 0;
//笛卡尔坐标信息
packet.slave_addr = 0x01;
packet.func_code = MODBUS_FUNC_CODE_02;
packet.start_addr = 242;
packet.data_len = 6;
modbus_tcp_packet((u8*)&packet);
is_modbus_recv_complete = 0;
}
2.解析机械手的返回信息
void modbus_msg_handler(u8 *msg,u16 msg_len)
{
union{
float val;
u8 bytes[4];
}info;
msg_len = msg_len;
if((msg[7]==MODBUS_FUNC_CODE_03)&&(msg[8]==16))
{
info.bytes[0] = msg[9];
info.bytes[1] = msg[12];
info.bytes[2] = msg[9];
info.bytes[3] = msg[10];
sys_write_vp(0x2100, (u8*)&info.val, 2);
info.bytes[0] = msg[13];
info.bytes[1] = msg[16];
info.bytes[2] = msg[13];
info.bytes[3] = msg[14];
sys_write_vp(0x2110, (u8*)&info.val, 2);
info.bytes[0] = msg[17];
info.bytes[1] = msg[20];
info.bytes[2] = msg[17];
info.bytes[3] = msg[18];
sys_write_vp(0x2120, (u8*)&info.val, 2);
info.bytes[0] = msg[21];
info.bytes[1] = msg[24];
info.bytes[2] = msg[21];
info.bytes[3] = msg[22];
sys_write_vp(0x2130, (u8*)&info.val, 2);
}else if((msg[7]==MODBUS_FUNC_CODE_02)&&(msg[8]==12))
{
info.bytes[0] = msg[11];
info.bytes[1] = msg[12];
info.bytes[2] = msg[9];
info.bytes[3] = msg[10];
sys_write_vp(0x2140, (u8*)&info.val, 2);
info.bytes[0] = msg[15];
info.bytes[1] = msg[14];
info.bytes[2] = msg[13];
info.bytes[3] = msg[14];
sys_write_vp(0x2150, (u8*)&info.val, 2);
info.bytes[0] = msg[19];
info.bytes[1] = msg[20];
info.bytes[2] = msg[17];
info.bytes[3] = msg[18];
sys_write_vp(0x2160, (u8*)&info.val, 2);
}
}
3.启动按钮的代码
if(btn_val==0x01)
{
packet.slave_addr = 0x01;
packet.func_code = MODBUS_FUNC_CODE_05;
packet.start_addr = 0x0000;
packet.data_len = 0xFF00;
modbus_tcp_packet((u8*)&packet);
}
4.修改机械手移动速度的代码
else if(btn_val==0x11)
{
sys_read_vp(0x2000, (u8*)&speed, 1);
packet.slave_addr = 0x01;
packet.func_code = MODBUS_FUNC_CODE_06;
packet.start_addr = 1300;
packet.data_len = 1;
modbus_tcp_packet((u8*)&packet);
sys_delay_ms(1000);
//修改速度
packet.slave_addr = 0x01;
packet.func_code = MODBUS_FUNC_CODE_06;
packet.start_addr = 1304;
packet.data_len = speed;
modbus_tcp_packet((u8*)&packet);
sys_delay_ms(100);
packet.slave_addr = 0x01;
packet.func_code = MODBUS_FUNC_CODE_06;
packet.start_addr = 1312;
packet.data_len = 1;
modbus_tcp_packet((u8*)&packet);
}
5.然后是机械手关节tcp命令表
MODBUS_TCP_PACKET packet;
u8 J1_P[] = {0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x00, 0xff, 0x00};
u8 J2_P[] = {0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x03, 0x00, 0x01};
u8 J3_P[] = {0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x02, 0xff, 0x00};
u8 J4_P[] = {0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x05, 0x00, 0x00};
u8 is_inited = 0;
感兴趣的可以详看代码
6.视频演示效果
https://b23.tv/GxmZQ9P
7.参考代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|