欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

My Arduino vol 5 — 面向对象地编写“圆梦小车”程序 -电机 博客分类: Arduino

程序员文章站 2024-02-21 15:55:28
...

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