Android Things Tutorial(十一)GPIO輸入 - 開關 by Michael | CodeData
top

Android Things Tutorial(十一)GPIO輸入 - 開關

分享:

Android Things Tutorial(十)GPIO輸出 – 繼電器模組 << 前情

嵌入式系統應用程式經常需要讀取各種零件與設備輸出的資訊,例如在各種電器設備常見的開關,這些開關可以執行開啟電源、調整音量或其它各種操作。讀取人體紅外線感應器的資訊,在偵測到人體活動的時候,執行開啟照明電燈或照相的工作。

認識開關零件

開關是一種應用很多的零件,例如行動電話的電源與音量,電器設備的電源與控制,都會使用各種不同規格與尺寸的開關零件。開關零件有非常多不同規格,包含尺寸、針腳、交流電或直流電,不過運作的原理大致上都差不多,都是用來控制電流是否可以通過。這是幾種常見的直流電開關零件,分別有2、4與6個針腳:

att_11_01

一種常見的開關零件是「Tactile push siwtch」,通常稱為輕觸開關或微動開關,下列圖形為了方便說明針腳的功能,為它們編製1到4的號碼。1、3和2、4永遠保持連接的狀態,在沒有按下開關的時候,1和2號針腳,還有3和4號針腳都沒有連接:

att_11_02

按下開關的時候,1和2號針腳,還有3和4號針腳就會連接。一般的應用使用1、2或3、4號針腳就可以了:

att_11_03

使用LED測試開關零件

在開始撰寫GPIO輸入的應用程式之前,可以先使用一個簡單的線路來認識開關零件。執行接下來的工作之前,先準備好這些設備與零件:

  • 麵包板
  • LED
  • 電阻、220 Ohm
  • Tactile push siwtch、輕觸開關、4個針腳
  • 公-母杜邦線 X 2
  • 麵包板連接線(公-公杜邦線)X 2

這種4個針腳的開關零件可以很容易插在麵包板上,建議你插在麵包板的中央分隔線上,這樣會比較容易連接其它線路。依照下列的線路圖連接所有的設備與零件:

att_11_04

在沒有按下開關的時候,開關的1和2號針腳沒有連接,電流不會通過,所以LED不會點亮。按下開關以後,開關的1和2號針腳就會連接,電流通過開關、電阻和LED,所以就會點亮LED。以這個應用來說,改用開關零件的3、4,還有對角的1、4與2、3,都可以有同樣的效果。例如下面這個線路圖的連接方式:

att_11_05

GPIO輸入方式

連接到GPIO輸入針腳的線路連接方式,分為「Pull Down Resistor」與「Pull Up Resistor」兩種。以使用GPIO讀取開關訊號的應用來說,下面的圖形採用Pull Down Resistor連接方式。開關的兩個針腳連接GPIO的3.3V與接地,並且在接地連接可以保護Raspberry Pi的10K Ohm電阻。再從接地的線路連接到針腳編號12號,並連接1K Ohm電阻。在沒有按下開關的時候,針腳編號12號接收到低電壓(0V)的訊號:

att_11_06

按下開關以後,針腳編號12號接收到高電壓(3.3V)的訊號:

att_11_07

下面的圖形採用Pull Up Resistor連接方式,開關的兩個針腳連接GPIO的3.3V與接地,在3.3V連接可以保護Raspberry Pi的10K Ohm電阻。從3.3V的線路連接到針腳編號12號,並連接1K Ohm電阻。在沒有按下開關的時候,針腳編號12號接收到高電壓(3.3V)的訊號:

att_11_08

按下開關以後,針腳編號12號接收到低電壓(0V)的訊號:

att_11_09

依照嵌入式系統的需求,可以選擇Pull Down Resistor或Pull Up Resistor連接方式,這樣可以讓系統的運作比較穩定。

設計讀取GPIO的App – Pull Down Resistor

應用程式把GPIO設定為輸入用途的時候,偵測輸入的電壓小於0.8V為低電壓,大於2.0V為高電壓。現在準備採用Pull Down Resistor連接方式,撰寫一個測試開關的應用程式。執行接下來的工作之前,先準備好這些設備與零件:

  • 麵包板
  • 電阻、10K Ohm
  • 電阻、1K Ohm
  • Tactile push siwtch、輕觸開關、四個針腳
  • 公-母杜邦線 X 3
  • 麵包板連接線(公-公杜邦線)X 2

參考下列的線路圖連接所有的零件與線路:

att_11_10

參考下面的程式碼,完成使用GPIO偵測開關的應用程式:

package net.macdidi5.at.hellobutton;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.things.pio.Gpio;
import com.google.android.things.pio.GpioCallback;
import com.google.android.things.pio.PeripheralManagerService;

import java.io.IOException;

public class MainActivity extends Activity {

    private static final String TAG = MainActivity.class.getSimpleName();

    // 連接開關的GPIO物件
    private Gpio buttonGpio;
    // 連接開關的GPIO pin
    private final String PIN_NAME = "BCM23";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate");

        // 建立設備管理員服物物件
        PeripheralManagerService service = new PeripheralManagerService();

        try {
            // 建立GPIO物件
            buttonGpio = service.openGpio(PIN_NAME);
            // 設定GPIO為輸入模式
            buttonGpio.setDirection(Gpio.DIRECTION_IN);
            // 設定GPIO的監聽狀態
            //    Gpio.EDGE_NONE:    不作用
            //    Gpio.EDGE_FALLING: 由高電壓變化為低電壓
            //    Gpio.EDGE_RISING:  由低電壓變化為高電壓
            //    Gpio.EDGE_BOTH:    高、低電壓變化
            buttonGpio.setEdgeTriggerType(Gpio.EDGE_BOTH);
            // 設定GPIO的作用模式
            //    Gpio.ACTIVE_HIGH: 偵測到高電壓時傳回true,低電壓傳回false
            //    Gpio.ACTIVE_LOW:  偵測到高電壓時傳回false,低電壓傳回true
            buttonGpio.setActiveType(Gpio.ACTIVE_HIGH);

            // 註冊GPIO監聽物件
            buttonGpio.registerGpioCallback(new GpioCallback() {
                @Override
                public boolean onGpioEdge(Gpio gpio) {
                    try {
                        // 顯示GPIO狀態
                        Log.i(TAG, "Button: " + gpio.getValue());
                    }
                    catch (IOException e) {
                        Log.e(TAG, e.toString());
                    }

                    return true;
                }
            });
        }
        catch (IOException e) {
            Log.e(TAG, e.toString());
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy");

        if (buttonGpio != null) {
            try {
                // 關閉GPIO物件
                buttonGpio.close();
            }
            catch (IOException e) {
                Log.e(TAG, e.toString());
            }
            finally {
                buttonGpio = null;
            }
        }
    }

}

執行應用程式,按下開關的時候,logcat會顯示「Button: true」,放開開關的時候會顯示「Button: false」。

設計讀取GPIO的App – Pull Up Resistor

接下來使用同樣的零件,參考下面的線路圖,把它改為使用Pull Up Resistor的作法:

att_11_11

如果執行上面的應用程式,測試的時候會得到相反的結果,按下開關的時候,logcat會顯示「Button: false」,放開開關的時候會顯示「Button: true」。

你可以參考下面的程式片段修改GPIO的設定:

buttonGpio.setActiveType(Gpio.ACTIVE_LOW);

執行應用程式,按下開關的時候,logcat會顯示「Button: true」,放開開關的時候會顯示「Button: false」。

你可以依照硬體線路的設計,選擇Pull Up Resistor或Pull Down Resistor的線路連接方式,應用程式的部份也可以透過「setActiveType」方法的設定,選擇適合的模式,這樣就可以提供非常靈活的設計。

比較簡易的線路

在需要連接開關的時候,你可能會在網路的資源或書籍,看到這種比較簡單的Pull Down Resister連接方式,把3.3V連接到開關的針腳後,再把GPIO輸入針腳連接到開關的另一個針腳,按下開關的時後讓3.3V傳送到指定的輸入針腳:

att_11_12

使用這種比較簡化的連接方式,在長時間運作或是連接的零件與設備比較多的時候,系統的穩定性就會比較差。在應用程式的測試階段,可以稍微偷懶一些,不過在製作正式的產品時,就不要採用這種簡化的作法。

下一步

認識基本的GPIO輸入應用以後,就可以繼續認識許多輸出訊號的零件與模組,接下來使用一般防盜系統常用的磁簧開關模組,設計偵測模組訊號的應用程式。

相關的檔案都可以在GitHub瀏覽與下載。

https://github.com/macdidi5/Android-Things-Tutorial

後續 >> Android Things Tutorial(十二)GPIO輸入 – 迷你磁簧開關模組

分享:
按讚!加入 CodeData Facebook 粉絲群

留言

留言請先。還沒帳號註冊也可以使用FacebookGoogle+登錄留言

關於作者

張益裕。目前的工作是講師與作者,專長是教育訓練課程規劃、教材編製與課程推廣,技術書籍與專欄寫作。涵蓋的領域有OOAD、Java程式設計、JavaFX、Java Embedded、Android與SQL。已出版電子書Google Play圖書Pubu

熱門論壇文章

熱門技術文章