在瑞士山区举办的为期两周的夏季学校中,深入学习了能源效率计算背后的理念。其中一个目标是理解物联网(IoT)和创客空间的基本原理。不仅仅停留在理论层面,还花费了一些夜晚实际构建了一些有趣的应用。
创建的一个简单玩具项目是一个汽车距离传感器。想法是创建一个与Arduino(或CC3200)兼容的小型代码库,这个代码库非常适合给定的接线。硬件设置也非常便携。
为了本教程,将需要以下部件:
超声波传感器是设置的主要组件。它的工作原理与蝙蝠的定位系统完全相同。它发出超声波,这些波被物体反射回来。发射和接收反射之间的时间可以用来计算到反射物体的距离。
超声波传感器提供四个不同的引脚。两个用于电源,GND和VCC,一个用于触发超声波发射的引脚,以及一个信号引脚,用于指示何时接收到反射。为了方便,不会用手工编写的代码来驱动超声波传感器,而是使用这个库。
有几种类型的七段显示器。它们的主要区别在于它们是否提供共阴极或共阳极。使用的七段显示器具有共阴极,即所有段共享一个连接到GND的公共连接。七段显示器除了公共引脚外,还为每个段提供了专用引脚。哪个引脚属于哪个段也是特定类型的。可以在显示器的数据表中查找分配。
由于ArduinoNano没有足够的引脚来独立驱动两个七段显示器,使用两个MOSFET以高速度在它们之间切换。这使可以使用一个引脚来驱动两个显示器的每个段。
让开始连接所有组件。首先,将超声波传感器的信号和触发引脚分别连接到Arduino的11号和12号引脚。当然,超声波传感器也连接到Arduino的电源引脚。每个七段显示器的共阴极通过一个220Ω电阻连接到相应的MOSFET的漏极引脚。MOSFET的源引脚连接到GND,栅极引脚连接到Arduino的9号和10号引脚。其中9号引脚属于驱动左侧显示器的MOSFET,10号引脚属于驱动右侧显示器的MOSFET。此外,两个显示器的每个段都连接到2号到8号引脚之一。
成功连接所有组件后,唯一缺少的就是软件。Arduino的软件是用C++方言编写的,使用Arduino集成开发环境。
除了提供主要源代码视图外,IDE还提供了一个按钮,用于编译源文件并将其上传到通过USB连接到计算机的Arduino。
几乎已经完成了!在本教程的剩余部分,将解释显示两个显示器上测量距离的必要源代码。
首先,需要包含超声波传感器库的头文件。
#include "Ultrasonic.h"
为了方便,使用预处理器定义引脚编号的可读名称。
#define TRIGGER 12
#define ECHO 11
#define DISPLAY_A 8
#define DISPLAY_B 7
#define DISPLAY_C 6
#define DISPLAY_D 5
#define DISPLAY_E 4
#define DISPLAY_F 3
#define DISPLAY_G 2
#define DISPLAY_LEFT 9
#define DISPLAY_RIGHT 10
进一步定义一个数组,包含按段字母顺序排列的引脚编号。
int ports[7] = {DISPLAY_A, DISPLAY_B, DISPLAY_C, DISPLAY_D, DISPLAY_E, DISPLAY_F, DISPLAY_G};
为了将数字转换为特定模式的启用段,使用另一个数组。
int leds[10][7] = {
{1, 1, 1, 1, 1, 1, 0},
{0, 1, 1, 0, 0, 0, 0},
{1, 1, 0, 1, 1, 0, 1},
{1, 1, 1, 1, 0, 0, 1},
{0, 1, 1, 0, 0, 1, 1},
{1, 0, 1, 1, 0, 1, 1},
{1, 0, 1, 1, 1, 1, 1},
{1, 1, 1, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 0, 1, 1}
};
例如,数字0被转换为{1, 1, 1, 1, 1, 1, 0},每个位置表明相应的显示器段是否应该启用或禁用。函数show(int x)在显示器上显示数字x。因此,它遍历所有段,查找每个段的引脚编号,并根据相应的模式启用该段。
void show(int x) {
for (int i = 0; i < 7; i++) {
digitalWrite(ports[i], leds[x][i] ? HIGH : LOW);
}
}
仍然缺少的是setup()函数。setup函数将使用的所有引脚的模式设置为OUTPUT,并初始化与计算机的串行连接,这对于调试非常有用。
void setup() {
for (int i = 0; i < 7; i++) {
pinMode(ports[i], OUTPUT);
}
pinMode(DISPLAY_LEFT, OUTPUT);
pinMode(DISPLAY_RIGHT, OUTPUT);
Serial.begin(9600);
}
此外,需要使用库初始化超声波传感器。
Ultrasonic ultrasonic(TRIGGER, ECHO);
int select = 0;
void loop() {
// 使用库请求以厘米为单位的距离
int dist = ultrasonic.Ranging(CM);
// 打印距离以供调试
Serial.println(dist);
for (int i = 0; i < 10; i++) {
if (select) {
// 启用左侧显示器
digitalWrite(DISPLAY_LEFT, HIGH);
digitalWrite(DISPLAY_RIGHT, LOW);
// 显示最高有效数字
show(dist / 10);
} else {
// 启用右侧显示器
digitalWrite(DISPLAY_LEFT, LOW);
digitalWrite(DISPLAY_RIGHT, HIGH);
// 显示最低有效数字
show(dist % 10);
}
// 切换到另一个显示器并休眠10ms
select = !select;
delay(10);
}
}