买了两个做双轮自平衡小车的电机装在了从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[NUMBER_OF_FIELDS]; //保存所有字段的数组
- 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[fieldIndex] = (values[fieldIndex] * 10) + (ch - '0');
- }
- }
- else if (ch == ',') //逗号是分界线
- {
- fieldIndex++;
- }
- else //回车行分别输出方向和距离的值
- {
- Direction = values[0];
- Distance = values[1];
- }
- }
- }
- //驱动函数定义
- 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. |