极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12167|回复: 0

用自带霍尔霍尔编码器的电机控制小车行进,比如"向左,1米"

[复制链接]
发表于 2016-4-4 17:57:50 | 显示全部楼层 |阅读模式
买了两个做双轮自平衡小车的电机装在了从oj买的小车地盘上,想要实现具体的<定向定量>控制.目前摸索出的代码如下:
  1. int STBY = 10;

  2. //motor A引脚初始化
  3. int PWMA = 6;   //speed control
  4. int AIN1 = 9;   //Direction
  5. int AIN2 = 8;   //Direction

  6. //Motor B引脚初始化
  7. int PWMB = 5;
  8. int BIN1 = 11;
  9. int BIN2 = 12;

  10. //connect OUTA to digital2
  11. #define PinA 2

  12. //connect OUTB to digital3
  13. #define PinB 3

  14. int count = 0;  //计数初始化

  15. unsigned long time = 0, old_time = 0; //time mark时间标记
  16. unsigned long time_delay = 0; //time mark

  17. //关于单个消息分为多个文本字段,中间以逗号为分隔标记
  18. const int NUMBER_OF_FIELDS = 2;     //两个字符段
  19. int fieldIndex = 0;   //当前字段
  20. int values[NUMBER_OF_FIELDS];   //保存所有字段的数组
  21. int Direction = 0;    //小车远东方向
  22. int Distance = 0;   //小车运行距离

  23. void setup() {
  24.   // put your setup code here, to run once:
  25.   Serial.begin(9600);   //波特率
  26.   /*引脚输入输出定义*/
  27.   pinMode(STBY, OUTPUT);

  28.   pinMode(PWMA, OUTPUT);
  29.   pinMode(AIN1, OUTPUT);
  30.   pinMode(AIN2, OUTPUT);

  31.   pinMode(PWMB, OUTPUT);
  32.   pinMode(BIN1, OUTPUT);
  33.   pinMode(BIN2, OUTPUT);

  34.   pinMode(PinA, INPUT);
  35.   pinMode(PinB, INPUT);

  36. }


  37. void loop() {
  38.   // put your main code here, to run repeatedly:

  39.   numberscut();   //切割字符的函数

  40.   if (digitalRead(PinA))
  41.   {
  42.     Code();
  43.   }
  44.   Serial.println(count);

  45.   switch (Direction)
  46.   {
  47.     case'0':  //向前
  48.       move(0, 50, 0);
  49.       move(1, 50, 0);
  50.       over(count);
  51.       break;
  52.     case'3':    //后
  53.       move(0, 50, 1);
  54.       move(1, 50, 1);
  55.       over(count);
  56.       break;
  57.     case'2':    //左
  58.       move(0, 50, 1);
  59.       move(1, 50, 0);
  60.       TurnLeft();
  61.       over(count);
  62.       break;
  63.     case'1':    //右
  64.       move(0, 50, 0);
  65.       move(1, 50, 0);
  66.       TurnRight();
  67.       over(count);
  68.       break;
  69.   }
  70.   // Serial.println(Direction);
  71.   //  Serial.println(Distance);
  72. }


  73. //切割字符函数定义
  74. void numberscut()
  75. {
  76.   if (Serial.available())
  77.   {
  78.     char ch = Serial.read();
  79.     if (ch >= '0' && ch <= '9')
  80.     {
  81.       if (fieldIndex < NUMBER_OF_FIELDS)
  82.       {
  83.         values[fieldIndex] = (values[fieldIndex] * 10) + (ch - '0');
  84.       }
  85.     }
  86.     else if (ch == ',')   //逗号是分界线
  87.     {
  88.       fieldIndex++;
  89.     }
  90.     else    //回车行分别输出方向和距离的值
  91.     {
  92.       Direction = values[0];
  93.       Distance = values[1];
  94.     }
  95.   }
  96. }

  97. //驱动函数定义
  98. void move(int motor, int speed, int direction)
  99. {
  100.   digitalWrite(STBY, HIGH);

  101.   boolean inPin1 = LOW;
  102.   boolean inPin2 = HIGH;

  103.   if (direction == 1)
  104.   {
  105.     inPin1 = HIGH;
  106.     inPin2 = LOW;
  107.   }

  108.   //0是左轮,1是右轮
  109.   if (motor == 1)
  110.   {
  111.     digitalWrite(AIN1, inPin1);
  112.     digitalWrite(AIN2, inPin2);
  113.     analogWrite(PWMA, speed);

  114.   }
  115.   else {
  116.     digitalWrite(BIN1, inPin1);
  117.     digitalWrite(BIN2, inPin2);
  118.     analogWrite(PWMB, speed);
  119.   }
  120. }

  121. void Code()
  122. {
  123.   while ((millis() - time_delay) > 5)    //延时防抖函数

  124.     count += 1;   //count 计数

  125.   time_delay = millis();

  126. }

  127. //运动设定距离后停止
  128. void over(int count)
  129. {
  130.   while (count >= Distance * 7.42)    //每7.42个脉冲是1毫米
  131.   {
  132.     digitalWrite(STBY, LOW);
  133.   }

  134. }

  135. //自身围绕中点左转90度
  136. void TurnLeft()
  137. {
  138.   move(0, 50, 1);
  139.   move(1, 50, 0);
  140.   while (count >= 966)     //966mm是已经根据车宽计算过的车体自转四分之一圈的长度
  141.   {
  142.     digitalWrite(STBY, LOW);
  143.   }
  144. }

  145. //右转90度
  146. void TurnRight()
  147. {
  148.   move(0, 50, 0);
  149.   move(1, 50, 1);
  150.   while (count >= 966)
  151.   {
  152.     digitalWrite(STBY, LOW);
  153.   }
  154. }
复制代码

然而,,,,,这些个破代码里面有很多很令我很疑惑的bug,由于才疏学浅绞尽奶汁还是搞不定.....
1/编码盘是13线霍尔编码器,电机减速比30:1,倍频之后应该是1560,但是觉得用不了那么精细的脉冲,而且UNO R3只有两个中断,所以就用数字引脚采集脉冲计数.
2/不知道怎么能把一条串行口消息中的"字符和数字"区分出来,所以干脆参考arduino cookbook中的教程全部用数组代替,于是主程序里的csae()就不友好了.
3/电机驱动芯片用的TB6612FNG.
回复

使用道具 举报

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

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

Archiver|联系我们|极客工坊

GMT+8, 2024-5-20 12:02 , Processed in 0.049289 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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