Le0 发表于 2016-4-4 17:57:50

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

买了两个做双轮自平衡小车的电机装在了从oj买的小车地盘上,想要实现具体的<定向定量>控制.目前摸索出的代码如下:int STBY = 10;

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

//Motor B引脚初始化
int PWMB = 5;
int BIN1 = 11;
int BIN2 = 12;

//connect OUTA to digital2
#define PinA 2

//connect OUTB to digital3
#define PinB 3

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

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

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

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

pinMode(PWMA, OUTPUT);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);

pinMode(PWMB, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);

pinMode(PinA, INPUT);
pinMode(PinB, INPUT);

}


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

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

if (digitalRead(PinA))
{
    Code();
}
Serial.println(count);

switch (Direction)
{
    case'0'://向前
      move(0, 50, 0);
      move(1, 50, 0);
      over(count);
      break;
    case'3':    //后
      move(0, 50, 1);
      move(1, 50, 1);
      over(count);
      break;
    case'2':    //左
      move(0, 50, 1);
      move(1, 50, 0);
      TurnLeft();
      over(count);
      break;
    case'1':    //右
      move(0, 50, 0);
      move(1, 50, 0);
      TurnRight();
      over(count);
      break;
}
// Serial.println(Direction);
//Serial.println(Distance);
}


//切割字符函数定义
void numberscut()
{
if (Serial.available())
{
    char ch = Serial.read();
    if (ch >= '0' && ch <= '9')
    {
      if (fieldIndex < NUMBER_OF_FIELDS)
      {
      values = (values * 10) + (ch - '0');
      }
    }
    else if (ch == ',')   //逗号是分界线
    {
      fieldIndex++;
    }
    else    //回车行分别输出方向和距离的值
    {
      Direction = values;
      Distance = values;
    }
}
}

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

boolean inPin1 = LOW;
boolean inPin2 = HIGH;

if (direction == 1)
{
    inPin1 = HIGH;
    inPin2 = LOW;
}

//0是左轮,1是右轮
if (motor == 1)
{
    digitalWrite(AIN1, inPin1);
    digitalWrite(AIN2, inPin2);
    analogWrite(PWMA, speed);

}
else {
    digitalWrite(BIN1, inPin1);
    digitalWrite(BIN2, inPin2);
    analogWrite(PWMB, speed);
}
}

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

    count += 1;   //count 计数

time_delay = millis();

}

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

}

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

//右转90度
void TurnRight()
{
move(0, 50, 0);
move(1, 50, 1);
while (count >= 966)
{
    digitalWrite(STBY, LOW);
}
}
然而,,,,,这些个破代码里面有很多很令我很疑惑的bug,由于才疏学浅绞尽奶汁还是搞不定.....
1/编码盘是13线霍尔编码器,电机减速比30:1,倍频之后应该是1560,但是觉得用不了那么精细的脉冲,而且UNO R3只有两个中断,所以就用数字引脚采集脉冲计数.
2/不知道怎么能把一条串行口消息中的"字符和数字"区分出来,所以干脆参考arduino cookbook中的教程全部用数组代替,于是主程序里的csae()就不友好了.
3/电机驱动芯片用的TB6612FNG.
页: [1]
查看完整版本: 用自带霍尔霍尔编码器的电机控制小车行进,比如"向左,1米"