(1) Android Things入門(mén)-環(huán)境搭建
上一篇簡(jiǎn)單的敘述一下Android Things系統(tǒng)的安裝和環(huán)境配置眷蚓,在文章最后我們導(dǎo)入了一個(gè)模板樣例酪刀,使用Android Studio進(jìn)行了編譯和下載。環(huán)境也搭建好了汤纸,應(yīng)用也都可以正常下載了,那接著就該對(duì)樹(shù)莓派已有的接口和Android Things的功能進(jìn)一步學(xué)習(xí)了。
我還是在 new-project-template 這個(gè)空白模板里學(xué)習(xí)GPIO控制的檐嚣,而沒(méi)有直接去看官方的GPIO例程,是希望自己可以寫(xiě)幾行代碼啰扛,出錯(cuò)了之后也能明白哪里的問(wèn)題嚎京。
先介紹一下硬件電路連接,開(kāi)關(guān)的一端連接輸入引腳GPIO7隐解,另一端連接GND挖藏;LED發(fā)光二極管正極接GPIO0,負(fù)極接GND厢漩。(關(guān)于樹(shù)莓派3引腳圖可自行搜索)
我們要實(shí)現(xiàn)當(dāng)開(kāi)關(guān)按下之后LED亮膜眠,松開(kāi)開(kāi)關(guān)后LED滅,是嵌入式入門(mén)最基礎(chǔ)的GPIO操作。
接著看程序宵膨,MainActivity繼承Activity之后重寫(xiě)了父類的onCreate和onDestroy方法架谎,如果打開(kāi)調(diào)試窗口里的Android Monitor可以看到下載之后啟動(dòng)會(huì)打印onCreate方法里的輸出提示,我們就在onCreate方法里面處理GPIO讀寫(xiě)功能辟躏。
在MainActivity中加入兩個(gè)私有成員變量
private Gpio inputPin; // 輸入引腳
private Gpio outputPin; // 輸出引腳
把鼠標(biāo)停留在當(dāng)前行谷扣,按Alt+Enter可導(dǎo)入包含Gpio的包。
在onCreate方法里對(duì)這兩個(gè)引腳進(jìn)行設(shè)置
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) {}
我們需要實(shí)例化GPIO處理類PeripheralManagerService捎琐,初始化輸入引腳打開(kāi)“BCM4”引腳對(duì)應(yīng)GPIO7(樹(shù)莓派有幾種不同的引腳命名方式)会涎,設(shè)置引腳為輸入,設(shè)置引腳懸空時(shí)為高電平瑞凑。初始化輸出引腳打開(kāi)“BCM17”引腳對(duì)應(yīng)GPIO0末秃,設(shè)置輸出默認(rèn)為低電平。
檢測(cè)GPIO可以有輪詢和中斷兩種方式籽御。
我們首先介紹輪詢方式练慕,就是不斷的讀輸入IO的電平值。因此我們?cè)趏nCreate方法里新建一個(gè)線程啟動(dòng)之后不斷的讀輸入IO的值技掏,對(duì)應(yīng)的改變輸出IO的值來(lái)控制LED發(fā)光铃将。
(new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) { // 線程中死循環(huán)的讀inputPin對(duì)應(yīng)IO的值
boolean status = inputPin.getValue();
if (status) {
outputPin.setValue(true); // 如果status為true,我們就設(shè)置outputPin為true哑梳,則LED亮
}
else {
outputPin.setValue(false);
}
Thread.sleep(5000);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
})).start();
中斷方式在Android Things中用監(jiān)聽(tīng)器來(lái)封裝劲阎,我們對(duì)輸入引腳設(shè)置監(jiān)聽(tīng),如果被觸發(fā)則調(diào)用事件回調(diào)方法處理我們的邏輯鸠真。我們還是在onCreate這個(gè)方法里去實(shí)現(xiàn)哪工,把上面介紹的建立線程部分注釋掉防止沖突,留下輸入輸出的配置弧哎。我們以上升沿和下降沿都觸發(fā)的事件為例雁比,其他事件分別為
- 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); // 設(shè)置觸發(fā)事件類型
outputPin = service.openGpio("BCM17");
outputPin.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
SensorCallBack callback = new SensorCallBack();
gpioPin.registerGpioCallback(callback); // 注冊(cè)我們的回調(diào)
}
catch(IOException e) {}
我們?cè)谏厦嬖O(shè)置了事件之后,必須創(chuàng)建一個(gè)回調(diào)類來(lái)處理這個(gè)事件的觸發(fā)撤嫩,這個(gè)回調(diào)類必須繼承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);
}
}
在回調(diào)類里有兩個(gè)父類的方法需要我們重寫(xiě)來(lái)實(shí)現(xiàn)要處理的行為,一個(gè)是IO中斷觸發(fā)序攘,另一個(gè)IO異常錯(cuò)誤
- public boolean onGpioEdge
- public boolean onGpioError
最后編譯下載茴她,按照電路圖的接線方法,當(dāng)按鍵按下之后燈亮程奠,松開(kāi)之后燈滅丈牢。試試看吧。