亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

使用 Arduino 的简单智能机械臂

组件和用品

Arduino UNO
× 1
微舵机
× 5
电位器
× 5
面包板(通用)
× 1

关于这个项目

在本教程中,我将制作一个简单的机械臂,该机械臂将使用主臂进行控制。手臂会记住动作并按顺序播放。这个概念并不新鲜我从“迷你机械臂 - by Stoerpeak”那里得到了这个想法我想做这个很久了,但当时我完全是菜鸟,对编​​程一无所知。现在我终于建立了一个,保持简单,便宜并与大家分享。

那么让我们开始吧......

第 1 步:您需要的东西

以下是您需要的物品清单:-

1. 伺服电机 x 5 (亚马逊链接)

2. 电位器 x 5 (亚马逊链接)

3. Arduino UNO。 (亚马逊链接)

4. 电池。 (我使用的是 5v 适配器)

5. 面包板。 (亚马逊链接)

6. 可用或容易找到的纸板/木头/太阳板/亚克力。

您还需要安装 Arduino IDE。

第 2 步:制作手臂

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

我只是用双面胶带把舵机粘在冰棒棍上,然后用螺丝固定。

对于 Master 手臂,我将电位计粘在冰棒棍上并制作了手臂。

参考图片会给你一个更好的主意。

我已将所有东西都安装在用作底座的 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 循环遍历记录,伺服器根据值执行步骤。您可以查看我用作参考的本教程“Arduino Potentiometer Servo Control &Memory”

代码:-(可下载文件附件如下)

  • 首先,我们将全局声明所有必需的变量,以便我们可以在整个程序中使用它们。对此无需特别说明。
#include 
//伺服对象
Servo Servo_0;
Servo Servo_1;
Servo Servo_2;
Servo Servo_3;
伺服Servo_4;
//电位器对象
int Pot_0;
int Pot_1;
int Pot_2;
int Pot_3;
int Pot_4;
//存储伺服位置的变量
int Servo_0_Pos;
int Servo_1_Pos;
int Servo_2_Pos;
int Servo_3_Pos;
int Servo_4_Pos;
//变量存储以前的位置值
int Prev_0_Pos;
int Prev_1_Pos;
int Prev_2_Pos;
int Prev_3_Pos;
int Prev_4_Pos;
//存储当前位置值的变量
int Current_0_Pos;
int Current_1_Pos;
int Current_2_Pos;
int Current_3_Pos;
int Current_4_Pos;
int Servo_Position; //存储角度
int Servo_Number; //存储舵机数量
int Storage[600]; //数组存储数据(增加数组大小会消耗更多内存)
int Index =0; // 数组索引从第 0 个位置开始
char data =0; //用于存储串行输入数据的变量。
  • 现在我们将编写一个设置函数,在其中设置引脚及其功能。这是首先执行的主函数。
void setup() 
{
Serial.begin(9600); //用于arduino和IDE之间的串行通信。
//伺服对象附加到PWM引脚。
Servo_0.attach(3);
Servo_1.attach(5);
Servo_2.attach(6);
Servo_3.attach(9);
Servo_4.attach(10);
//舵机在初始化时设置为100位置。
Servo_0.write(100);
Servo_1.write(100);
Servo_2.write(100);
Servo_3.write(100);
Servo_4. write(100);
Serial.println("按'R'录音,'P'播放");
}

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

void Map_Pot()
{
/* 舵机旋转 180 度
但是使用它来限制不是一个好主意
因为它使舵机持续嗡嗡声
这很烦人,所以我们限制舵机在
之间移动: 1-179 */
Pot_0 =analogRead(A0); // 从pot读取输入并将其存储在变量Pot_0中。
Servo_0_Pos =map(Pot_0, 0, 1023, 1, 179); //根据0到1023之间的值映射舵机
Servo_0.write(Servo_0_Pos); //将舵机移动到那个位置。

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(); //读取pot值的函数调用

while (Serial.available()> 0)
{
data =Serial.read();
if (data =='R')
Serial.println("记录移动...");
if (data =='P')
Serial.println("播放记录移动.. .");
}
if (data =='R') //如果输入'R',则开始记录。
{
//将值存储在一个变量
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_Pos_Pos;
地图
(); // 调用映射函数进行比较

if (abs(Prev_0_Pos ==Servo_0_Pos)) // 比较得到绝对值
{
Servo_0.write(Servo_0_Pos); // 如果值匹配,伺服重新定位
if (Current_0_Pos !=Servo_0_Pos) // 如果值不匹配
{
Storage[Index] =Servo_0_Pos + 0; // 值被添加到数组
Index++; // 索引值增加 1
}
Current_0_Pos =Servo_0_Pos;
}
/* 类似地,对所有舵机进行值比较,为每个条目添加 +100 作为差异值。 */
if (abs(Prev_1_Pos ==Servo_1_Pos))
{
Servo_1.write(Servo_1_Pos);
if (Current_1_Pos !=Servo_1_Pos)
{
存储[索引] =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)
{
存储[索引] =Servo_4_Pos + 400;
Index++;
}
Current_4_Pos =Servo_4_Pos;
}
/* 值打印在串口监视器上,'\t' 用于以表格格式显示值 */
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(索引);
延迟(50);
}
if (data =='P') //如果输入'P',开始播放记录的动作。
{
for (int i =0; i {
Servo_Number =Storage[i] / 100; // 找到舵机数量
Servo_Position =Storage[i] % 100; // 找到舵机位置
开关(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;
案例3:
Servo_3.write(Servo_Position);
break;
案例4:
Servo_4.write(Servo_Position);
break;
}
延迟(50);
}
}
}
  • 代码准备好后,现在将其上传到 arduino 开发板。

智能手臂已准备就绪。功能还没有Stoerpeak做的那么流畅。

如果您可以改进代码或对我有任何建议,请在评论部分告诉我。

话虽如此,让我们继续测试......

唱片播放.ino

第 5 步:测试

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

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

移动完成后,您必须输入“P”才能播放记录的移动。只要板子没有复位,舵机就会继续执行移动。

希望你喜欢这个项目。

谢谢...

代码

  • Record-Play.ino
  • 代码片段 #1
  • 代码片段#2
  • 代码片段 #3
  • 代码片段 #4
Record-Play.inoArduino
打开文件时出错。
代码片段 #1纯文本
#include //伺服对象Servo Servo_0;Servo Servo_1;Servo Servo_2;Servo Servo_3;Servo Servo_4;//电位器对象sint Pot_0;int Pot_1;int Pot_2; int Pot_3;int Pot_4;//存储伺服位置的变量int Servo_0_Pos;int Servo_1_Pos;int Servo_2_Pos;int Servo_3_Pos;int Servo_4_Pos;//存储先前位置值的变量int Prev_0_Pos; int Prev_1_Pos; int Prev_2_Pos;int Prev_3_Pos; int Prev_4_Pos;//存储当前位置值的变量int Current_0_Pos; int Current_1_Pos; int Current_2_Pos; int Current_3_Pos;int Current_4_Pos;int Servo_Position; //存储角度 int Servo_Number; //存储的servoint Storage[600]; //数组存储数据(增加数组大小会消耗更多内存)int Index =0; // 数组索引从第 0 个位置开始char data =0; //用于存储来自串行输入的数据的变量。
代码片段#2纯文本
void setup() { Serial.begin(9600); //用于arduino和IDE之间的串行通信。 //伺服对象附加到PWM引脚。 Servo_0.attach(3); Servo_1.attach(5); Servo_2.attach(6); Servo_3.attach(9); Servo_4.attach(10); //伺服在初始化时设置为100位置。 Servo_0.write(100); Servo_1.write(100); Servo_2.write(100); Servo_3.write(100); Servo_4.write(100); Serial.println("按'R'录音,'P'播放"); }
代码片段 #3纯文本
void Map_Pot(){ /* 舵机旋转 180 度,但使用它来限制不是一个好主意,因为它使舵机连续嗡嗡声很烦人,所以我们限制舵机在 1-179 之间移动 * / Pot_0 =模拟读取(A0); // 从pot读取输入并将其存储在变量Pot_0中。 Servo_0_Pos =map(Pot_0, 0, 1023, 1, 179); //根据0到1023之间的值映射舵机 Servo_0.write(Servo_0_Pos); //将伺服移动到那个位置。 Pot_1 =模拟读取(A1); Servo_1_Pos =map(Pot_1, 0, 1023, 1, 179); Servo_1.write(Servo_1_Pos); Pot_2 =模拟读取(A2); Servo_2_Pos =map(Pot_2, 0, 1023, 1, 179); Servo_2.write(Servo_2_Pos); Pot_3 =模拟读取(A3); Servo_3_Pos =map(Pot_3, 0, 1023, 1, 179); Servo_3.write(Servo_3_Pos); Pot_4 =模拟读取(A4); Servo_4_Pos =map(Pot_4, 0, 1023, 1, 179); Servo_4.write(Servo_4_Pos);}
代码片段 #4纯文本
void loop() { Map_Pot(); //读取pot值的函数调用 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') //如果输入'R',开始录音。 { //将值存储在变量中 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(); // 调用映射函数进行比较 if (abs(Prev_0_Pos ==Servo_0_Pos)) // 比较得到绝对值 { Servo_0.write(Servo_0_Pos); // 如果值匹配,伺服将重新定位 if (Current_0_Pos !=Servo_0_Pos) // 如果值不匹配 { Storage[Index] =Servo_0_Pos + 0; // 值被添加到数组 Index++; // 索引值加 1 } Current_0_Pos =Servo_0_Pos; } /* 类似地,对所有舵机进行值比较,为每个条目添加+100 作为差分值。 */ 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;指数++; } 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;指数++; } 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;指数++; } 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;指数++; } Current_4_Pos =Servo_4_Pos; } /* 值打印在串行监视器上,'\t' 用于以表格格式显示值 */ 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("索引 ="); Serial.println(索引);延迟(50); } if (data =='P') //如果输入了'P',开始播放记录的动作。 { for (int i =0; i  

示意图


制造工艺

  1. 使用 Arduino 和 RFID 和 Python 的考勤系统
  2. 使用 Arduino、1Sheeld 和 Android 的通用远程控制
  3. 使用 Arduino 和智能手机的 DIY 电压表
  4. 使用物联网远程控制机械臂
  5. IOT - 使用 ESP8266、Arduino 和超声波传感器的智能罐
  6. 使用 Arduino 的频率和占空比测量
  7. Arduino 3D 打印机械臂
  8. 智能鞋(自动系带和发电)
  9. Nunchuk 控制机械臂(使用 Arduino)
  10. Sonar 使用 arduino 并在处理 IDE 上显示
  11. 使用 Bolt 和 Arduino 控制 LED 亮度
  12. 使用 Arduino 和 ESP8266 的 WiFi 登录页面的智能门锁