Android Things 具有独特的功能,可通过外设 API 和内置设备支持轻松连接到外部电子组件。在本文中,您将了解可以连接到的不同类型的外围设备,以便使用 Android Things 自定义您的物联网设备。
Android Things 允许大多数设备通过使用 Peripheral API 连接到原型板,该 Peripheral API 支持 GPIO、PWM、I2C、SPI 和 UART 接口,每个接口都是用于与外设通信的行业标准接口。在本节中,您将了解这些接口是什么,以及如何使用这些连接与已连接到 Android Things 原型板的设备进行通信。
通用输入/输出(GPIO)引脚用于与组件进行数字(二进制)通信,例如读取按钮是否被按下,或者打开或关闭 LED。在本教程中将会看到的 I/O 方法中,最简单的方法是使用 GPIO,只需要一个引脚,并将布尔值用于高或低状态。
在连接到 GPIO引脚之前,您需要知道该引脚的唯一名称。您可以通过检索 PeripheralManagerService
并调用 getGpioList()
来获取所有可用引脚的名称。在 Raspberry Pi 上,将返回以下列表:
[BCM12,BCM13,BCM16,BCM17,BCM18,BCM19,BCM20,BCM21,BCM22,BCM23,BCM24,BCM25,BCM26,BCM27,BCM4,BCM5,BCM6]
要弄清楚这些代表哪个引脚,可以参考 Raspberry Pi I/O 图。
一旦获得了将要读取或写入的引脚名称,就可以通过调用 PeripheralManagerService
中的 openGpio(String pin_name)
来获取该引脚的 Gpio
对象引用。
try {
mGpio = service.openGpio(PIN_NAME);
} catch (IOException e){
}
GPIO 引脚可用于输入或输出。如果您将使用该引脚来读取信息,则需要将引脚方向配置为 DIRECTION_IN
,并设置该引脚的触发类型,以便知道何时让应用程序知道发生了某些事情。
mGpio.setDirection(Gpio.DIRECTION_IN);
mGpio.setEdgeTriggerType(Gpio.EDGE_BOTH);
触发器类型由 EDGE_NONE
,EDGE_RISING
,EDGE_FALLING
和 EDGE_BOTH
组成。如果按下按钮,则在按钮电路完成且物理引脚上出现高电压信号时发生上升事件。当按钮被释放时发生下降事件。 您的代码将根据您设置的触发类型被通知更改。
现在您的 GPIO
正在侦听边缘触发器,您将需要创建一个 GpioCallback
来在您的应用程序中,注册 GPIO
组件的值。
private GpioCallback mCallback = new GpioCallback() {
@Override
public boolean onGpioEdge(Gpio gpio) {
try {
Log.d("Tuts+", "GPIO value: " + gpio.getValue());
} catch( IOException e ) {
}
return super.onGpioEdge(gpio);
}
@Override
public void onGpioError(Gpio gpio, int error) {
super.onGpioError(gpio, error);
}
};
一旦你的回调被创建,注册它与您的 Gpio
对象。
mGpio.registerGpioCallback(mCallback);
如果您的 GPIO
引脚正在写入信息,则需要将方向设置为 DIRECTION_OUT_INITIALLY_LOW
或 DIRECTION_OUT_INITIALLY_HIGH
,具体取决于您希望组件是开启还是关闭。输出引脚不需要触发器类型。
mGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
为了写入设备,您可以调用 Gpio
对象上的 setValue(boolean)
来设置组件的状态。
mGpio.setValue(true);
一旦您的应用程序运行完毕,您将需要取消注册您的输入回调,如果它已被创建和注册,并使用 onDestroy()
中的 close()
方法关闭对外设的访问。
脉宽调制(PWM)设备,使用称为比例控制信号的数字状态的交替来发生作用。比例控制信号有三个主要部分需要注意:
通过调整信号的占空比,可以控制波形的平均 “开启” 时间。下面你可以看到一个 50% 周期信号的例子。
一些可以使用 PWM 信号的设备,包括使用频率来确定其位置的伺服电机,或者可以使用 PWM 信号来调节亮度的 LED 矩阵。
即使只有电机和 GPIO 设备,也可以创建大量的物联网设备,例如带电动激光的 “智能” 猫树。
与GPIO类似,您可以通过创建 PeripheralManagerService
并调用 getPwmList()
来检索可用的PWM端口列表。在 Raspberry Pi
上,这个列表将如下所示:
[PWM0, PWM1]
一旦知道了要使用的 PWM
引脚的名称,就可以使用 openPwm(String)
方法打开与该外设的连接。它需要包装在 try/catch
块中,以处理抛出 IOException
的可能性。
try {
mPwm = service.openPwm(PIN_NAME);
} catch( IOException e ) {
}
一旦打开了与 PWM 引脚的连接,就可以控制其上的设置,例如频率和占空比。
mPwm.setPwmFrequencyHz(120);
mPwm.setPwmDutyCycle(25);
mPwm.setEnabled(true);
在完成应用程序并销毁 Activity
之前,您需要关闭连接并释放 PWM
设备的引用。
@Override
protected void onDestroy() {
super.onDestroy();
if( mPwm != null ) {
try {
mPwm.close();
mPwm = null;
} catch( IOException e ) {
}
}
}
内部集成电路(I2C)总线,允许您的项目通过一个物理连接与多个设备进行通信,并允许您仅通过 Raspberry Pi 或其他嵌入式设备的几个引脚发送复杂的数据。I2C 使用设备之间的同步通信,并依靠时钟信号确保设备在适当的时间响应。
发出时钟信号的设备(通常是您的 Android Things 设备)被称为主设备,所有接收该信号的外设都称为从设备。
与仅需要单个引脚的 PWM 和 GPIO 不同,I2C 器件需要三个连接:
值得注意的是,每个 I2C 从设备都使用设置的地址进行编程,并且只有当主设备对该特定地址发出数据请求时才会响应。
一些可以使用这种连接方法的外围设备,包括分段式 LED 矩阵显示器和各种先进的传感器。
每个 Android Things 设备将有一组用于 I2C 的引脚,您可以通过查看特定原型板的文档来找到这些引脚。对于 Raspberry Pi,可以参考本文顶部的引脚分配图,其中指出 SDA 和 SDL 是引脚 3 和 5。要查找 I2C 的名称,可以运行以下代码:
PeripheralManagerService manager = new PeripheralManagerService();
List<string> deviceList = manager.getI2cBusList();
if( !deviceList.isEmpty() ) {
Log.d( "Tuts+", deviceList.toString() );
}
上面的代码片段将在 Raspberry Pi 上输出以下内容:
[I2C1]
一旦知道了 I2C 总线的名称,就可以使用其软件地址连接到该总线上的设备。您可以在外围设备组件的 “数据表” 中,找到软件地址和其他低级连接详细信息 - 如果要为嵌入式项目使用外设,则需要阅读!
private I2cDevice mDevice;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
PeripheralManagerService manager = new PeripheralManagerService();
mDevice = manager.openI2cDevice(I2C_DEVICE_NAME, I2C_ADDRESS);
} catch (IOException e) {}
}
通过I2C与设备进行通信时,可以使用系统管理总线(SMBus)协议将数据放入寄存器中,或者检索已保存在每个外围设备寄存器中的数据。 这是使用设备地址和寄存器地址完成的,Android Things 允许您使用以下方法从寄存器读取或写入多个寄存器中的字节组:
readRegByte()
和 writeRegByte()
:从特定的寄存器读取或写入一个字节。readRegWord()
和 writeRegWord()
:以小尾数格式从外设上的两个连续寄存器读取或写入字节。readRegBuffer()
和 writeRegBuffer()
:读取或写入多达 32 个连续寄存器的字节。 值被写入或检索为一个字节数组(byte array
)。public void singleByte(I2cDevice device, int address) throws IOException {
// Read one register from slave
byte value = device.readRegByte(address);
// Write the value back to slave
device.writeRegByte(address, value);
}
public byte[] multipleBytes(I2cDevice device, int startAddress) throws IOException {
// Read three consecutive register values
byte[] data = new byte[3];
device.readRegBuffer(startAddress, data, data.length);
return data;
}
当您的应用准备关闭 Android Things 设备时,请务必注销您的 I2C 总线。
@Override
protected void onDestroy() {
super.onDestroy();
if (mDevice != null) {
try {
mDevice.close();
mDevice = null;
} catch (IOException e) {}
}
}
原文链接:https://code.tutsplus.com/tutorials/android-things-peripheral-inputoutput--cms-27891
观光\评论区