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

在 Intel® Edison 板上使用带超声波测距传感器的 MCU

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (1投票)

2015年11月13日

CPOL

8分钟阅读

viewsIcon

28307

Intel® Edison 板除了 CPU 外,还包含一个内部微控制器单元 (MCU)。在本文中,我将解释使用内部 MCU 的优势,主要体现在两个方面:

获取新的 Intel® 物联网开发者套件,这是一个完整的硬件和软件解决方案,允许开发人员使用 Intel® Galileo 和 Intel® Edison 板创建令人兴奋的新解决方案。请访问 Intel® 物联网开发者专区

Intel® Edison 板除了 CPU 外,还包含一个内部微控制器单元 (MCU)。在本文中,我将解释使用内部 MCU 的优势,主要体现在两个方面:

  • 实时性
  • 能效

MCU 在许多应用中都很重要。例如,Intel® Edison 板上的 Linux* 在处理传感器时无法提供实时响应。自 2.1 版以来,Intel® Edison® 板固件软件发行版一直支持 MCU。

让我们来看看 Intel® Edison 计算模块中使用的片上系统 (SoC)

Intel® Edison 计算模块中使用的 SoC 包含两个 CPU

  • 双核 Intel® Atom™ 处理器,运行频率为 500 MHz。标记为主机 CPU
  • MCU,采用 Minute Intel® 架构,运行频率为 100 MHz。标记为MCU

Minute Intel 架构核心是一种能效高的架构,基于 Intel® 486 并增加了与 Intel® Pentium® 处理器兼容的指令。MCU 包含丰富的 I/O 子系统(GPIO、I2C、高速 UART、DMA)和 SRAM,并且可以访问 Intel® Edison 计算模块的所有 GPIO 引脚。代码和数据的总 SRAM 大小为 192 kb。MCU 运行 WindRiver 的实时 Viper* OS。

MCU 程序在 Viper 核心上运行,并独立于 Intel Atom 处理器控制连接到 MCU 的外设。例如,它可以控制 GPIO 引脚,通过 I2C 和 UART 协议与传感器通信,以及与 Intel Atom 处理器通信。

使用 Intel® Edison 板上的 MCU 的原因

使用 MCU 有两个主要好处:提供微秒级的实时延迟和提高能效。

Intel Atom 处理器和 Yocto Project* 标准 Linux* 发行版“开箱即用”不支持实时应用程序。

Linux 应用程序可能会被调度器抢占,导致不可接受的、不可预测的延迟,因此无法提供实时响应。

MCU 运行单个应用程序和实时操作系统,这使得提供实时响应成为可能。

许多传感器都需要实时响应,因为通信协议依赖于对短时序的严格遵守。

要在没有内部 MCU 的情况下将这些传感器连接到 Intel® Edison 板,需要使用外部 MCU。在这种情况下,所有传感器通信都在外部 MCU 中实现。例如,SparkFun Block* for Intel® Edison board – Arduino extension board 提供了外部 MCU 功能。然而,使用外部 MCU 会增加物料清单 (BOM) 成本并增加解决方案的复杂性。

在 CPU 设置为睡眠状态,而 MCU 正等待外部事件(例如,当传感器值高于阈值时)的应用中,MCU 可以提高能效。

当外部事件发生时,MCU 会唤醒 CPU。实现示例可在文章 使用 MCU SDK 和 API:代码示例 中找到。

为了说明如何使用内部 MCU,我们将超声波测距传感器 HC-SR04 连接到 Intel® Edison 板。我们将把测量到的距离输出到 Grove* LCD RGB 背光显示屏。

超声波测距传感器 HC-SR04

该传感器有四个引脚

  • Vcc:5V
  • Trig:触发信号给传感器。MCU 向传感器发送一个 10 us 的脉冲。传感器启动一次测量。
  • Echo:传感器到 MCU 的回波信号。脉冲宽度与测量距离成正比。
  • Gnd:接地

下图在示波器屏幕上展示了该协议

  • 通道 1:Trig
  • 通道 2:Echo

MCU 向 Trig 引脚发送一个脉冲。之后,传感器通过 Echo 引脚发出响应脉冲。

脉冲持续时间与测量距离成正比。

距离计算使用以下公式(来自传感器数据手册)

距离 (cm) = Echo 脉冲持续时间 (us) / 58

根据数据手册,该传感器可以测量 2 cm 到 400 cm 的距离。

如果没有微秒级的实时延迟,则无法以估计的精度测量如此短的脉冲持续时间。例如,调度器可能会抢占测量过程,导致测量结果无效。

将 HC-SR04 传感器连接到 Intel® Edison 板上的 MCU

Components

  • Intel® Edison 计算模块
  • Intel® Edison 板(适用于 Arduino)
  • Grove 基本扩展板
  • Grove LCD RGB 背光
  • 超声波测距传感器 HC-SR04
  • 面包板

首先,组装 Intel® Edison 计算模块和 Intel® Edison 板(适用于 Arduino)。然后,将 Grove Base Shield 扩展板连接到 Intel® Edison 板(适用于 Arduino)。将 Grove LCD RGB 背光连接到 Grove Basic Shield 上的任意 I2C 端口。

按以下方式将超声波测距传感器 HC-SR04 连接到 Grove Basic Shield:

  • Vcc 连接到 +5V
  • Trig 连接到引脚 3
  • Echo 连接到引脚 4
  • Gnd 连接到 Gnd

引脚 3 和 4 是随机选择的。您可以为此目的使用任何 GPIO 引脚。

更新 Intel® Edison 板固件

MCU 支持已添加到 Intel® Edison 板固件软件发行版 2.1 版中。如果您使用的是旧版本固件,则需要更新。

要获取当前固件版本,请使用以下命令

# configure_edison –version

本示例基于固件版本 146。

固件更新说明可在文章 刷写 Intel® Edison 中找到。我更喜欢使用文章中描述的备选刷写方法。

请在刷写前仔细阅读说明。

通过以太网连接 Intel® Edison 板(通过 USB)

您必须配置网络连接才能从 MCU SDK 连接到 Intel® Edison 板。

为此,将 USB 线连接到顶部的 micro-USB 端口,并将拨动开关设置到底部位置(朝向 micro-USB 端口)。

在 Linux 上配置网络

# ifconfig usb0 192.168.2.2

Intel® Edison 板 IP 地址:192.168.2.15

有关更多信息,请参阅文章 通过以太网(USB 连接)连接到您的 Intel® Edison 板

MCU SDK

开发人员需要 MCU SDK 来创建内部 MCU 的应用程序。MCU SDK 是一个基于 Eclipse* 的跨平台 IDE。安装过程在文章 安装 MCU SDK 中进行了说明。

MCU SDK 提供了创建、编译、上传到板以及调试 MCU 应用程序的功能。

与 MCU 通信

在 Linux 级别,有几种接口可用于与 MCU 通信

/dev/ttymcu0 — 用于发送/接收数据到/来自 MCU 的接口。可以使用标准的 Linux readwrite 文件操作进行操作。MCU 程序可以使用 host_sendhost_receive 函数。

/dev/ttymcu1 — 用于通过 debug_print 函数从 MCU 发送调试消息的接口。

/sys/devices/platform/intel_mcu/log_level — 用于设置调试消息的日志级别的接口(fatal、error、warning、info、debug)。

使用 MCU 操作 Intel® Edison 板(适用于 Arduino)的引脚

MCU 集成在 Intel® Edison 计算模块中,可以控制 70 引脚 Hirose 模块连接器上的 GPIO。

要将 MCU 与 Intel® Edison 板(适用于 Arduino)一起使用,您需要找到 Intel® Edison 计算模块 GPIO 引脚与 Intel® Edison 板(适用于 Arduino)引脚之间的映射。配置多路复用器和电平转换器,将 GPIO 从 Intel® Edison 计算模块路由到 Intel® Edison 板(适用于 Arduino)的引脚。

在 Linux 级别工作时,这些例程由 MRAA 库处理。对于 MCU,开发人员需要使用脚本(init_DIG.sh、init_i2c8.sh、init_mcu_PWM.sh、set_DIG.sh、read_DIG.sh、init_UART1.sh)来处理。有关更多信息,请参阅 Intel® Edison Kit for Arduino* Hardware Guide 中的表 4。

Linux 脚本

下面的 Python* 脚本 show_distance.py 从内部 MCU 获取数据并在 Grove LCD 显示屏上显示。我们将使用 UPM 库中的 Jhd1313m1 模块来操作 Grove LCD 显示屏。

show_distance.py(注意:所有文件/脚本都作为 .zip 文件包含在本文章末尾)

import time
import pyupm_i2clcd

RET_ERROR = -1

if __name__ == '__main__':
    lcd = pyupm_i2clcd.Jhd1313m1(6, 0x3E, 0x62)
    with open('/dev/ttymcu0', 'w+t') as f:
        while True:
            f.write('get_distance\n') # Send command to MCU
            f.flush()
            line = f.readline() # Read response from MCU, -1 = ERROR
            value = int(line.strip('\n\r\t '))
            lcd.clear()
            if value == RET_ERROR:
                lcd.setColor(255, 0, 0) # RED
                lcd.write('ERROR')
            else:
                lcd.setColor(0, 255, 0) # GREEN
                lcd.write('%d cm' % (value,))
            time.sleep(1)

MCU 程序

MCU 程序等待来自主机 CPU 的 get_distance 命令。如果程序收到 get_distance 命令,它将测量距离并将结果发送到主机 CPU(距离以 cm 为单位,错误时为 -1)。

设置 Intel® Edison 板(适用于 Arduino)的引脚

# ./init_DIG.sh -o 3 -d output
# ./init_DIG.sh -o 4 -d input

MCU 操作 Intel® Edison 计算模块上的 GPIO 引脚,这些引脚的编号与 Intel® Edison 板(适用于 Arduino)上的标签不同。有关更多信息,请参阅文章 使用 MCU 闪烁 LED 中的表格。

mcu.c(注意:所有文件/脚本都作为 .zip 文件包含在本文章末尾)

#include "mcu_api.h"
#include "mcu_errno.h"

// Arduino Extension PIN = 3
#define TRIG 12
// Arduino Extension PIN = 4
#define ECHO 129

// From HC-SR04 datasheet
#define MIN_DISTANCE 2
#define MAX_DISTANCE 400

#define MAX_WAIT 10000
#define RET_ERROR -1

int get_distance() {
	// Send Trig signal to HC-SR04
	gpio_write(TRIG, 1);
	mcu_delay(10);
	gpio_write(TRIG, 0);

	// Read Echo signal from HC-SR04
	int i;

	i = 0;
	while ((gpio_read(ECHO) == 0) && (i < MAX_WAIT)) {
		mcu_delay(1);
		i++;
	}

	unsigned long t0 = time_us();
	if (gpio_read(ECHO) == 0 || i == MAX_WAIT) {
		return RET_ERROR;
	}

	i = 0;
	while ((gpio_read(ECHO) == 1) && (i < MAX_WAIT)) {
		mcu_delay(1);
		i++;
	}

	unsigned long t1 = time_us();
	if (gpio_read(ECHO) == 1 || i == MAX_WAIT) {
		return RET_ERROR;
	}

	unsigned long distance = (t1 - t0) / 58;
	if (MIN_DISTANCE < distance && distance < MAX_DISTANCE) {
		return distance;
	} else {
		return RET_ERROR;
	}
}

#define MAX_BUF 255
unsigned char buf[MAX_BUF];

void mcu_main() {
	// Setup Trig as OUTPUT
	gpio_setup(TRIG, 1);
	// Initially set Trig to LOW
	gpio_write(TRIG, 0);
	// Setup Echo as INPUT
	gpio_setup(ECHO, 0);

	while (1) {
		unsigned int len;
		len = host_receive(buf, MAX_BUF);

		if ((len >= 12) && (strncmp(buf, "get_distance", 12) == 0)) {
			unsigned int distance;
			distance = get_distance();
			len = mcu_snprintf(buf, MAX_BUF, "%d\n", distance);
			host_send(buf, len);
		}
	}
}

将我们的脚本添加到自动启动

要启动我们的脚本,首先创建一个 shell 脚本

文件/home/root/startup.sh

startup.sh(注意:所有文件/脚本都作为 .zip 文件包含在本文章末尾)

#!/bin/bash

cd /home/root

# configure PIN3 as GPIO OUPUT (TRIG signal)
./init_DIG.sh -o 3 -d output

# configure PIN4 as GPIO INPUT (ECHO signal)
./init_DIG.sh -o 4 -d input

python show_distance.py

将脚本标记为可执行文件

# chmod a+x /home/root/startup.sh
# chmod a+x /home/root/init_DIG.sh

Yocto Project Linux 使用 systemd,因此我们需要创建一个“service”文件来将脚本添加到自动启动。

创建文件/lib/systemd/system/startup-script.service

startup-script.service(注意:所有文件/脚本都作为 .zip 文件包含在本文章末尾)

[Unit]
Description=Startup User Script
After=syslog.target

[Service]
ExecStart=/home/root/startup.sh

[Install]
WantedBy=multi-user.target

将服务添加到自动启动

# systemctl enable startup-script

重启后,符号显示屏将显示测量到的距离

源代码

使用的资源

© . All rights reserved.