使用Arduino Nano开发板制作手势控制的机械臂 

机械臂是引人入胜的工程创作之一,看着这些东西倾斜和摇动像人类的手臂一样完成复杂的事情总是令人着迷。这些机械臂可以在装配线中进行焊接、钻孔、喷漆等剧烈机械工作的行业中找到,最近还开发了高精度的先进机械臂来执行复杂的外科手术。在之前的文章中,我们3D打印了机械臂,并使用MG995伺服电机制作了机械臂。我们将再次使用相同的3D打印机器人手臂,通过 Arduino Nano、MPU6050陀螺仪和弯曲(Flex)传感器制作手势控制的机器人手臂。

通过3D打印的机械臂位置可以通过与MPU6050陀螺仪和弯曲传感器相连的手套来控制。 Flex传感器用于控制机械手的夹具伺服电机,MPU6050用于在X和Y轴上移动机器人。如果您没有打印机,那么您也可以像为 Arduino机器人手臂项目建造的那样,用简单的纸板制作手臂。

首先,让我们先了解MPU6050传感器和弯曲传感器。

MPU6050陀螺仪和加速度计传感器

MPU6050基于微机械系统(MEMS)技术。该传感器具有一个3轴加速度计、一个3轴陀螺仪和内置温度传感器。它可以用来测量诸如加速度、速度、方向、位移等参数。我们之前已经将MPU6050与 Arduino Raspberry pi进行了连接,并且还使用它构建了一些项目,例如自平衡机器人、Arduino数字量角器 Arduino测斜仪。

MPU6050传感器的功能:

●    通信:具有可配置I2C地址的I2C协议

●    输入电源:3-5Vd

●    内置16位ADC提供高精度

●    内置DMP提供高计算能力

●    可用于与磁力计等其他I2C设备接口

●    内置温度传感器

弯曲传感器

弯曲传感器实际上是一个可变电阻器。弯曲传感器时,它的电阻会发生变化。通常有2.2英寸和4.5英寸两种尺寸。

为什么我们在项目中使用柔性传感器?在此手势控制的机械臂中,使用弯曲传感器控制机械臂的抓取器。当手套上的弯曲传感器弯曲时,安装在夹具上的伺服电机旋转,夹具打开。

准备好3D打印的机械臂

本文中使用的3D打印机械手是根据ThinZverse中EEZYbotARM提供的设计制作的。 Thingiverse链接中提供了制作3D打印机械臂和带有视频的组装细节的完整过程,该链接在上方共享。

上图是组装4台伺服电机后3D打印的机械臂的图像。

所需的组件

●     Arduino Nano开发板

●    弯曲传感器

●    10k电阻

●    MPU6050

●    连接线

●    面包板

电路原理图

下图显示了基于 Arduino的手势控制机械臂的电路连接。

MPU6050和 Arduino Nano之间的电路连接:

弯曲传感器包含两个引脚。它不包含极性端子。因此,第一个引脚P1通过一个10k的上拉电阻连接到 Arduino Nano的模拟引脚A0,第二个引脚P2接地到 Arduino

将MPU6050和Flex传感器安装到手套上

我们将MPU6050和Flex传感器安装在手套上。此处,通过线缆连接手套和机械臂,也可以通过使用RF连接或蓝牙连接将其无线连接。

连接完成后,手势控制机械臂的最终设置如下图所示:

为机械臂编程 Arduino Nano

这里解释了一些重要的代码。

首先,包括必要的库文件。 Wire.h库用于 Arduino Nano和MPU6050与Servo.h之间的I2C通信,以控制伺服电机。

#include<Wire.h>               
#include<Servo.h>   

接下来,声明用于类伺服的对象。当我们使用四个伺服电动机时,将创建四个对象。

Servo servo_1;      
Servo servo_2;
Servo servo_3;
Servo servo_4;

接下来,声明MPU6050的I2C地址和要使用的变量。

const int MPU_addr=0x68;        //MPU6050 I2C Address
int16_t axis_X,axis_Y,axis_Z;
int minVal=265;
int maxVal=402;
double x;
double y;
double z;

void setup()函数中,将串行通信的波特率设置为9600。

Serial.begin(9600);

并在 Arduino Nano和MPU6050之间建立了I2C通信:

  Wire.begin();                      //Initilize I2C Communication
  Wire.beginTransmission(MPU_addr);  //Start communication with MPU6050
  Wire.write(0x6B);                  //Writes to Register 6B
  Wire.write(0);                     //Writes 0 into 6B Register to Reset
  Wire.endTransmission(true);        //Ends I2C transmission

另外,为伺服电机连接定义了四个PWM引脚。

servo_1.attach(2);   // Forward/Reverse_Motor
  servo_2.attach(3);   // Up/Down_Motor
  servo_3.attach(4);   // Gripper_Motor
  servo_4.attach(5);   // Left/Right_Motor

接下来,在void loop函数中,再次在MPU6050和 Arduino Nano之间建立I2C连接,然后开始从MPU6050的寄存器读取X、Y、Z轴数据并将它们存储在相应的变量中。

 Wire.beginTransmission(MPU_addr);   
  Wire.write(0x3B);                  //Start with regsiter 0x3B
  Wire.endTransmission(false);     
  Wire.requestFrom(MPU_addr,14,true);  //Read 14 Registers
                         axis_X=Wire.read()<<8|Wire.read();               
                         axis_Y=Wire.read()<<8|Wire.read();
                         axis_Z=Wire.read()<<8|Wire.read();

然后,将MPU6050传感器的轴数据的最小值和最大值映射在-90到90的范围内。

int xAng = map(axis_X,minVal,maxVal,-90,90);   
int yAng = map(axis_Y,minVal,maxVal,-90,90);
int zAng = map(axis_Z,minVal,maxVal,-90,90);

然后使用以下公式以0到360的形式计算x,y,z值

 x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);      
  y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

然后在 Arduino Nano的A0引脚上读取挠曲传感器的模拟输出数据,并根据弯曲传感器的数字值设置夹具的伺服角度。因此,如果弯曲传感器数据大于750,则夹具的伺服电机角度为0度,如果小于750,则为180度。

int gripper;
  int flex_sensorip = analogRead(A0);            
  if(flex_sensorip > 750)      
        {
          gripper = 0;
        }
        else
        {
          gripper = 180;
        }
   servo_3.write(gripper);           

然后,将MPU6050在X轴上从0到60的移动映射为0到90度,以实现伺服电机的机械臂正向/反向运动。

   if(x >=0 && x <= 60)
  {
     int mov1 = map(x,0,60,0,90);
     Serial.print("Movement in F/R = ");
     Serial.print(mov1);
     Serial.println((char)176);
     servo_1.write(mov1);
  }

MPU6050在X轴上从250到360的运动被映射为0到90度,用于伺服电机的上/下运动机械手。

使用 Arduino进行手势控制的机械臂的工作

最后,将代码上传到 Arduino Nano,并戴上MPU6050和弯曲传感器安装的手套。

现在,向下移动手以使机械臂向前移动,向上移动以使机械臂向上移动。然后向左或向右倾斜手,以向左或向右旋转机械手。弯曲手打开夹持器,然后松开以使其闭合。

完整代码:

//Code for Gesture Controlled Robotic ARM (Arduino Nano & MPU6050)
//Circuit Digest

#include<Wire.h>                //I2C Wire Library 
#include<Servo.h>               //Servo Motor Library

Servo servo_1;      
Servo servo_2;
Servo servo_3;
Servo servo_4;

const int MPU_addr=0x68;        //MPU6050 I2C Address
int16_t axis_X,axis_Y,axis_Z;
int minVal=265;
int maxVal=402;

double x;
double y;
double z;
 
void setup()
{
  Serial.begin(9600);
  
  Wire.begin();                      //Initilize I2C Communication
  Wire.beginTransmission(MPU_addr);  //Start communication with MPU6050
  Wire.write(0x6B);                  //Writes to Register 6B
  Wire.write(0);                     //Writes 0 into 6B Register to Reset
  Wire.endTransmission(true);        //Ends I2C transmission
  
  servo_1.attach(2);   // Forward/Reverse_Motor
  servo_2.attach(3);   // Up/Down_Motor
  servo_3.attach(4);   // Gripper_Motor
  servo_4.attach(5);   // Left/Right_Motor
  
}

void loop()
{
  Wire.beginTransmission(MPU_addr);    
  Wire.write(0x3B);                  //Start with regsiter 0x3B 
  Wire.endTransmission(false);     
  Wire.requestFrom(MPU_addr,14,true);  //Read 14 Registers 
  
  axis_X=Wire.read()<<8|Wire.read();                //Reads the MPU6050 X,Y,Z AXIS Value
  axis_Y=Wire.read()<<8|Wire.read();
  axis_Z=Wire.read()<<8|Wire.read();
  
  int xAng = map(axis_X,minVal,maxVal,-90,90);     // Maps axis values in terms of -90 to +90  
  int yAng = map(axis_Y,minVal,maxVal,-90,90);
  int zAng = map(axis_Z,minVal,maxVal,-90,90);
       
  x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);       //Formula to convert into degree
  y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
  z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

  int gripper;
  int flex_sensorip = analogRead(A0);            //Reads flex sensor output
     
  if(flex_sensorip > 750)
        {
          gripper = 0;
        }
        else
        {
          gripper = 180;
        }
  
   servo_3.write(gripper);                    //Writes gripper value to 3rd servo motor
  
  if(x >=0 && x <= 60) 
  {
     int mov1 = map(x,0,60,0,90);
     Serial.print("Movement in F/R = ");
     Serial.print(mov1);
     Serial.println((char)176);
     servo_1.write(mov1);
  } 
 
  else if(x >=300 && x <= 360) 
  {
     int mov2 = map(x,360,250,0,180);
     Serial.print("Movement in Up/Down = ");
     Serial.print(mov2);
     Serial.println((char)176);
     servo_2.write(mov2);
  } 

 if(y >=0 && y <= 60) 
  {
     int mov3 = map(y,0,60,90,180);
     Serial.print("Movement in Left = ");
     Serial.print(mov3);
     Serial.println((char)176);
     servo_4.write(mov3);
  } 
 
  else if(y >=300 && y <= 360) 
  {
     int mov3 = map(y,360,300,90,0);
     Serial.print("Movement in Right = ");
     Serial.print(mov3);
     Serial.println((char)176);
     servo_4.write(mov3);
  } 
}

Similar Posts

Leave a Reply