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=newPeripheralManagerService();
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() 方法来关闭连接。
publicclassHomeActivityextendsActivity{
// GPIO Pin Name
privatestaticfinalString
GPIO_NAME=...;
privateGpio
mGpio;
@Override
protectedvoid
onCreate(Bundle
savedInstanceState){
super.onCreate(savedInstanceState);
// Attempt to access the GPIO
try{
PeripheralManagerService
manager=newPeripheralManagerService();
mGpio=
manager.openGpio(GPIO_NAME);
}catch(IOException
e){
Log.w(TAG,"Unable
to access GPIO", e);
}
}
@Override
protectedvoid
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() 方法读取当前状态。
以下代码向展示,用高电平,如何设置一个输入:
publicvoid
configureInput(Gpio
gpio)throwsIOException{
// 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值,表示监听者应该继续为每个端口状态改变接收事件。
下面的代码为给定的输入端口,注册状态更改的中断侦听器:
publicvoid
configureInput(Gpio
gpio)throwsIOException{
//
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);
}
privateGpioCallback
mGpioCallback=newGpioCallback(){
@Override
publicboolean
onGpioEdge(Gpio
gpio){
//
Read the active low pin state
if(gpio.getValue()){
//
Pin is LOW
}else{
//
Pin is HIGH
}
//
Continue listening for more interrupts
returntrue;
}
@Override
publicvoid
onGpioError(Gpio
gpio,int
error){
Log.w(TAG,
gpio +":
Error event "+
error);
}
};
(4)当应用程序不再侦听传入的事件,注销任何中断处操作:
- publicclassHomeActivityextendsActivity{
privateGpio
mGpio;
...
@Override
protectedvoid
onStart(){
super.onStart();
//
Begin listening for interrupt events
mGpio.registerGpioCallback(mGpioCallback);
}
@Override
protectedvoid
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()方法,如何设置一个输出最初状态是高电平,然后切换到低电平状态:
publicvoid
configureOutput(Gpio
gpio)throwsIOException{
//
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效果图