1. Peripheral I/O
Android Things提供外设的I / O API与传感器和执行器,使用行业标准的协议和接口进行通信。
- General Purpose Input/Output (GPIO) ---使用这个API的简单的传感器,如运动探测器,接近探测器,和液位开关,报告当前状态为高或低的二进制值。
- Pulse Width Modulation (PWM) ---使用此API的伺服电机,直流电机和灯,需要一个比例信号,以提供细粒度的控制输出。
- Serial Communication-使用这些API在同一本地总线上,连接两个或多个智能设备之间传输较大的数据有效载荷。下表概述了每个支持的串行协议的基本属性:
1.1 GPIO
General Purpose Input/Output (GPIO) 引脚提供一个可编程接口来读取二进制输入设备的状态(如按钮开关)或控制一个二进制的闭合状态,输出到设备上(如LED)。
您可以配置GPIO引脚作为输入或输出或高或低的状态。作为输入,外部源决定状态,并且您的应用程序可以读取当前值或响应状态的变化。作为输出,应用程序配置PIN的状态。
注意:为避免损坏的GPIO引脚,在进行导线连接时,再次检查你的硬件设备的输入和输出的限制。参见
Hardware 101并查阅硬件文档。
1.1.1 GPIO口连接管理
为了打开一个GPIO端口的连接,你需要知道的端口名称。在初始化阶段,或在应用程序移植到新的硬件上,通过PeripheralManagerService 的getgpiolist()方法,获取到所有可用的端口名称是非常有帮助的。
PeripheralManagerService
manager
=
new
PeripheralManagerService
();
List
<
String
>
portList
=
manager
.
getGpioList
();
if
(
portList
.
isEmpty
())
{
Log
.
i
(
TAG
,
"No GPIO port available on this device."
);
}
else
{
Log
.
i
(
TAG
,
"List of available ports: "
+
portList
);
}
一旦你知道了目标端口的名字,使用peripheralmanagerservice连接到该端口。当你使用该端口完成了GPIO通信,关闭连接,释放资源连接。此外,在现有连接关闭之前,不能使用同一个接口打开新的连接。使用端口的
close() 方法来关闭连接。
public
class
HomeActivity
extends
Activity
{
// GPIO Pin Name
private
static
final
String
GPIO_NAME
=
...;
private
Gpio
mGpio
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
// Attempt to access the GPIO
try
{
PeripheralManagerService
manager
=
new
PeripheralManagerService
();
mGpio
=
manager
.
openGpio
(
GPIO_NAME
);
}
catch
(
IOException
e
)
{
Log
.
w
(
TAG
,
"Unable to access GPIO"
,
e
);
}
}
@Override
protected
void
onDestroy
()
{
super
.
onDestroy
();
if
(
mGpio
!=
null
)
{
try
{
mGpio
.
close
();
mGpio
=
null
;
}
catch
(
IOException
e
)
{
Log
.
w
(
TAG
,
"Unable to close GPIO"
,
e
);
}
}
}
}
1.1.2 Reading from an input
读一个输入模式的GPIO口值,步骤为:
(1)使用setDirection() 方法进行配置,模式参数设置为direction_in。
(2)配置一个高(近Ioref)或低(接近零)的电压信号返回ture,通过调用 setActiveType() 方法,参数配置为ACTIVE_HIGH 或是 ACTIVE_LOW。
(3) 通过getValue() 方法读取当前状态。
以下代码向展示,用高电平,如何设置一个输入:
public
void
configureInput
(
Gpio
gpio
)
throws
IOException
{
// Initialize the pin as an input
gpio
.
setDirection
(
Gpio
.
DIRECTION_IN
);
// High voltage is considered active
gpio
.
setActiveType
(
Gpio
.
ACTIVE_HIGH
);
...
// Read the active high pin state
if
(
gpio
.
getValue
())
{
// Pin is HIGH
}
else
{
// Pin is LOW
}
}
1.1.2 监听GPIO口输入状态
一个GPIO端口配置为输入模式,当该端口状态处于高、低改变时,可以通知你的应用程序。注册这些改变事件,步骤为
(1)使激活端口与gpiocallback进行关联。
(2)使用setedgetriggertype()方法,来声明一个状态变化触发的中断事件。边缘触发器支持以下四种类型:
- edge_none:不中断事件。这是默认值。
- edge_rising:一个从低到高的转换的中断
- edge_falling:一个从高到低转换的中断
- edge_both:所有状态转换中断
(3)通过 onGpioEdge()函数 返回true值,表示监听者应该继续为每个端口状态改变接收事件。
下面的代码为给定的输入端口,注册状态更改的中断侦听器:
public
void
configureInput
(
Gpio
gpio
)
throws
IOException
{
// Initialize the pin as an input
gpio
.
setDirection
(
Gpio
.
DIRECTION_IN
);
// Low voltage is considered active
gpio
.
setActiveType
(
Gpio
.
ACTIVE_LOW
);
// Register for all state changes
gpio
.
setEdgeTriggerType
(
Gpio
.
EDGE_BOTH
);
gpio
.
registerGpioCallback
(
mGpioCallback
);
}
private
GpioCallback
mGpioCallback
=
new
GpioCallback
()
{
@Override
public
boolean
onGpioEdge
(
Gpio
gpio
)
{
// Read the active low pin state
if
(
gpio
.
getValue
())
{
// Pin is LOW
}
else
{
// Pin is HIGH
}
// Continue listening for more interrupts
return
true
;
}
@Override
public
void
onGpioError
(
Gpio
gpio
,
int
error
)
{
Log
.
w
(
TAG
,
gpio
+
": Error event "
+
error
);
}
};
(4)当应用程序不再侦听传入的事件,注销任何中断处操作:
- publicclassHomeActivityextendsActivity{
private
Gpio
mGpio
;
...
@Override
protected
void
onStart
()
{
super
.
onStart
();
// Begin listening for interrupt events
mGpio
.
registerGpioCallback
(
mGpioCallback
);
}
@Override
protected
void
onStop
()
{
super
.
onStop
();
// Interrupt events no longer necessary
mGpio
.
unregisterGpioCallback
(
mGpioCallback
);
}
}
1.1.3 GPIO口设置为输出
以编程方式控制GPIO端口的状态:
- 配置一个输出口,使用setdirection()方法,参数模式为direction_out_initially_high或direction_out_initially_low。这些模式确保端口在初始状态时也配置正确。
- 配置一个高(近Ioref)或低(接近零)的电压信号返回ture,通过调用 setActiveType() 方法,参数配置为ACTIVE_HIGH 或是 ACTIVE_LOW。
- 使用setvalue()方法设置当前状态。
下面的代码显示了使用setvalue()方法,如何设置一个输出最初状态是高电平,然后切换到低电平状态:
public
void
configureOutput
(
Gpio
gpio
)
throws
IOException
{
// Initialize the pin as a high output
gpio
.
setDirection
(
Gpio
.
DIRECTION_OUT_INITIALLY_HIGH
);
// Low voltage is considered active
gpio
.
setActiveType
(
Gpio
.
ACTIVE_LOW
);
...
// Toggle the value to be LOW
gpio
.
setValue
(
true
);
}
2. DEMO示例
Blink、Button分别展示通过GPIO,如何点亮一个LED灯,获取按钮的输入信号。
树莓派 3效果图