# <center>1. LED and Button</center>
<p style="text-align:right">Steven Lee</p>
## Raspberry Pi 3B GPIO 定義

```
sudo git clone https://github.com/WiringPi/WiringPi
```

```
cd WiringPi/
sudo ./build
```

```
gpio readall
```

## 電壓、電流及電阻

* 電壓及電流
* 在現實世界中,⽔的流動稱為⽔流。⽔流的流向與⼤⼩會由⽔位的⾼低差來決定(油⾼處往低處流)。在電⼦的世界中同樣適⽤。
* 電⼦的流動稱為電流,電流的流向與⼤⼩會由電位的⾼低來決定。
* 電位的⾼低差被稱為電壓或電位差,電壓的單為是伏特(Volt,V)。
* 電流的單位為安培(Ampere,A)。
* 電流的⼤⼩與電壓成正比。
* ⼀般我們會以⼤地的電位為0,所以電⼦元件或裝置若標⽰輸出5V,表⽰其輸出的電⼒電位-⼤地電位 = 5V。
* 電⼦元件或裝置也常會以GND或G(Ground的簡稱)來標⽰0電位點(負極)。
* 電阻
* 電阻是物體對於電流通過時的阻礙能⼒,在電壓固定的條件下,電阻值越⾼,代表阻礙能⼒越強,能通過這個物體的電流量就會越⼩,反之電阻值越⼩,可通過的電流愈⼤。
* 低電阻的物體稱為導體,只要在導體兩端加上電位差(電壓),就會讓電流通過導體,⽽電阻值超⾼的物體則稱為絕緣體,可以阻絕電流通過。
* 歐姆定律
* V = I x R
* 電阻除了是阻礙電流能⼒值以外,也是⼀種電⼦元件的名字。 當我們做實驗時,避免電流量過⼤⽽燒壞其中的零件,會額外加上電阻的元件,⽤來阻礙電流進⽽控制電流⼤⼩。
* 為了搭配不同的需求,市⾯上有各種不同的電阻值的電阻可供選擇,⼩型電阻會以⾊環來表⽰其電阻值及誤差值。

* 迴路
* 電⼦零件的連接必須構成迴路才能產⽣作⽤, 所謂的迴路指的是能夠讓電流流通的電路. (由+極出發, 經過電阻R, 最後流回負極(-))
## 麵包線與杜邦線
* 麵包板的正式名稱為免焊萬⽤電路板,俗稱麵包板(bread board)。
* 麵包板不需要焊接,就可以進⾏簡易的電路組裝,⼗分快速⽅便。
* 市⾯上的麵包板有很多種尺⼨,可依需求去購買。
* 麵包板的表⾯有很多的插孔。插孔下⽅有相連的⾦屬夾,當零件的接腳插入麵包板時,實際上是插入⾦屬夾,進⽽和同⼀條⾦屬夾上的其他插孔的零件相通。
* 麵包板(如下圖所⽰),內側每排5個插孔的⾦屬夾片接通,但左右不相通,這個部分⽤於插入電⼦零件。外側插孔則供正負電源使⽤正電接到紅⾊標線處,負電則接到藍⾊或⿊⾊的標線處。

* 杜邦線
* 杜邦線是兩端已經做好接頭的單⼼線,可以很⽅便的⽤來連接麵包板及各種電⼦元件。 (有公⺟、公公、⺟⺟)
* 單⼼線是指電線內部為只有⼀條⾦屬導線所構成的電線。
## GPIO
* GPIO(General-purpose input/output),通⽤型之輸入輸出的簡稱,其接腳可以供使⽤者由程式控制⾃由使⽤,針腳(Pin)依現實考量可作為通⽤輸入(GPI)或通⽤輸出(GPO)或通⽤輸入與輸出(GPIO),是⼀種具有彈性且可以藉由軟體控制 (software-controlled) 的數位訊號。
* 常⾒於開發版以針腳 (Pin) 的形式呈現,這些針腳即是開發版與外界溝通的重要橋樑。簡單來說,你可以想像成是開關,使⽤者可以打開或關閉(input),或由開發版來打開或關閉 (output)。每⼀個 GPIO 可以被當成 input,output,analog 或 alternate function
* Input:是指記憶體⽅接收來⾃設備的訊號源
* Output:是指記憶體傳送訊號給設備
* Alternate function:此時要⽤memory中另外規劃給⽬標設備⽤的register對Pin腳進⾏控制。
## GPIO⽤途
* GPI : input/output的⽅向是對CPU⽽⾔,因此GPI就是從外部給CPU signal。舉例來說,EC(Embedded Controller)控制電源鍵,按下後,EC就將某個GPI拉high,此時CPU收到high後,觸發wakeup source,系統就resume。
* GPO : GPO就是由CPU發出來的。舉例來說,EC控制LED。當系統進入suspend,就把某根接到EC的GPO拉low。EC收到後,就把LED變成橘⾊。
## 實作前須知
### 正極圖示

### 負極圖示

### 訊號輸出圖示

:::danger
### <center>正極最後接</center>
### <center>正極最後接</center>
### <center>正極最後接</center>
:::
## 雙色LED燈


``` python=
import time #匯入時間模組
import RPi.GPIO as GPIO #匯入RPi.GPIO 模組, 使⽤別名 GPIO
GPIO.setwarnings(False) #在執⾏的過程中將所有的警告訊息關閉
GPIO.setmode(GPIO.BOARD) # BCM mode: 為使⽤CPU定義的數字, BORAD: 為使⽤實體(板⼦)上
的數字.
GPIO.setup(3, GPIO.OUT) # 設定板⼦上的第三位腳位為輸出模式
GPIO.setup(5, GPIO.OUT) # 設定板⼦上的第五位腳位為輸出模式
while True:
GPIO.output(3, 1) # 設定板⼦上的第三位腳位輸出⾼電位(3.3V)
GPIO.output(5, 0) # 設定板⼦上的第五位腳位輸出低電位(0V)
time.sleep(0.5)
GPIO.output(3, 0) # 設定板⼦上的第三位腳位輸出低電位
GPIO.output(5, 1) # 設定板⼦上的第五位腳位輸出⾼電位
time.sleep(0.5)
```
* 思考⼀下,在執⾏程式時,LED會有怎樣的⾏為?
## PWM(Pulse Width Modulation,脈波寬度調變)
* 脈波寬度調變訊號是⼀種透過數位的⽅式所產⽣的類比訊號。⼀個脈波寬度調變訊號包含了兩個主要的參數:⼯作週期與頻率。
* ⼯作週期所描述的是訊號中邏輯⾼準位所占的時間與完成⼀個訊號週期的比例。
* ⽽頻率則是表⽰這個脈衝寬度調變訊號能多快完成⼀個周期(舉例來說,1000 Hz的訊號每秒會完成1000個週期),也可以理解為在⾼低狀態之間切換的速率。
* 藉由在⼀定速率的數位訊號⾼低的變化,再配合上特定的⼯作週期,該輸出在供給功率給裝置時則會呈現⼀個固定電壓的類比訊號。
### PWM運作原理
* 舉例來說:利⽤⼀個僅有邏輯準位⾼(1 V)與低(0 V)的數位訊號去產⽣產⽣⼀個0.25伏的訊號,你可以利⽤脈衝寬度調變的⽅式去定義⼀個⼯作週期25%的1 V訊號。若是數位訊號的頻率夠⾼,實際上輸出的訊號電壓則會是⼀個周期內的電壓的平均。若是數位訊號的低準位是0 V,則該平均下來的訊號則可以透過⾼準位的電壓乘上⼯作週期,也就是 <a style="color:red">1 V x 0.25 = 0.25 V</a>。

* LED 燈控制的例⼦
* 週期指的是重複⼀次時所需要的時間,通常以T表⽰,單位為秒(s)
* 頻率通常以f(frequence)表⽰,是週期倒數關係,即f = 單位赫茲(Hz),當頻率為50Hz,代表每⼀秒鐘變化50次,或每⼀秒鐘產⽣50次⽅波。
* ⼯作週期(duty cycle,dc),表⽰在⼀個週期之中,⾼電位持續的時間比例,範圍介於0~100%之間。

```python=
import time
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(3, GPIO.OUT)
GPIO.setup(5, GPIO.OUT)
GPIO.output(3, 0)
GPIO.output(5, 1)
p1 = GPIO.PWM(3,1000) #設定頻率為1000Hz
p2 = GPIO.PWM(5,10) #設定頻率為10Hz
while True:
for dc in range(5, 101, 5): #dc: duty cycle
p1.start(dc)
#p2.start(dc)
time.sleep(0.2)
```
* 思考⼀下,在執⾏程式時,LED會有怎樣的⾏為?
* 思考⼀下,⽣活周遭的例⼦
* 風扇,⾺達,⾳響
## LED 呼吸例⼦
```
課堂提供- 請各位同學實作看看
```
## RGB三色燈模組
* 請各位同學實作看看
* 請根據接腳試著接線, 並且依序控制rgb燈
* 試著利⽤rgb燈做混⾊燈控制
## 輕觸按鍵模組
### 瞬時按鈕開發
按鈕有很多種分類⽅式,其中⼀種⽅式是跟據連通或斷開的時機⽽分成兩類,分別是⾃持按鈕 (Maintained buttons) 與瞬時按鈕 (Momentary buttons)。
⾃持按鈕就是電源開關,當我們打開教室燈的電源開關,即使⼿已經離開電源開關,燈也不會因為失去電源⽽關閉。同樣的情況當我們關閉電源開關時,只要再次按下電源開關,燈就不會再亮直到有⼈再次打開電源。也就是說,當我們改變⾃持按鈕的狀態後,按鈕就會⼀直維持在同⼀個狀態,直到有⼈再次改變它。
### 在哪可以看見瞬時按鈕呢?
例如傳統電話鍵盤上的每⼀個按鍵都可以看作是⼀個瞬時按鈕。當你按下 1 這個按鍵時,話機接收到電路開通的訊號並打出 1 這個數字。⽽當你放開按鍵後,這個按鍵的電路就被斷開了。不過這裡有⼀個問題,那就是如果⼀直按著 1 按鍵,這時候話機要怎麼處理?從電路的⾓度來看,只要⼀直按著 1 按鍵,就表⽰電路⼀直在開通的狀態,所以電腦會不斷地輸出 1 這個字⺟嗎?如果你⼀直按著 1 按鍵不放,通常這個情形會由軟體來控制,會比較有彈性。
針對這個問題,還有另外⼀個選擇,就是不要管⼀直按著這件事。也就是說,不管按了多久,都只算按了⼀次,系統也只會有⼀次的反應。以鍵盤的例⼦來說,就是不管你按了 1 按鍵多久,螢幕上都只會打出⼀個 1 數字。這樣做雖然通常可以減化軟體的處理,但是在很多時候可能對使⽤者操作⽽⾔就不是那麼⽅便了。為什麼前⾯的句⼦是說 “通常” ?是的,因為⼀般按鈕還有⼀種稱為回彈 (bounce) 的現象。所謂的回彈,簡單來說就是當我們按下按鈕時,對電路⽽⾔並不是⾺上就由斷開變成連通的狀態,按鈕的接觸點會有⼀些反彈跳動的情況,所以造成電路也處於⼀種不穩定的狀態。當然,這個跳動的時間很短暫,但是如果沒有好好地加以處理,仍有可能造成程式的誤判。


以圖中的⽅向來看,即使未按下按鈕,上⾯兩隻接腳仍處於閉路的狀態。同樣的,下⾯兩隻接腳也處於閉路的狀態。但是左右兩邊卻是開路的,只有⽽當按鈕按下時,左右兩邊才會形成閉路

當按鈕沒按下時,因為接腳已經接到5V,所以讀到的值會是1,當按鈕按下時,形成迴路,接到GND,所以讀到的值會是0。[這主要看電路的設計]


```python=
import time
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.IN)
GPIO.add_event_detect(12, GPIO.FALLING)
while True:
'''
if GPIO.input(12) == 0:
print("status is 0")
else:
print("status is 1")
'''
if GPIO.input(12) == 1:
print("off")
if GPIO.event_detected(12):
print("button pressed-on")
time.sleep(0.5)
```
## 請試著實作利用按鈕控制LED燈
## 課外補充
* 感測器的基本組成元件
* 感測模組
* 轉換模組
* 通訊模組
* Raspberry 3B、3B+或 4B 主板上有兩個 LED,⼀個紅⾊⼀個綠⾊,紅⾊ LED 突然熄滅但系統還是在正常運作
* 電⼒不⾜
###### tags: `物聯網`