
这个项目出自一个13岁的小创客Wiktor之手。
▲ 机械臂演示夹3粒橡皮到指定位置
作者使用Fusion 360进行3D建模,使用VS Code编程。这个机器人手臂配备了MG90s伺服电机、28BYJ-48步进电机,以及许多3D打印部件。
材料清单

3D打印部件- 基座舱体 x 1
- 基座盖 x 1
- 左夹爪 x 1
- 右夹爪 x 1
- 下臂 x 1
- 上臂 x 1
- 基座圆盘 x 1
- 肩部伺服支架 x 1
- 夹爪伺服支架 x 1
- 夹爪支架 x 1
电子元件- MG90s伺服电机 x 2
- SG92R伺服电机 x 1(可以用MG90s替代)
- 28BYJ-48步进电机 x 1
- ULN2003驱动器 x 1
- 自定义“伺服驱动”板 x 1(见步骤1)
- Arduino Uno
硬件配件- 伺服轮 x 3(如图所示的类型)
- M4x12mm螺栓 x 2
- M4螺母 x 2
- M3x10mm螺栓 x 2(12mm也可以)
- M2x12mm螺栓 x 4
- M2垫圈 x 8
- M2x7mm螺栓 x 4(将12mm切割至7mm)
- M3x12mm螺栓 x 4
- 固定伺服轮的螺钉 x 3
- M2x7mm螺钉 x 1(来自伺服“套件”)
- M3x5mm热插入件 x 2
线- 20cm公对母跳线 x 9
- 10cm母对母跳线 x 2
- 10cm伺服线延长线 x 1(可以用普通跳线替代)
附件下载
STL文件可以在文末下载
步骤1:自定义“伺服驱动”板为什么要制作这个板?
在做这个项目时,我没有找到合适的伺服驱动器,所以决定自己制作一个。这个板子非常简单,基本上就是把所有的阳极和阴极连接在一起。
如何制作这样的板?
要制作这样的板,你需要:
然后,你需要将穿孔板和引脚焊接到位,如图所示。


之后,可以连接所有正负引脚。
你还需要连接信号引脚:
- 信号引脚1(靠近电源轨) - 信号引脚1
- 信号引脚2(靠近电源轨) - 信号引脚2
- 以此类推
为什么这样设计?
最让人困惑的部分是信号引脚,我来解释一下。
我希望能够直接将伺服连接器插入到这个板上,这就意味着我们需要将三个引脚并排放置。但如果我就这样放置引脚,就无法将其连接到Arduino上。
步骤2:组装基座
现在让我们开始组装我们的机械臂。
基座
基座的设计比较宽松,这样几乎可以在任何3D打印机上打印出来。
但这也意味着你需要稍微弯曲一下,才能确保它贴合得更紧。
弯曲基座
注意:要弯曲基座,你可能需要一个打火机。请小心使用!

首先,你需要选择一个弯曲的位置。
我建议在USB孔上方稍微弯曲。
由于我们使用的塑料非常坚硬,正常情况下是无法弯曲的,所以你需要加热它,让它稍微软化一点。
在小心加热我们选择的位置后,用某个圆的东西按下去。
如果顺利的话,应该可以把盖子压上去,并且不会滑落。
如果盖子一直滑落,只需重复上述步骤。
安装步进电机
要安装步进电机,我们将使用两个M4x12螺栓和两个M4螺母。
将步进电机放置,使轴通过中间孔,并确保螺孔对齐。

将螺栓穿过孔并用螺母固定好。
确保螺栓头部朝上,如果螺母朝上,它们会与基座圆盘发生碰撞。
安装基座圆盘
现在你可以拿起基座圆盘,添加M3热插入件。
警告:焊接铁非常危险,使用时请务必小心。
轻轻将热插入件放在基座圆盘上的孔上。
然后,取一个加热到约300°C的焊接铁,轻轻按压热插入件,让它们嵌入孔中。
有时候热插入件可能会粘在焊接铁上,这时可以用镊子夹住,确保热插入件保持在正确的位置。

将所有部件组装在一起
现在你可以将基座圆盘放在步进电机上,然后把盖子放在盒子上。
恭喜你!!!你已经组装好了基座。
步骤3:接线
在继续之前,先把所有东西连接好。

步进电机
首先,将步进电机连接到驱动板,具体连接方式请参考图示。
接下来,将引脚连接到Arduino上:
- IN1 - 2(Arduino)
- IN2 - 3(Arduino)
- IN3 - 4(Arduino)
- IN4 - 5(Arduino)
这些连接在图中也有显示。
自定义板
将最上面的两个引脚这样连接到Arduino:
确保步进驱动板的电源引脚连接到这个板上,位置在三引脚宽区段的上方(就在你插入Arduino引脚的下方)。
你还需要将信号引脚连接到Arduino:
- 信号引脚1(最左侧) - 9(Arduino)
- 信号引脚2 - 10(Arduino)
- 信号引脚3 - 11(Arduino)
注意:
底部的信号引脚(靠近电源轨)对应于上面信号排的最左侧引脚等。越低的伺服连接器对应越低的关节,例如,底部引脚用于肩关节,下一个用于肘关节。
安装伺服电机
现在,伺服电机的连接非常简单,只需按照上述说明将它们连接到相应的引脚即可。
确保将所有伺服线穿过盖子上的孔。

小贴士
另外一个建议是,将Arduino放置在我在图中放置的位置,这样你可以在不打开盒子的情况下插入它。
步骤4:肩关节组装肩部伺服支架安装
首先,拿起肩部伺服支架和两个M3x10螺栓,将伺服支架固定到位。

安装伺服电机

伺服电机的安装非常简单。
只需将伺服电机放入支架中,并用两个M2x12mm的螺栓和两个垫圈固定好。
螺钉应该能轻松拧入塑料中并牢固固定,如果不牢固,可以使用M2热插入件。
安装下臂


首先,拿一个伺服轮,然后把一个小螺钉放入轮子中以固定它。
接着,将带螺钉的轮子放入下臂。你可以通过检查下臂是否有另一个伺服槽来识别下臂。
然后用一个M2x7mm的螺栓将其固定到手臂上。
在继续之前,我们需要将肩部伺服设置为90度位置。
为此,我们需要上传一个简单的代码到Arduino上。
安装Arduino IDE,插入你的Arduino,选择对应的端口,选择“Arduino Uno”作为开发板,然后上传以下代码:
- #include <Servo.h>
-
- Servo myServo; // Create a Servo object
-
- void setup() {
- myServo.attach(9); // Attach the servo to pin 9
- myServo.write(90); // Set servo to 90 degrees
- }
-
- void loop() {
- // No action is needed in the loop for this task
- }
复制代码
现在可以把带有轮子的下臂放在伺服上并固定,使手臂指向上方。

步骤5:肘关节组装
肘关节也很简单,安装几乎与肩关节相同。固定好伺服后,拿起上臂,将轮子(带着螺钉)放入,并固定好。通过更改以下代码,将肘关节设置为90度:把
复制代码
改成:
复制代码
安装手臂就完成了!

步骤6:夹爪组装
现在,夹爪的组装可能是最复杂的一步。
首先,我们需要安装夹爪伺服支架和夹爪支架。
伺服支架要安装在右侧,你可以用两个M3x12mm的螺栓将其固定。

夹爪支架则安装在左侧,使用相同的螺栓。
接下来,把伺服电机安装到支架上,并用两个M2x7mm的螺钉固定好。
然后,将一个带螺钉的伺服轮放入夹爪的右侧,并用小螺钉固定它。
接着,你可以把夹爪安装到伺服电机上。

最后一步是将夹爪的左侧安装到支架上,确保当夹爪伺服(针脚11)设置为180度时,夹爪会闭合。
步骤7:上传代码到Arduino
现在我们需要上传写给Arduino的代码,按照之前的方法进行:
- 将Arduino连接到计算机
- 安装并打开Arduino IDE
- 将以下代码粘贴到IDE中
- 选择正确的端口和板(Arduino Uno)
- 点击上传!
这是代码: - // CONFIG //
- const int STEPPER_IN1 = 2;
- const int STEPPER_IN2 = 3;
- const int STEPPER_IN3 = 4;
- const int STEPPER_IN4 = 5;
- const int STEPS_PER_REVOLUTION = 2048;
-
- const int SHOULDER_IN = 9;
- const int ELBOW_IN = 10;
- const int GRIPPER_IN = 11;
- // INCLUDE //
- #include <Arduino.h>
- #include <Servo.h>
- #include <Stepper.h>
- // VARIABLES //
- Servo shoulder;
- Servo elbow;
- Servo gripper;
- Stepper base(STEPS_PER_REVOLUTION, STEPPER_IN1, STEPPER_IN3, STEPPER_IN2, STEPPER_IN4);
- int joint;
- int amount;
- int currentShoulder;
- int currentElbow;
- int currentGripper;
- int currentBase;
- // FUNCTIONS //
- void moveServos(int shoulderAngle, int elbowAngle, int gripperAngle);
- void moveStepper(Stepper stepper, int degrees);
- void calibrate();
-
- // MAIN CODE //
-
- void setup(){
- //Start Serial
- Serial.begin(9600);
- //Set up motors
- shoulder.attach(SHOULDER_IN);
- elbow.attach(ELBOW_IN);
- gripper.attach(GRIPPER_IN);
- base.setSpeed(10); // lower than 15 is recommended, above 25 will break the motor
- currentBase = 0;
- //Set servos into Zero position
- shoulder.write(97);
- currentShoulder = 97;
- elbow.write(90);
- currentElbow = 90;
- gripper.write(160);
- currentGripper = 160;
-
- //calibrate();
- // delay(1000);
- // moveServoSmooth(elbow, 0, 45, 5);
- // moveStepper(base, -0.25f);
- // delay(1000);
- // moveServoSmooth(shoulder, 90, 0, 5);
- // moveServoSmooth(elbow, 45, 0, 5);
- }
-
- void loop() {
- while (Serial.available() > 0) {Serial.read();} // Clear
- while (Serial.available() == 0) {} // Wait for data
- String consoleInput = Serial.readString(); //Read data
- consoleInput.trim(); //Trim, to remove any EOL characters or similiar
-
- if(consoleInput.length() == 12){
- int baseInput = consoleInput.substring(0,3).toInt();
- int shoulderInput = consoleInput.substring(3,6).toInt();
- int elbowInput = consoleInput.substring(6,9).toInt();
- int gripperInput = consoleInput.substring(9,12).toInt();
-
- moveStepper(base, baseInput-360);
- moveServos(shoulderInput,elbowInput,gripperInput);
- Serial.print("recieved: '");
- Serial.print(consoleInput);
- Serial.println("'");
- Serial.println("done");
- }
- else{
- Serial.println("Wrong input!");
- }
- }
-
- // FUNCTIONS //
- void moveServos(int shoulderAngle, int elbowAngle, int gripperAngle) {
- //17ms
- bool finishedServos[] = {false,false,false};
-
- while(true){
- if(currentShoulder != shoulderAngle){
- if (currentShoulder < shoulderAngle){
- shoulder.write(currentShoulder+1);
- currentShoulder++;
- delay(17);
- }
- if (currentShoulder > shoulderAngle){
- shoulder.write(currentShoulder-1);
- currentShoulder--;
- delay(17);
- }
- }
- else{
- finishedServos[0] = true;
- }
-
-
- if(currentElbow != elbowAngle){
- if (currentElbow < elbowAngle){
- elbow.write(currentElbow+1);
- currentElbow++;
- delay(17);
- }
- if (currentElbow > elbowAngle){
- elbow.write(currentElbow-1);
- currentElbow--;
- delay(17);
- }
- }
- else{
- finishedServos[1] = true;
- }
-
-
- if(currentGripper != gripperAngle){
- if (currentGripper < gripperAngle){
- gripper.write(currentGripper+1);
- currentGripper++;
- delay(17);
- }
- if (currentGripper > gripperAngle){
- gripper.write(currentGripper-1);
- currentGripper--;
- delay(17);
- }
- }
- else{
- finishedServos[2] = true;
- }
-
- if(finishedServos[0] && finishedServos[1] && finishedServos[2]){
- break;
- }
- }
- finishedServos[0] = false;
- finishedServos[1] = false;
- finishedServos[2] = false;
- }
-
- void moveStepper(Stepper stepper, int degrees){
- stepper.step((2048/360)*(currentBase-degrees));
- currentBase = degrees;
- digitalWrite(STEPPER_IN1, LOW);
- digitalWrite(STEPPER_IN2, LOW);
- digitalWrite(STEPPER_IN3, LOW);
- digitalWrite(STEPPER_IN4, LOW);
- }
-
- void calibrate(){
- // Serial.println("The servos in 5s will be set to a pole like position");
- // delay(5000);
- // moveServoSmooth(shoulder, 0, 90, 5);
- // moveServoSmooth(elbow, 0, 90, 5);
- // Serial.println("If the servos aren't in a pole like position, please adjust them, you have 10s");
- // delay(10000);
- // Serial.println("Now please set the stepper motor into such a positon, that the arm is facing toward the hole that the wires go into. You have 10s");
- // moveServoSmooth(elbow, 90, 0, 5);
- // delay(10000);
- // Serial.println("Calibration complete!");
- }
复制代码
上传代码后,当你打开串口监视器时,将其设置为9600波特率,并发送例如123, Arduino会在200至300毫秒后响应“输入错误!”这是因为它只接受长度为12个字符的输入。我将在下一步解释原因。
步骤8:通信协议
这段代码是为了让你能够方便地通过串口控制机器人。
首先,所有发送的消息必须是12个字符长,为什么呢?
因为机器人有四个关节,每个关节的位置需要3个字符来表示,所以
那么这些数字具体代表什么呢?
- 前三个数字是用于基座的,记住基座要移动到的位置是你输入的值减去360度。
- 接下来的三个数字是用于肩部的,它会直接移动到你输入的位置。
- 再后面的三个数字是用于肘部,其工作方式与肩部相同。
- 最后三个数字是用于夹爪的,它们的工作方式与肘部相同,但我不建议设置夹爪低于90度。
为什么使用这个协议?
这个协议的好处主要有两个:首先,它非常简单;其次,这种方式让你可以添加自己的功能,比如你可以加一个ESP32模块,让机器人支持Wi-Fi控制。
步骤9:PC程序
仅仅发送12个数字的字符串并不是很直观,对吧?所以我决定开发一个PC程序来全面控制机器人。
下载和(可选)编译
首先,你需要确认你的Arduino使用的是哪个端口,也就是你上传代码时用的那个端口。
接下来,下载Robo Control.rar文件,解压后,进入bin文件夹,运行程序并选择你的端口。(这些文件可以在文末打包下载)
如果没有为你的端口提供预编译的.exe文件,你需要自己进行编译。我提供了一个CMake文件。
如果你不知道如何使用CMake进行编译,可以参考这个网站:https://hsf-training.github.io/hsf-training-cmake-webpage/02-building/index.html。
步骤10:如何使用?

- 将机器人设置为类似极点的位置。
- 将所有电机的设置归零。
- 向机器人发送11、12、13、14的值。
- 播放当前加载的程序。
- 保存当前的程序。
- 在顶部栏输入程序名称以加载程序,这也可以用来创建新文件。
- 输入你的程序名称。
- 从加载的文件中删除最后一个位置。
- 将当前的11、12、13、14值添加到当前文件中。
- 大致显示你即将发送到手臂的数据。
- 输入夹爪的值,并显示出来。
- 输入肘部的值。
- 输入肩部的值。
- 输入基座的值。
- 大致显示基座的方向。
步骤11:结束语
感谢你陪我完成这个项目,特别感谢我的妈妈对我的鼓励和提供的小零食。
请在评论中告诉我你对此项目的看法,这是我第一个真正的大型项目。如果你需要帮助,可以在Discord上给我发消息:@xtagz_69
原文地址:https://www.instructables.com/A- ... vos-and-28BYJ-48-S/
项目作者:tagvian
译文首发于:DF创客社区
转载请注明来源信息
|