上一篇简单的叙述一下Android Things系统的安装和环境配置,在文章最后我们导入了一个模板样例,使用Android Studio进行了编译和下载。环境也搭建好了,应用也都可以正常下载了,那接着就该对树莓派已有的接口和Android Things的功能进一步学习了。
我还是在 new-project-template 这个空白模板里学习GPIO控制的,而没有直接去看官方的GPIO例程,是希望自己可以写几行代码,出错了之后也能明白哪里的问题。
先介绍一下硬件电路连接,开关的一端连接输入引脚GPIO7,另一端连接GND;LED发光二极管正极接GPIO0,负极接GND。(关于树莓派3引脚图可自行搜索)
我们要实现当开关按下之后LED亮,松开开关后LED灭,是嵌入式入门最基础的GPIO操作。
接着看程序,MainActivity继承Activity之后重写了父类的onCreate和onDestroy方法,如果打开调试窗口里的Android Monitor可以看到下载之后启动会打印onCreate方法里的输出提示,我们就在onCreate方法里面处理GPIO读写功能。
在MainActivity中加入两个私有成员变量
private Gpio inputPin; // 输入引脚
private Gpio outputPin; // 输出引脚
把鼠标停留在当前行,按Alt+Enter可导入包含Gpio的包。
在onCreate方法里对这两个引脚进行设置
PeripheralManagerService service = new PeripheralManagerService();
try {
inputPin = service.openGpio("BCM4");
inputPin.setDirection(Gpio.DIRECTION_IN);
inputPin.setActiveType(Gpio.ACTIVE_HIGH);
outputPin = service.openGpio("BCM17");
outputPin.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
}
catch(IOException e) {}
我们需要实例化GPIO处理类PeripheralManagerService,初始化输入引脚打开“BCM4”引脚对应GPIO7(树莓派有几种不同的引脚命名方式),设置引脚为输入,设置引脚悬空时为高电平。初始化输出引脚打开“BCM17”引脚对应GPIO0,设置输出默认为低电平。
检测GPIO可以有轮询和中断两种方式。
我们首先介绍轮询方式,就是不断的读输入IO的电平值。因此我们在onCreate方法里新建一个线程启动之后不断的读输入IO的值,对应的改变输出IO的值来控制LED发光。
(new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) { // 线程中死循环的读inputPin对应IO的值
boolean status = inputPin.getValue();
if (status) {
outputPin.setValue(true); // 如果status为true,我们就设置outputPin为true,则LED亮
}
else {
outputPin.setValue(false);
}
Thread.sleep(5000);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
})).start();
中断方式在Android Things中用监听器来封装,我们对输入引脚设置监听,如果被触发则调用事件回调方法处理我们的逻辑。我们还是在onCreate这个方法里去实现,把上面介绍的建立线程部分注释掉防止冲突,留下输入输出的配置。我们以上升沿和下降沿都触发的事件为例,其他事件分别为
- EDGE_NONE
- EDGE_RISING
- EDGE_FALLING
- EDGE_BOTH
PeripheralManagerService service = new PeripheralManagerService();
try {
inputPin = service.openGpio("BCM4");
inputPin.setDirection(Gpio.DIRECTION_IN);
inputPin.setActiveType(Gpio.ACTIVE_HIGH);
gpioPin.setEdgeTriggerType(Gpio.EDGE_BOTH); // 设置触发事件类型
outputPin = service.openGpio("BCM17");
outputPin.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
SensorCallBack callback = new SensorCallBack();
gpioPin.registerGpioCallback(callback); // 注册我们的回调
}
catch(IOException e) {}
我们在上面设置了事件之后,必须创建一个回调类来处理这个事件的触发,这个回调类必须继承GpioCallback,在MainActivity中最后面加入以下代码
private class SensorCallBack extends GpioCallback {
@Override
public boolean onGpioEdge(Gpio gpio) {
try {
boolean callBackState = gpio.getValue();
if(callBackState) {
outputPin.setValue(false);
}
else {
outputPin.setValue(true);
}
}
catch(IOException ioe) {
ioe.printStackTrace();
}
return true;
}
@Override
public void onGpioError(Gpio gpio, int error) {
super.onGpioError(gpio, error);
}
}
在回调类里有两个父类的方法需要我们重写来实现要处理的行为,一个是IO中断触发,另一个IO异常错误
- public boolean onGpioEdge
- public boolean onGpioError
最后编译下载,按照电路图的接线方法,当按键按下之后灯亮,松开之后灯灭。试试看吧。