亲,“电路城”已合并升级到更全、更大、更强的「新与非网」。点击查看「新与非网」

本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页

简单智能主从控制机械臂

发布时间:2022-11-02
分享到:

简单智能主从控制机械臂

发布时间:2022-11-02
分享到:

制作一个简单的主从控制机械臂,可以记录和播放动作。

在本文中,我将说明如何去制作一个简单的主从控制机械臂。手臂会记住动作并按顺序弹奏。这个概念并不新鲜,我是从“迷你机械臂-by Stoerpeak”中得到灵感的,我想做这个很长时间了,但那时我完全是一个新手,对编程一无所知。现在我终于建造了一个,我最纯粹的目的还是希望它能够简单,便宜,并且可以与你们所有人分享。

让我们开始:

第 1 步:你需要的东西

以下是你需要的东西:-

  • 1. 伺服电机x 5
  • 2. 电位器x 5
  • 3.Arduino UNO
  • 4. 电池
  • 5. 试验板
  • 6. 硬纸板/木头/太阳能板/丙烯酸,只要有或容易找到的就行

你还需要安装Arduino IDE。

第 2 步:制作手臂

我这里使用冰棒棍做手臂,当然你也可以使用任何可用的材料。你也可以尝试不同的机械设计来制作更好的手臂,因为我的设计不是很稳定。

在固定组件方面,我只是用双面胶带把伺服棒粘到冰棒棒上,用螺丝把它们拧紧。

对于主臂,我把电位器粘到冰棒棒上,做了手臂。

参考图片会给你一个更好的想法。之后我把所有的东西都装在一个A4大小的帆布板上用作基础。

第 3 步:建立联系

在这一步我们将做所有必要的连接,参考上面的图片。

  • 首先将所有的伺服器并联到电源上(红线到+ve,黑线或棕色线到Gnd)
  • 接下来将信号线即黄色或橙色线连接到arduino的PWM引脚。
  • 现在将电位器并联到arduino的+5v和Gnd。
  • 将中端连接到ardunio的模拟引脚。

在这里,数字引脚3,5,6,9和10用于控制伺服

模拟引脚A0到A4用于电位器的输入。

接在引脚3上的伺服由接在A0上的电位器控制

连接到引脚5上的伺服由A1上的锅控制,以此类推

注意:即使伺服系统不是由arduino供电的,请确保将伺服系统的Gnd连接到arduino,否则手臂将无法工作。

第 4 步:编码

这段代码的逻辑相当简单,电位器的值存储在一个数组中,然后使用for循环遍历记录,伺服器按照值执行步骤。

代码:

首先,我们将全局声明所有必要的变量,以便在整个程序中使用它们。这一点不需要特别解释。

#include <Servo.h>
//Servo Objects
Servo Servo_0;
Servo Servo_1;
Servo Servo_2;
Servo Servo_3;
Servo Servo_4;
//Potentiometer Objects
int Pot_0;
int Pot_1;
int Pot_2; 
int Pot_3;
int Pot_4;
//Variable to store Servo Position
int Servo_0_Pos;
int Servo_1_Pos;
int Servo_2_Pos;
int Servo_3_Pos;
int Servo_4_Pos;
//Variable to store Previous position values
int Prev_0_Pos; 
int Prev_1_Pos; 
int Prev_2_Pos;
int Prev_3_Pos; 
int Prev_4_Pos;
//Variable to store Current position values
int Current_0_Pos; 
int Current_1_Pos; 
int Current_2_Pos; 
int Current_3_Pos;
int Current_4_Pos;
int Servo_Position; //Stores the angle 
int Servo_Number; //Stores no of servo
int Storage[600]; //Array to store data (Increasing array size will consume more memory)
int Index = 0; // Array index starts from 0th position
char data = 0; //variable to store data from serial input.

现在我们将编写一个setup函数,在这里我们将设置引脚及其函数。这是首先执行的主要函数。

void setup() 
{
  Serial.begin(9600); //For Serial communication between arduino and IDE.
  //Servo objects are attached to PWM pins.
  Servo_0.attach(3);
  Servo_1.attach(5);
  Servo_2.attach(6);
  Servo_3.attach(9);
  Servo_4.attach(10);
  //Servos are set to 100 position at initialization. 
  Servo_0.write(100);
  Servo_1.write(100);
  Servo_2.write(100);
  Servo_3.write(100);
  Servo_4.write(100);
  Serial.println("Press 'R' to Record and 'P' to play"); 
}

现在我们必须使用模拟输入引脚读取电位器的值,并将它们映射到控制伺服。为此,我们将定义一个函数并将其命名为Map_Pot();,你可以给它起任何你想要的名字,它是一个用户定义的函数。

void Map_Pot()
{
 /* The servos rotate at 180 degrees
    but to using it to limits is not
    a good idea as it makes the servos buzz continuously
    which is annoying so we limit the servo to move
    between: 1-179 */
   Pot_0 = analogRead(A0);               // Read input from pot and store it in the Variable Pot_0.
   Servo_0_Pos = map(Pot_0, 0, 1023, 1, 179); //Map servos as per the value between 0 to 1023
   Servo_0.write(Servo_0_Pos);           //Move the servo to that position.
   
   Pot_1 = analogRead(A1);
   Servo_1_Pos = map(Pot_1, 0, 1023, 1, 179);
   Servo_1.write(Servo_1_Pos); 
   
   Pot_2 = analogRead(A2); 
   Servo_2_Pos = map(Pot_2, 0, 1023, 1, 179);
   Servo_2.write(Servo_2_Pos);
   
   Pot_3 = analogRead(A3); 
   Servo_3_Pos = map(Pot_3, 0, 1023, 1, 179);
   Servo_3.write(Servo_3_Pos);
   
   Pot_4 = analogRead(A4);
   Servo_4_Pos  = map(Pot_4, 0, 1023 , 1, 179);
   Servo_4.write(Servo_4_Pos);
}

现在我们来写循环函数:

void loop() 
{
   Map_Pot();  //Function call to read pot values
   
   while (Serial.available() > 0) 
   {
     data = Serial.read();
     if (data == 'R')
     Serial.println("Recording Moves...");
     if (data == 'P')
     Serial.println("Playing Recorded Moves...");
   }
  if (data == 'R') //If 'R' is entered, start recording.
  {
    //Store the values in a variable
    Prev_0_Pos = Servo_0_Pos;
    Prev_1_Pos = Servo_1_Pos;
    Prev_2_Pos = Servo_2_Pos;
    Prev_3_Pos = Servo_3_Pos;
    Prev_4_Pos = Servo_4_Pos;
   
    Map_Pot();  // Map  function recalled for comparison 
    
    if (abs(Prev_0_Pos == Servo_0_Pos)) // absolute value is obtained by comparing 
    {
      Servo_0.write(Servo_0_Pos); // If values match servo is repositioned 
      if (Current_0_Pos != Servo_0_Pos)  // If values don't match
    {
        Storage[Index] = Servo_0_Pos + 0; // Value is added to array 
        Index++;  // Index value incremented by 1 
      }
      Current_0_Pos = Servo_0_Pos; 
    }
    /* Similarly the value comparison is done for all the servos, +100 is added every for entry 
       as a differential value. */
    if (abs(Prev_1_Pos == Servo_1_Pos))
    {
      Servo_1.write(Servo_1_Pos);
      if (Current_1_Pos != Servo_1_Pos)
      {
        Storage[Index] = Servo_1_Pos + 100; 
        Index++;
    }
     Current_1_Pos = Servo_1_Pos;
   }
   
   if (abs(Prev_2_Pos == Servo_2_Pos))
   {
     Servo_2.write(Servo_2_Pos);
     if (Current_2_Pos != Servo_2_Pos)
     {
       Storage[Index] = Servo_2_Pos + 200;  
       Index++;
     }
    Current_2_Pos = Servo_2_Pos;
   }
   
   if (abs(Prev_3_Pos == Servo_3_Pos))
   {
     Servo_3.write(Servo_3_Pos); 
     if (Current_3_Pos != Servo_3_Pos)
     {
       Storage[Index] = Servo_3_Pos + 300;  
       Index++;
     }
     Current_3_Pos = Servo_3_Pos;   
   }  
   if (abs(Prev_4_Pos == Servo_4_Pos))
   {
     Servo_4.write(Servo_4_Pos);
     if (Current_4_Pos != Servo_4_Pos)
     {
      Storage[Index] = Servo_4_Pos + 400;  
      Index++;
     }
    Current_4_Pos = Servo_4_Pos;
  }
  /* Values are printed on serial monitor, '\t' is for displaying values in tabular format */   
  Serial.print(Servo_0_Pos);  
  Serial.print(" \t "); 
  Serial.print(Servo_1_Pos); 
  Serial.print(" \t "); 
  Serial.print(Servo_2_Pos); 
  Serial.print(" \t "); 
  Serial.print(Servo_3_Pos); 
  Serial.print(" \t "); 
  Serial.println(Servo_4_Pos);
  Serial.print ("Index = "); 
  Serial.println(Index); 
  delay(50); 
  }
  if (data == 'P') //IF 'P' is entered , Start playing recorded moves.
  {
    for (int i = 0; i < Index; i++) //Traverse the array using for loop
    {
      Servo_Number = Storage[i] / 100;  // Finds number of servo
      Servo_Position = Storage[i] % 100; // Finds position of servo
      switch(Servo_Number) 
      { 
        case 0:
             Servo_0.write(Servo_Position);
             break;
        case 1:
             Servo_1.write(Servo_Position);
             break;
        case 2:
             Servo_2.write(Servo_Position);
             break;      
        case 3:
             Servo_3.write(Servo_Position);
             break;
        case 4:
             Servo_4.write(Servo_Position);
             break;
       }
     delay(50);
   }
 }
}

代码准备好之后,现在把它上传到arduino板。

智能手臂已经准备好工作了。说了这么多,现在让我们继续测试。

第 5 步:测试

成功将代码上传到板后,打开“Serial Monitor”,您可以在工具选项中找到它。当串行监视器启动arduino将重置。现在你可以用主臂控制机械臂了。但是没有任何记录。

要开始录制,在监视器中输入“R”,现在您可以执行您想要录制的动作。

在移动完成后,你必须输入“P”以播放记录的移动。只要板子不复位,伺服器就会继续执行动作。

如果您对此项目有任何想法、意见或问题,请在下方留言。

以上内容翻译自网络,原作者:Harsh Dethe,如涉及侵权,可联系删除。

加入微信技术交流群

技术交流,职业进阶

关注与非网服务号

获取电子工程师福利

加入电路城 QQ 交流群

与技术大牛交朋友

讨论