找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 25525|回复: 43
打印 上一主题 下一主题
收起左侧

基于Arduino的可学习机械臂制作 附代码

  [复制链接]
跳转到指定楼层
楼主
本帖最后由 cj52 于 2019-4-19 00:06 编辑

前段时间在知乎上看到有用Arduino做机械臂的,自己也做了一个来玩玩。
基本原理很简单,就是电位器(蓝白可调电阻)来控制舵机。
制作2个机械臂,从机械臂的关节处用电位器接合,主机械臂用舵机,将电位器的电压与舵机的角度相映射就能让舵机与电位器同步运作。
学习的具体内容见代码,基本上就是记录学习过程中的几个主要动作,然后根据这些主要动作来模糊推测大动作之间的小动作。

制作出来的实物图如下:


视频效果自取链接:https://pan.baidu.com/s/1gRzXL1DkdWBaYyxTWxKEyA    提取码:g9su
                             https://pan.baidu.com/s/1ngaNVAzMBjx2wjF1jojfbw   提取码:2vh6
                             https://pan.baidu.com/s/1vqZn4FpYyzftkw7iwNzFrA   提取码:cndx
第二个视频中主机械臂出现突变是因为从机械臂的电位器接触不良。
*******************************************************************************

Arduino源程序如下:

#include <Servo.h>
Servo servo_0;  //定义4个舵机
Servo servo_1;
Servo servo_2;
Servo servo_3;
int sensorPin0 = A0;  //电位器阻值输入口
int sensorPin1 = A1;
int sensorPin2 = A2;
int sensorPin3 = A3;
int SensVal_0;
int SensVal_1;
int SensVal_2;
int SensVal_3;
boolean playmode = false;  //设置运行模式,初始化为学习
float angle0[30];// 存储底座舵机动作的数组,最多存30个
float angle1[30];//手臂舵机角度数组
float angle2[30];//手掌舵机角度数组
float angle3[30];//夹子舵机角度数组
float dif[4],temp[4];// 差分值与中间数组

int i,j,k,stepsMax,num=0,key_value,num1=0,del;
void setup() {
  // put your setup code here, to run once:
  pinMode(4, INPUT);  // 键盘输入口
   servo_0.attach(6); // 连接舵机
   servo_1.attach(9);
   servo_2.attach(10);
   servo_3.attach(11);
   Serial.begin(115200);
}
void loop()
{
  // put your main code here, to run repeatedly:
  if(playmode == false)      //学习模式
  {
    SensVal_1 = analogRead(sensorPin1); //读取电位器阻值
    //Serial.println(SensVal_1);
    SensVal_1 = map(SensVal_1, 0, 1024, 500, 2500);//将电位器阻值与舵机角度映射,实现两个机械臂的同步
   
    SensVal_0 = analogRead(sensorPin0);
    //Serial.println(SensVal_0);
    SensVal_0 = map(SensVal_0, 0, 1024, 500, 2500);
  
    SensVal_2 = analogRead(sensorPin2);
    //Serial.println(SensVal_2);
    SensVal_2 = map(SensVal_2, 0, 1024, 500, 2500);
  
    SensVal_3 = analogRead(sensorPin3);
     //Serial.println(SensVal_3);
    SensVal_3 = map(SensVal_3, 0, 1024, 500, 2500);
   
    servo_0.writeMicroseconds(SensVal_0); //控制主机械臂跟随从机械臂运行
    servo_1.writeMicroseconds(SensVal_1);
    servo_2.writeMicroseconds(SensVal_2);
    servo_3.writeMicroseconds(SensVal_3);
  }
   else         //运行模式
   {
      for(i=0;i<num;i++)
      {
        temp[0]=angle0;    //暂存当前动作角度值
        
temp[1]=angle1;
        temp[2]=angle2;
        temp[3]=angle3;
        j=i+1;                //指向下一个动作
        if(j==num) j=0;
        dif[0] = abs(angle0[j]-angle0);     //下一动作与当前动作做差分
        dif[1] = abs(angle1[j]-angle1);
        dif[2] = abs(angle2[j]-angle2);
        dif[3] = abs(angle3[j]-angle3);
        
        stepsMax = max(dif[0],dif[1]);         //找出最大差分值
        stepsMax = max(stepsMax,dif[2]);
        stepsMax = max(stepsMax,dif[3]);
        //将两个动作分为最大差分值个小动作,即用每个舵机的差分值除以最大差分值
        if (angle0[j] < angle0) dif[0] = 0-dif[0]/stepsMax; else dif[0] = dif[0]/stepsMax;
        if (angle1[j] < angle1) dif[1] = 0-dif[1]/stepsMax; else dif[1] = dif[1]/stepsMax;
        if (angle2[j] < angle2) dif[2] = 0-dif[2]/stepsMax; else dif[2] = dif[2]/stepsMax;
        if (angle3[j] < angle3) dif[3] = 0-dif[3]/stepsMax; else dif[3] = dif[3]/stepsMax;
        
        for(k=0;k<stepsMax;k++)   // 运行至下一大动作
        {
          //Serial.println("stepin");
          angle0 += dif[0];    //运行到下一小动作
          angle1 += dif[1];
          angle2 += dif[2];
          angle3 += dif[3];
         
          servo_0.writeMicroseconds(angle0);
          servo_1.writeMicroseconds(angle1);
          servo_2.writeMicroseconds(angle2);
          servo_3.writeMicroseconds(angle3);
          delay(1);
        }
         //Serial.println("stepout");
        angle0=temp[0];            //返回暂存的动作值
        angle1=temp[1];
        angle2=temp[2];
        angle3=temp[3];
      }
   }
   //Serial.println(digitalRead(4));
   Button();    //按键检测
}
void Button() //按键检测
{
  if (digitalRead(4) == true)
  {
    delay(20);                //消抖
    if (digitalRead(4) == true)
    {
        key_value = 1;
        delay(1000);
        if(digitalRead(4) == true) key_value = 2; //长按进入运行模式
    }
  }
   
    if ((key_value == 1)) // 记录舵机当前位置
    {
      
     angle0[num1]=SensVal_0;
     angle1[num1]=SensVal_1;
     angle2[num1]=SensVal_2;
     angle3[num1]=SensVal_3;
     num1++;                    //指针加1
     key_value = 0;
     playmode = false;
    }
    else if (key_value == 2)
    {
      num = num1;               //取出动作的总数
      num1=0;                   //为下一次学习做准备
      playmode = true;          //运行模式
      key_value = 0;
    }
}

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶2 踩
回复

使用道具 举报

来自 2#
ID:318910 发表于 2020-1-27 18:37 | 只看该作者
本帖最后由 cj52 于 2020-1-30 10:52 编辑

有问题的代码是因为那些数组后面少了下标i,这个论坛的编辑器把i识别成斜体变换了,所以有问题的代码后面都是斜体,而且i不见了,改动只需要在angle0 angele1等这些数组后面加上方括号,里面再加上i即可
回复

使用道具 举报

来自 3#
ID:318910 发表于 2020-3-4 21:03 | 只看该作者
cj52 发表于 2020-1-27 18:37
有问题的代码是因为那些数组后面少了下标i,这个论坛的编辑器把i识别成斜体变换了,所以有问题的代码后面都是 ...

今天学会了回复图片和文件。。。所以在这里回复下面有同学要的接线图 附软件流程图和当时实验报告 哈哈哈哈

实习51hei.doc

2.16 MB, 下载次数: 57, 下载积分: 黑币 -5

实习报告

回复

使用道具 举报

地板
ID:426684 发表于 2019-4-16 20:00 | 只看该作者
作者自己测试过该代码吗?

float angle0[30];  编译出错?  
回复

使用道具 举报

5#
ID:318910 发表于 2019-4-18 16:04 | 只看该作者
探索软件 发表于 2019-4-16 20:00
作者自己测试过该代码吗?

float angle0[30];  编译出错?

测试过  刚又编译了一次 没有问题啊

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

6#
ID:521352 发表于 2019-4-26 10:08 | 只看该作者
厉害!我对自制机器人的理解还处在MATLAB阶段。。。
回复

使用道具 举报

7#
ID:474784 发表于 2019-7-19 02:07 来自手机 | 只看该作者
问题,同一楼编译出错
回复

使用道具 举报

8#
ID:474784 发表于 2019-7-19 02:16 来自手机 | 只看该作者
数组不能复制
回复

使用道具 举报

9#
ID:474784 发表于 2019-7-19 02:47 来自手机 | 只看该作者
探索软件 发表于 2019-4-16 20:00
作者自己测试过该代码吗?

float angle0[30];  编译出错?

加我好友qq   1595141562   
我刚刚改了一下代码,就好了。
回复

使用道具 举报

10#
ID:115780 发表于 2019-9-5 21:19 | 只看该作者
改动的哪里代码啊 ?
回复

使用道具 举报

11#
ID:628606 发表于 2019-10-23 06:18 | 只看该作者
彭大伟 发表于 2019-7-19 02:47
加我好友qq   1595141562   
我刚刚改了一下代码,就好了。

改到哪里了?可以把改的地方再发一次吗?谢谢。。。
回复

使用道具 举报

12#
ID:628217 发表于 2019-10-23 08:51 | 只看该作者
动手能力真强啊,底座感觉太单薄了,保持平衡会有问题
回复

使用道具 举报

13#
ID:656210 发表于 2019-12-4 19:42 | 只看该作者
作者你好请问能私聊问你些事情吗?
回复

使用道具 举报

14#
ID:171746 发表于 2019-12-15 18:23 | 只看该作者
Arduino:1.8.9 (Windows 7), 开发板:"Arduino/Genuino Uno"

The sketch name had to be modified.
Sketch names must start with a letter or number, followed by letters,
numbers, dashes, dots and underscores. Maximum length is 63 characters.

C:\Users\Administrator\Documents\Arduino\jiqibi_xuexi_001\jiqibi_xuexi_001.ino: In function 'void loop()':

jiqibi_xuexi_001:63:16: error: cannot convert 'float [30]' to 'float' in assignment

         temp[0]=angle0;    //暂存当前动作角度值

                ^

jiqibi_xuexi_001:64:16: error: cannot convert 'float [30]' to 'float' in assignment

         temp[1]=angle1;

                ^

jiqibi_xuexi_001:65:16: error: cannot convert 'float [30]' to 'float' in assignment

         temp[2]=angle2;

                ^

jiqibi_xuexi_001:66:16: error: cannot convert 'float [30]' to 'float' in assignment

         temp[3]=angle3;

                ^

In file included from sketch\jiqibi_xuexi_001.ino.cpp:1:0:

jiqibi_xuexi_001:69:32: error: invalid operands of types 'float' and 'float [30]' to binary 'operator-'

         dif[0] = abs(angle0[j]-angle0);     //下一动作与当前动作做差分

                                ^

D:\A
回复

使用道具 举报

15#
ID:171746 发表于 2019-12-15 18:27 | 只看该作者
请把改动的发一下吗?  谢谢
回复

使用道具 举报

16#
ID:171746 发表于 2019-12-15 18:42 | 只看该作者
weixiao_99 发表于 2019-12-4 19:42
作者你好请问能私聊问你些事情吗?

改到哪里了?可以把改的地方再发一次吗?谢谢
回复

使用道具 举报

17#
ID:318910 发表于 2020-1-27 18:45 | 只看该作者
weixiao_99 发表于 2019-12-4 19:42
作者你好请问能私聊问你些事情吗?

可以啊
回复

使用道具 举报

18#
ID:318910 发表于 2020-1-27 18:54 | 只看该作者
本帖最后由 cj52 于 2020-1-29 16:42 编辑
探索软件 发表于 2019-4-16 20:00
作者自己测试过该代码吗?

float angle0[30];  编译出错?

先跟你道个歉,上次我说测试没问题是因为我用的是我电脑中的代码测试,没有用这里的代码。快一年没有上这个论坛了,今天上来发现有很多朋友都说这个问题,我把这里的代码复制过去编译,发现确实有问题。不知道怎么从电脑上传到这里就漏了一些东西,就是数组名后面的下标掉了,错误的地方就变成了把数组名(也就是指针)赋给float变量,所以出错了,改动只需在数组名(angle0,angle1,angle2,angle3)后面加上下标即可
回复

使用道具 举报

19#
ID:318910 发表于 2020-1-27 18:58 | 只看该作者
快一年没有上到这个论坛了,今天闲来无事登上来才发现这个帖子都有4000多的浏览了,有点小激动。看到很多朋友都说有编译问题,才把这里的代码复制来测试了一遍找到了问题所在,错误的具体原因和改动方法已经回复在一楼了,有需要的朋友可以看看
回复

使用道具 举报

20#
ID:318910 发表于 2020-1-27 18:58 | 只看该作者
lucq7896 发表于 2019-12-15 18:27
请把改动的发一下吗?  谢谢

已经在一楼回复了
回复

使用道具 举报

21#
ID:318910 发表于 2020-1-27 19:01 | 只看该作者
彭大伟 发表于 2019-7-19 02:07
问题,同一楼编译出错

问题已经回复在一楼,谢谢
回复

使用道具 举报

22#
ID:318910 发表于 2020-1-27 19:02 | 只看该作者
cd5566 发表于 2019-9-5 21:19
改动的哪里代码啊 ?

已经回复在一楼,谢谢
回复

使用道具 举报

23#
ID:318910 发表于 2020-1-27 19:02 | 只看该作者
s7club 发表于 2019-10-23 06:18
改到哪里了?可以把改的地方再发一次吗?谢谢。。。

已经回复在一楼,谢谢
回复

使用道具 举报

24#
ID:693988 发表于 2020-2-16 18:10 | 只看该作者
up主你好,我把数组名都改了,下载了不能跟着电位计随动,只能长按按键的时候才能随动,能不能解答一下,谢谢
回复

使用道具 举报

25#
ID:693988 发表于 2020-2-16 18:12 | 只看该作者
程序编译时没问题了,只是下载到板子里不能随动,麻烦解答一下,谢谢
回复

使用道具 举报

26#
ID:701071 发表于 2020-3-2 11:52 | 只看该作者
热心市民王先生2 发表于 2020-2-16 18:12
程序编译时没问题了,只是下载到板子里不能随动,麻烦解答一下,谢谢

你好,请问问题解决了吗,能分享一下资料吗?
回复

使用道具 举报

27#
ID:701071 发表于 2020-3-2 14:26 | 只看该作者
cj52 发表于 2020-1-27 18:37
有问题的代码是因为那些数组后面少了下标i,这个论坛的编辑器把i识别成斜体变换了,所以有问题的代码后面都是 ...

接线图可以发一下吗?请问
回复

使用道具 举报

28#
ID:701486 发表于 2020-3-3 05:34 | 只看该作者
建议上传到优酷,方便观看

这个操作方式挺新奇的
回复

使用道具 举报

29#
ID:318910 发表于 2020-3-4 20:31 | 只看该作者
小张总 发表于 2020-3-2 14:26
接线图可以发一下吗?请问

可以啊 但我不知道怎么回复图片。。。
回复

使用道具 举报

30#
ID:318910 发表于 2020-3-4 21:03 | 只看该作者
小张总 发表于 2020-3-2 14:26
接线图可以发一下吗?请问

哈哈哈 我会回复图片了 已经回复在一楼
回复

使用道具 举报

31#
ID:693988 发表于 2020-3-17 14:43 | 只看该作者
小张总 发表于 2020-3-2 11:52
你好,请问问题解决了吗,能分享一下资料吗?

没有呢
回复

使用道具 举报

32#
ID:693988 发表于 2020-3-17 14:46 | 只看该作者
cj52 发表于 2020-1-27 19:02
已经回复在一楼,谢谢

已经按照你说的添加了下标了,编译也没有问题,但现在不按按键,舵机根本就不能随动
回复

使用道具 举报

33#
ID:318910 发表于 2020-3-18 13:35 | 只看该作者
热心市民王先生2 发表于 2020-3-17 14:46
已经按照你说的添加了下标了,编译也没有问题,但现在不按按键,舵机根本就不能随动

接线对不对? 滑动变阻器是不是没有引入AD口?因为蓝白可调电阻从最小的阻值到最大的阻值刚好转了一圈,所以随动的原理是将蓝白可调电阻作为角度传感器,把它的阻值与旋转角度对应起来,通过AD采样电阻上的电压,就知道大概转了多少角度,然后把这个角度换算成舵机的PWM值,再去控制舵机,这样就能随动了。你可以先自己写一小段代码在面包板上测试一下,用一个滑动变阻器来控制一个舵机旋转,我觉得这个挺有意思的。。可以发散到其他许多地方,比如远程控制等,你不妨也拓展拓展,做一些有意思的东西,不必拘泥于这一个机械臂。

评分

参与人数 1黑币 +90 收起 理由
admin + 90 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

34#
ID:693988 发表于 2020-3-19 13:59 | 只看该作者
cj52 发表于 2020-3-18 13:35
接线对不对? 滑动变阻器是不是没有引入AD口?因为蓝白可调电阻从最小的阻值到最大的阻值刚好转了一圈, ...

好的,谢谢啦
回复

使用道具 举报

35#
ID:717402 发表于 2020-3-28 11:09 | 只看该作者
初来咋到,请多关照,向大师们致敬!
回复

使用道具 举报

36#
ID:742968 发表于 2020-5-2 19:19 | 只看该作者
热心市民王先生2 发表于 2020-2-16 18:10
up主你好,我把数组名都改了,下载了不能跟着电位计随动,只能长按按键的时候才能随动,能不能解答一下,谢 ...

按键没接对哦,要用微动按键,你可以把  Serial.println(key_value);    这句加一下。就可以知道你按键对不对了。
回复

使用道具 举报

37#
ID:747036 发表于 2020-5-8 16:42 | 只看该作者
好厉害,支持支持
回复

使用道具 举报

38#
ID:739532 发表于 2020-5-21 15:14 | 只看该作者
楼主好厉害
回复

使用道具 举报

39#
ID:617786 发表于 2020-5-27 18:53 | 只看该作者
大佬能加一下你QQ吗请教按键问题,为神魔串口监视器一直读出来按键值是1,一直按着才是0.

回复

使用道具 举报

40#
ID:617786 发表于 2020-5-27 19:27 | 只看该作者
大佬你用的按键是哪种按键,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表