马达是我们经常使用到的电动装置,它可以将电能转化成动能,驱动其他东西的运动。听起来很抽象,举几个例子吧。

我们小时候玩的四驱车,带动轮子转动的那个小装置就是马达;夏天让风扇旋转带给我们凉意,也是马达的功劳。

第6节 马达 - 图1

根据使用电源的不同,可以将马达分成直流马达和交流马达。因为我们的小硬件使用的通常都是直流电,所以采用的也基本都是直流马达,通过马达来驱动外接设备运动。

6.1 工作原理

将电能转化成动能的物理原理,我们在中学已经学过,它利用了两个原理:电磁感应和磁铁的同性相斥异性相吸。

  1. 将一根磁棒放在金属罩中间,两端悬上一个金属柱子,金属柱子上面有线圈;
  2. 当线圈通过电流的时候,就能产生磁场,磁棒根据极性改变位置;
  3. 改变电流方向,线圈磁场方向发生调换,磁棒再次根据极性改变位置;
  4. 如此往复,磁棒就旋转了起来。

第6节 马达 - 图2

一个马达的外形大致如此,

第6节 马达 - 图3

马达的转速是比较高的,如果要将旋转的能力转化为车轮转动的能力,就要为马达添加一些齿轮一样的附属机械结构,将马达的转速和车轮的转速匹配起来。下图中马达被黄色的结构包裹,这里面就实现了这样的一个转化。

第6节 马达 - 图4

马达有两个接线的地方,一处接正极,另一处就接负极。
第6节 马达 - 图5

具体哪个接正极哪个接负极没有规定,都可以,它们的接法只是确定了马达旋转的方向:

  1. 在不超过极限电压的情况下,对马达施加的电压越大,马达就转动的越快;
  2. 调转正负极的连接顺序,马达的旋转方向也发生调转;

6.2 马达驱动板

马达的正负极不能直接连接到Arduino开发板的引脚上,必须使用一个转换电路。否则马达在转动的过程中可能会产生强大的电流,击穿开发板上的元器件。

为此,可以使用专门的马达驱动板,来连接使用马达。下面两种驱动板可以用来驱动能力较强的大马达。

第6节 马达 - 图6

也可以使用集成了转换电路的马达模块,例如下图这个集成了风扇的小马达模块。

第6节 马达 - 图7

6.3 使用小马达

在此我们选用集成了转换电路的风扇马达模块来讲解,开发板使用Arduino UNO。

小马达对电压的要求不高,可以直接使用开发板提供的5v电压驱动,不必单独外接一个电源。

该模块有4个引脚,

模块引脚 功能说明
INA 控制接口A
INB 控制接口B
VCC 直流电
GND 接地

因为要调整直流马达的转动速度,INAINB最好接到具有PWM功能的接口上,通过设置该引脚的级数数,来调节马达的转速。这里,我们将INA连接到D9INB连接到D10

模块引脚 连接 Arduino扩展板
INA <—> D9组S引脚
INB <—> D10组S引脚
VCC <—> D9组V引脚
GND <—> D9组G引脚

第6节 马达 - 图8

6.3.1 代码设计

首先要初始化INAINB连接的接口,让Arduino开发板拥有向它们输出的能力,将INA引脚设置成低电平LOW,改变INB引脚的值,来达到控制马达转速的效果,

  1. //INA使用具有PWM功能的D9引脚
  2. int INA = 9;
  3. //INB使用具有PWM功能的D8引脚
  4. int INB = 10;
  5. void setup() {
  6. //设置引脚为输出
  7. pinMode(INA, OUTPUT);
  8. pinMode(INB, OUTPUT);
  9. digitalWrite(INA, LOW);
  10. }

这里将调整的级数,调整在了0~100。理论上可以调整的级数应该是0~255级。

  1. void loop() {
  2. //从0级到100级
  3. for(int level = 0 ; level < 100+1; level++)
  4. {
  5. //调整INB上的电压级数,达到改变风扇转速的效果
  6. analogWrite(INB, level);
  7. delay(100);
  8. }
  9. }

但是由于马达电流负载的原因,设置到高级数时,例如245级,可能会让开发板过载。因此可以把最大级数设置的稍微小一点,例如230级。下面我们还将转速做动态的变化,从慢到快,再从快到慢,

  1. int INA = 9;
  2. int INB = 10;
  3. int START_LEVEL = 0;
  4. int END_LEVEL = 230;
  5. void setup() {
  6. pinMode(INA, OUTPUT);
  7. pinMode(INB, OUTPUT);
  8. digitalWrite(INA, LOW);
  9. }
  10. void loop() {
  11. //从0级慢慢加速到230级
  12. for(int level = START_LEVEL ; level < END_LEVEL+1; level++)
  13. {
  14. analogWrite(INB, level);
  15. delay(100);
  16. }
  17. //从230级慢慢减速到0级
  18. for(int level = END_LEVEL; level > START_LEVEL ; level--)
  19. {
  20. analogWrite(INB, level);
  21. delay(100);
  22. }
  23. }

6.3.2 结果观察

马达开始缓慢的旋转,越转越快;达到最快转速时,又开始减速,直到停止;整个过程周而复始。

第6节 马达 - 图9

6.3.3 马达的反转

目前,我们的INA始终保持的低电平,而INB始终保持的高电平(虽然它的值在不停的变化)。因此电机始终朝着一个方向发生变化。

如果想修改马达旋转的方向,可以将INB设置为低电平LOW,改变INA引脚为高电平,

  1. int INA = 9;
  2. int INB = 10;
  3. int START_LEVEL = 0;
  4. int END_LEVEL = 230;
  5. void setup() {
  6. pinMode(INA, OUTPUT);
  7. pinMode(INB, OUTPUT);
  8. }
  9. void loop() {
  10. //朝着一个方向旋转,先加速,再减速
  11. //INA设置为LOW
  12. digitalWrite(INA, LOW);
  13. for(int level = START_LEVEL ; level < END_LEVEL+1; level++)
  14. {
  15. //改写INB的级数
  16. analogWrite(INB, level);
  17. delay(100);
  18. }
  19. for(int level = END_LEVEL; level > START_LEVEL ; level--)
  20. {
  21. //改写INB的级数
  22. analogWrite(INB, level);
  23. delay(100);
  24. }
  25. //朝着另一个方向旋转,先加速,再减速
  26. //INB设置为LOW
  27. digitalWrite(INB, LOW);
  28. for(int level = START_LEVEL ; level < END_LEVEL+1; level++)
  29. {
  30. //改写INA的级数
  31. analogWrite(INA, level);
  32. delay(100);
  33. }
  34. for(int level = END_LEVEL; level > START_LEVEL ; level--)
  35. {
  36. //改写INA的级数
  37. analogWrite(INA, level);
  38. delay(100);
  39. }
  40. }

6.4 使用大马达(利用L298N电机驱动板)

要使用大马达,一定需要为马达提供较大的电压,Arduino开发板的电压只有5v,达不到驱动马达转动的要求的。因此,为这种马达提供服务的转接板需要额外接入电源。

第6节 马达 - 图10

下图是L298N电机驱动板的使用说明,

第6节 马达 - 图11

外接电源不要超过24v,这是常用马达所能承受的最大电压;
ENA IN1IN2控制1号马达的转动;
ENB IN3IN4控制2号马达的转动;

特别需要注意的是,这个驱动板有2种用法:一种是马达的转动速度固定,保持最大速度;另一种就是可以通过PWM进行转速的调节。

6.4.1 定速转动

定速转动只负责马达转动,不管马达转动的快慢(不需要PWM调节转动速度)。这时就需要使用图中红色的短接线,将ENA ENB连接起来(或者让这2个端口保持高电平)。不然向马达输出电压的对应模块不会有电压,也就不能带动马达转动;
第6节 马达 - 图12

在这种情况下,输入端口有如下规则,

电机模块序号 转动方式 IN1引脚电平 IN2引脚电平 ENA调速
1号马达 正转 HIGH LOW 短接
1号马达 反转 LOW HIGH 短接
1号马达 不转 LOW LOW 短接
电机模块序号 转动方式 IN3引脚电平 IN4引脚电平 ENB调速
2号马达 正转 HIGH LOW 短接
2号马达 反转 LOW HIGH 短接
2号马达 不转 LOW LOW 短接

6.4.1.1 硬件连接

我们这里只来验证马达1和马达2全力开动的情况,也就是说不考虑调速,让ENAENB保持短接。

连接2个马达到电机驱动板的马达接口,

马达 马达驱动板接口
马达1正极 OUT1
马达1负极 OUT2
马达2正极 OUT3
马达2负极 OUT4

第6节 马达 - 图13

马达上的电极正负极没有关系,都可以(正负只影响转动的方向,如果不满意转动方向,以后可以进行调换)。


连接电机驱动板的控制信号到Arduino开发板上,连线如下:

马达驱动板引脚 Arduino开发板引脚
IN1 4
IN2 5
IN3 6
IN4 7

第6节 马达 - 图14


连接电机驱动板的外接电源,连线如下:

马达驱动板引脚 外接引脚
VCC 电源正极
GND 电源负极和Arduino GND引脚
5V Arduino Vin引脚

第6节 马达 - 图15

特别注意的是,驱动板的5V输出要连接到Arduino开发板上。

以下是连接后的整体效果:
第6节 马达 - 图16

上图,我们连接了两个驱动轮胎的马达,可以制作小车了;如果只用一端连接普通马达,那么就可以制作风扇。

只要能驱动马达转动,马达再去带动其他机械结构运动就行了,所以马达的可玩性很高。

6.4.1.2 代码设计

如下代码,可以实现2个马达的运动:

  1. int IN1=4;
  2. int IN2=5;
  3. int IN3=6;
  4. int IN4=7;
  5. void setup() {
  6. //初始化电机不动
  7. pinMode(IN1, OUTPUT);
  8. digitalWrite(IN1, HIGH);
  9. pinMode(IN2, OUTPUT);
  10. digitalWrite(IN2, HIGH);
  11. pinMode(IN3, OUTPUT);
  12. digitalWrite(IN3, HIGH);
  13. pinMode(IN4, OUTPUT);
  14. digitalWrite(IN4, HIGH);
  15. }
  16. void loop() {
  17. // 正向旋转2秒
  18. digitalWrite(IN1,LOW);
  19. digitalWrite(IN2,HIGH);
  20. digitalWrite(IN3,LOW);
  21. digitalWrite(IN4,HIGH);
  22. delay(2000);
  23. // 反向旋转2秒
  24. digitalWrite(IN1,HIGH);
  25. digitalWrite(IN2,LOW);
  26. digitalWrite(IN3,HIGH);
  27. digitalWrite(IN4,LOW);
  28. delay(2000);
  29. }

6.4.1.3 结果观察

部署代码到设备上以后,一定要打开外接电源上的开关,才能为马达提供动力。
可以看到2个马达开始转动,并且每隔2秒,换向一次周而复始。说明我们使用大马达的方法也成功了。

6.4.2 变速转动

要控制马达的转速。这时就需要使用图中红色的短接线移除。哪个电压输出模块要实现转速调节,就移除它对应的那根短接线;

第6节 马达 - 图17

输入端口做如下设置,

电机模块序号 转动方式 IN1引脚电平 IN2引脚电平 ENA调速
1 正转 HIGH LOW 0-255级数字
1 反转 LOW HIGH 0-255级数字
1 不转 LOW LOW 0-255级数字
电机模块序号 转动方式 IN3引脚电平 IN4引脚电平 ENB调速
2 正转 HIGH LOW 0-255级数字
2 反转 LOW HIGH 0-255级数字
2 不转 LOW LOW 0-255级数字

6.4.2.1 硬件连接

硬件连接的方法大部分和前面定速转动中的连接方式一模一样,只是在一个地方有区别:因为要做PWM调速,所以要把短接的ENAENB取开,让Arduino主板分别控制它们的值。

连接电机驱动板的控制信号到Arduino开发板上,连线如下:

马达驱动板引脚 Arduino开发板引脚
IN1 4
IN2 5
IN3 6
IN4 7
INA 11
INB 9

第6节 马达 - 图18


以下是连接后的整体效果:
第6节 马达 - 图19

6.4.2.2 代码设计

如下代码,可以实现2个马达的运动:

  1. //使用L298N驱动板
  2. // IN1连接引脚4
  3. // IN2连接引脚5
  4. // IN3连接引脚6
  5. // IN4连接引脚7
  6. int IN1=4;
  7. int IN2=5;
  8. int IN3=6;
  9. int IN4=7;
  10. // INA连接引脚11
  11. // INB连接引脚9
  12. int INA = 11;
  13. int INB = 9;
  14. void setup() {
  15. //设置引脚为输出
  16. pinMode(IN1,OUTPUT);
  17. pinMode(IN2,OUTPUT);
  18. pinMode(IN3,OUTPUT);
  19. pinMode(IN4,OUTPUT);
  20. pinMode(INA,OUTPUT);
  21. pinMode(INB,OUTPUT);
  22. }
  23. void loop() {
  24. int i;
  25. //让电机的转速从0到255正向加速转动
  26. for(i=0;i<=255;i++)
  27. {
  28. digitalWrite(IN1,LOW);
  29. digitalWrite(IN2,HIGH);
  30. digitalWrite(IN3,LOW);
  31. digitalWrite(IN4,HIGH);
  32. analogWrite(INA,i);
  33. analogWrite(INB,i);
  34. delay(50);
  35. }
  36. //让电机的转速从255到0正向减速转动
  37. for(i=255;i>0;i--)
  38. {
  39. digitalWrite(IN1,LOW);
  40. digitalWrite(IN2,HIGH);
  41. digitalWrite(IN3,LOW);
  42. digitalWrite(IN4,HIGH);
  43. analogWrite(INA,i);
  44. analogWrite(INB,i);
  45. delay(50);
  46. }
  47. //让电机的转速从0到255反向加速转动
  48. for(i=0;i<255;i++)
  49. {
  50. digitalWrite(IN1,HIGH);
  51. digitalWrite(IN2,LOW);
  52. digitalWrite(IN3,HIGH);
  53. digitalWrite(IN4,LOW);
  54. analogWrite(INA,i);
  55. analogWrite(INB,i);
  56. delay(50);
  57. }
  58. //让电机的转速从255到0反向减速转动
  59. for(i=255;i>0;i--)
  60. {
  61. digitalWrite(IN1,HIGH);
  62. digitalWrite(IN2,LOW);
  63. digitalWrite(IN3,HIGH);
  64. digitalWrite(IN4,LOW);
  65. analogWrite(INA,i);
  66. analogWrite(INB,i);
  67. delay(50);
  68. }
  69. }

6.4.2.3 结果观察

部署代码到设备上以后,一定要打开外接电源上的开关,才能为马达提供动力。
可以看到2个马达开始转动,并且速度会逐渐增大,换向一次周而复始。说明我们使用调速大马达的方法也成功了。