65.9K
CodeProject 正在变化。 阅读更多。
Home

使用超声波换能器的汽车距离传感器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (11投票s)

2018 年 6 月 28 日

CPOL

6分钟阅读

viewsIcon

18522

downloadIcon

98

使用带超声波换能器的 Arduino 的汽车距离传感器

引言

不久前,我有幸在瑞士山区的一个为期两周的暑期学校里,向一群极具才华的人们传授了能源效率计算背后的概念。这次暑期学校的目标之一是理解物联网(IoT)和创客空间背后的主要原理。我们不想停留在理论层面,因此我们花了一些晚上时间来实际构建有趣的应用程序。

我们创建的一个简单玩具项目是汽车距离传感器。其想法是创建一个小型 Arduino(或 CC3200)兼容的代码库,这与给定的接线完美匹配。硬件设置也将非常便携。

本文的成果可能看起来像这样(显示的是 CC3200 板,Arduino 看起来很相似)

Car Distance Sensor using CC3200

零件

您将需要以下部件来完成本教程

  • 一个超声波换能器,
  • 两个七段数码管显示器,
  • 一个 Arduino Nano,
  • 两个逻辑电平 N 沟道 MOSFET,以及
  • 两个 220Ω 电阻。

让我们简要回顾一下其中一些部件。

超声波换能器

超声波换能器是该设置的主要组成部分。它的工作原理与蝙蝠的导航系统完全相同。它会发射超声波,超声波会被物体反射回来。然后,可以利用发射和接收反射之间的时间来计算到反射物体的距离。

超声波换能器提供四个不同的引脚。两个用于电源的引脚,GND 和 VCC,一个用于触发超声波发射的引脚,以及一个在接收到反射时发出信号的引脚。

Utrasonic Transducer

为了方便起见,我们不打算手动编写代码来驱动超声波换能器,而是使用这个库

七段数码管显示器

有几种不同类型的七段数码管显示器。它们的主要区别在于它们提供的是共阴极还是共阳极。我们使用的七段数码管显示器具有共阴极,也就是说,所有段都共享一个与 GND 的公共连接。除了公共引脚外,七段数码管显示器还为每个段提供一个专用引脚。哪个引脚属于哪个段也是特定于类型的。您可以在显示器的数据手册中查找分配。显示器的段以字母 A 到 G 标记,如下图所示。

Seven-Segment Display

由于 Arduino Nano 提供的引脚不足以独立驱动两个七段数码管显示器,因此我们使用两个 MOSFET 以高速率在它们之间进行切换。这样,我们就可以为两个显示器的每个段仅使用一个引脚。

MOSFET-Symbols

每个 MOSFET 提供三个引脚:栅极引脚 (G),源极引脚 (S) 和漏极引脚 (D)。当栅极引脚没有施加电压时,MOSFET 处于截止状态,即源极和漏极引脚之间的电阻非常高,以至于这两个引脚之间没有电流流过。当施加高于 MOSFET 阈值电压的电压时(由于我们使用的是逻辑电平 MOSFET,因此阈值电压应低于 5V),MOSFET 就会导通。此时,源极和漏极引脚相互连接,电流可以在这两个引脚之间自由流动。

接线

让我们开始连接所有组件。

Wiring

首先,超声波换能器的信号和触发引脚分别连接到 Arduino 的 11 号和 12 号引脚。当然,超声波换能器也连接到 Arduino 的电源引脚。每个七段数码管显示器的共阴极通过一个 220Ω 电阻连接到相应的 MOSFET 的漏极引脚。MOSFET 的源极引脚连接到 GND,栅极引脚连接到 Arduino 的 9 号和 10 号引脚。其中,9 号引脚属于驱动左侧显示器的 MOSFET,10 号引脚属于驱动右侧显示器的 MOSFET。此外,两个显示器的每个段都连接到 2 到 8 号引脚之一。

软件

在成功连接所有组件后,唯一缺少的就是软件。Arduino 的软件使用 C++ 的一个方言,并在 Arduino 集成开发环境 (IDE) 中编写。

IDE

IDE

此外,除了主源代码视图外,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);

最后,我们需要编写 loop() 函数。loop 函数在一个无限循环中执行,该循环由测量距离然后将其显示在显示器上组成。为了显示距离,我们以 10ms 的速率使用 MOSFET 在两个显示器之间切换。我们将距离的最高有效数字显示在左侧显示器上,最低有效数字显示在右侧显示器上。这样,两个显示器一起以十进制系统显示测得的距离(以厘米为单位)。

int select = 0;

void loop() {
    // request the distance in centimeters using the library
    int dist = ultrasonic.Ranging(CM);
    
    // print the distance for debugging purposes
    Serial.println(dist);

    for (int i = 0; i < 10; i++) {
        if (select) {
            // enable the left display
            digitalWrite(DISPLAY_LEFT, HIGH);
            digitalWrite(DISPLAY_RIGHT, LOW);
            // show the most significant digit
            show(dist / 10);
        } else {
            // enable the right display
            digitalWrite(DISPLAY_LEFT, LOW);
            digitalWrite(DISPLAY_RIGHT, HIGH);
            // show the least significant digit
            show(dist % 10);
        }
        // switch to the other display and sleep for 10ms
        select = !select;
        delay(10);
    }
}

关注点

暑期学校由几个小组组成。每位小组组长都必须在晚上进行一次全体演讲。我们小组的主题是“物联网——今天和明天”,这是一个混合了常识、有趣的事实和实际演示的主题。

在我们的演示中,我们使用超声波换能器构建了一个板子,以展示如何制作汽车距离传感器。测量到的距离通过 WiFi 实时传输到我们的演示中,这给许多听众留下了深刻的印象。

历史

  • v1.0.0 | 初始发布 | 2018 年 6 月 28 日
© . All rights reserved.