辞职得空,最近主要是看杂七杂八的书为主。前日看到“嵌入式之梦”的BOSS在微博上亮了一下。就想到了随车附送的那段arduino演示程序。我觉得大部分初学者应该都看的好痛苦吧= =。
既然arduino支持c++,我也就以我业余的c++水平写上一段小小的教程望抛砖引雨吧。
阅读本文需要的基本知识:H桥电路基本作用,Arduino开发的基本环境。
第一章 让马达动起来
基本电路及说明
小车的动力装置主要是两侧的两个大轮子,分别是用独立的H桥构建出来的。
分别引出3只脚:CT1,CT2,CT3
CT1:PWM信号输入脚,你可以认为这是油门。
CT2,CT3:两路高低输入,可以让电机正转反转和不转,你可以认为这是自动排挡。
我们枚举一下所有信号输入和其对应的行动状态。这里都只先考虑一侧电机的运动状态。
表1-控制电路输入值与电机工作状态
Ct1 | Ct2 | Ct3 | 状态 |
X | 0 | 0 | 刹车 |
PWM | 1 | 0 | 正转 |
PWM | 0 | 1 | 反转 |
0 | 1 | 1 | 滑行 |
1 | 1 | 1 | 刹车 |
通过表格我们得出一侧电机的运动状态也只有4种,刹车,正转,反转,滑行,刹车。
建模及分析
面向对象中建模很重要的两个概念是“属性”和“行为”。通过上面的分析,现在的电机的属性只有3路输入电路,行为就是4种运动状态。
类名 | Motor(马达) |
属性 | ct1,ct2,ct3 |
行为 | forward stop backward neutral(滑行,空挡) |
转换为C++的代码的类定义为:
/*
* Motor.h
*
* Created on: 2011-10-17
* Author: Akira Panda
*/
#ifndef MOTOR_H_
#define MOTOR_H_
class Motor {
public:
Motor();
Motor(int ct1, int ct2, int ct3);
void init();
void setSpeed(int speed);
void forward();
void stop();
void backward();
void neutral();
private:
int _ct1;
int _ct2;
int _ct3;
};
#endif /* MOTOR_H_ */
代码里主要多了几个比较特殊的方法分别是:
- Motor();
- Motor(int ct1, int ct2, int ct3);
两种带参数和不带参数的构造方法。
void setSpeed(int speed);
设定速度的方法,其实就是修改Ct1的值。这里只是我把速度和运行模式分开的。这种方式大概所有学过汽车的童鞋都很好理解,排挡、刹车、油门分离。
一些基本的C++语法我也不多解释了,都是可以google到的。
这里主要说一些构造init方法。
这个方法是用来做初始化的。主要是当初我被电机乱转的问题给难住了,最后发现如果在代码里没有明确的设定引脚的output模式就会导致不定期的放出高电压从而扰乱电机的运行状态。所以这个init方法相当于汽车发动转钥匙的作用:初始化所有的引脚。
代码与实现
我们一段段来实现这些代码。
起步
首先需要实现的是构造方法
- Motor();
- Motor(int ct1, int ct2, int ct3);
默认构造方法暂时不实现。 Motor(int ct1, int ct2, int ct3);为主要的构造方法,输入参数为三路控制电路的引脚值。
Motor::Motor(int ct1, int ct2, int ct3) {
//分别赋值
this->_ct1 = ct1;
this->_ct2 = ct2;
this->_ct3 = ct3;
//调用init方法进行引脚的初始化
this->init();
}
void Motor::init() {
pinMode(this->_ct1, OUTPUT);
pinMode(this->_ct2, OUTPUT);
pinMode(this->_ct3, OUTPUT);
//起步速度0,模式改为刹车(停止)
this->setSpeed(0);
this->stop();
}
这样电机可以正常的启动初始化了,只是现在他还不太明白什么叫前进,什么叫停止。
我们在一一实现所有的运行模式。
实现运行模式
void Motor::setSpeed(int speed) {
analogWrite(this->_ct1, this->_speed);
}
void Motor::forward() {
digitalWrite(this->_ct2, HIGH);
digitalWrite(this->_ct3, LOW);
}
void Motor::backward() {
digitalWrite(this->_ct2, LOW);
digitalWrite(this->_ct3, HIGH);
}
void Motor::stop() {
digitalWrite(this->_ct2, LOW);
digitalWrite(this->_ct3, LOW);
}
void Motor::neutral() {
digitalWrite(this->_ct1, LOW);
digitalWrite(this->_ct2, HIGH);
digitalWrite(this->_ct3, HIGH);
}
如何调用代码
现在关于电机的代码已经完成了。
让我们来看看如何在arduino中使用这些代码,首先需要把刚才的Motor.h和Motor.cpp作为库放入arduino的目录中,路径为{arduino目录}libraries\{自己起个名}\。
然后在编辑器里引入头文件<Motor.h>即可
#include <Motor.h>
//初始化马达
//这里使用的是9,8,7三个脚
const int L_CT1 = 9;
const int L_CT2 = 8;
const int L_CT3 = 7;
//通过构造函数初始化
Motor leftMotor(L_CT1, L_CT2, L_CT3);
void setup() {
}
void loop{
//模式改为前进,速度100
leftMotor.forward();
leftMotor.setSpeed(100);
delay(1000);
//模式改为停止
leftMotor.stop();
leftMotor.setSpeed(0);
//模式改为后退,速度为50
leftMotor.backward();
leftMotor.setSpeed(100);
delay(1000);
}
OK,基本上电机部分已经编码完成。虽然有些地方还可以继续修改。下一篇,我将会将两个电机作为整体来描述小车的动力部分编码。