单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:11595|回复:13
打印上一主题下一主题

机械臂(夹乒乓球)+蓝牙控制小车制作 含单片机源程序

 [复制链接]
跳转到指定楼层
楼主
ID:200362发表于 2017-6-4 20:36|只看该作者回帖奖励
之前在51hei论坛上没有找到这方面的有用的资料,但看其他帖子也给我了很大的启发,所以决定把源程序发出来。
这辆车作用是用机械臂来夹乒乓球,放在盒子中,然后从盒子里倒出来。

先上图


单片机源程序如下:
  1. /************************************************
  2.   机械臂蓝牙小车
  3.   用到定时器0工作方式1 16位定时计数(PWM),定时器1工作方式2 8位自动重装
  4.   (波特率9600),串口工作方式1  
  5. *************************************************/
  6. #include<reg52.h>
  7. #define uchar unsigned char
  8. #define uint unsigned int
  9. uint i,j,tmp;
  10. sbit right_go=P1^0;
  11. sbit right_back=P1^1;
  12. sbit left_go=P1^2;
  13. sbit left_back=P1^3;

  14. sbit right_go2=P1^4;
  15. sbit right_back2=P1^5;
  16. sbit left_go2=P1^6;
  17. sbit left_back2=P1^7;

  18. sbit ENA1=P2^0;
  19. sbit ENB1=P2^3;
  20. sbit ENA2=P2^0;
  21. sbit ENB2=P2^3;

  22. sbit pwm1 =P3^3;
  23. sbit pwm2 =P3^4;
  24. sbit pwm3 =P3^5;
  25. sbit pwm4 =P3^6;
  26. uchar count,num1;       //0.5ms次数标识
  27. uchar jd1,jd2,jd3,jd4;             //角度标识
  28. void delay(uint z)//调节电机转速
  29. {
  30.        uint x,y;
  31.        for(x=z;x>0;x--)
  32.            for(y=110;y>0;y--);
  33. }

  34. void go()
  35. {
  36.        ENA1=1;
  37.        ENB1=1;
  38.        ENA2=1;
  39.        ENB2=1;
  40.        right_back=0;
  41.        left_go=1;
  42.        left_back=0;
  43.        right_go=1;

  44.        right_back2=0;
  45.        left_go2=1;
  46.        left_back2=0;
  47.        right_go2=1;
  48.           

  49. //       right_back=0;
  50. //       left_go=0;
  51. //       left_back=0;
  52. //       right_go=0;
  53. //       right_back2=0;
  54. //       left_go2=0;
  55. //       left_back2=0;
  56. //       right_go2=0;
  57.     


  58. }

  59. void back()
  60. {
  61.        ENA1=1;
  62.        ENB1=1;
  63.        ENA2=1;
  64.        ENB2=1;
  65.        right_back=1;
  66.        left_go=0;
  67.        left_back=1;
  68.        right_go=0;

  69.        right_back2=1;
  70.        left_go2=0;
  71.        left_back2=1;
  72.        right_go2=0;

  73.     
  74. //       right_back=0;
  75. //       left_go=0;
  76. //       left_back=0;
  77. //       right_go=0;
  78. //       right_back2=0;
  79. //       left_go2=0;
  80. //       left_back2=0;
  81. //       right_go2=0;
  82.     
  83. }

  84. void left()
  85. {
  86.        ENA1=1;
  87.        ENB1=1;
  88.        ENA2=1;
  89.        ENB2=1;
  90.        right_go=1;
  91.        right_back=0;
  92.        left_go=0;
  93.        left_back=1;

  94.        right_go2=1;
  95.        right_back2=0;
  96.        left_go2=1;
  97.        left_back2=0;


  98. //       right_go=0;
  99. //       right_back=0;
  100. //       left_go=0;
  101. //       left_back=0;

  102. //       right_go2=0;
  103. //       right_back2=0;
  104. //       left_go2=0;
  105. //       left_back2=0;
  106.     

  107. }

  108. void right()
  109. {
  110.        ENA1=1;
  111.        ENB1=1;
  112.        ENA2=1;
  113.        ENB2=1;
  114.    right_back=1;
  115.        left_go=1;
  116.        left_back=0;
  117.        right_go=0;

  118.        right_back2=0;
  119.        left_go2=1;
  120.        left_back2=0;
  121.        right_go2=1;


  122. //       right_back=0;
  123. //       left_go=0;
  124. //       left_back=0;
  125. //       right_go=0;

  126. //       right_back2=0;
  127. //       left_go2=0;
  128. //       left_back2=0;
  129. //       right_go2=0;

  130. }

  131. void stop()
  132. {
  133.        right_back=0;
  134.        left_go=0;
  135.        left_back=0;
  136.        right_go=0;

  137.        right_back2=0;
  138.        left_go2=0;
  139.        left_back2=0;
  140.        right_go2=0;
  141. }
  142. /*void duoji1_up()
  143. {
  144.        jd1++;            
  145.    num=0;           //按键按下 则20ms周期从新开始
  146.    if(jd1==6)
  147.      jd1=5;           //已经是180度,则保持    
  148. }
  149. void duoji1_dwon()
  150. {
  151.        jd1--;            
  152.    num=0;
  153.    if(jd1==0)
  154.      jd1=1;           //已经是0度,则保持
  155. }
  156. void duoji2_up()
  157. {
  158.        jd2++;            
  159.    num=0;           //按键按下 则20ms周期从新开始
  160.    if(jd2==6)
  161.      jd2=5;           //已经是180度,则保持    
  162. }  
  163. void duoji2_dwon()
  164. {
  165.        jd2--;            
  166.    num=0;
  167.    if(jd2==0)
  168.      jd2=1;           //已经是0度,则保持
  169. }       */

  170. void init()
  171. {
  172.        TMOD= 0x21;
  173.    TH1 = 0xfd;
  174.    TL1 = 0xfd;
  175.        TH0= 0xff;       //0.5ms
  176.        TL0=0x8c;         //0.25ms       //0.125ms
  177.        ET0=1;          
  178.        TR0=1;
  179.    TR1= 1;    
  180.    REN= 1;
  181.    SM0= 0;
  182.    SM1= 1;  
  183.    ES= 1;       //串口中断允许位
  184.    EA=1;
  185.        right_back=0;
  186.        left_go=0;
  187.        left_back=0;
  188.        right_go=0;

  189.        right_back2=0;
  190.        left_go2=0;
  191.        left_back2=0;
  192.        right_go2=0;
  193. //       jd1=1;
  194. //   jd2=1;      
  195. //       num=0;
  196. }

  197. void main()
  198. {
  199.        jd1=14;
  200.        jd2=6;
  201.        jd3=5;
  202.        jd4=6;
  203.        count=0;
  204.        init();
  205.        while(1)
  206.        {
  207.            switch(tmp)
  208.            {
  209.           
  210.            case 0x01: go(); break;
  211.                  case 0x02: back(); break;
  212.                  case 0x03: left(); break;
  213.                  case 0x04: right(); break;
  214.                  case 0x00: stop(); break;            
  215.                  case 0x05:                                   //爪子
  216.                        jd1++;
  217.                        count=0;
  218.                        tmp=0;
  219.                        if(jd1==15)
  220.                        jd2=3;                
  221.                        if(jd1==18)
  222.                          {
  223.                            jd1=17;
  224.                            delay(200);
  225.                            jd2=15;
  226.                           
  227.                            }break;
  228.                  case 0x06:      
  229.                        tmp=0;
  230.                        jd1--;
  231.                        count=0;
  232.                        if(jd1==0)
  233.                            jd1=1; break;
  234. //                       case 0x07:                         //支架
  235. //                       jd2++;
  236. //                       count=0;
  237. //                       tmp=0;
  238. //                       if(jd2==6)
  239. //                           jd2=5; break;
  240. //                 case 0x08:      
  241. //                       tmp=0;
  242. //                       jd2--;
  243. //                       count=0;
  244. //                       if(jd2==0)
  245. //                           jd2=1; break;
  246.                  case 0x09:                         //门
  247.                        jd3++;
  248.                        count=0;
  249.                        tmp=0;
  250.                        if(jd3==21)
  251.                            jd3=20; break;
  252.                  case 0x10:      
  253.                        tmp=0;
  254.                        jd3--;
  255.                        count=0;
  256.                        if(jd3==0)
  257.                            jd3=1; break;    
  258.                  default:break;

  259.            }


  260.        }
  261. }
  262. void time0() interrupt 1
  263. {
  264.        TH0  = 0xff;        
  265.        TL0  = 0x8c;

  266.    if(count<jd1)           //判断0.5ms次数是否小于角度标识
  267.      pwm1=1;                       //确实小于,PWM输出高电平                          
  268.    else
  269.        pwm1=0;                       //大于则输出低电平
  270.        if(count<jd2)
  271.            pwm2=1;
  272.        else
  273.            pwm2=0;
  274.        if(count<jd3)
  275.            pwm3=1;
  276.        else
  277.            pwm3=0;    
  278.        if(count<jd4)
  279.            pwm4=1;
  280.        else
  281.            pwm4=0;                          
  282.        count=(count+1);             //0.5ms次数加1    
  283.    count=count%160;     //次数始终保持为40 即保持周期为20ms
  284.           
  285.     
  286. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

全部资料下载地址:
程序.rar(1.56 KB, 下载次数: 181)



评分

黑币 +105
收起理由
+ 5
很给力!
+ 100
共享资料的黑币奖励!

查看全部评分

沙发
ID:200362发表于 2017-6-4 21:07|只看该作者
虽然做出来了,但还是有些问题想问一下大神们。
1:用4200mah的航模电池驱动两块LM298,然后再通过降压模块降到5V给单片机供电,并且驱动舵机,为什么接航模电池那两根线会非常发烫,变软(很吓人!!!)?
   最后只能用双电源解决。
2:原先是打算控制4个舵机,夹子一个,关节一个,整只 手臂转动一个,然后从盒子里倒球一个(门舵机)。但是最后的门 舵机总会被控制前面三个舵机的指令干扰,无法运行,最后只能把控制转动的舵机去掉。我想问的是为什么控制3个舵机可以,4个就不行了(也加了滤波电容)?

这里   count=(count+1);             //0.5ms次数加1    
       count=count%160;     //次数始终保持为40 即保持周期为20ms
       注释错了 该是0.25ms次数加1      
板凳
ID:192765发表于 2017-6-17 15:33|只看该作者
咋没人回楼主呢 我也好想知道为什么
地板
ID:187365发表于 2017-6-18 15:42|只看该作者
看起来很棒
5#
ID:106371发表于 2017-10-28 16:20|只看该作者
终于解决蓝牙控制舵机问题了,不过为啥两个舵机控制有冲突
6#
ID:241881发表于 2017-11-19 20:44|只看该作者
LM298输出电流驱动舵机是不分正负的,降压模块是分正负的,反向时会短路通过大电流
7#
ID:560831发表于 2019-6-12 14:12|只看该作者
很给力!
8#
ID:437102发表于 2019-9-17 19:24|只看该作者
试试 看好不好用
9#
ID:368810发表于 2021-8-7 17:40|只看该作者
是收集一定空间内所有的乒乓球还是收集一个就倒出来啊?
10#
ID:977393发表于 2021-11-3 17:11|只看该作者
机器识别是用到那个了
11#
ID:582255发表于 2022-10-13 09:11|只看该作者
乒乓球需要识别吗?还是直接去抓
12#
ID:582255发表于 2022-10-13 09:11|只看该作者
乒乓球咋识别的 啊
13#
ID:208271发表于 2024-1-23 22:05|只看该作者
ereerr 发表于 2017-6-4 21:07
虽然做出来了,但还是有些问题想问一下大神们。
1:用4200mah的航模电池驱动两块LM298,然后再通过降压模 ...

是不是电池有问题,这麽大电流还没有输出保护
14#
ID:155719发表于 2024-2-1 08:40|只看该作者
这个木头外壳很有感觉啊

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

Powered by 单片机教程网