本文使用一种使用 CNC 扩展板和 Arduino Uno 控制步进电机驱动的 EEZYBOT MK2 机械臂的简单方法。
EEZYBOT MK2 手臂
如果你搜索过很酷的机械臂,那么您很可能偶然发现过这个。EEZYBOT MK2 手臂共享 ABB IRB460 的运动连杆,比例为 1:7。然而,这个手臂设计用于伺服系统,这使得它有点摇晃和不那么优雅。它使用 3 个步进电机来移动其连杆。
如果您在组装手臂时遇到问题,网上有很多教程。
选择起始位置
与伺服系统不同,步进电机没有任何位置感知。我们必须通过在手臂通电时首先设置归位程序来解决这个问题。我们将使用 3 个限位开关来设置我们的起始位置。连杆的工作方式有些复杂,但是一旦组装好手臂并查看一切如何移动,您就会很容易理解开关的位置。
即没有像笛卡尔系统那样的XY,但无论如何我们都会这样称呼它们以使事情变得更容易。
您可以在手臂主底座的任何位置设置 Z 限位开关。添加一点热胶,这样当手臂移动时你的电线就不会脱落。
接线
接线非常简单,因为所有端子都标记在 CNC 防护罩上。只是不要以错误的方式插入您的 A4988 驱动程序!带有 Y 限位开关一侧的步进电机必须插入 CNC 防护罩中 Y 步进电机的端子。X限位开关一侧的电机也是如此。(我们称这些 X 和 Y 是因为这样更容易处理 CNC 屏蔽)将旋转臂底座的最终步进器连接到 Z 端子,并根据它们的名称连接止动件。极性无关紧要。
找一个合适的 12V 电源,它可以为电机提供电流而不会停转。
代码
我们将使用 Arduino 的 AccelStepper 库来平稳地驱动步进器。该库允许您轻松地同时加速、减速和运行多个步进电机。您可以使用库管理器(Sketch > Include Library > Library Manager)直接通过 Arduino IDE 获取此库
现在我们已经拥有了我们需要的一切,让我们一步一步地回顾代码。
首先,我们将为要使用的引脚定义一些名称。您可以通过快速谷歌图片搜索找到 CNC 屏蔽的引脚图。我们还将为我们的 3 个步进电机创建 AccelStepper 对象。
#define XSTEP 2 //Stepper Motor Step pin
#define YSTEP 3
#define ZSTEP 4
#define XDIR 5 // Stepper motor Direction control pin
#define YDIR 6
#define ZDIR 7
#define ENABLE 8 // CNC Shield Enable Pin
#define XLIMIT 9 // Limit switch pins
#define YLIMIT 10
#define ZLIMIT 11
#define XMOTORACC 250 // Acceleration and Max Speed values
#define XMOTORMAXSPEED 1000
#define YMOTORACC 250
#define YMOTORMAXSPEED 1000
#include <AccelStepper.h>
AccelStepper XMOTOR(1,XSTEP,XDIR);
AccelStepper YMOTOR(1,YSTEP,YDIR);
AccelStepper ZMOTOR(1,ZSTEP,ZDIR);
让我们做一个小辅助函数来设置我们的引脚:
void pinsetup(){
pinMode(ENABLE,OUTPUT);
digitalWrite(ENABLE,LOW);
pinMode(XLIMIT,INPUT_PULLUP);
pinMode(YLIMIT,INPUT_PULLUP);
pinMode(ZLIMIT,INPUT_PULLUP);
}
现在已经完成了,让我们回顾一下我们的归位程序的逻辑:
void autohome(){ //We're using this to call our homing routine
xyhome();
zhome();
}
void xyhome() {
int initial_xhome = -1;
int initial_yhome = -1;
// Set Max Speed and Acceleration of each Steppers at startup for homing
XMOTOR.setMaxSpeed(500.0); // Set Max Speed of Stepper (Slower to get better accuracy)
XMOTOR.setAcceleration(50.0); // Set Acceleration of Stepper
YMOTOR.setMaxSpeed(500.0); // Set Max Speed of Stepper (Slower to get better accuracy)
YMOTOR.setAcceleration(50.0); // Set Acceleration of Stepper
// Start Homing procedure of Stepper Motor at startup
while (digitalRead(YLIMIT)) { // Make the Stepper move CCW until the switch is activated
XMOTOR.moveTo(initial_xhome); // Set the position to move to
YMOTOR.moveTo(initial_yhome); // Set the position to move to
initial_xhome--; // Decrease by 1 for next move if needed
initial_yhome--;
XMOTOR.run(); // Start moving the stepper
YMOTOR.run();
delay(5);
}
XMOTOR.setCurrentPosition(0); // Set the current position as zero for now
YMOTOR.setCurrentPosition(0);
initial_xhome = -1;
initial_yhome = 1;
while(digitalRead(XLIMIT)){
XMOTOR.moveTo(initial_xhome); // Set the position to move to
YMOTOR.moveTo(initial_yhome); // Set the position to move to
initial_xhome--; // Decrease by 1 for next move if needed
initial_yhome++;
XMOTOR.run(); // Start moving the stepper
YMOTOR.run();
delay(5);
}
YMOTOR.setCurrentPosition(0); // Set the current position as zero for now
YMOTOR.setMaxSpeed(250.0); // Set Max Speed of Stepper (Slower to get better accuracy)
YMOTOR.setAcceleration(10.0); // Set Acceleration of Stepper
initial_yhome = 1;
while (!digitalRead(YLIMIT)) { // Make the Stepper move CW until the switch is deactivated
YMOTOR.moveTo(initial_yhome);
YMOTOR.run();
initial_yhome++;
delay(5);
}
YMOTOR.setCurrentPosition(0);
YMOTOR.setMaxSpeed(YMOTORMAXSPEED); // Set Max Speed of Stepper (Faster for regular movements)
YMOTOR.setAcceleration(YMOTORACC); // Set Acceleration of Stepper
XMOTOR.setCurrentPosition(0); // Set the current position as zero for now
XMOTOR.setMaxSpeed(250.0); // Set Max Speed of Stepper (Slower to get better accuracy)
XMOTOR.setAcceleration(10.0); // Set Acceleration of Stepper
initial_xhome = 1;
while (!digitalRead(XLIMIT)) { // Make the Stepper move CW until the switch is deactivated
XMOTOR.moveTo(initial_xhome);
XMOTOR.run();
initial_xhome++;
delay(5);
}
XMOTOR.setCurrentPosition(0);
XMOTOR.setMaxSpeed(XMOTORMAXSPEED); // Set Max Speed of Stepper (Faster for regular movements)
XMOTOR.setAcceleration(XMOTORACC); // Set Acceleration of Stepper
}
void zhome() {
int initial_zhome = -1;
// Set Max Speed and Acceleration of each Steppers at startup for homing
ZMOTOR.setMaxSpeed(100.0); // Set Max Speed of Stepper (Slower to get better accuracy)
ZMOTOR.setAcceleration(100.0); // Set Acceleration of Stepper
// Start Homing procedure of Stepper Motor at startup
while (digitalRead(ZLIMIT)) { // Make the Stepper move CCW until the switch is activated
ZMOTOR.moveTo(initial_zhome); // Set the position to move to
initial_zhome--; // Decrease by 1 for next move if needed
ZMOTOR.run(); // Start moving the stepper
delay(5);
}
ZMOTOR.setCurrentPosition(0); // Set the current position as zero for now
ZMOTOR.setMaxSpeed(50.0); // Set Max Speed of Stepper (Slower to get better accuracy)
ZMOTOR.setAcceleration(50.0); // Set Acceleration of Stepper
initial_zhome = 1;
while (!digitalRead(ZLIMIT)) { // Make the Stepper move CW until the switch is deactivated
ZMOTOR.moveTo(initial_zhome);
ZMOTOR.run();
initial_zhome++;
delay(5);
}
ZMOTOR.setCurrentPosition(0);
ZMOTOR.setMaxSpeed(1000.0); // Set Max Speed of Stepper (Faster for regular movements)
ZMOTOR.setAcceleration(1000.0); // Set Acceleration of Stepper
}
机械臂首先在 X 和 Y 电机上执行归位程序。由于链接的工作方式,这是通过几个步骤完成的。
- 首先,X 和 Y 电机向相反方向移动,以便首先按下 Y 限位开关。
- 按下 Y 限位开关后,两个电机都朝同一方向转动,从而按下 X 限位开关。
- 按下 X 开关后,电机稍微移动一点,使开关被按下(按下时按下,而不是悲伤有点按下。)
- 最后转动 Z 电机,按下 Z 限位开关。
第一次进行归位程序时,您必须非常小心。如果您的步进器以相反的方式移动,只需关闭电源,然后翻转电机的连接器。
现在已经完成了,从你的 setup() 函数调用 autohome() 以便它只运行一次。将循环()留空。如果出现问题,请保持电源关闭。
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinsetup();
autohome();
Serial.println("HOMING OK");
}
如果你一次成功,你的电机会转向正确的方向,限位开关会恰到好处地点击,并且归位程序将毫无问题地工作。但是,如果您像我一样,则必须在一切正常运行之前进行一些小的更改。因此,如果归位出错,请务必断开电源,以免弄乱 3D 打印的手臂。
最后,您可以在 loop() 中编写自己的逻辑,以便您的手臂移动到您想要的位置。由于手臂的连接方式,X 和 Y 电机以几乎笛卡尔的方式控制末端执行器。
void loop() {
XMOTOR.runToNewPosition(100);
delay(1000);
YMOTOR.runToNewPosition(50);
delay(1000);
YMOTOR.runToNewPosition(-50);
delay(1000);
YMOTOR.runToNewPosition(0);
delay(1000);
XMOTOR.runToNewPosition(0);
delay(1000);
}
拓展
我看过很多关于如何使用流行的 GRBL 固件来控制这个手臂的教程。但是,这意味着您需要一台计算机向手臂发送串行命令才能使其移动。如果您只需要 MK2 手臂做一些动作,您可以轻松地将它们硬编码到 Arduino 中,让它自己做。
不过,这并不意味着你不能用串行命令来控制它!您可以简单地将串行定界符代码合并到此代码中,并将 XY 和 Z 电机步长作为字符串发送(用特殊字符分隔 - 例如 5、6、7*,这将使 X 电机移动 5 步,Y 移动 6 步和Z 为 7。* 用于指示字符串的结尾)。
您还可以进一步开发它以发送末端执行器的 3D 空间坐标,并让 arduino 使用逆运动学甚至基本三角学计算出所需的步骤。
如果您对此项目有任何想法、意见或问题,请在下方留言。
以上内容翻译自网络,原作者:Samira Peiris,如涉及侵权,可联系删除。