当前位置:   article > 正文

esp32舵机机械臂_esp32 机器人控制

esp32 机器人控制

前言

参考【太极创客】零基础入门学用Arduino 第二部分 meArm机械臂 合辑_哔哩哔哩_bilibili

主要是使用esp32控制四个舵机,学会使用串口通讯以及蓝牙通讯。

代码部分

  1. #include <ESP32Servo.h>
  2. #include <Arduino.h>
  3. #include <BluetoothSerial.h>
  4. #define SERVO_base 2 //电机接口
  5. #define SERVO_rArm 4
  6. #define SERVO_fArm 5
  7. #define SERVO_claw 18
  8. #define MAX_WIDTH 2500 //脉宽范围50ms~2500ms
  9. #define MIN_WIDTH 500
  10. //存储电机极限值(const指定该数值为常量,常量数值在程序运行中不能改变)
  11. const int baseMin = 0;
  12. const int baseMax = 180;
  13. const int rArmMin = 30;
  14. const int rArmMax = 180;
  15. const int fArmMin = 50;
  16. const int fArmMax = 180;
  17. const int clawMin = 70;
  18. const int clawMax = 100;
  19. int DSD = 15; //Default Servo Delay (默认电机运动延迟时间)
  20. int moveStep = 3; //手柄模式步进角度
  21. bool mode = 0; //手柄与命令模式 0手柄 1命令
  22. // 定义 servo 对象
  23. Servo base, rArm, fArm, claw; //建立4个电机对象 底座、大臂、小臂、夹子
  24. BluetoothSerial SerialBT; //蓝牙对象
  25. void reportStatus(); //舵机状态信息
  26. void servoMove(char servoName, int toPos, int servoDelay); //电机移动
  27. void armCmd(char serialCmd); //命令模式
  28. void armJoy(char serialCmd); //手柄模式
  29. void armIniPos(); //初始化电机角度
  30. void setup()
  31. {
  32. Serial.begin(9600); //开启串口
  33. // 分配硬件定时器
  34. ESP32PWM::allocateTimer(0);
  35. // 设置频率
  36. base.setPeriodHertz(50);
  37. rArm.setPeriodHertz(50);
  38. fArm.setPeriodHertz(50);
  39. claw.setPeriodHertz(50);
  40. // 关联 servo 对象与 GPIO 引脚,设置脉宽范围
  41. base.attach(SERVO_base, MIN_WIDTH, MAX_WIDTH);
  42. rArm.attach(SERVO_rArm, MIN_WIDTH, MAX_WIDTH);
  43. fArm.attach(SERVO_fArm, MIN_WIDTH, MAX_WIDTH);
  44. claw.attach(SERVO_claw, MIN_WIDTH, MAX_WIDTH);
  45. //初始化电机角度
  46. base.write(90);
  47. delay(10);
  48. fArm.write(90);
  49. delay(10);
  50. rArm.write(90);
  51. delay(10);
  52. claw.write(90);
  53. delay(10);
  54. reportStatus();//输出当前电机角度信息
  55. Serial.begin(9600);
  56. SerialBT.begin("eh"); // 如果没有参数传入则默认是蓝牙名称是: "ESP32"
  57. Serial.printf("BT initial ok and ready to pair. \r\n");
  58. }
  59. void loop()
  60. {
  61. if (Serial.available()>0) {
  62. char serialCmd = Serial.read();
  63. delay(10);
  64. SerialBT.write(serialCmd);
  65. delay(10);
  66. if( mode == 1 ){
  67. armCmd(serialCmd); //指令模式
  68. } else {
  69. armJoy(serialCmd); //手柄模式
  70. }
  71. }
  72. if (SerialBT.available())
  73. {
  74. //Serial.write(SerialBT.read());
  75. char serialCmd = SerialBT.read();
  76. Serial.print(" ");
  77. Serial.write(serialCmd);
  78. Serial.println(" ");
  79. if( mode == 1 ){
  80. armCmd(serialCmd); //指令模式
  81. } else {
  82. armJoy(serialCmd); //手柄模式
  83. }
  84. }
  85. }
  86. void armJoy(char serialCmd) //手柄模式
  87. {
  88. int baseJoyPos;
  89. int rArmJoyPos;
  90. int fArmJoyPos;
  91. int clawJoyPos;
  92. switch(serialCmd)
  93. {
  94. case 'a':
  95. Serial.println("Received Command: a");
  96. baseJoyPos = base.read()+moveStep;
  97. servoMove('b',baseJoyPos,DSD);
  98. break;
  99. case 'd':
  100. Serial.println("Received Command: d");
  101. baseJoyPos = base.read()-moveStep;
  102. servoMove('b',baseJoyPos,DSD);
  103. break;
  104. case 'w':
  105. Serial.println("Received Command: w");
  106. baseJoyPos = rArm.read()+moveStep;
  107. servoMove('r',baseJoyPos,DSD);
  108. break;
  109. case 's':
  110. Serial.println("Received Command: s");
  111. baseJoyPos = rArm.read()-moveStep;
  112. servoMove('r',baseJoyPos,DSD);
  113. break;
  114. case '8':
  115. Serial.println("Received Command: 8");
  116. baseJoyPos = fArm.read()+moveStep;
  117. servoMove('f',baseJoyPos,DSD);
  118. break;
  119. case '5':
  120. Serial.println("Received Command: 5");
  121. baseJoyPos = fArm.read()-moveStep;
  122. servoMove('f',baseJoyPos,DSD);
  123. break;
  124. case '4':
  125. Serial.println("Received Command: 4");
  126. baseJoyPos = claw.read()+moveStep;
  127. servoMove('c',baseJoyPos,DSD);
  128. break;
  129. case '6':
  130. Serial.println("Received Command: 6");
  131. baseJoyPos = claw.read()-moveStep;
  132. servoMove('c',baseJoyPos,DSD);
  133. break;
  134. case 'm' : //切换至指令模式
  135. mode = 1;
  136. Serial.println("Command: Switch to Instruction Mode.");
  137. break;
  138. case 'o':
  139. reportStatus();
  140. break;
  141. case 'i':
  142. armIniPos();
  143. break;
  144. default:
  145. Serial.println("Unknown Command.");
  146. return;
  147. }
  148. }
  149. void armCmd(char serialCmd) //命令模式
  150. {
  151. if (serialCmd == 'b' || serialCmd == 'c' || serialCmd == 'f' || serialCmd == 'r'){
  152. int servoData = Serial.parseInt();
  153. servoMove(serialCmd, servoData, DSD); // 机械臂舵机运行函数(参数:舵机名,目标角度,延迟/速度)
  154. } else {
  155. switch(serialCmd){
  156. case 'o': // 输出舵机状态信息
  157. reportStatus();
  158. break;
  159. case 'i':
  160. armIniPos();
  161. break;
  162. case 'm' : //切换至手柄模式
  163. mode = 0;
  164. Serial.println("Command: Switch to Joy-Stick Mode.");
  165. break;
  166. default: //未知指令反馈
  167. Serial.println("Unknown Command.");
  168. }
  169. }
  170. }
  171. void armIniPos(){ //初始化电机角度
  172. Serial.println("+Command: Restore Initial Position.");
  173. int robotIniPosArray[4][3] = {
  174. {'b', 90, DSD},
  175. {'r', 90, DSD},
  176. {'f', 90, DSD},
  177. {'c', 90, DSD}
  178. };
  179. for (int i = 0; i < 4; i++){
  180. servoMove(robotIniPosArray[i][0], robotIniPosArray[i][1], robotIniPosArray[i][2]);
  181. }
  182. }
  183. void servoMove(char servoName, int toPos, int servoDelay) //电机移动
  184. {
  185. //串口监视器输出接收指令信息
  186. Serial.println("");
  187. Serial.print("+Command: Servo ");
  188. Serial.print(servoName);
  189. Serial.print(" to ");
  190. Serial.print(toPos);
  191. Serial.print(" at servoDelay value ");
  192. Serial.print(servoDelay);
  193. Serial.println(".");
  194. Serial.println("");
  195. int fromPos; //建立变量,存储电机起始运动角度值
  196. switch(servoName){
  197. case 'b':
  198. if(toPos >= baseMin && toPos <= baseMax){
  199. fromPos = base.read(); // 获取当前电机角度值用于“电机运动起始角度值”
  200. if (fromPos <= toPos){ //如果“起始角度值”小于“目标角度值”
  201. for (int i=fromPos; i<=toPos; i++){
  202. base.write(i);
  203. delay (servoDelay);
  204. //Serial.println(base.read());
  205. }
  206. } else { //否则“起始角度值”大于“目标角度值”
  207. for (int i=fromPos; i>=toPos; i--){
  208. base.write(i);
  209. delay (servoDelay);
  210. //Serial.println(base.read());
  211. }
  212. }
  213. break;
  214. } else {
  215. Serial.println("+Warning: Base Servo Value Out Of Limit!");
  216. return;
  217. }
  218. case 'c':
  219. if(toPos >= clawMin && toPos <= clawMax){
  220. fromPos = claw.read(); // 获取当前电机角度值用于“电机运动起始角度值”
  221. if (fromPos <= toPos){ //如果“起始角度值”小于“目标角度值”
  222. for (int i=fromPos; i<=toPos; i++){
  223. claw.write(i);
  224. delay (servoDelay);
  225. //Serial.println(claw.read());
  226. }
  227. } else { //否则“起始角度值”大于“目标角度值”
  228. for (int i=fromPos; i>=toPos; i--){
  229. claw.write(i);
  230. delay (servoDelay);
  231. // Serial.println(claw.read());
  232. }
  233. }
  234. break;
  235. } else {
  236. Serial.println("+Warning: Claw Servo Value Out Of Limit!");
  237. return;
  238. }
  239. case 'f':
  240. if(toPos >= fArmMin && toPos <= fArmMax){
  241. fromPos = fArm.read(); // 获取当前电机角度值用于“电机运动起始角度值”
  242. if (fromPos <= toPos){ //如果“起始角度值”小于“目标角度值”
  243. for (int i=fromPos; i<=toPos; i++){
  244. fArm.write(i);
  245. delay (servoDelay);
  246. //Serial.println(fArm.read());
  247. }
  248. } else { //否则“起始角度值”大于“目标角度值”
  249. for (int i=fromPos; i>=toPos; i--){
  250. fArm.write(i);
  251. delay (servoDelay);
  252. //Serial.println(fArm.read());
  253. }
  254. }
  255. break;
  256. } else {
  257. Serial.println("+Warning: fArm Servo Value Out Of Limit!");
  258. return;
  259. }
  260. case 'r':
  261. if(toPos >= rArmMin && toPos <= rArmMax){
  262. fromPos = rArm.read(); // 获取当前电机角度值用于“电机运动起始角度值”
  263. if (fromPos <= toPos){ //如果“起始角度值”小于“目标角度值”
  264. for (int i=fromPos; i<=toPos; i++){
  265. rArm.write(i);
  266. delay (servoDelay);
  267. //Serial.println(rArm.read());
  268. }
  269. } else { //否则“起始角度值”大于“目标角度值”
  270. for (int i=fromPos; i>=toPos; i--){
  271. rArm.write(i);
  272. delay (servoDelay);
  273. //Serial.println(rArm.read());
  274. }
  275. }
  276. break;
  277. } else {
  278. Serial.println("+Warning: rArm Servo Value Out Of Limit!");
  279. return;
  280. }
  281. }
  282. }
  283. void reportStatus(){ //舵机状态信息
  284. Serial.println("");
  285. Serial.println("");
  286. Serial.println("+ Robot-Arm Status Report +");
  287. Serial.print("Claw Position: "); Serial.println(claw.read());
  288. Serial.print("Base Position: "); Serial.println(base.read());
  289. Serial.print("Rear Arm Position:"); Serial.println(rArm.read());
  290. Serial.print("Front Arm Position:"); Serial.println(fArm.read());
  291. Serial.println("++++++++++++++++++++++++++");
  292. Serial.println("");
  293. }

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号