arduino_face_tracker.ino 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /********************************************************************************
  2. Copyright: 2016-2019 ROS小课堂 www.corvin.cn
  3. Author: corvin
  4. Description:
  5. 使用dfrobot的arduino UNO开发板,再接扩展板。当然其他公司的UNO板也行,这里代码还
  6. 兼容其他型号的arduino板,包括arduino Mega2560, arduino DUE等。可以在相应版的扩展板
  7. 上接了两个舵机,这样就可以组成二自由度的云台。通过串口可以发送命令控制两个舵机的旋转,在
  8. 控制转动前需要先使能指定pwm引脚上的舵机,具体操作命令格式如下:
  9. (0).使能pwm 2号引脚上的舵机,该引脚舵机索引值为0,因为为了兼容UNO,Mega2560,DUE板,就
  10. 把所有pwm引脚全都包含了,Mega2560和DUE都有12个PWM引脚,分别为2,3,4,5,6,7,8,9,10,
  11. 11,12,13,这样2号引脚上的舵机索引就是0。第2个参数表明使能(非0)或禁用(0):
  12. e 0 1
  13. (1).控制云台旋转,舵机索引分别为为0(左右旋转),1(上下旋转):
  14. w 0 90 20:该串口命令中w表示写入,0表示0号舵机,90表示旋转到90度,每次移动延时20ms
  15. w 1 30 50:表示1号舵机移动到30度,每个移动周期延时50ms.
  16. (2).读取指定舵机ID的当前角度:
  17. r 0:串口输入该命令,则返回90,表示0号舵机当前在90度位置.
  18. r 1:输入该命令后,返回30,表示1号舵机当前在30度位置。
  19. (3).获取所有舵机的使能状态命令s:
  20. s:0 0 0 1 0 0 0 0 0 0 0 0:返回的一串数字表明第几个舵机使能。
  21. (4).获取所有舵机的角度p:
  22. p: 0 0 0 90 0 0 0 0 0 0 0 0:第4个舵机当前在90度位置。
  23. History:
  24. 20181121: initial this code.
  25. 20181128: add delay time param when set servo target position.
  26. 20181130: 新增命令v可以获取代码版本号,命令e,d用来启用舵机或禁用指定pwm引脚上的舵机。
  27. 在使用w命令控制舵机移动前,需要使用e先使能该舵机才可以。
  28. 20181203: 删除d命令-禁用指定舵机,使用e命令的第2个参数来表示使能或禁用。第2个参数为0,
  29. 表示禁用,非零以外值都表示使能。
  30. 20181204:新增获取所有舵机当前使能状态命令s和获取当前所有舵机的角度p,返回内容之间有空格。
  31. 20181207: 将存储串口数据的一些全局零散变量都用一个类serialData来实现了,这样代码更清晰.
  32. ********************************************************************************/
  33. #define FIRMWARE_VERSION 1
  34. #define CONNECT_BAUDRATE 57600
  35. #include <Servo.h>
  36. #include "serialData.h"
  37. #include "commands.h"
  38. #include "servos.h"
  39. /* Run a command. Commands char are defined in commands.h */
  40. void runCommand(void)
  41. {
  42. serialObj.arg1 = atoi(serialObj.argv1);
  43. serialObj.arg2 = atoi(serialObj.argv2);
  44. serialObj.arg3 = atoi(serialObj.argv3);
  45. switch (serialObj.cmd_chr)
  46. {
  47. case GET_CONNECT_BAUDRATE: // 'b'
  48. Serial.println(CONNECT_BAUDRATE);
  49. break;
  50. case SET_ONE_SERVO_ENABLE: // 'e'
  51. myServos[serialObj.arg1].setEnable(serialObj.arg2);
  52. Serial.println("OK");
  53. break;
  54. case SET_ONE_SERVO_POS: // 'w'
  55. myServos[serialObj.arg1].setTargetPos(serialObj.arg2, serialObj.arg3);
  56. Serial.println("OK");
  57. break;
  58. case GET_ONE_SERVO_POS: // 'r'
  59. Serial.println(myServos[serialObj.arg1].getServoObj().read());
  60. break;
  61. case GET_ALL_SERVOS_POS: // 'p'
  62. for (byte i = 0; i < N_SERVOS; i++)
  63. {
  64. Serial.print(myServos[i].getCurrentPos());
  65. Serial.print(' ');
  66. }
  67. Serial.println("");
  68. break;
  69. case GET_ALL_SERVOS_ENABLE: // 's'
  70. for (byte i = 0; i < N_SERVOS; i++)
  71. {
  72. Serial.print(myServos[i].isEnabled());
  73. Serial.print(' ');
  74. }
  75. Serial.println("");
  76. break;
  77. case GET_FIRMWARE_VERSION: // 'v'
  78. Serial.println(FIRMWARE_VERSION);
  79. break;
  80. default:
  81. Serial.println("Invalid Command");
  82. break;
  83. }
  84. }
  85. /* Setup function--runs once at startup. */
  86. void setup()
  87. {
  88. Serial.begin(CONNECT_BAUDRATE);
  89. serialObj.resetCmdParam();
  90. /* when power on init all servos position */
  91. for (byte i = 0; i < N_SERVOS; i++)
  92. {
  93. myServos[i].initServo(myServoPins[i], servoInitPosition[i], 0);
  94. }
  95. }
  96. /* Enter the main loop. Read and parse input from the serial port
  97. and run any valid commands.
  98. */
  99. void loop()
  100. {
  101. while (Serial.available() > 0)
  102. {
  103. char tmp_chr = Serial.read(); // Read the next character
  104. if (tmp_chr == 13) // Terminate a command with a CR
  105. {
  106. runCommand();
  107. serialObj.resetCmdParam();
  108. }
  109. else if (tmp_chr == ' ') // Use spaces to delimit parts of the command
  110. {
  111. serialObj.argCnt++;
  112. serialObj.argIndex = 0;
  113. }
  114. else // get valid param
  115. {
  116. if (serialObj.argCnt == 0) // The first arg is the single-letter command
  117. {
  118. serialObj.cmd_chr = tmp_chr;
  119. }
  120. else if (serialObj.argCnt == 1) // Get after cmd first param
  121. {
  122. serialObj.argv1[serialObj.argIndex] = tmp_chr;
  123. serialObj.argIndex++;
  124. }
  125. else if (serialObj.argCnt == 2)
  126. {
  127. serialObj.argv2[serialObj.argIndex] = tmp_chr;
  128. serialObj.argIndex++;
  129. }
  130. else if (serialObj.argCnt == 3)
  131. {
  132. serialObj.argv3[serialObj.argIndex] = tmp_chr;
  133. serialObj.argIndex++;
  134. }
  135. }
  136. } //end while
  137. // Check everyone servos isEnabled, when true will move servo. Other don't move servo.
  138. for (byte i = 0; i < N_SERVOS; i++)
  139. {
  140. if (myServos[i].isEnabled())
  141. {
  142. myServos[i].moveServo();
  143. }
  144. }
  145. }//end loop