单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 529|回复: 0
打印 上一主题 下一主题
收起左侧

桌面机械臂DARM制作教程

[复制链接]
跳转到指定楼层
楼主
cp00147 发表于 2019-9-26 16:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

以下内容为网络转载:

组装教程










这里有三个长度都是圆心到圆心的距离这个长度是越精确越好,也看你使用要求写字、画画、激光雕刻之类的长度差一点点都不是大问题
打印件有点收缩率,和碳管组装时或紧或大,请自行找工具处理一下╮(╯▽╰)╭




在底座安装前 要预先将电机都固定好 电机固定螺丝孔留了调节余量 使用2GT-232闭口皮带的话 将电机靠近旋转轴方向固定 然后上紧螺丝 限位可以后面安装 也可以一起安装了



底座安装看着螺丝洞装吧╮(╯▽╰)╭没什么难度装皮带可能有点紧需要耐心2GT16齿同步轮按上图的方向安装



这里的驱动轴 可能是最难装的部分 有两根紧绷的同步带拉着 同样需要耐心慢慢装 ╮(╯▽╰)╭
两边各有两颗M8垫片 共四颗垫片
光轴固定好后 用锁紧打印件 将两边锁紧



力臂的组装按着感觉装吧装出来和上图一样就没错了
提示下标注尺寸的地方是两个旋转轴之间的距离和上面那根平衡臂是一样长 214.7mm
请自行确定好尺寸




全部装在一起就OK了如何你长度都没搞错那DARM 机械臂部分就都装好了
用手活动下是否灵活╮(╯▽╰)╭
以上组装教程有哪里不明白的地方可以回帖提问撸主必将一一作答
后续电路和固件部分教程准备。。。请随时留意更新。。。

DARM 接线图

ramp1.4


melzi


Ramps1.4:的电机接线端是杜邦线四芯插,如果发现电机方向不对 只要将插头反向插入。
Melzi :如果是Melzi电机方向不对,只要对换左边或右边的两根线,如线序为红蓝黑绿 则红蓝对换或绿黑对换。
限位开关接常闭,接线时不分正负。但插ramps1.4限位的时候要小心插入标识S和—的位置不要插入+和-的位置(插错会造成短路╮(╯▽╰)╭看好再插,插完再检查一遍。。。)

这里要感谢群友似曾相识 的鼎力相助 (*^__^*)





红色箭头所示方向 为各轴旋转正方向 接电机线的时候要确定好

HEX烧录

2560烧录方法


Melzi烧录方法

联机调试



指令详细说明
M84 解除电机自锁(当你需要手动调整机械臂角度的时候需要用到)
M92 每转动一度需要的电机脉冲数量 XYZ对应各自的电机
M366 机械臂臂长等参数 B200:主臂长200mm;S214.7:副臂长214.7mm;C40:光轴垂直投影和旋转中心的距离40mm;H58:笔夹中心线到副臂靠近笔夹侧旋转轴的距离58mm。
M367 机械臂原点偏移量 将有图示做说明
M368 限位触发角度设置
M500 保存参数到EEPROM
M502 恢复默认参数到EEPROM
M503 读取EEPROM数据并显示
G90 绝对坐标系
G91 相对坐标系
G92 当前坐标设定
G93 当前机械臂角度设定
G94 恢复笛卡尔坐标系G代码动作(默认为绝对坐标系)
G95 执行G代码直接控制角度动作(默认为相对坐标系)

机械臂坐标系




通过M367 偏移量设置可以任意定义原点坐标╮(╯▽╰)╭

限位调试:
首先限位在未触发前是常闭的
限位接到控制板后可以用M119命令来查看限位的状态
Open是未触发;TRIGGERED是已触发
限位的安装时主臂限位偏上 副臂限位偏下 如下图


第一步:如果当前电机处于锁定发送M84 解除电机锁定
然后将机械臂摆成下图的角度(其实角度可以自己定只要你确定这个角度是对的)



第二步:确定好角度后就不要再动机械臂发送G93 X90 Y-35 Z0(X表达主臂处于90度位置,Y表示副臂处于-35度位置,Z表示旋转轴处于0度位置这里的单位都是角度)如果不是90度或-35度都没关系 输入你确定好的角度就可以
第三步:发送M114 记下当前的X Y Z的值等下验证用(如X58.87 Y100.00 Z50.75)
第四步:将XY速度调整到120先操作+y去触发副臂限位然后再操作+x去触发主臂限位(一定要先Y再X)


第五步:使用M368 发送刚才的触发角度并用M500 保存EEPROM和G28 角度初始化
第六步:发送G94回到笛卡尔坐标系
第七步:输入G1 X58.87 Y100.00 Z50.75 F900 (XYZ为刚才记下来的验证坐标)
当机械臂停在坐标位置后再用角度测量工具验证下角度是否正确
如果不正确请回到第一步 重新调整 ╮(╯▽╰)╭

原点定义:


高度调整请根据实际情况
1、G28 角度初始化后 可以运行到新坐标原点或其他点(如 G1X0 Y0 F900)
2、操作Z轴 慢慢下降 到达工作平面
3、使用M114 命令查看当前Z坐标 如当前Z坐标为-50
4、查看M367 的Z值 如Z为-10
5、将两个Z值相加 使用M367 保存新的Z值
6、使用M500 保存EEPROM
7、使用G28 重新初始化角度 现在Z轴0点已经在工作平台上了
可以使用G1 X0 Y0 Z0 F900 移动到原点位置来确定一下

使用M500后已经将参数保存到EEPROM里只要机械臂和工作平台没有移动过位置,
设定的新原点坐标一直保存在那里只要G28 初始化角度就可以跑G代码了(或将G28加到G代码的开头自动运行)

.baidu.com/s/1c1phimc

调试DARM 用到的软件

有兴趣的盆友 可以加QQ群:250369605 来一起玩转机械臂!!!

DARM 写字教程
打开文泰雕刻软件选择200*200 创建新文件


定义原定


输入文字




生成刀路


保存刀路


给刀路文件添加运行速度


使用Pronterface软件打开刚才生成的刀路文件


一切就绪就可以让机械臂 写字了 ╮(╯▽╰)╭

.baidu.com/s/1Mftoi 文泰雕刻软件网盘链接

对于部分吧友的2560的使用CH340芯片 将无法用之前帖子里提供的方法烧录HEX文件
可以使用ArduinoBuilder软件烧录 方法如下:

激光雕刻教程




DARM 的两个主要函数
1、 void calculate_SCARA_forward_Transform(float f_scara[3]) 机械臂正解函数
2、 void calculate_delta(float cartesian[3]) 机械臂反解函数
先来分析一下正解函数
正解函数是 已知机械臂的各旋转角度 求得笛卡尔坐标系三维坐标值



先想象机械臂由主臂和副臂构成的一个平面坐标系,如下图


CencerOffset 旋转轴偏移量
HeadOffset 头部偏移量
Linkage_1 主臂长度
Linkage_2 副臂长度
f_scara[X_AXIS] 主臂旋转角度
f_scara[Y_AXIS] 副臂旋转角度



x_sin = sin(f_scara[X_AXIS]/SCARA_RAD2DEG)* Linkage_1;
x_cos = cos(f_scara[X_AXIS]/SCARA_RAD2DEG)* Linkage_1;
y_sin = sin(f_scara[Y_AXIS]/SCARA_RAD2DEG)* Linkage_2;
y_cos = cos(f_scara[Y_AXIS]/SCARA_RAD2DEG)* Linkage_2;



主要是为了得到arm_xy的值。
然后想象从上往下观察机械臂,现在主臂和副臂构成一条线,加上两个偏移量就是arm_xy



delta[X_AXIS] = arm_xy *cos(f_scara[Z_AXIS]/SCARA_RAD2DEG) - SCARA_offset[X_AXIS];
delta[Y_AXIS] = arm_xy *sin(f_scara[Z_AXIS]/SCARA_RAD2DEG) - SCARA_offset[Y_AXIS];
delta[Z_AXIS] = x_sin + y_sin -SCARA_offset[Z_AXIS];
通过上面的公式就能得到当前笛卡尔坐标系的xyz三个坐标轴。
Z坐标(delta[Z_AXIS]) 可以看上面的第二幅 已经得出。

几个参数说明:
1、SCARA_RAD2DEG 这是弧度转角度的计算因子
SCARA_RAD2DEG = 180/pi = 57.2957795
2、SCARA_offset[X_AXIS]、SCARA_offset[Y_AXIS]、SCARA_offset[Z_AXIS]
是各轴笛卡尔坐标系下的偏移量,为了自定义原点坐标,就是M367修改的参数值。



SCARA_pos[X_AXIS] = cartesian[X_AXIS] *axis_scaling[X_AXIS] + SCARA_offset[X_AXIS];
SCARA_pos[Y_AXIS] = cartesian[Y_AXIS] *axis_scaling[Y_AXIS] + SCARA_offset[Y_AXIS];
SCARA_pos[Z_AXIS] = cartesian[Z_AXIS] *axis_scaling[Z_AXIS] + SCARA_offset[Z_AXIS];
先由上面公式得到实际的xyz坐标值
SCARA_pos[X_AXIS] 代表X轴坐标
SCARA_pos[Y_AXIS] 代表Y轴坐标
SCARA_pos[Z_AXIS] 代表Z轴坐标



此图为由上向下观察机械臂,主臂和副臂成一条直线。
ARM_XY = sqrt(pow(SCARA_pos[X_AXIS],2) +pow(SCARA_pos[Y_AXIS],2)) - CencerOffset - HeadOffset;
首先得到ARM_XY的值。



通过ARM_XY和SCARA_pos[Z_AXIS]得到ARM_XYZ。



这里用到了余弦定理(即已知三角形的三边,求角度)
cosa=(b^2+c^2-a^2)/2bc
cosb=(a^2+c^2-b^2)/2ac
cosc=(a^2+b^2-c^2)/2ab
SCARA_C2 = (pow(ARM_XYZ,2) -pow(Linkage_1,2) - pow(Linkage_2,2))/(2 * Linkage_1 * Linkage_2);
SCARA_S2 = sqrt( 1 - pow(SCARA_C2,2) );

SCARA_K1 = Linkage_1 + Linkage_2 *SCARA_C2;
SCARA_K2 = Linkage_2 * SCARA_S2;

SCARA_theta = (atan2(SCARA_pos[Z_AXIS],ARM_XY)+atan2(SCARA_K2,SCARA_K1));
SCARA_psi = atan2(SCARA_S2, SCARA_C2);
主要获得大臂夹角SCARA_theta 和大小臂夹角SCARA_psi

注:SCARA_C2 公式是(pow(Linkage_1,2) + pow(Linkage_2,2)- (pow(ARM_XYZ,2))/(2 *Linkage_1 * Linkage_2)前面加负号的简化公式。



delta[X_AXIS] = SCARA_theta * SCARA_RAD2DEG
delta[Y_AXIS] = (SCARA_theta - SCARA_psi) *SCARA_RAD2DEG
delta[Z_AXIS] =atan2(SCARA_pos[Y_AXIS],SCARA_pos[X_AXIS]) * SCARA_RAD2DEG;
最后都乘以弧度转角度因子得到各轴转动角度。



回答群友的问题
这里的f_scara[Y_AXIS]是一个负值
如果副臂旋转角度出现在在正方向 那f_scara[Y_AXIS]就是正值


比如这样







控制板的选择主要看这三个文件boards.h Configuration.h pins.h
打开boards.h 里面定义了各类型控制板的宏定义
如果我们用的是2560+ramps1.4
则需要找到#define BOARD_RAMPS_13_EFB 33
如果我们用的是Melzi
则需要找到#define BOARD_MELZI 63


然后打开Configuration.h
找到MOTHERBOARD 定义部分



这里就是定义你的固件是要使用哪种控制板
#ifndef MOTHERBOARD
#define MOTHERBOARD BOARD_ULTIMAKER //BOARD_MELZI
#endif
上面代码的意思是如果没有定义MOTHERBOARD 则定义MOTHERBOARD为BOARD_ULTIMAKER
所以我们可以在这段以前先定义MOTHERBOARD 如下
#define MOTHERBOARD BOARD_RAMPS_13_EFB
或者
#define MOTHERBOARD BOARD_MELZI
这里也可以填写
#define MOTHERBOARD 33

#define MOTHERBOARD 63
关于#define的用法请自行百度搜索

然后讲一下
pins.h里的内容



比如我们选择的是ramps1.4为例
我们定位到pins.h里的第533行



由上面的宏定义可知
如果我们定义了#define MOTHERBOARD BOARD_RAMPS_13_EFB
那IS_RAMPS 就为真
#if IS_RAMPS || MB(3DRAG) || MB(AZTEEG_X3)|| MB(AZTEEG_X3_PRO)
只要IS_RAMPS为真就能执行之后的一系列宏定义

想自己修改各脚位的功能就可以在这里修改。
我之前Melzi的Z轴步进电机驱动坏了我就通过修改Melzi在pins.h里对应的脚位定义,把E轴和Z轴对调。
在开源的第一代机械臂固件里,Melzi配置下面的E轴和Z轴还是相互对调的,如果自己编译一代固件并玩Melzi控制板的朋友需要注意一下。

注:之前帮被别人适配UM控制板 控制DARM 所以DARM的开源固件里实际选择的是UM控制板如果自己编译固件的朋友请使用上面教的方法自行修改一下。

修改限位参数:
在Configuration.h里关于限位的设置(可以搜索关键字,找到下面的内容)
// coarse Endstop Settings
#define ENDSTOPPULLUPS // Comment this out(using // at the start of the line) to disable the endstop pullup resistors

#ifndef ENDSTOPPULLUPS
//fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS isdefined
//#define ENDSTOPPULLUP_XMAX
//#define ENDSTOPPULLUP_YMAX
#define ENDSTOPPULLUP_ZMAX //open pin, inverted
#define ENDSTOPPULLUP_XMIN //open pin, inverted
#define ENDSTOPPULLUP_YMIN //open pin, inverted
//#define ENDSTOPPULLUP_ZMIN
#endif

#ifdef ENDSTOPPULLUPS
#define ENDSTOPPULLUP_XMAX
#define ENDSTOPPULLUP_YMAX
#define ENDSTOPPULLUP_ZMAX
#define ENDSTOPPULLUP_XMIN
#define ENDSTOPPULLUP_YMIN
#define ENDSTOPPULLUP_ZMIN
#endif

// The pullups are needed if you directlyconnect a mechanical endswitch between the signal and ground pins.
const bool X_MIN_ENDSTOP_INVERTING = true;// set to true to invert the logic of the endstop.
const bool Y_MIN_ENDSTOP_INVERTING = true;// set to true to invert the logic of the endstop.
const bool Z_MIN_ENDSTOP_INVERTING = true;// set to true to invert the logic of the endstop.
const bool X_MAX_ENDSTOP_INVERTING = false;// set to true to invert the logic of the endstop.
const bool Y_MAX_ENDSTOP_INVERTING = false;// set to true to invert the logic of the endstop.
const bool Z_MAX_ENDSTOP_INVERTING = true;// set to true to invert the logic of the endstop.
//#define DISABLE_MAX_ENDSTOPS
//#define DISABLE_MIN_ENDSTOPS

// Disable max endstops for compatibilitywith endstop checking routine
#if defined(COREXY) &&!defined(DISABLE_MAX_ENDSTOPS)
#define DISABLE_MAX_ENDSTOPS
#endif

分解开来讲解一下:
#define ENDSTOPPULLUPS
宏定义ENDSTOPPULLUPS 意思为限位端口的输出弱上拉是否使能

#ifndef ENDSTOPPULLUPS
//fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS isdefined
//#define ENDSTOPPULLUP_XMAX
//#define ENDSTOPPULLUP_YMAX
#define ENDSTOPPULLUP_ZMAX //open pin, inverted
#define ENDSTOPPULLUP_XMIN //open pin, inverted
#define ENDSTOPPULLUP_YMIN //open pin, inverted
//#define ENDSTOPPULLUP_ZMIN
#endif
如果ENDSTOPPULLUPS 没有被定义则定义下面的内容
#ifndef ENDSTOPPULLUPS
#endif
里面的内容可以根据实际情况选择或屏蔽掉

#ifdef ENDSTOPPULLUPS
#define ENDSTOPPULLUP_XMAX
#define ENDSTOPPULLUP_YMAX
#define ENDSTOPPULLUP_ZMAX
#define ENDSTOPPULLUP_XMIN
#define ENDSTOPPULLUP_YMIN
#define ENDSTOPPULLUP_ZMIN
#endif
如果ENDSTOPPULLUPS被之前定义了则使能全部限位的输入弱上拉

const bool X_MIN_ENDSTOP_INVERTING = true;// set to true to invert the logic of the endstop.
const bool Y_MIN_ENDSTOP_INVERTING = true;// set to true to invert the logic of the endstop.
const bool Z_MIN_ENDSTOP_INVERTING = true;// set to true to invert the logic of the endstop.
const bool X_MAX_ENDSTOP_INVERTING = false;// set to true to invert the logic of the endstop.
const bool Y_MAX_ENDSTOP_INVERTING = false;// set to true to invert the logic of the endstop.
const bool Z_MAX_ENDSTOP_INVERTING = true;// set to true to invert the logic of the endstop.
定义限位的触发极性
ENDSTOP_INVERTING的字面意思是限位触发极性反向
ENDSTOP_INVERTING = true 表示低电平触发(即不触发状态处于高电平)
因为启动了输入弱上拉功能,所以在没有接任何的限位传感器的情况下,检测到的输入是高电平,处于未触发状态。
所以如果我们可以将不使用的限位端口都设置成true 就不会影响机器运行。

一般的机械限位接线方法有常开 和 常闭 两种
常开和常闭 就字面意思来解释 常开就是在没有触发的情况下,两个触点是处于断开的状态并一直保存着断开的状态。直到触发了限位,触点闭合改变输出信号。常闭可以自己理解。
DARM 默认用的是常闭接法,所以在没触发的情况下,触点是闭合的(即是跟GND处于短接状态)
如果使用常闭限位,需要将相应的ENDSTOP_INVERTING设置为false
如果你暂时不想接限位,可以将ENDSTOP_INVERTING设置为true。先完成其他的调试。
不然的话ENDSTOP_INVERTING=false所对应的限位开关一直处于触发状态,控制步进电机动作将受到限位的影响,将不能向正处于触发状态的限位方向运动。


以上的Word格式文档51黑下载地址:
桌面机械臂DARM 制作教程.docx (2.7 MB, 下载次数: 4)





分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 顶 踩
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

Powered by 单片机教程网

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