——來(lái)自迪文開發(fā)者論壇
本期為大家推送迪文開發(fā)者論壇獲獎(jiǎng)開源案例——四軸機(jī)械臂控制系統(tǒng)。工程師采用T5L,基于DGUS軟件“旋轉(zhuǎn)指示”控件實(shí)現(xiàn)機(jī)械臂的實(shí)時(shí)位置顯示,并通過(guò)串口控制機(jī)械臂的運(yùn)動(dòng)過(guò)程。不同以往只展示機(jī)械臂的角度數(shù)值,該方案可以實(shí)現(xiàn)在屏幕上實(shí)時(shí)顯示機(jī)械臂的旋轉(zhuǎn)狀態(tài)。除此之外,工程師還增加了機(jī)械臂自動(dòng)運(yùn)動(dòng)功能。
【演示視頻】
完整開發(fā)資料含迪文屏DGUS工程資料與C51代碼,獲取方式:
1. 前往迪文開發(fā)者論壇獲?。?span style="font-family: 微軟雅黑, "Microsoft YaHei"; text-decoration: underline; line-height: 150%; color: rgb(51, 102, 153); background: rgb(255, 255, 255);">http://inforum.dwin.com.cn:20080/forum.php?mod=viewthread&tid=8596&_dsign=692ed954
2.微信公眾號(hào)中回復(fù)“四軸機(jī)械臂”獲取。
【UI素材展示】
UI素材可根據(jù)實(shí)際的應(yīng)用進(jìn)行多樣化的設(shè)計(jì),工程師設(shè)計(jì)了一套富有科技感的界面。
【UI開發(fā)示例】
【C51代碼設(shè)計(jì)】
(1)獲取機(jī)械臂當(dāng)前控制的角度
//獲取機(jī)械臂狀態(tài)
void get_arm_config_status()
{
u8 i = 0;
for(i = 0;i < 4;i++)
{
arm_angle_value[i] = Read_Dgus(0x1100 + i * 2);
//Write_Dgus(0x1110 + i * 2, Va[i]);
}
}
(2)機(jī)械臂的運(yùn)動(dòng)過(guò)程設(shè)計(jì):使機(jī)械臂根據(jù)設(shè)置的角度,緩慢移動(dòng)到指定位置。
//設(shè)置機(jī)械臂角度
void set_arm_angle()
{
int i = 0;
for(i = 0;i < 4;i++)
{
if(arm_angle_value[i] != arm_angle_value_last[i])
{
if(arm_angle_value[i] < arm_angle_value_last[i])
{
arm_angle_value_last[i]--;
}
else
{
arm_angle_value_last[i]++;
}
Write_Dgus(0x1110 + i * 2, arm_angle_value_last[i]);
if(i == 1) //第二軸運(yùn)動(dòng)
{
u16 armiii_pos_x = 0;
u16 armiii_pos_y = 0;
u16 armiv_pos_x = 0;
u16 armiv_pos_y = 0;
armiii_pos_x = sin((float)(225 - arm_angle_value_last[i]) * TRIGONOMETRIC) * 80 + armii_start_pos[0];
armiii_pos_y = cos((float)(225 - arm_angle_value_last[i]) * TRIGONOMETRIC) * 80 + armii_start_pos[1];
armiv_pos_x = sin((float)(180 - arm_angle_value_last[i+1]) * TRIGONOMETRIC) * 83 + armiii_pos_x;
armiv_pos_y = cos((float)(180 - arm_angle_value_last[i+1]) * TRIGONOMETRIC) * 83 + armiii_pos_y;
armiii_current_pos[0] = armiii_pos_x;
armiii_current_pos[1] = armiii_pos_y;
OneSendData4(armiii_pos_x/256);
OneSendData4(armiii_pos_x%256);
OneSendData4(armiii_pos_y/256);
OneSendData4(armiii_pos_y%256);
Write_Dgus(0x2100 + 4, armiii_pos_x); //第三軸的位置
Write_Dgus(0x2100 + 5, armiii_pos_y);
Write_Dgus(0x2200 + 4, armiv_pos_x); //第三軸的位置
Write_Dgus(0x2200 + 5, armiv_pos_y);
}
else if(i == 2)
{
u16 armiv_pos_x = sin((float)(180 - arm_angle_value_last[i]) * TRIGONOMETRIC) * 83 + armiii_current_pos[0];
u16 armiv_pos_y = cos((float)(180 - arm_angle_value_last[i]) * TRIGONOMETRIC) * 83 + armiii_current_pos[1];
Write_Dgus(0x2200 + 4, armiv_pos_x); //第三軸的位置
Write_Dgus(0x2200 + 5, armiv_pos_y);
}
break;
}
}
}
(3)按鍵設(shè)計(jì):開發(fā)者設(shè)計(jì)了復(fù)位、添加、刪除、開始、停止按鍵功能
//獲取按鍵狀態(tài)
void get_key_status(u16 addr)
{
u16 Va=Read_Dgus(addr);
//u16 V1=Read_Dgus(0x0f01);
if(Va != 0x0000)
{
if(Va == 0x0001) //復(fù)位
{
Write_Dgus(0x1100 + 0, 0);
Write_Dgus(0x1100 + 2, 0);
Write_Dgus(0x1100 + 4, 0);
Write_Dgus(0x1100 + 6, 90);
}
else if(Va == 0x0002) //添加
{
if(arm_auto_cnt < 5)
{
u8 i = 0;
u8 send_str[30] = {0};
for(i = 0;i < 4;i++)
{
arm_auto_list[arm_auto_cnt][i] = arm_angle_value[i];
}
sprintf(send_str, "I:%d II:%d III:%d IV:%d", arm_auto_list[arm_auto_cnt][0], arm_auto_list[arm_auto_cnt][1], arm_auto_list[arm_auto_cnt][2], arm_auto_list[arm_auto_cnt][3]);
write_dgus_vp(0x1500 + 0x20 * arm_auto_cnt, send_str, 16);
arm_auto_cnt++;
}
}
else if(Va == 0x0003) //開始
{
auto_start_flag = 1;
auto_start_cnt = 0;
}
else if(Va == 0x0004) //停止
{
auto_start_flag = 0;
Write_Dgus(0x1100 + 0, arm_angle_value_last[0]);
Write_Dgus(0x1100 + 2, arm_angle_value_last[1]);
Write_Dgus(0x1100 + 4, arm_angle_value_last[2]);
Write_Dgus(0x1100 + 6, arm_angle_value_last[3]);
}
else if(Va >= 0x0010 && Va <= 0x0014) //刪除內(nèi)容
{
u16 delete_select = Va - 0x0010;
if(arm_auto_cnt > delete_select) //有刪除的內(nèi)容
{
u8 i = 0;
u8 send_str[30] = {0};
for(i = delete_select;i < arm_auto_cnt - 1;i++)
{
memcpy(arm_auto_list[i], arm_auto_list[i + 1], 8);
}
memset(arm_auto_list[i], 0, 8);
for(i = delete_select;i < arm_auto_cnt - 1;i++)
{
sprintf(send_str, "I:%d II:%d III:%d IV:%d\0", arm_auto_list[i][0], arm_auto_list[i][1], arm_auto_list[i][2], arm_auto_list[i][3]);
write_dgus_vp(0x1500 + 0x20 * i, send_str, 16);
}
memset(send_str, 0, 30);
write_dgus_vp(0x1500 + 0x20 * i, send_str, 16);
arm_auto_cnt--;
}
}
Write_Dgus(addr, 0);
}
}
(4)機(jī)械臂自動(dòng)運(yùn)動(dòng)功能
//自動(dòng)運(yùn)動(dòng)
void auto_run()
{
if(auto_start_flag == 1 && arm_auto_cnt >= 2) //動(dòng)作必須兩個(gè)及以上
{
if(memcmp(arm_angle_value, arm_auto_list[auto_start_cnt], 8) != 0) //不等于
{
Write_Dgus(0x1100 + 0, arm_auto_list[auto_start_cnt][0]);
Write_Dgus(0x1100 + 2, arm_auto_list[auto_start_cnt][1]);
Write_Dgus(0x1100 + 4, arm_auto_list[auto_start_cnt][2]);
Write_Dgus(0x1100 + 6, arm_auto_list[auto_start_cnt][3]);
}
else if(memcmp(arm_angle_value_last, arm_auto_list[auto_start_cnt], 8) == 0) //當(dāng)前運(yùn)動(dòng)等于目標(biāo)
{
auto_start_cnt++;
if(auto_start_cnt >= arm_auto_cnt)
{
auto_start_cnt = 0;
}
}
}
}