数字信号与模拟信号

在 Arduino 中,电路之间通过电压来传递信息,传递的信息可以分为两大类:数字信号与模拟信号。
数字信号,简单地理解就是 0 和 1,只有可能是这两者其中之一,不存在 0.3 或 0.5 的数字信号。在 Arduino 中,用高电压 5V 代表 1,用低电压 0V 代表 0。
模拟信号,则可以在 0 到 1 之间取到任意值,可以是 0.5,也可以是 0.14159265…… 在 Arduino 中,模拟信号的电压可以是 0V - 5V 之间的任意值,一般把模拟输入分为 1024 份,把模拟输出分为 256 份。

数字信号的输出

在 Arduino 中,0 - 13 号引脚是数字引脚,可以用于输出数字信号或接收数字信号。以 13 号引脚为例,13 号引脚与板载 LED 的连接如下图所示:
Arduino数字模拟输入与输出 - 图1
当引脚 13 输出高电平(1)时,LED 将被点亮;输出低电平(0)时,LED 将熄灭。以第一课中的程序为例,控制 LED 闪烁,只需要让引脚 13 周期性输出高低电平即可。
Arduino数字模拟输入与输出 - 图2
Arduino 的程序有两个重要组成部分:初始化和循环,分别是 setup 和 loop 。程序开始时,会执行一次 setup ,然后不断地运行 loop 函数中的内容。mBlock 中的「forever」积木块对应 Arduino 的 loop 函数。以上程序对应的 Arduino 代码是:

  1. #include <Arduino.h>
  2. #include <Wire.h>
  3. #include <Servo.h>
  4. #include <SoftwareSerial.h>
  5. double angle_rad = PI / 180.0;
  6. double angle_deg = 180.0 / PI;
  7. void setup()
  8. {
  9. }
  10. void loop()
  11. {
  12. pinMode(13, OUTPUT);
  13. digitalWrite(13, 1);
  14. delay(1000 * 0.5);
  15. pinMode(13, OUTPUT);
  16. digitalWrite(13, 0);
  17. delay(1000 * 0.5);
  18. }

自动生成的 Arduino 代码中有些冗余,但用于学习还是没有问题的,经过几次尝试,应该可以发现几个函数的功能:

  1. //设置 13 号引脚为输出模式
  2. pinMode(13, OUTPUT);
  3. //令引脚 13 输出高电平,若第二个参数为 0,则是输出低电平。第二个参数通常用 HIGH 和 LOW 替代 1 和 0。
  4. digitalWrite(13, 1);
  5. //等待 500 毫秒,也就是 0.5 秒
  6. delay(1000 * 0.5);

数字信号的输入

接下来看一个数字信号输入的例子。准备材料:杜邦线 5 条(双公头)、Arduino Leonardo 一块、薄膜键盘一张。
Arduino数字模拟输入与输出 - 图3
用杜邦线把键盘和 Leonardo 按照以下的原理图连接起来。
Arduino数字模拟输入与输出 - 图4
如下图。点开大图可看清接线顺序。
Arduino数字模拟输入与输出 - 图5
编写程序识别按下的按键。当按下按键 1 时,让板载 LED 发亮,否则熄灭。只用到按键 1,其他按键暂时不用。
Arduino数字模拟输入与输出 - 图6
对应的代码为:

  1. #include <Arduino.h>
  2. #include <Wire.h>
  3. #include <Servo.h>
  4. #include <SoftwareSerial.h>
  5. double angle_rad = PI / 180.0;
  6. double angle_deg = 180.0 / PI;
  7. void setup()
  8. {
  9. pinMode(1, INPUT);
  10. }
  11. void loop()
  12. {
  13. if(digitalRead(1))
  14. {
  15. pinMode(13, OUTPUT);
  16. digitalWrite(13, 0);
  17. }
  18. else
  19. {
  20. pinMode(13, OUTPUT);
  21. digitalWrite(13, 1);
  22. }
  23. delay(1000 * 0.1);
  24. }

函数功能介绍:

  1. //设置引脚为输入模式
  2. pinMode(1, INPUT);
  3. //读取引脚 1 的数字信号,低电平返回 0,高电平返回 1
  4. digitalRead(1);

模拟信号的输出

Arduino 板上标有波浪线的引脚可以输出模拟信号,常用于控制电机、呼吸灯等器件。控制模拟信号输出的函数名为 analogWrite,第一个参数是引脚号,第二个参数是模拟电压(0 - 255,对应 0 V- 5V)。但这个函数执行的动作实际上并不是通过引脚直接输出一个模拟电压,而是输出一个 PWM(脉宽调制)波。
PWM 波,可以理解为是间歇性输出高电平和低电平,组成一个矩形波,其中高电平所占的时间比例称为「占空比」。analogWrite 函数控制的实际上就是占空比。举个例子:
Arduino数字模拟输入与输出 - 图7
对应代码:

  1. #include <Arduino.h>
  2. #include <Wire.h>
  3. #include <Servo.h>
  4. #include <SoftwareSerial.h>
  5. double angle_rad = PI / 180.0;
  6. double angle_deg = 180.0 / PI;
  7. void setup()
  8. {
  9. }
  10. void loop()
  11. {
  12. pinMode(5, OUTPUT);
  13. analogWrite(5, 150);
  14. delay(1000 * 0.1);
  15. }

用示波器测量引脚 5 的波形如下图:
Arduino数字模拟输入与输出 - 图8
可以观察到,PWM 占空比约为 60%(精确值为 58.59%),频率为 490.2Hz(理想值为 490.196Hz)。此时用电压表测量,得到引脚 5 输出的电压值为 2.95V ≈ 2.93V = 150 / 256 * 5.0V 。
Arduino数字模拟输入与输出 - 图9

模拟信号的输入

Arduino 板上有一系列模拟值读取口,Leonardo 上有 6 个口,为 A0 - A5。结合输入与输出,可以制作一个旋钮变阻器控制 LED 亮度的案例。模拟值读取使用的函数是 analogRead,参数是管脚号,返回值为 0 - 1023 之间的整数,例如 400 表示的电压值为 400 / 1024 * 5.0V = 1.95V 。