GPIO

GPIO,是 General Purpose Input Output(通用输入/输出) 的缩写,它是一种常见的硬件接口,用以表示开关量。

如果想更多的了解 GPIO,可以到这里

前提条件

使用GPIO

请根据外设的数据手册,确定外设的接口类型为 GPIO。

配置 driver.json

确定自己的硬件接口是 GPIO 后,需要声明硬件接口类型为 GPIO。在 driver.json 文件里的 inputs,指定接口类型(type)为 GPIO。

{
...
"inputs": {
"gpio-in": {
"type": "gpio",
"args": {
"direction": "in",
"edge": "both"
}
},
"gpio-out": {
"type": "gpio",
"args": {
"direction": "out",
"level": "low"
}
}
}
}

接口属性

GPIO 接口可以配置如下属性:

  • direction 定义接口的类型:

    • in,输入模式,读取接口传输的数据,也可通过中断响应用户输入,比如,一个按钮可以响应用户输入,也可以读取当前状态,判断是否被按下
    • out,输出模式,用以控制外设,比如,LED 灯常定义为输出模式,控制 LED 灯开与关
  • edge 定义接口中断触发的边沿类型,只有当接口类型为 in 时,该字段才有效:

    • none 无;
    • rising 上边沿触发
    • falling 下边沿触发
    • both 上下边沿均触发
  • level 定义接口初始电平高低,只有当接口类型是 out 时,该字段才有效:

    • high 接口初始电平为高
    • low 接口初始电平为低

编写驱动

输入设备

在 GPIO 输入模式下,外界输入会触发中断事件,驱动程序可以根据输入值触发相应的事件。应用程序可以编写监听事件做相应的处理,下面是一个例子:

// 驱动代码
gpio.on('interrupt',function(value){
if (that._value === value) {
return;
}

that._value = value;

if (value === 0) {
that.emit('event_0');
} else {
that.emit('event_1');
}
});
// 应用代码
$('#device').on('event_0', function() {
console.log('event_0');
}

$('#device').on('event_1', function() {
console.log('event_1');
}

输出设备

当 GPIO 处于输出模式下,驱动可以向 GPIO 接口写入高电平(Level.high)或低电平(Level.low),下面是一个例子:

var Level = require('gpio').Level;
...

function turnOn(callback) {
gpio.write(Level.high, function(error) {
if (error) {
callback(error);
return;
}
});
}

如果想了解更多细节,请参考其 API 文档

应用

大按键模块(CK002)

大按键模块拥有一个双边沿触发的 I/O 输入端口,在 driver.json 文件中声明一个类型为 GPIO 的接口,设定接口为输入接口,双边沿触发。

"models": [
"CK002"
],
"inputs": {
"gpio": {
"type": "gpio",
"args": {
"direction": "in",
"edge": "both"
}
}
}

大按键模块可以通知用户按键按下(push)或放开(release)。在实现上,它会监听 ‘interrupt’ 事件,根据按键状态,触发pushrelease事件,供应用程序监听。

'use strict';

var driver = require('ruff-driver');

var ButtonState = {
pushed: 0,
released: 1
};

module.exports = driver({
attach: function (inputs) {
var that = this;

this._gpio = inputs['gpio'];
this._state = ButtonState.released;

this._gpio.on('interrupt', function (state) {
if (that._state === state) {
return;
}

that._state = state;

if (state === ButtonState.pushed) {
that.emit('push');
} else {
that.emit('release');
}
});
}
});

蜂鸣器(FC-49)

蜂鸣器拥有一个高电平触发的 I/O 输出端口,在 driver.json 文件中声明一个类型为 GPIO 的接口,设定接口为输出端口,初始电平为低电平。

"models": [
"FC-49"
],
"inputs": {
"gpio": {
"type": "gpio",
"args": {
"direction": "out",
"level": "low"
}
}
}

我们为蜂鸣器模块提供三个接口,分别是开启蜂鸣器(turnOn)、关闭蜂鸣器(turnOff)以及蜂鸣器是否正在鸣叫(isOn),其具体实现方式如下:

  • turnOn,向 GPIO 口写入高电平,蜂鸣器开始鸣叫
  • turnOff,向 GPIO 口写入低电平,触发蜂鸣器停止鸣叫
  • isOn,读取 GPIO 口的电平高低,返回蜂鸣器是否鸣叫
'use strict';

var Level = require('gpio').Level;

var driver = require('ruff-driver');

module.exports = driver({

attach: function (inputs) {
this._gpio = inputs['gpio'];
},
exports: {
turnOn: function (callback) {
this._gpio.write(Level.high, callback);
},
turnOff: function (callback) {
this._gpio.write(Level.low, callback);
},
isOn: function (callback) {
var readCallback = callback && function (error, value) {
if (error) {
callback(error);
return;
}

callback(undefined, !!value);
};

this._gpio.read(readCallback);
}
}
});