极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2210|回复: 0

12自由度六足机器人实现蓝牙遥控功能

[复制链接]
发表于 2023-3-28 10:07:46 | 显示全部楼层 |阅读模式
本帖最后由 机器谱 于 2023-3-28 10:07 编辑

1. 功能描述
      R111样机是一款拥有12个自由度的串联仿生六足机器人。本文为这个六足机器人增加蓝牙遥控功能,可以通过安卓手机APP对机器人的动作实现遥控。
2. 电子硬件
     在这个示例中,我们采用了以下硬件,请大家参考:

主控板
Basra主控板(兼容Arduino Uno)
扩展板SH-SR舵机扩展板
舵机标准舵机
电池7.4V锂电池
通信
蓝牙串口模块

电路连接说明:
12自由度六足机器人结构上装有12个舵机,所以将采用 SH-SR舵机扩展板
舵机接线顺序:1、3; 4、 5; 6、 8;11、13;15、 21;24、26。


蓝牙串口模块可以通过杜邦线与扩展板进行连接,具体可以参考 如何使用探索者通信模块 一文中蓝牙串口模块部分。


3. 功能实现
     下面的例程可以实现通过安卓手机APP按钮实现机器人前进、后退、左转、右转、跳舞等动作。安卓APP的设置也可以参考
如何使用探索者通信模块一文中蓝牙串口模块部分。
     你也可以设计自己想要的动作,利用Controller 1.0b软件获取想要的动作参数,拷贝到下面的例程里。
将参考例程(R111_bluetooth.ino)下载到主控板:

  1. /*------------------------------------------------------------------------------------

  2.   版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

  3.            Distributed under MIT license.See file LICENSE for detail or copy at

  4.            https://opensource.org/licenses/MIT

  5.            by 机器谱 2023-02-16 https://www.robotway.com/

  6.   ------------------------------*/

  7. #include <Arduino.h>

  8. #include <avr/pgmspace.h>

  9. #include "Config.h"

  10. #include <Tlc5940.h>

  11. #include <tlc_servos.h>


  12. int count_input = 0;

  13. boolean _b = false;


  14. /*************+++++++++++动作组数组,请将转换后的动作组数据粘贴到相应的动作组中+++++++****************/

  15. const PROGMEM int actionInit[] = {

  16.   1090, 1790, 1220, 980, 650, 1800, 1020, 1330, 520, 1155, 1260, 2020,

  17.   1090, 1790, 1220, 980, 650, 1800, 1020, 1330, 520, 1155, 1260, 2020,

  18. //   1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,

  19. //   1090, 1790, 1220, 980, 650, 1800, 1020, 1330, 520, 1155, 1260, 2020

  20. };

  21. const PROGMEM int actionMove[] = {

  22.   1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,

  23.   1660, 1790, 1320, 1080, 1280, 1800, 920, 1230, 1090, 1255, 1360, 2020,

  24.   1660, 1230, 1320, 1080, 1280, 1190, 920, 1230, 1090, 1255, 1360, 1540,

  25.   1090, 1300, 1120, 880, 650, 900, 1120, 1430, 520, 1055, 1160, 1300,

  26.   1660, 1300, 1120, 880, 1280, 900, 1120, 1430, 1090, 1055, 1160, 1300,

  27. };

  28. const PROGMEM int actionLeft[] = {

  29.   1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,

  30.   1080,1160,1420,780,650,1100,1220,1130,520,955,1460,1430,

  31.   1700,1160,1420,780,1440,1100,1220,1130,1100,955,1460,1430,

  32.   1700,1700,1020,1180,1440,1800,820,1530,1100,1355,1060,2020,

  33.   1700,1160,1020,1180,1440,1100,820,1530,1100,1355,1060,1430,

  34. };

  35. const PROGMEM int actionRight[] = {

  36.   1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,

  37.   1700,1700,1420,780,1440,1800,1220,1130,1100,955,1460,2020,

  38.   1700,1160,1420,780,1440,1100,1220,1130,1100,955,1460,1430,

  39.   1090,1160,1020,1180,650,1100,820,1530,520,1355,1060,1430,

  40.   1700,1160,1020,1180,1440,1100,820,1530,1100,1355,1060,1430,

  41. };

  42. const PROGMEM int actionBack[] = {

  43.   1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,

  44.   1700,1680,1020,780,1440,1800,1220,1530,1100,955,1060,2020,

  45.   1700,1060,1020,780,1440,1100,1220,1530,1100,955,1060,1430,

  46.   1100,1060,1220,1180,650,1100,1020,1130,520,1355,1260,1430,

  47.   1700,1060,1220,1180,1440,1100,1020,1130,1110,1355,1260,1430,

  48. };

  49. const PROGMEM int actionDance[] = {

  50.   1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,

  51.   1090,1790,1220,980,650,1800,1020,1330,520,1155,1260,2020,

  52.   1490,1590,1220,980,850,1400,1020,1330,1320,1155,1260,2020,

  53.   1490,1590,1220,980,850,1400,1020,1330,1320,1155,1700,1700,

  54.   1490,1590,1220,980,850,1400,1020,1330,1320,1155,1700,2020,

  55.   1090,1790,1220,980,650,1800,1020,1330,520,1155,1260,2020,

  56.   1490,1590,1220,980,850,1400,1020,1330,520,1155,1260,1220,

  57.   1490,1590,1220,980,850,1400,1020,1330,800,700,1260,1220,

  58.   1490,1590,1220,980,850,1400,1020,1330,520,700,1260,1220,

  59.   1090,1790,1220,980,650,1800,1020,1330,520,1155,1260,2020,

  60.   1670,1190,1220,980,1370,1100,1020,1330,1100,1155,1260,1430,

  61.   1090,1190,1220,980,1370,1800,620,1730,1100,1155,1260,1430,

  62.   1090,1190,1220,980,1370,1100,620,1730,1100,1155,1260,1430,

  63.   1670,1190,1220,980,1370,1800,620,1730,1100,1155,1260,1430,

  64.   1090,1190,1220,980,1370,1100,620,1730,1100,1155,1260,1430,

  65.   1090,1190,1220,980,1370,1800,700,1570,1100,1155,1260,1430,

  66.   1670,1190,1220,980,1370,1100,700,1570,1100,1155,1260,1430,

  67.   1670,1190,1220,980,1370,1100,700,1570,520,520,1930,2020,

  68.   1670,1190,1220,980,1370,1100,700,1570,800,520,1930,1700,

  69.   1670,1190,1220,980,1370,1100,700,1570,520,520,1930,2020,

  70.   1670,1190,1220,980,1370,1100,700,1570,800,520,1930,1700,

  71.   1670,1190,1220,980,1370,1100,700,1570,1100,1155,1260,1430,

  72.   1670,1190,1220,980,1370,1100,1020,1330,1100,1155,1260,1430,

  73.   1670,1190,1220,980,1370,1100,1020,1330,1100,1155,1260,1430,

  74.   1670,1190,1220,980,900,1590,1020,1330,720,1155,1260,1430,

  75.   1320,1540,1220,980,1370,1100,1020,1330,1100,1155,1260,1830,

  76.   1670,1190,1220,980,1370,1100,1020,1330,1100,1155,1260,1430,

  77.   1320,1410,1220,980,1370,1100,1020,1330,1100,1155,1260,1950,

  78.   1300,1670,1220,980,1370,1100,1020,1330,1100,1155,1260,1600,

  79.   1670,1190,1220,980,940,1540,1020,1330,920,1155,1260,1430,

  80.   1670,1190,1220,980,1235,1480,1020,1330,580,1155,1260,1430,

  81.   1670,1190,1220,980,940,1540,1020,1330,920,1155,1260,1430,

  82.   1670,1190,990,1210,940,1540,1140,1100,920,1400,1060,1430,

  83.   1300,1670,990,1210,1370,1100,1140,1100,1100,1400,1060,1600,

  84.   1320,1540,990,1210,1370,1100,1140,1100,1100,1400,1060,1830,

  85.   1670,1190,990,1210,1370,1100,1140,1100,1100,1400,1060,1430,

  86.   1670,1190,990,1210,1370,1100,1140,1100,1100,1400,1060,1430,

  87.   1670,1190,1280,920,1370,1100,920,1410,1100,1030,1410,1430,

  88.   1670,1190,990,1210,1370,1100,1140,1100,1100,1400,1060,1430,

  89.   1670,1190,1280,920,1370,1100,920,1410,1100,1030,1410,1430,

  90.   1670,1190,1220,980,1370,1100,1020,1330,1100,1155,1260,1430,

  91. };


  92. /************************+++++---------分割线--------++++++*****************************/


  93. //动作组数组长度获取函数,增加动作组时需要按如下格式添加:actPwmNum[增加的动作组序号] = sizeof(增加的动作组名称) / sizeof(增加的动作组名称[0]);

  94. void act_length()

  95. {

  96.   actPwmNum[0] = (sizeof(actionMove) / sizeof(actionMove[0]))/servo_num;

  97.   actPwmNum[1] = (sizeof(actionLeft) / sizeof(actionLeft[0]))/servo_num;

  98.   actPwmNum[2] = (sizeof(actionRight) / sizeof(actionRight[0]))/servo_num;

  99.   actPwmNum[3] = (sizeof(actionBack) / sizeof(actionBack[0]))/servo_num;

  100.   actPwmNum[4] = (sizeof(actionDance) / sizeof(actionDance[0]))/servo_num;

  101.   actPwmNum[5] = (sizeof(actionInit) / sizeof(actionInit[0]))/servo_num;


  102. //   for(int i=0;i<act_num;i++)

  103. //   {

  104. //    Serial.println(actPwmNum[i]);  

  105. //   }


  106.   //---+++---在此处添加------+++-------

  107. }


  108. //map映射函数

  109. long map_servo(long x, long in_min, long in_max, long out_min, long out_max)

  110. {

  111.   return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;

  112. }


  113. //PWM 转换为舵机角度的函数,增加动作组时需要修改

  114. void vlaue2angle(int p, int act)

  115. {

  116.   switch(act)

  117.   {

  118.     case 0:   value_cur[p] = map_servo(pgm_read_word_near(actionMove + p + servo_num * count_input), 500, 2500, 0, 180);   break;

  119.     case 1:   value_cur[p] = map_servo(pgm_read_word_near(actionLeft + p + servo_num * count_input), 500, 2500, 0, 180);   break;

  120.     case 2:   value_cur[p] = map_servo(pgm_read_word_near(actionRight + p + servo_num * count_input), 500, 2500, 0, 180);   break;

  121.     case 3:   value_cur[p] = map_servo(pgm_read_word_near(actionBack + p + servo_num * count_input), 500, 2500, 0, 180);   break;

  122.     case 4:   value_cur[p] = map_servo(pgm_read_word_near(actionDance + p + servo_num * count_input), 500, 2500, 0, 180); break;

  123.     case 5:   value_cur[p] = map_servo(pgm_read_word_near(actionInit + p + servo_num * count_input), 500, 2500, 0, 180); break;

  124.     default: break;

  125.   }

  126. }


  127. //舵机初始化函数,动作组第一行为舵机初始化值

  128. void servo_init(int act, int num)

  129. {  

  130.   if(!_b)

  131.   {

  132.     for(int i=0;i<servo_num;i++)

  133.     {

  134.       vlaue2angle(i, act);

  135.       tlc_setServo(servo_pin[i], value_cur[i]);

  136.       value_pre[i] = value_cur[i];

  137.     }

  138.     Tlc.update();

  139.     //delay(1000);

  140.   }



  141.   num == 1 ? _b = true : _b = false;


  142. }


  143. //舵机移动函数,参数: act:动作组宏定义名称 ;num:动作组执行的次数,num > 0 ;

  144. void servo_move(int act, int num)

  145. {  

  146.   float value_delta[servo_num] = {};

  147.   float in_value[servo_num] = {};



  148.   servo_init(act, num);



  149.   for(int i=0;i< num * actPwmNum[act];i++)

  150.   {

  151.     //Serial.println(i);

  152.     //Serial.println(count_input);

  153.     count_input++;

  154.    

  155.     if(count_input == actPwmNum[act])

  156.     {

  157.       count_input = 0;

  158.       continue;

  159.     }

  160.    

  161.     for(int i=0;i<servo_num;i++)

  162.     {

  163.       vlaue2angle(i, act);

  164.       in_value[i] = value_pre[i];

  165.       value_delta[i] = (value_cur[i] - value_pre[i]) / frequency;


  166.       /******************************串口查看输出******************************/

  167. //      Serial.print(value_pre[i]);

  168. //      Serial.print(" ");

  169. //      Serial.print(value_cur[i]);

  170. //      Serial.print(" ");

  171. //      Serial.print(value_delta[i]);

  172. //      Serial.println();

  173.       /******************************串口查看输出******************************/

  174.     }

  175. //    Serial.println();

  176.    

  177.     for(int i=0;i<frequency;i++)

  178.     {

  179.       for(int k=0;k<servo_num;k++)

  180.       {

  181.         in_value[k] += value_delta[k];  

  182.         value_pre[k] = in_value[k];


  183.         /******************************串口查看输出******************************/

  184. //        Serial.print(in_value[k]);

  185. //        Serial.print(" ");

  186.         /******************************串口查看输出******************************/

  187.       }

  188. //      Serial.println();

  189.      
  190.       for(int j=0;j<servo_num;j++)

  191.       {      

  192.         tlc_setServo(servo_pin[j], in_value[j]);

  193.         delayMicroseconds(servo_speed);

  194.       }

  195.       Tlc.update();

  196.     }

  197.     delayMicroseconds(action_delay);


  198.     /******************************串口查看输出******************************/

  199. //    for(int i=0;i<servo_num;i++)

  200. //    {

  201. //      Serial.println(value_pre[i]);  

  202. //    }

  203.     /******************************串口查看输出******************************/

  204.   }


  205. }

  206. /******************************-------分割线--------******************************/

  207. //初始化函数

  208. void setup() {

  209.   Serial.begin(9600);     //开启串口通信,波特率9600

  210.   Tlc.init(0);

  211.   tlc_initServos();


  212.   act_length();



  213.   delay(action_delay);

  214. }

  215. //主函数,三种执行动作的方式

  216. void loop() {

  217.   /******************************+++++++++++++ 1、串口控制+++++++++******************************/

  218. //   while(Serial.available())

  219. //   {

  220. //    int data;

  221. //    data = Serial.parseInt();

  222. //

  223. //    switch(data)

  224. //    {

  225. //      case 1: servo_move(action_move, 2);   break;

  226. //      case 2: servo_move(action_back, 2);   break;

  227. //      case 3: servo_move(action_left, 1);   break;

  228. //      case 4: servo_move(action_right, 1); break;

  229. //      case 5: servo_move(action_dance, 1); break;

  230. //      case 6: servo_move(action_init, 1);   break;

  231. //      case 7:

  232. //      {

  233. //        servo_move(action_move, 4);

  234. //        delay(actChangeDelay);

  235. //        servo_move(action_back, 4);

  236. //        delay(actChangeDelay);

  237. //        servo_move(action_left, 4);

  238. //        delay(actChangeDelay);

  239. //        servo_move(action_right, 4);

  240. //        delay(actChangeDelay);

  241. //        servo_move(action_dance, 2);

  242. //      }

  243. //      break;

  244. //      default: break;  

  245. //    }

  246. //   }

  247.   /**************+++++++++++++ 2、指定每个动作执行的次数,以 while 循环结束+++++++++**************/

  248.     servo_move(action_move, 6);

  249.     delay(actChangeDelay);

  250.     servo_move(action_back, 6);

  251.     delay(actChangeDelay);

  252.     servo_move(action_left, 4);

  253.     delay(actChangeDelay);

  254.     servo_move(action_right, 4);

  255.     delay(actChangeDelay);

  256.     servo_move(action_dance, 2);

  257.     delay(1000);

  258. //    while(1){ };

  259.   /************+++++++++++ 3、重复执行一个动作,次数设置为 1 ,取消 while 循环++++++++**************/

  260. //    servo_move(action_dance, 1);

  261. //    while(1){};

  262. }
复制代码

4. 资料下载
资料内容:
​①蓝牙遥控-例程源代码
​②Controller1.0b资料包
资料下载地址:https://www.robotway.com/h-col-197.html

想了解更多机器人开源项目资料请关注 机器谱网站 https://www.robotway.com


回复

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-26 13:19 , Processed in 0.038360 second(s), 17 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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