在物联网(IoT)项目中,经常需要在微秒级的时间尺度上操作硬件。例如,一个digitalWrite
操作可能需要6-7微秒,而一个digitalRead
操作需要4-5微秒。本文将介绍如何使用Node.js和PCDuino v3开发板来实现这些操作。
PCDuino v3是一款小型但功能强大的迷PC和开发板,价格大约为50欧元。它提供了对硬件GPIO(通用输入输出引脚)的访问。GPIO引脚的物理布局与知名的Arduino UNO板相同。目前,它可以运行Android 4.2和Ubuntu 12.04操作系统。在Ubuntu系统上,可以安装Node.js,用于访问硬件资源(例如,读取温度传感器)以及提供HTTP服务器实例和创建Web应用程序。
为了访问硬件资源,需要使用名为iotduino的开源模块,该模块可在官方npm仓库中找到。iotduino模块能够复制以下Arduino特有的功能:
pinMode(pin, state)
- 设置引脚模式为INPUT(0x0)、OUTPUT(0x1)或INPUT_PULLUP(0x2)digitalRead(pin)
- 读取选定引脚的当前状态digitalWrite(pin, state)
- 在调用pinMode
并将OUTPUT作为状态参数后,将引脚状态设置为LOW(0x0)或HIGH(0x1)analogRead(pin)
- 读取模拟引脚的值。A0和A1引脚具有6位ADC分辨率(因此方法返回的值在[0, 63]区间内),而A2、A3、A4和A5引脚具有12位ADC分辨率(因此方法返回的值在[0, 4095]区间内)。注意,ADC电压参考为3.3V(实际上取决于许多因素),因此可以测量高达3.3V的正电压(如果需要,可以使用电阻分压电路测量更高的电压)。analogWrite(pin, value)
- 在选定引脚上创建PWM效果。支持的引脚有GPIO3、GPIO5、GPIO6、GPIO9、GPIO10和GPIO11。value
参数是一个在[0, 255]范围内的整数。该方法与setPwmFrequency
方法结合使用。setPwmFrequency(pin, frequency)
- 设置指定引脚的PWM频率。GPIO5和GPIO6引脚仅支持:195Hz、260Hz、390Hz、520Hz和781Hz,而GPIO3、GPIO9、GPIO10和GPIO11引脚支持[126, 2000]Hz范围内的整数值。pulseIn(pin, state, timeout)
- 读取指定引脚和提供状态的脉冲时间。它以微秒为单位返回值。micros()
- 读取从纪元(1970年1月1日,00:00:00 UTC)开始经过的微秒数(在C/C++中为无符号长整型)。delay(milliseconds)
- 暂停代码执行指定的毫秒数。delayMicroseconds(microseconds)
- 暂停代码执行指定的微秒数。为了简化代码阅读,提供了以下常量组:
安装这个模块非常简单:
npm install iotduino
用于本地安装(仅对特定应用程序可用),或者
npm install -g iotduino
用于全局安装(对任何Node应用程序可用)。在Linux系统上,需要使用sudo
或以root
身份登录,才能全局安装此模块。
如果在安装过程中遇到以下错误:
Error: Cannot find module 'iotduino'
请检查NODE_PATH
变量(使用echo $NODE_MODULES
)以验证它是否指向正确的位置(通常是/usr/local/lib/node_modules
)。
让考虑一个LED闪烁的场景:
var duino = require('iotduino'),
pinMode = duino.PinMode, pinState = duino.PinState,
pins = duino.Pins, ledPin = pins.GPIO13;
//
pin 13 (GPIO13) is set as OUTPUT
duino.pinMode(ledPin, pinMode.OUTPUT);
//
repeat every 500 milliseconds, 2 times per second
setInterval(function () {
//
alternate the pin state between HIGH and LOW
duino.digitalWrite(ledPin, !duino.digitalRead(ledPin));
}, 500);
GPIO13连接到PCDuino v3板上的内置LED,与Arduino UNO板的情况相同,因此这个示例无需额外努力或外部组件即可工作。创建一个blink.js文件,复制/粘贴上述代码,保存然后执行:
node blink.js
现在板上的LED应该每秒闪烁两次。
读取HC-SR04超声波传感器(用于测量高达4米的距离,精度约为2厘米)也相当简单:
var duino = require('iotduino'),
pinMode = duino.PinMode, pinState = duino.PinState,
pins = duino.Pins, trigPin = pins.GPIO2, echoPin = pins.GPIO3,
distanceCm = -1;
//
the trigger pin (GPIO2) is set as OUTPUT
duino.pinMode(trigPin, pinMode.OUTPUT);
//
the echo pin (GPIO3) is set as INPUT
duino.pinMode(echoPin, pinMode.INPUT);
//
read the sensor every 333 milliseconds, ~3 times per second
setInterval(function () {
//
the sensor receives LOW at the trigger pin,
//
to prepare it for data reading
duino.digitalWrite(trigPin, pinState.LOW);
//
wait for the sensor to get ready
duino.delayMicroseconds(2);
//
inform the sensor that we want to make a reading
duino.digitalWrite(trigPin, pinState.HIGH);
duino.delayMicroseconds(10);
//
end the commands chain to the sensor
duino.digitalWrite(trigPin, pinState.LOW);
//
read the value HIGH time period from the sensor
//
and compute the distance based on it and the physical laws
distanceCm = duino.pulseIn(echoPin, pinState.HIGH, 100000) / 58.0;
//
show the distance value in the console
console.log("Distance: " + distanceCm.toFixed(2) + " cm");
}, 333);
上述示例需要以下硬件连接:
trig
引脚连接到PCDuino板的GPIO2引脚echo
引脚连接到PCDuino板的GPIO3引脚注意:HC-SR04传感器板需要5V电源。虽然PCDuino v3 GPIO引脚的功能与Arduino UNO板相同(或几乎相同),但它们并不耐受5V。因此,需要一个硬件电压电平转换器,将5V转换为3.3V,然后再转换回5V,以避免对GPIO和板造成永久性损坏。