外围I/O接口
Android Things提供外围I/O接口APIs 使用工业标准协议和接口来与传感器和驱动器进行交互。
- 通用输入输出(GPIO:General Purpose Input/Output):使用这些API来与一些简单的传感器交互,比如运动检测器,距离检测器以及开关等,这些可以使用二进制数值来报告它们当前的状态–高或者低。
- 脉宽调制信号(PWM:Pulse Width Modulation):使用这些API来与那些需要成比例的信号来提供对输出的细粒度控制,比如伺服机(servo motors),直流电动机(DC motors)以及灯。
- 串行通信(Serial Communication):使用这些API在连接在同一个本地总线上的两个或者多个智能设备之间传输更大负荷的数据。下面的表格列出了所支持的串行协议的基本属性:
协议名称 | 传输类型 | 线缆数 | 外设数量 | 传输速度 |
---|---|---|---|---|
I2C | 同步 | 2 | 最大127 | 速度较低 |
SPI | 同步 | 4+ | 无限 | 速度最高 |
UART | 异步 | 2或者4 | 1 | 速度中等 |
GPIO
通用输入输出(GPIO)针脚提供了一个可编程的接口来读取一个二进制输入设备的状态(比如一个按钮开关)或者控制二进制输出设备的打开或者关闭状态(比如一个LED灯)。
你可以配置具有高或低状态的 GPIO针脚作为输入或者输出。如果作为一个输入,一个外部源决定它的状态,并且你的app可以读取当前值或者对状态的变化作出反应。如果作为一个输出,你的app可以配置针脚的状态。
注意:为避免损坏GPIO针脚,进行电线连接之前务必查看你的硬件的输入和输出的范围。
管理连接
为了打开一个到GPIO端口的连接,你应该知道唯一的端口名。在开发的初期阶段,或者当连接一个app到一个新设备时,通过 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);
}
}
}
}
读取输入
读取一个GPIO端口作为输入:
1. 使用 setDirection() 的 DIRECTION_IN 参数配置一个端口作为输入端口。
2. 通过使用ACTIVE_HIGH或者ACTIVE_LOW调用setActiveType() 方法配置返回为true时是高电压还是低电压信号。
3. 通过调用getValue()方法访问当前的状态。
下面的代码向你展示了如何将高电压信号与一个输入返回true值关联起来。
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
}
}
监听输入的状态变化
一个被配置为输入的GPIO端口可以当它的状态在高和低之间变化时通知你的app。你只需要注册这些变更事件的监听器即可:
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 (mDevice.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.当你的app不再需要监听传入的事件时,应该取消注册任何中断处理器。
public class HomeActivity extends Activity {
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);
}
}
写输出端口
以编程方式控制GPIO端口的状态:
1. 使用setDirction()方法的DIRECTION_OUT_INITIALLY_HIGH 或者DIRECTION_OUT_INITIALLY_HIGH 模式来配置一个端口作为输出端口。这些方法确保在配置的同时也正确的设置端口的初始状态。
2. 通过使用ACTIVE_HIGH或者ACTIVE_LOW调用setActiveType() 方法配置返回为true时是高电压还是低电压信号。
3. 通过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);
}
原文地址:
https://developer.android.com/things/sdk/pio/gpio.html