本帖最后由 RRoy 于 2025-1-15 16:29 编辑   
 
 
 
这个项目出自一个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创客社区 
 
转载请注明来源信息