用自带霍尔霍尔编码器的电机控制小车行进,比如"向左,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]