回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【Arduino 动手做】DIY Arduino 机器人手臂,带智能手机控制 简单

头像 驴友花雕 2025.06.17 3 0

在本教程中,我们将学习如何制作一个 Arduino 机械臂,该机械臂可以使用定制的 Android 应用程序进行无线控制和编程。我将向您展示构建它的整个过程,从设计和 3D 打印机器人部件、连接电子元件和 Arduino 编程开始,到开发我们自己的 Android 应用程序来控制机器人手臂。

概述
Arduino 机械臂 3D 模型
3D 打印机械臂
组装机械臂
Arduino 机械臂电路图
Arduino 机械臂代码
控制 Android 应用程序
Arduino 机械臂控制 MIT App Inventor 项目文件
您可以观看以下视频或阅读下面的书面教程。

使用 App 中的滑块,我们可以手动控制机器人手臂的每个伺服或轴的运动。此外,使用 “Save” 按钮,我们可以记录每个位置或步骤,然后机器人手臂可以自动运行并重复这些步骤。使用相同的按钮,我们可以暂停自动作以及重置或删除所有步骤,以便我们可以记录新的步骤。

Arduino 机械臂 3D 模型
首先,我使用 Solidworks 3D 建模软件设计了机械臂。机械臂有 5 个自由度。

Arduino 机械臂 3D 模型
对于前 3 个轴,腰部、肩部和肘部,我使用了 MG996R 伺服器,对于另外 2 个轴,手腕滚动和手腕俯仰,以及夹持器,我使用了较小的 SG90 微型伺服器。

您可以从 Cults3D 获取此 3D 模型以及用于 3D 打印的 STL 文件。

3D 打印机械臂
使用我的新 3D 打印机 Creality CR-10,我 3D 打印了 Arduino 机械臂的所有部件。


我在短短几个小时内就准备好了 Arduino 机械臂的所有部件。


阅读更多: 15 大必备 3D 打印机配件和工具

组装机械臂
好了,现在我们已经准备好组装机器人手臂了。我从连接第一个伺服电机的底座开始,使用包装中包含的螺钉。然后在伺服器的输出轴上,我固定了一个圆角,一个螺栓。


在它上面,我放置了上部并用两个螺丝固定它。

Arduino 机械臂底座组件
在这里,首先进行伺服,然后将圆角连接到下一个零件上,然后使用输出轴上的螺栓将它们相互固定。


我们可以在这里注意到,在肩轴上,最好包含某种弹簧,或者就我而言,我使用橡皮筋为伺服器提供一些帮助,因为该伺服器承载了手臂其余部分的全部重量以及有效载荷。


以类似的方式,我继续组装机器人手臂的其余部分。至于夹持机构,我使用了大约 4 毫米的螺栓和螺母来组装它。

3D 打印机机械臂
最后,我将夹爪机构连接到最后一个伺服器上,Arduino 机械臂就完成了。

Arduino 机械臂 - 3D 打印
Arduino 机械臂电路图
下一阶段是连接电子设备。这个项目的电路图其实很简单。我们只需要一个 Arduino 板和一个 HC-05 蓝牙模块,用于与智能手机通信。六个伺服电机的控制引脚连接到 Arduino 板的六个数字引脚。

Arduino 机械臂原理图电路图
为了给伺服系统供电,我们需要 5V,但这必须来自外部电源,因为 Arduino 无法处理它们都可以吸收的电流量。电源必须能够处理至少 2A 的电流。因此,一旦我们将所有内容连接在一起,我们就可以继续对 Arduino 进行编程并制作 Android 应用程序。

您可以从以下链接获取此示例所需的组件:

MG996R 伺服电机................................亚马逊 / Banggood / 全球速卖通
SG90 微型伺服电机 ..........................亚马逊 / Banggood / 全球速卖通
HC-05 蓝牙模块 .........................亚马逊 / Banggood / 全球速卖通
Arduino 板 ...........................................亚马逊 / Banggood / 全球速卖通
5V 2A 直流电源 ...........................亚马逊 / Banggood / 全球速卖通
披露:这些是附属链接。作为 Amazon Associate,我从符合条件的购买中赚取收入。

Arduino 机械臂代码
由于代码较长,为了更好地理解,我将把程序的源代码分成几个部分发布,并为每个部分提供说明。在本文的最后,我将发布完整的源代码。

因此,首先我们需要包括用于蓝牙模块串行通信的 SoftwareSerial 库以及伺服库。这两个库都包含在 Arduino IDE 中,因此您不必从外部安装它们。然后我们需要定义六个舵机、HC-05 蓝牙模块和一些用于存储舵机当前和之前位置的变量,以及用于存储自动模式的位置或步骤的数组。

我使用 MIT App Inventor 在线应用程序制作了该应用程序,以下是它的工作原理。在顶部,我们有两个按钮用于将智能手机连接到 HC-05 蓝牙模块。然后在左侧我们有机器人手臂的图像,在右侧我们有六个用于控制伺服系统的滑块和一个用于速度控制的滑块。

 

00.jpg
02.jpg
03.jpg
04.jpg
05.jpg
06.jpg
07.jpg

 

项目代码

 

代码
/*        
       DIY Arduino Robot Arm Smartphone Control  
        by Dejan, www.HowToMechatronics.com  
*/

#include <SoftwareSerial.h>
#include <Servo.h>

Servo servo01;
Servo servo02;
Servo servo03;
Servo servo04;
Servo servo05;
Servo servo06;

SoftwareSerial Bluetooth(3, 4); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX)

int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos; // current position
int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos; // previous position
int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50]; // for storing positions/steps
int speedDelay = 20;
int index = 0;
String dataIn = "";

void setup() {
  servo01.attach(5);
  servo02.attach(6);
  servo03.attach(7);
  servo04.attach(8);
  servo05.attach(9);
  servo06.attach(10);
  Bluetooth.begin(38400); // Default baud rate of the Bluetooth module
  Bluetooth.setTimeout(1);
  delay(20);
  // Robot arm initial position
  servo1PPos = 90;
  servo01.write(servo1PPos);
  servo2PPos = 150;
  servo02.write(servo2PPos);
  servo3PPos = 35;
  servo03.write(servo3PPos);
  servo4PPos = 140;
  servo04.write(servo4PPos);
  servo5PPos = 85;
  servo05.write(servo5PPos);
  servo6PPos = 80;
  servo06.write(servo6PPos);
}

void loop() {
  // Check for incoming data
  if (Bluetooth.available() > 0) {
    dataIn = Bluetooth.readString();  // Read the data as string
    
    // If "Waist" slider has changed value - Move Servo 1 to position
    if (dataIn.startsWith("s1")) {
      String dataInS = dataIn.substring(2, dataIn.length()); // Extract only the number. E.g. from "s1120" to "120"
      servo1Pos = dataInS.toInt();  // Convert the string into integer
      // We use for loops so we can control the speed of the servo
      // If previous position is bigger then current position
      if (servo1PPos > servo1Pos) {
        for ( int j = servo1PPos; j >= servo1Pos; j--) {   // Run servo down
          servo01.write(j);
          delay(20);    // defines the speed at which the servo rotates
        }
      }
      // If previous position is smaller then current position
      if (servo1PPos < servo1Pos) {
        for ( int j = servo1PPos; j <= servo1Pos; j++) {   // Run servo up
          servo01.write(j);
          delay(20);
        }
      }
      servo1PPos = servo1Pos;   // set current position as previous position
    }
    
    // Move Servo 2
    if (dataIn.startsWith("s2")) {
      String dataInS = dataIn.substring(2, dataIn.length());
      servo2Pos = dataInS.toInt();

      if (servo2PPos > servo2Pos) {
        for ( int j = servo2PPos; j >= servo2Pos; j--) {
          servo02.write(j);
          delay(50);
        }
      }
      if (servo2PPos < servo2Pos) {
        for ( int j = servo2PPos; j <= servo2Pos; j++) {
          servo02.write(j);
          delay(50);
        }
      }
      servo2PPos = servo2Pos;
    }
    // Move Servo 3
    if (dataIn.startsWith("s3")) {
      String dataInS = dataIn.substring(2, dataIn.length());
      servo3Pos = dataInS.toInt();
      if (servo3PPos > servo3Pos) {
        for ( int j = servo3PPos; j >= servo3Pos; j--) {
          servo03.write(j);
          delay(30);
        }
      }
      if (servo3PPos < servo3Pos) {
        for ( int j = servo3PPos; j <= servo3Pos; j++) {
          servo03.write(j);
          delay(30);
        }
      }
      servo3PPos = servo3Pos;
    }
    // Move Servo 4
    if (dataIn.startsWith("s4")) {
      String dataInS = dataIn.substring(2, dataIn.length());
      servo4Pos = dataInS.toInt();
      if (servo4PPos > servo4Pos) {
        for ( int j = servo4PPos; j >= servo4Pos; j--) {
          servo04.write(j);
          delay(30);
        }
      }
      if (servo4PPos < servo4Pos) {
        for ( int j = servo4PPos; j <= servo4Pos; j++) {
          servo04.write(j);
          delay(30);
        }
      }
      servo4PPos = servo4Pos;
    }
    // Move Servo 5
    if (dataIn.startsWith("s5")) {
      String dataInS = dataIn.substring(2, dataIn.length());
      servo5Pos = dataInS.toInt();
      if (servo5PPos > servo5Pos) {
        for ( int j = servo5PPos; j >= servo5Pos; j--) {
          servo05.write(j);
          delay(30);
        }
      }
      if (servo5PPos < servo5Pos) {
        for ( int j = servo5PPos; j <= servo5Pos; j++) {
          servo05.write(j);
          delay(30);
        }
      }
      servo5PPos = servo5Pos;
    }
    // Move Servo 6
    if (dataIn.startsWith("s6")) {
      String dataInS = dataIn.substring(2, dataIn.length());
      servo6Pos = dataInS.toInt();
      if (servo6PPos > servo6Pos) {
        for ( int j = servo6PPos; j >= servo6Pos; j--) {
          servo06.write(j);
          delay(30);
        }
      }
      if (servo6PPos < servo6Pos) {
        for ( int j = servo6PPos; j <= servo6Pos; j++) {
          servo06.write(j);
          delay(30);
        }
      }
      servo6PPos = servo6Pos; 
    }
    // If button "SAVE" is pressed
    if (dataIn.startsWith("SAVE")) {
      servo01SP[index] = servo1PPos;  // save position into the array
      servo02SP[index] = servo2PPos;
      servo03SP[index] = servo3PPos;
      servo04SP[index] = servo4PPos;
      servo05SP[index] = servo5PPos;
      servo06SP[index] = servo6PPos;
      index++;                        // Increase the array index
    }
    // If button "RUN" is pressed
    if (dataIn.startsWith("RUN")) {
      runservo();  // Automatic mode - run the saved steps 
    }
    // If button "RESET" is pressed
    if ( dataIn == "RESET") {
      memset(servo01SP, 0, sizeof(servo01SP)); // Clear the array data to 0
      memset(servo02SP, 0, sizeof(servo02SP));
      memset(servo03SP, 0, sizeof(servo03SP));
      memset(servo04SP, 0, sizeof(servo04SP));
      memset(servo05SP, 0, sizeof(servo05SP));
      memset(servo06SP, 0, sizeof(servo06SP));
      index = 0;  // Index to 0
    }
  }
}

// Automatic mode custom function - run the saved steps
void runservo() {
  while (dataIn != "RESET") {   // Run the steps over and over again until "RESET" button is pressed
    for (int i = 0; i <= index - 2; i++) {  // Run through all steps(index)
      if (Bluetooth.available() > 0) {      // Check for incomding data
        dataIn = Bluetooth.readString();
        if ( dataIn == "PAUSE") {           // If button "PAUSE" is pressed
          while (dataIn != "RUN") {         // Wait until "RUN" is pressed again
            if (Bluetooth.available() > 0) {
              dataIn = Bluetooth.readString();
              if ( dataIn == "RESET") {     
                break;
              }
            }
          }
        }
        // If speed slider is changed
        if (dataIn.startsWith("ss")) {
          String dataInS = dataIn.substring(2, dataIn.length());
          speedDelay = dataInS.toInt(); // Change servo speed (delay time)
        }
      }
      // Servo 1
      if (servo01SP[i] == servo01SP[i + 1]) {
      }
      if (servo01SP[i] > servo01SP[i + 1]) {
        for ( int j = servo01SP[i]; j >= servo01SP[i + 1]; j--) {
          servo01.write(j);
          delay(speedDelay);
        }
      }
      if (servo01SP[i] < servo01SP[i + 1]) {
        for ( int j = servo01SP[i]; j <= servo01SP[i + 1]; j++) {
          servo01.write(j);
          delay(speedDelay);
        }
      }

      // Servo 2
      if (servo02SP[i] == servo02SP[i + 1]) {
      }
      if (servo02SP[i] > servo02SP[i + 1]) {
        for ( int j = servo02SP[i]; j >= servo02SP[i + 1]; j--) {
          servo02.write(j);
          delay(speedDelay);
        }
      }
      if (servo02SP[i] < servo02SP[i + 1]) {
        for ( int j = servo02SP[i]; j <= servo02SP[i + 1]; j++) {
          servo02.write(j);
          delay(speedDelay);
        }
      }

      // Servo 3
      if (servo03SP[i] == servo03SP[i + 1]) {
      }
      if (servo03SP[i] > servo03SP[i + 1]) {
        for ( int j = servo03SP[i]; j >= servo03SP[i + 1]; j--) {
          servo03.write(j);
          delay(speedDelay);
        }
      }
      if (servo03SP[i] < servo03SP[i + 1]) {
        for ( int j = servo03SP[i]; j <= servo03SP[i + 1]; j++) {
          servo03.write(j);
          delay(speedDelay);
        }
      }

      // Servo 4
      if (servo04SP[i] == servo04SP[i + 1]) {
      }
      if (servo04SP[i] > servo04SP[i + 1]) {
        for ( int j = servo04SP[i]; j >= servo04SP[i + 1]; j--) {
          servo04.write(j);
          delay(speedDelay);
        }
      }
      if (servo04SP[i] < servo04SP[i + 1]) {
        for ( int j = servo04SP[i]; j <= servo04SP[i + 1]; j++) {
          servo04.write(j);
          delay(speedDelay);
        }
      }

      // Servo 5
      if (servo05SP[i] == servo05SP[i + 1]) {
      }
      if (servo05SP[i] > servo05SP[i + 1]) {
        for ( int j = servo05SP[i]; j >= servo05SP[i + 1]; j--) {
          servo05.write(j);
          delay(speedDelay);
        }
      }
      if (servo05SP[i] < servo05SP[i + 1]) {
        for ( int j = servo05SP[i]; j <= servo05SP[i + 1]; j++) {
          servo05.write(j);
          delay(speedDelay);
        }
      }

      // Servo 6
      if (servo06SP[i] == servo06SP[i + 1]) {
      }
      if (servo06SP[i] > servo06SP[i + 1]) {
        for ( int j = servo06SP[i]; j >= servo06SP[i + 1]; j--) {
          servo06.write(j);
          delay(speedDelay);
        }
      }
      if (servo06SP[i] < servo06SP[i + 1]) {
        for ( int j = servo06SP[i]; j <= servo06SP[i + 1]; j++) {
          servo06.write(j);
          delay(speedDelay);
        }
      }
    }
  }
}

【Arduino 动手做】DIY Arduino 机器人手臂,带智能手机控制
项目链接:https://howtomechatronics.com/tutorials/arduino/diy-arduino-robot-arm-with-smartphone-control/
项目作者: Dejan

项目视频 :https://www.youtube.com/watch?v=_B3gWd3A_SI
Arduino 机械臂控制 MIT App Inventor 项目文件:
https://howtomechatronics.com/tutorials/arduino/diy-arduino-robot-arm-with-smartphone-control/#unlock
3D 文件:https://cults3d.com/en/3d-model/various/arduino-based-robot-arm-howtomechatronics

 

01.jpg
00161---.gif

评论

user-avatar
icon 他的勋章
    展开更多