何謂輕觸開關
輕觸開關英文為 Tactile[ˋtæktɪl] push switch, 就是按下後會通電, 放開後就斷電. 所以可以在按下開關後, 灌入3.3V電壓, 讓GPIO偵測有電壓進來, 然後觸發GPIO的監聽程式, 進而引發GpioPinDigitalStateChangeEvent 事件, 然後由此事件去執行某項工作.
輕觸開關結構圖
TPS開關的結構圖如下所式, 未按下時, 12未通電, 34也未通電. 按下後12通電, 34也通電.
注意事項
輕觸開關需將GPIO更改為Input, 這就不是開玩笑了. 因為會把3.3V的電壓灌進GPIO之中, 若沒有加入電阻的話, 電流過大, 會造成樹莓派的板子燒毀.
一般建議會在把電流灌進GPIO的針腳前, 加上一顆1KΩ的電阻. 經V=IR計算, 3.3=I*1000, 灌進GPIO針腳的電流I值為 3.3mA, 這就蠻小的了. 反正GPIO是要偵測是否有3.3V的電壓進來, 所以電流越小越好.
另外為了加一層防護措施, 也要加一條線路到GND, 中間也要加入一個10KΩ的電阻, 這是為了Pull Up Resistor 的連接方式
連接方式如下所示
Pull Down Resistor
Pull Up Resistor
那到底要幹什麼
底下程式, 使用二顆輕觸開關, buttonLed按一下點亮Led, 再點一下關掉Led. buttonPower則會關閉整個程式
首先, GPIO0為程式關閉按鈕, GPIO1為Led燈的開關, GPIO2為Led的電源.
GPIO0及GPIO1設定為Input :
gpioController.provisionDigitalInputPin(RaspiPin.GPIO_00, PinPullResistance.PULL_DOWN);
然後二個GPIO 使用 AddListener(GpioPinListenerDigital) 監控按鈕的狀況, 當按鈕為High時, 執行要作的任務
程式結束前, 請使用 removeAllListeners()將監控程式移除
PowerSwitch.java package powerswitch; import com.pi4j.io.gpio.GpioController; import com.pi4j.io.gpio.GpioFactory; import com.pi4j.io.gpio.GpioPinDigitalInput; import com.pi4j.io.gpio.GpioPinDigitalOutput; import com.pi4j.io.gpio.PinPullResistance; import com.pi4j.io.gpio.PinState; import com.pi4j.io.gpio.RaspiPin; import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent; import com.pi4j.io.gpio.event.GpioPinListenerDigital; import java.util.logging.Level; import java.util.logging.Logger; public class PowerSwitch { static Led led1; static boolean closeFlag=false; static boolean busy=false; public static void main(String[] args) { GpioController gpioController=GpioFactory.getInstance(); G.buttonPower=gpioController.provisionDigitalInputPin(RaspiPin.GPIO_00, PinPullResistance.PULL_DOWN); G.buttonLed=gpioController.provisionDigitalInputPin(RaspiPin.GPIO_01, PinPullResistance.PULL_DOWN); G.pinLed=gpioController.provisionDigitalOutputPin(RaspiPin.GPIO_03, "LED", PinState.LOW); G.buttonPower.addListener(new GpioPinListenerDigital(){ @Override public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) { PinState state=event.getState(); if(state.isHigh()){ closeFlag=true; } } }); G.buttonLed.addListener(new GpioPinListenerDigital(){ @Override public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) { if(busy)return; busy=true; PinState state=event.getState(); if(state.isHigh()){ if(led1==null){ led1=new Led(); led1.start(); } else{ led1.close(); led1=null; } } busy=false; } }); while(!closeFlag){ try {Thread.sleep(500);} catch (InterruptedException ex) {} } G.buttonPower.removeAllListeners(); G.buttonLed.removeAllListeners(); if(led1!=null)led1.close(); gpioController.shutdown(); System.out.println("Game over"); } } class Led extends Thread{ private boolean runFlag=true; public void run(){ while(runFlag){ G.pinLed.pulse(500); G.delay(550); } } public void close(){ runFlag=false; G.pinLed.setState(PinState.LOW); this.interrupt(); } } G.java如下 package powerswitch; import com.pi4j.io.gpio.GpioPinDigitalInput; import com.pi4j.io.gpio.GpioPinDigitalOutput; public class G { public static GpioPinDigitalInput buttonPower, buttonLed; public static GpioPinDigitalOutput pinLed; public static void delay(int t){ try {Thread.sleep(t);} catch (InterruptedException ex) {} } }