BaseX.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * @Author: Sorzn
  3. * @Date: 2019-12-12 14:33:45
  4. * @LastEditTime: 2019-12-13 15:58:32
  5. * @Description: M5Stack project
  6. * @FilePath: /M5Stack/examples/Modules/BaseX/BaseX.cpp
  7. */
  8. #include "M5Stack.h"
  9. #include "BaseX.h"
  10. #define MAX(in, max) (((in) > (max)) ? (in) : (max))
  11. #define MIN(in, min) (((in) < (min)) ? (in) : (min))
  12. #define CONSTRAIN(in, min, max) MAX(min, MIN(in, max))
  13. uint8_t BASE_X::CheckPos(uint8_t pos)
  14. {
  15. pos = pos - 1;
  16. pos = CONSTRAIN(pos, 0, 3);
  17. return pos;
  18. }
  19. /**
  20. * @description:
  21. * @param pos: 1 ~ 4
  22. * @param mode: NORMAL, POSITION LOCK, SPEED LOCK
  23. * @return: None
  24. */
  25. void BASE_X::SetMode(uint8_t pos, uint8_t mode)
  26. {
  27. pos = CheckPos(pos);
  28. M5.I2C.writeByte(BASE_X_ADDR, BASE_X_CONFIG_ADDR + (0x10 * pos), mode);
  29. }
  30. /**
  31. * @description:
  32. * @param pos: 1 ~ 4
  33. * @return: encoder value
  34. */
  35. int32_t BASE_X::GetEncoderValue(uint8_t pos)
  36. {
  37. uint8_t addr;
  38. uint8_t read_buf[4] = {0, 0, 0, 0};
  39. pos = CheckPos(pos);
  40. addr = BASE_X_ENCODER_ADDR + 4*pos;
  41. M5.I2C.readBytes(BASE_X_ADDR, addr, 4, read_buf);
  42. return (read_buf[0] << 24) | (read_buf[1] << 16) | (read_buf[2] << 8) | read_buf[3];
  43. }
  44. /**
  45. * @description:
  46. * @param pos: 1 ~ 4
  47. * @param encoder: INT32_MIN ~ INT32_MAX
  48. * @return: None
  49. */
  50. void BASE_X::SetEncoderValue(uint8_t pos, int32_t encoder)
  51. {
  52. uint8_t addr;
  53. uint8_t write_buf[4] = {0, 0, 0, 0};
  54. pos = CheckPos(pos);
  55. addr = BASE_X_ENCODER_ADDR + 4*pos;
  56. write_buf[0] = encoder >> 24;
  57. write_buf[1] = encoder >> 16;
  58. write_buf[2] = encoder >> 8;
  59. write_buf[3] = encoder & 0xff;
  60. M5.I2C.writeBytes(BASE_X_ADDR, addr, write_buf, 4);
  61. }
  62. /**
  63. * @description:
  64. * @param pos: 1 ~ 4
  65. * @param duty: Set motor speed, -127 ~ 127
  66. * @return:
  67. */
  68. void BASE_X::SetMotorSpeed(uint8_t pos, int8_t duty)
  69. {
  70. uint8_t addr;
  71. pos = CheckPos(pos);
  72. addr = BASE_X_PWM_DUTY_ADDR + pos;
  73. M5.I2C.writeByte(BASE_X_ADDR, addr, duty);
  74. }
  75. /**
  76. * @description:
  77. * @param pos: 1 ~ 4
  78. * @return Motor run speed, -127 ~ 127:
  79. */
  80. int8_t BASE_X::GetMotorSpeed(uint8_t pos)
  81. {
  82. uint8_t read_data;
  83. uint8_t addr;
  84. pos = CheckPos(pos);
  85. addr = BASE_X_PWM_DUTY_ADDR + pos;
  86. M5.I2C.readByte(BASE_X_ADDR, addr, &read_data);
  87. return read_data;
  88. }
  89. /**
  90. * @description:
  91. * @param pos: 1 ~ 4
  92. * @return: Motor encoder increments every 20 ms
  93. */
  94. int8_t BASE_X::GetMotorSpeed20MS(uint8_t pos)
  95. {
  96. uint8_t read_data;
  97. uint8_t addr;
  98. pos = CheckPos(pos);
  99. addr = BASE_X_SPEED_ADDR + pos;
  100. M5.I2C.readByte(BASE_X_ADDR, addr, &read_data);
  101. return read_data;
  102. }
  103. void BASE_X::SetPositionPID(uint8_t pos, uint8_t kp, uint8_t ki, uint8_t kd)
  104. {
  105. uint8_t write_buf[3] = {0, 0, 0};
  106. uint8_t addr;
  107. pos = CheckPos(pos);
  108. addr = BASE_X_CONFIG_ADDR + pos * 0x10 + 0x01;
  109. write_buf[0] = kp;
  110. write_buf[1] = ki;
  111. write_buf[2] = kd;
  112. M5.I2C.writeBytes(BASE_X_ADDR, addr, write_buf, 3);
  113. }
  114. /**
  115. * @description:
  116. * @param pos: 1 ~ 4
  117. * @param position_point: in POSITION mode, motor will lock in this value, INT32_MIN ~ INT32_MAX
  118. * @return: None
  119. */
  120. void BASE_X::SetPositionPoint(uint8_t pos, int32_t position_point)
  121. {
  122. uint8_t addr;
  123. uint8_t write_buf[4] = {0, 0, 0, 0};
  124. pos = CheckPos(pos);
  125. addr = BASE_X_CONFIG_ADDR + pos * 0x10 + 0x04;
  126. write_buf[0] = position_point & 0xff;
  127. write_buf[1] = position_point >> 8;
  128. write_buf[2] = position_point >> 16;
  129. write_buf[3] = position_point >> 24;
  130. // Serial.printf(" %x %x %x %x \r\n", write_buf[0], write_buf[1], write_buf[2], write_buf[3]);
  131. M5.I2C.writeBytes(BASE_X_ADDR, addr, write_buf, 4);
  132. }
  133. /**
  134. * @description:
  135. * @param pos: 1 ~ 4
  136. * @param max_pwm: 0 ~ 127, POSITION mode, max speed
  137. * @return:
  138. */
  139. void BASE_X::SetPostionPIDMaxSpeed(uint8_t pos, uint8_t max_pwm)
  140. {
  141. uint8_t addr;
  142. pos = CheckPos(pos);
  143. addr = BASE_X_CONFIG_ADDR + pos * 0x10 + 0x08;
  144. M5.I2C.writeByte(BASE_X_ADDR, addr, max_pwm);
  145. }
  146. void BASE_X::SetSpeedPID(uint8_t pos, uint8_t kp, uint8_t ki, uint8_t kd)
  147. {
  148. uint8_t write_buf[3] = {0, 0, 0};
  149. uint8_t addr;
  150. pos = CheckPos(pos);
  151. addr = BASE_X_CONFIG_ADDR + pos * 0x10 + 0x09;
  152. write_buf[0] = kp;
  153. write_buf[1] = ki;
  154. write_buf[2] = kd;
  155. M5.I2C.writeBytes(BASE_X_ADDR, addr, write_buf, 3);
  156. }
  157. /**
  158. * @description:
  159. * @param pos: 1 ~ 4
  160. * @param speed_point: speed_point is lock GetMotorSpeed20MS(), not GetMotorSpeed(), maybe -20 ~ 20
  161. * @return: None
  162. */
  163. void BASE_X::SetSpeedPoint(uint8_t pos, int8_t speed_point)
  164. {
  165. uint8_t addr;
  166. pos = CheckPos(pos);
  167. addr = BASE_X_CONFIG_ADDR + pos * 0x10 + 0x0c;
  168. M5.I2C.writeByte(BASE_X_ADDR, addr, (uint8_t)speed_point);
  169. }
  170. /**
  171. * @description:
  172. * @param pos: 1 ~ 2
  173. * @param angle: 0 ~ 180
  174. * @return: None
  175. */
  176. void BASE_X::SetServoAngle(uint8_t pos, uint8_t angle)
  177. {
  178. uint8_t addr;
  179. pos = CheckPos(pos);
  180. addr = BASE_X_SERVO_ANGLE_ADDR + pos;
  181. M5.I2C.writeByte(BASE_X_ADDR, addr, angle);
  182. }
  183. /**
  184. * @description:
  185. * @param pos: 1 ~ 2
  186. * @param width: 500 ~ 2500
  187. * @return: None
  188. */
  189. void BASE_X::SetServoPulseWidth(uint8_t pos, uint16_t width)
  190. {
  191. uint8_t addr;
  192. uint8_t write_buf[2] = {0, 0};
  193. pos = CheckPos(pos);
  194. addr = BASE_X_SERVO_PULSE_ADDR + pos * 0x02;
  195. write_buf[0] = width >> 8;
  196. write_buf[1] = width & 0xff;
  197. M5.I2C.writeBytes(BASE_X_ADDR, addr, write_buf, 2);
  198. }