2011年8月17日 星期三

Android IOIO Digital I/O 篇(上) -- Digital Output

數位輸入和輸出是數位硬體系統的基本建構區塊,這就是經常所聽到的GPIO。
一個 logic-level 信號有兩種狀態:LOW 和 HIGH,分別為 0 和 1 也可以用 false 和 true 來表示。
每個Android IOIO接腳功能可以是 Digital Input 或 Digital Output 這取決於軟體寫作方式。

本單元分為上下兩篇為IOIO入門基礎,本篇為上篇主要介紹Digital Output部分,Digital Output是預設的操作方式,此時:
當每個腳位為 LOW 狀態時電壓將降至 0V (接地);
當每個腳位為 HIGH 狀態時會輸出電壓3.3V。

比較特別的地方是當需要驅動5V電路時,某些腳位[註1]在程式中我們只要定義為open-drain mode便可以當成"open-drain"功能,
所謂open-drain mode當:
腳位為 LOW 狀態時電壓將降至 0V (接地);
腳位為 HIGH 狀態時為高阻抗(斷路)。

關於"open-drain"有興趣的可以去翻一下塵封已久的電子學應該可以找到比較詳細的資料。
使用open-drain mode要注意,不建議使用混和電壓;例如如接腳1為5V及接腳2為3.3V兩電壓共用在同一電路上,
此時當腳位同時為 LOW 接地狀態時3.3V及5V電路的接地可能產生巨額洩漏電流會流向接腳會造成IOIO損壞或者損壞對方電路上的零件。

另外,為保護IOIO流入20mA以上過大電流,最好在接電壓的中間串一個限流電阻,該電阻在3.3V時建議值為150Ω以上。

實作:
在實作Digital Output建議先執行過HelloIOIO,然後以相同的方法執行HelloIOIOPower,
首先到 http://codaset.com/ytai/ioio/wiki/Downloads 下載Demo程式,例如:App-IOIO0301.zip 然後解開該檔案,在applications目錄中就可以看到HelloIOIOPower專案。
從這這隻程式在手機上執行時未接到IOIO會顯示 "Waiting for IOIO to connect..." ,當IOIO接到手機時則會顯示 "IOIO connected!"。
所以在這支程式中我們可以學習到如何判斷IOIO有沒有接到手機。

不過這篇的重點是Digital Output,在程式第 100 行可以看到:

DigitalOutput led = ioio_.openDigitalOutput(0, true);

這表示 Pin0 定義成 led 然後預設是High電位,不過是不是在IOIO上沒看到 Pin0呢?
此時的Pin0指的是IOIO正中央start的那個LED,因為Pin0只能做這個功能所以這行程式寫成下列方式同樣可以執行:

DigitalOutput led = ioio.openDigitalOutput(IOIO.LED_PIN, true);

由此可知,在括號中代表的意思是 (pinNum, startValue)
pinNum:代表IOIO接腳 ( 0~48;0=start LED)
startValue代表程式執行時預設值(true or false),這個起始預設值可有可無。

然後可以接著看到程式中第 102 行:

led.write(!button_.isChecked());

這行代表當偵測到按下button後,寫入false然後你會看到LED會亮起來,反之則熄滅。
因此,如果要設定一個接腳一般的寫法是:
led.write(false); --> 為LOW,接地(0V)
out.write(true); --> 為High,高電位(+3.3V)

所以如果將程式中 0 這個數字改成 1~48時,當執行程式的時候你可以拿三用電表去測量接腳的電壓變化,將會看到 0V(false) or 3.3V(true)的變化。

接下來open-drain mode要怎樣做呢?
要使用open-drain mode只要將:

DigitalOutput led = ioio_.openDigitalOutput (pinNum, startValue) ;

改成:

DigitalOutput out = ioio.openDigitalOutput(pinNum, DigitalOutput.Spec.Mode.OPEN_DRAIN, startValue);

從上面看來差別在 DigitalOutput.Spec.Mode.OPEN_DRAIN 這個部分,此時再次拿三用電表去測量接腳的電壓變化,可以看到???
這部分就賣個關子,由實驗者自行找答案了............

以下是我使用 Digital Output 做幾個LED Demo:
1. LED開關
電路圖如下:

程式執行畫面如下:

執行結果:
video

2.七段顯示器執行結果:(由於輸出電壓只有3.3V如接限流電阻會比較暗,這部分我並沒有使用限流電阻)
video

3.時鐘: (這部分電路使用掃描方式來顯示時間,在程式還有很大空間可以修改因為執行結果會閃爍)
video

註1:
欲使用open-drain模式,請參照接腳表中5V欄位有打勾的才有支援,查詢IOIO接腳表網址:
https://github.com/ytai/ioio/wiki/Getting-To-Know-The-Board
上述網址中的下半部找到: Detailed Pin Function Table

參考:
Wiki: 'Digital I/O' for ytai's IOIO
https://github.com/ytai/ioio/wiki/Digital-IO

12 則留言:

  1. 很好的技術文章,推一下。
    買了幾個IOIO,剛開始玩,希望能找到同好。

    回覆刪除
  2. 你好 我想請問一個問題
    我還是ANDROID的新手,我想讓手機在有電話撥入時,
    可透過IOIO的DIGITAL OUTPUT讓外接的東西響,
    我已經找到手機的撥接程式和這篇文章都各自成功過,
    但如何讓他們結合在一個程式碼中呢?

    回覆刪除
  3. Sorry!近期比較忙些~今天才回覆:
    我的建議你直接改HelloIOIOPower那隻程式,把硬體控制部分及監聽手機電話撥入的程式或服務放在IOIOThread的thread內:
    class IOIOThread extends Thread {
    }
    雖然android手機接上IOIO時有充電的動作不過記得還是要做sleep動作主要原因是降低CPU運算....

    回覆刪除
  4. 老師您好,請問ioio版在台灣要如何取得呢?謝謝您

    回覆刪除
  5. 請問手機中的應用程式是利用什麼方式傳到IOIO Board這塊板子的。是透過哪一個通訊協定?

    回覆刪除
  6. 時鐘: (這部分電路使用掃描方式來顯示時間,在程式還有很大空間可以修改因為執行結果會閃爍) <<<< 把掃描的頻率加快,就不會閃了.但會比較暗,可以調一下限流電限.
    PIN

    回覆刪除
  7. 老師你好想請問arduino due的i/o輸出是3.3v,可是我要驅動5v的繼電器有什麼方法可以使這電壓上升的嗎?


    我使用了TB88-50這個也在網路上找到電路圖,我電感和二極體都沒有用跟他一樣的出來的電壓只有1.5mv怎麼會這樣一定要跟他一樣嗎?(附上我使用的電路圖網址)

    http://tw.myblog.yahoo.com/wukc-soft/article?mid=568

    老師友推薦的IC或是方法請再告訴我謝謝。

    回覆刪除
    回覆
    1. 我的建議,
      1.最省錢的方式就是換掉5V繼電器改用3V繼電器。
      2.用光耦合器將信號隔離,避免電路的干擾,你可以參考下面網頁倒數第七章電路圖。
      比較不會建議用升壓方式來做,一般升壓方式用在同一電路上的Vcc,不建議用在GPIO輸出推電路。

      刪除
    2. 請問,有關於IOIO digital input 的代碼解析嗎?謝謝

      刪除
  8. 請問一下為什麼我設定輸出之後輸出電壓都小於3V?

    回覆刪除
    回覆
    1. 大致兩個情況試試:
      1.檢查一下輸入電壓Vin是否5V,以及3V或5V輸出電壓是否正確。
      2.測試另一塊IOIO,可能這塊有問題。

      刪除