My Arduino vol 5 — 面向对象地编写“圆梦小车”程序 -电机 博客分类: Arduino
辞职得空,最近主要是看杂七杂八的书为主。前日看到“嵌入式之梦”的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,基本上电机部分已经编码完成。虽然有些地方还可以继续修改。下一篇,我将会将两个电机作为整体来描述小车的动力部分编码。