当前位置:   article > 正文

ARDUINO ,TB6612 ,MG310 电机,PID调速_mg310电机手册

mg310电机手册

 ARDUINO ,TB6612 ,MG310 电机,PID调速

  1. #include <PID_v1.h>
  2. int AIN1 = 9;
  3. int AIN2 = 8;
  4. int PWMA = 3;
  5. int STBY = 10;
  6. int motor_A = 21; // 编码器连接的引脚
  7. int motor_B = 20; // 编码器连接的引脚
  8. volatile int count = 0; // 编码器计数
  9. void count_A() {
  10. //单频计数实现
  11. //手动旋转电机一圈,输出结果为 一圈脉冲数 * 减速比
  12. /*if(digitalRead(motor_A) == HIGH){
  13. if(digitalRead(motor_B) == LOW){//A 高 B 低
  14. count++;
  15. } else {//A 高 B 高
  16. count--;
  17. }
  18. }*/
  19. //2倍频计数实现
  20. //手动旋转电机一圈,输出结果为 一圈脉冲数 * 减速比 * 2
  21. if(digitalRead(motor_A) == HIGH){
  22. if(digitalRead(motor_B) == HIGH){//A 高 B 高
  23. count++;
  24. } else {//A 高 B 低
  25. count--;
  26. }
  27. } else {
  28. if(digitalRead(motor_B) == LOW){//A 低 B 低
  29. count++;
  30. } else {//A 低 B 高
  31. count--;
  32. }
  33. }
  34. }
  35. void count_B() {
  36. if(digitalRead(motor_B) == HIGH){
  37. if(digitalRead(motor_A) == LOW){//B 高 A 低
  38. count++;
  39. } else {//B 高 A 高
  40. count--;
  41. }
  42. } else {
  43. if(digitalRead(motor_A) == HIGH){//B 低 A 高
  44. count++;
  45. } else {//B 低 A 低
  46. count--;
  47. }
  48. }
  49. }
  50. int reducation = 20; // 减速比
  51. int pulse = 260; // 编码器旋转一圈产生的脉冲数
  52. int per_round = pulse * reducation * 4; // 车轮旋转一圈产生的脉冲数
  53. long start_time = millis(); // 一个计算周期的开始时刻,初始值为 millis()
  54. long interval_time = 50; // 一个计算周期 50ms
  55. double current_vel;
  56. // 获取当前转速的函数
  57. void get_current_vel() {
  58. long right_now = millis();
  59. long past_time = right_now - start_time;
  60. if (past_time >= interval_time) {
  61. // 禁止中断
  62. noInterrupts();
  63. // 计算转速
  64. current_vel = (double)count / per_round / past_time * 1000 * 60;
  65. // 清零计数器
  66. count = 0;
  67. // 重置开始时间
  68. start_time = right_now;
  69. // 重启中断
  70. interrupts();
  71. Serial.println(current_vel);
  72. }
  73. }
  74. // 创建 PID 对象
  75. // 1.当前转速 2.计算输出的pwm 3.目标转速 4.kp 5.ki 6.kd 7.当输入与目标值出现偏差时,向哪个方向控制
  76. double pwm; // 电机驱动的PWM值
  77. double target = 40;
  78. double kp = 1, ki = 3.0, kd = 0.1;
  79. PID pid(&current_vel, &pwm, &target, kp, ki, kd, DIRECT);
  80. // 速度更新函数
  81. void update_vel() {
  82. // 获取当前速度
  83. get_current_vel();
  84. // 计算需要输出的PWM
  85. pid.Compute();
  86. // 激活电机驱动
  87. digitalWrite(STBY, HIGH);
  88. // 根据pwm的正负值设置电机转向和PWM
  89. if (pwm >= 0) {
  90. digitalWrite(AIN1, HIGH);
  91. digitalWrite(AIN2, LOW);
  92. analogWrite(PWMA, pwm);
  93. } else {
  94. digitalWrite(AIN1, LOW);
  95. digitalWrite(AIN2, HIGH);
  96. analogWrite(PWMA, -pwm); // 取pwm的绝对值
  97. }
  98. }
  99. void setup() {
  100. Serial.begin(57600); // 设置波特率
  101. pinMode(motor_A, INPUT);
  102. pinMode(motor_B, INPUT);
  103. // 设置电机驱动引脚为输出
  104. pinMode(AIN1, OUTPUT);
  105. pinMode(AIN2, OUTPUT);
  106. pinMode(PWMA, OUTPUT);
  107. pinMode(STBY, OUTPUT);
  108. // 设置编码器中断
  109. attachInterrupt(digitalPinToInterrupt(motor_A), count_A, CHANGE);
  110. attachInterrupt(digitalPinToInterrupt(motor_B), count_B, CHANGE);
  111. pid.SetMode(AUTOMATIC);
  112. }
  113. void loop() {
  114. delay(10);
  115. update_vel();
  116. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/893149
推荐阅读
相关标签
  

闽ICP备14008679号