221
1 Raspberry Pi 遊戲機工作坊 - GPIO 開始和世界連接 台灣樹莓派 <[email protected]>

用Raspberry Pi學GPIO - 自己做遊戲機

Embed Size (px)

Citation preview

Page 1: 用Raspberry Pi學GPIO - 自己做遊戲機

1

Raspberry Pi 遊戲機工作坊- 從 GPIO 開始和世界連接

台灣樹莓派 <[email protected]>

Page 2: 用Raspberry Pi學GPIO - 自己做遊戲機

姓名標示 — 非商業性 — 相同方式分享

CC (Creative Commons)

姓名標示 — 你必須給予 適當表彰、提供指向本授權條款的連結,以及 指出(本作品的原始版本)是否已被變更。你可以任何合理方式為前述表彰,但不得以任何方式暗示授權人為你或你的使用方式背書。

非商業性 — 你不得將本素材進行商業目的之使用。

相同方式分享 — 若你重混、轉換本素材,或依本素材建立新素材,你必須依本素材的授權條款來散布你的貢獻物。

Page 3: 用Raspberry Pi學GPIO - 自己做遊戲機

3

● Element14指定台灣地區 Raspberry Pi獨家經銷商

about 台灣樹莓派

http://farnell.com/raspberrypi-consumer/approved-retailers.php?region=apac&MER=MER-LM-OB-RPICC-76315

Page 4: 用Raspberry Pi學GPIO - 自己做遊戲機

● 專注於 Raspberry Pi 應用與推廣

● 舉辦社群聚會 / 工作坊 / 讀書會 /黑客松

● Website :● https://www.raspberrypi.com.tw/

● Facebook : ● 搜尋 RaspberryPi.Taiwan● https://www.facebook.com/RaspberryPi.Taiwan

about 台灣樹莓派

Page 5: 用Raspberry Pi學GPIO - 自己做遊戲機

5

● COSCUP,MakerConf,PyCon講者

● 投影片

● http://www.slideshare.net/raspberrypi-tw/presentations

● 程式碼

● https://github.com/raspberrypi-tw

分享 x 社群

Page 6: 用Raspberry Pi學GPIO - 自己做遊戲機

6

● Raspberry Pi的 GPIO介紹

● 環境設定● 輸入 /輸出

● 數位 /類比● 練習與實做

本次主題

Page 7: 用Raspberry Pi學GPIO - 自己做遊戲機

7

● 了解電子電路原理● 學習如何根據規格撰寫控制程式● 親手完成遊戲機

目標

Page 8: 用Raspberry Pi學GPIO - 自己做遊戲機

8

● $ sudo apt-get update● $ sudo apt-get install -y python-dev python-pip libsdl1.2-dev x11vnc

● $ sudo pip install spidev evdev

安裝今日所需套件

Page 9: 用Raspberry Pi學GPIO - 自己做遊戲機

9

Raspberry Pi GPIO 介紹

Page 10: 用Raspberry Pi學GPIO - 自己做遊戲機

10

● General Purpose Input Output● GPIO 是一種可用軟體控制的數位訊號

什麼是 GPIO ?

http://www.tek.com/datasheet/tps2000b-series-digital-storage-oscilloscopes-datasheet

Page 11: 用Raspberry Pi學GPIO - 自己做遊戲機

11

● 決定是輸入還是輸出● 輸出:寫值到某根腳位● 輸入:從某根腳位讀值

● 等待中斷 (interrupt) 的發生

● 決定是正緣觸發還是負緣觸發

用軟體控制什麼 ?

Page 12: 用Raspberry Pi學GPIO - 自己做遊戲機

12

GPIO 腳位在哪裡?

http://www.raspberrypi-spy.co.uk/

Pin1 Pin2

Pin25 Pin26

Pin3 Pin4Z

Z 字型的腳位編號

Page 13: 用Raspberry Pi學GPIO - 自己做遊戲機

13

● C● C + wiringPi● C#● Ruby● Perl● Python● Scratch● Java Pi4J Library● Shell script

如何控制 Raspberry Pi 的 GPIO ?

Page 14: 用Raspberry Pi學GPIO - 自己做遊戲機

14

Python + GPIO

Page 15: 用Raspberry Pi學GPIO - 自己做遊戲機

15

● 變數 ,物件 , 型別 ,註解

● 模組● 縮排● 迴圈● 條件判斷● 函式

Python 五分鐘速成

Page 16: 用Raspberry Pi學GPIO - 自己做遊戲機

16

● 動態型別 (dynamic typing)

# 這是註解

i = 3 # 變數 i指到數字物件 3

i = [1, 2, 3, 4, 5] # 變數 i指到串列物件

print i[2] # 印出串列中第三個元素

i = “abcde” # 變數 i指到字串物件

print i[2] # 印出字串中第三個元素

變數 , 物件 , 型別 , 註解

Page 17: 用Raspberry Pi學GPIO - 自己做遊戲機

17

# import MODULE

import RPi.GPIO

# import MODULE as ALIAS

import RPi.GPIO as GPIO

模組

Page 18: 用Raspberry Pi學GPIO - 自己做遊戲機

18

● 用縮排取代大括號● 程式碼的區塊是用縮排分隔

● 不使用 tab, 使用空白鍵

● 常見縮排為 4 個空白鍵

縮排

Page 19: 用Raspberry Pi學GPIO - 自己做遊戲機

19

● 自動迭代 (iterator)

for i in xrange(start, stop[, step]) :

process

for i in xrange(0, 11, 5) :

process

迴圈

Page 20: 用Raspberry Pi學GPIO - 自己做遊戲機

20

if condition_1:

process_1

elif condition_2:

process_2

else :

process_3

process_4

條件判斷

Page 21: 用Raspberry Pi學GPIO - 自己做遊戲機

21

def function_name():

process

def function_name(param_name):

process

def function_name(param_name = 3):

process

函式

Page 22: 用Raspberry Pi學GPIO - 自己做遊戲機

22

● GPIO高電位輸出為 3.3V● GPIO容忍輸入電位為 3.3V● 單一 Pin輸出電流為 3mA,輸出總和小於 50mA● GPIO輸入低電位為小於 0.8V,高電位為大於 1.3V

幾個 GPIO 的數字

https://www.scribd.com/doc/101830961/GPIO-Pads-Control2

Page 23: 用Raspberry Pi學GPIO - 自己做遊戲機

23

● Python + RPi.GPIO = 70 kHz● C + BCM 2835 = 5.4 MHz● Ruby + wiringpi bindings = 21 kHz

GPIO Benchmark

http://www.tek.com/datasheet/tps2000b-series-digital-storage-oscilloscopes-datasheet

Page 24: 用Raspberry Pi學GPIO - 自己做遊戲機

24

電子入門套件

● 紅/黃/綠LED x2

● 1/4W電阻,1Kx5,2Kx5

● 830洞大型麵包板 x1

● 按鍵 x4

● 蜂鳴器 x2

● 人體紅外線感測器(PIR) x1

● 傾斜開關 x1

● MCP3008 ADC IC x1

● 光敏電阻 x1

● XY搖桿 x1

● HC-SR04超音波距離感測器

● 10K可變電阻

● 20pin公對公 / 公對母/母對母排線 x1

Page 25: 用Raspberry Pi學GPIO - 自己做遊戲機

25

本套件相容於全系列 Raspberry Pi

購買套件:https://www.raspberrypi.com.tw/2557/

Page 26: 用Raspberry Pi學GPIO - 自己做遊戲機

26

數位輸出

Page 27: 用Raspberry Pi學GPIO - 自己做遊戲機

27

實驗1:硬體的 Hello World

目的:從硬體到軟體的思維

Page 28: 用Raspberry Pi學GPIO - 自己做遊戲機

28

● 發光二極體● 單向導通● 省電

LED

http://upload.wikimedia.org/wikipedia/commons/c/c8/5mm_Red_LED.jpg

長腳接正極 Vcc短腳接負極GND

Page 29: 用Raspberry Pi學GPIO - 自己做遊戲機

29

● 電路組成元件 :電源、導線、負載

● 閉路 :當三者形成一完整路徑 ,有電流經過電路

● 歐姆定律 :導體兩端的電壓與通過的電流成正比

● V = I x R

電路一分鐘速成

I

I

V RV R

I

https://zh.wikipedia.org/wiki/电路

Page 30: 用Raspberry Pi學GPIO - 自己做遊戲機

30

Raspberry Pi + LED

直接插入嗎 ?

先看看規格吧

Page 31: 用Raspberry Pi學GPIO - 自己做遊戲機

31

● VF:順向電壓

● IF: 在順向電壓下的最大電流

LED 的特性

https://learn.adafruit.com/all-about-leds/forward-voltage-and-kvl

Page 32: 用Raspberry Pi學GPIO - 自己做遊戲機

32

● 在順向電壓下 LED能承受的最大電流是 20mA● 由於順向電壓 (Typical) 為 1.85V ● Raspberry Pi 的 GPIO腳位能提供 3.3V● 計算公式:電阻 =電壓 / 電流

R =V/I

R =(3.3-1.85)/0.02=72.5歐姆● 表示最小要接 72.5歐姆的電阻 , 才能避免 LED燒毀

如何解讀?

Page 33: 用Raspberry Pi學GPIO - 自己做遊戲機

33

電阻阻值計算

www.digikey.tw/tw/zht/mkt/5-band-resistors.html

四環:右側為金或銀

五環:前四環很靠近1K=棕黑黑棕 (棕 )2K=紅黑黑棕 (棕 )

Page 34: 用Raspberry Pi學GPIO - 自己做遊戲機

34

要接哪一個腳位?

Page 35: 用Raspberry Pi學GPIO - 自己做遊戲機

35

要接哪一個腳位?

目標:一隻腳接地 , 一隻腳給電

Page 36: 用Raspberry Pi學GPIO - 自己做遊戲機

36

線路圖LED RPi長腳 (RED) Pin12 (GPIO18)短腳 (BLACK) Pin6 (Ground)

Page 37: 用Raspberry Pi學GPIO - 自己做遊戲機

37

麵包板的種類

https://goo.gl/JipVgH

Page 38: 用Raspberry Pi學GPIO - 自己做遊戲機

38

麵包板的使用

http://bugworkshop.blogspot.tw/2012/12/diy-breadboard.html

1. 藍色和綠色兩塊不通2. 藍色水平相通3. 紅色垂直相通 麵包板的內部結構

Page 39: 用Raspberry Pi學GPIO - 自己做遊戲機

39

使用麵包板方便多了

1k電阻:棕黑黑棕 (棕 )

Page 40: 用Raspberry Pi學GPIO - 自己做遊戲機

40

使用麵包板方便多了

Page 41: 用Raspberry Pi學GPIO - 自己做遊戲機

41

● 試試看這樣接

不會亮嗎? 因為你沒寫程式阿

Page 42: 用Raspberry Pi學GPIO - 自己做遊戲機

42

各腳位的意義

https://goo.gl/f2rPpN

Page 43: 用Raspberry Pi學GPIO - 自己做遊戲機

43

開始用 Python 控制 GPIO吧

Page 44: 用Raspberry Pi學GPIO - 自己做遊戲機

44

● 載入模組 (Import module) ● 選擇編號系統 (Define pin numbering)● 定義腳位 (Setup up a channel)● 讀取輸入 / 寫入輸出 (Input/Output)● 清理 (Cleanup)

Python Code基本流程

http://code.google.com/p/raspberry-gpio-python/wiki/BasicUsage

Page 45: 用Raspberry Pi學GPIO - 自己做遊戲機

45

#!/usr/bin/python ●

● import RPi.GPIO as GPIO # Import module

● import time ●

● GPIO.setmode(GPIO.BOARD) # Define pin numbering

● LED_PIN = 12

● GPIO.setup(LED_PIN, GPIO.OUT) # Setup up a channel●

● print("LED is on")

● GPIO.output(LED_PIN, GPIO.HIGH) # Input/Output status

● time.sleep(3)

● GPIO.cleanup() # Cleanup

一個實際的範例

Page 46: 用Raspberry Pi學GPIO - 自己做遊戲機

46

DEMOled_on.py

Page 47: 用Raspberry Pi學GPIO - 自己做遊戲機

47

使用:nano <檔名,例如led_on.py>

離開:Ctrl + x

> 令存新檔:y

> 不存離開:n

> 離開:Ctrl + c

nano 編輯器使用

Page 48: 用Raspberry Pi學GPIO - 自己做遊戲機

48

● $ cd < 目錄 > # 跳到 <目錄 >● $ cd .. # 回上一層● $ cd ~ # 回 <家目錄 >

● $ pwd # 查看目前工作目錄

● $ ls # 列出檔案與目錄

● $ sudo reboot # 重開機

你必須知道的 Linux 指令

Page 49: 用Raspberry Pi學GPIO - 自己做遊戲機

49

$ cd ~

$ git clone https://github.com/raspberrypi-tw/gpio-game-console.git

$ cd ~/gpio-game-console

$ cd 01-led_on

$ sudo python led_on.py

讀寫 GPIO 會存取 /dev/mem, 需 root 權限(2015-09-24 以後的 image 可以用一般使用者身份執行 )

執行方式

Page 50: 用Raspberry Pi學GPIO - 自己做遊戲機

50

● Wiki● http://sourceforge.net/p/raspberry-gpio-python/wiki/Home/

● Code● http://sourceforge.net/p/raspberry-gpio-python/code/ci/default/tree/

● Reference detail● http://elinux.org/RPi_Low-level_peripherals● http://elinux.org/RPi_BCM2835_GPIOs● http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf

更多 RPi.GPIO 的使用方法

Page 51: 用Raspberry Pi學GPIO - 自己做遊戲機

51

實驗2:控制 LED閃爍

目的:熟悉 Python語法

Page 52: 用Raspberry Pi學GPIO - 自己做遊戲機

52

一樣的線路圖LED RPi長腳 (RED) Pin12 (GPIO18)短腳 (BLACK) Pin6 (Ground)

Page 53: 用Raspberry Pi學GPIO - 自己做遊戲機

53

GPIO.setmode(GPIO.BOARD)

● LED_PIN = 12

● GPIO.setup(LED_PIN, GPIO.OUT)

● while True:

● print("LED is on")

● GPIO.output(LED_PIN, GPIO.HIGH)

● time.sleep(1)

● print("LED is off")

● GPIO.output(LED_PIN, GPIO.LOW)

● time.sleep(1)

● GPIO.cleanup()

永不停止的 while 迴圈-按Ctrl+c跳出迴圈

Page 54: 用Raspberry Pi學GPIO - 自己做遊戲機

54

DEMOled_blink_warning.py

$ cd ~/gpio-game-console

$ cd 02_1-led_blink_warning

$ sudo python led_blink_warning.py

Page 55: 用Raspberry Pi學GPIO - 自己做遊戲機

55

RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.

Page 56: 用Raspberry Pi學GPIO - 自己做遊戲機

56

為什麼出現Warning ?

Page 57: 用Raspberry Pi學GPIO - 自己做遊戲機

57

● 在正常情況下執行完畢結束● 遇到錯誤跳出

● 受到中斷停止 (收到終止訊號 ,例如 Ctrl+c)

程式何時會結束 ?

Page 58: 用Raspberry Pi學GPIO - 自己做遊戲機

58

try:

● while True:

● print("LED is on")

● GPIO.output(LED_PIN, GPIO.HIGH)

● time.sleep(1)

● print("LED is off")

● GPIO.output(LED_PIN, GPIO.LOW)

● time.sleep(1)

● except KeyboardInterrupt:

● print "Exception: KeyboardInterrupt"

● finally:

● GPIO.cleanup()

接住例外

Page 59: 用Raspberry Pi學GPIO - 自己做遊戲機

59

DEMOled_blink.py

$ cd ~/gpio-game-console

$ cd 02_2-led_blink

$ sudo python led_blink.py

Page 60: 用Raspberry Pi學GPIO - 自己做遊戲機

60

實驗3:用 LED 做交通號誌

目的:結構化程式設計

Page 61: 用Raspberry Pi學GPIO - 自己做遊戲機

61

● 紅 ,黃 ,綠燈依序亮燈

● 紅燈亮 4秒 ,黃燈亮 2秒 ,綠燈亮 4秒

設計一個紅綠燈

http://www.clipartbest.com/traffic-light-photo

Page 62: 用Raspberry Pi學GPIO - 自己做遊戲機

62

線路圖

Page 63: 用Raspberry Pi學GPIO - 自己做遊戲機

63

DEMOtraffic_light_nonstructure.py

$ cd ~/gpio-game-console

$ cd 03_1-traffic_light_nonstructure

$ sudo python traffic_light_nonstructure.py

Page 64: 用Raspberry Pi學GPIO - 自己做遊戲機

64

def TrafficLight(pin, duration):

GPIO.output(pin, GPIO.HIGH)

time.sleep(duration)

GPIO.output(pin, GPIO.LOW)

try :

while True:

TrafficLight(RED_PIN, 4);

TrafficLight(YEL_PIN, 2);

TrafficLight(GRN_PIN, 4);

finally:

GPIO.cleanup()

把亮燈拿到外面

Page 65: 用Raspberry Pi學GPIO - 自己做遊戲機

65

DEMOtraffic_light.py

$ cd ~/gpio-game-console

$ cd 03_2-traffic_light

$ sudo python traffic_light.py

Page 66: 用Raspberry Pi學GPIO - 自己做遊戲機

66

數位輸入

Page 67: 用Raspberry Pi學GPIO - 自己做遊戲機

67

實驗4:讀取按鍵輸入

目的:了解硬體和軟體的差異

Page 68: 用Raspberry Pi學GPIO - 自己做遊戲機

68

● 開關:按鍵式 ,滑動式 ,傾斜式 ...

按鍵 Button / 開關 Switch

http://nicegear.co.nz/

Page 69: 用Raspberry Pi學GPIO - 自己做遊戲機

69

● 常開 (normal open, N.O.)● 常閉 (normal close, N.C.)

按鍵 Button / 開關 Switch

http://www.engineersgarage.com/sites/default/files/imagecache/Original/wysiwyg_imageupload/4214/Switch-2_0.jpg

Page 70: 用Raspberry Pi學GPIO - 自己做遊戲機

70

按鍵的內部結構

http://www.ladyada.net/learn/arduino/lesson5.html

● 按下前

● 長邊相連 (1&2,3&4)● 短邊不相連

● 按下後● 四點都通

1 2

3 4

Page 71: 用Raspberry Pi學GPIO - 自己做遊戲機

71

簡單的按鍵接法

BUTTON RPi腳 1 Pin6 (Ground)腳 3 Pin11 (GPIO17)

Page 72: 用Raspberry Pi學GPIO - 自己做遊戲機

72

● Input 空接會讀到雜訊

問題在哪裡?

按鍵按下前未導通,讀到??按鍵按下後,讀到低電位

Page 73: 用Raspberry Pi學GPIO - 自己做遊戲機

73

更好的按鍵接法

http://geekgurldiaries.blogspot.tw/2012/12/part-2.html

Page 74: 用Raspberry Pi學GPIO - 自己做遊戲機

74

上拉電阻

http://playground.arduino.cc/CommonTopics/PullUpDownResistor

- 還沒按下按鍵 - 按下按鍵時

Page 75: 用Raspberry Pi學GPIO - 自己做遊戲機

75

線路圖BUTTON RPi腳 1 Pin6 (Ground)腳 3 Pin11 (GPIO17) Pin1 (3.3V)

1k電阻

Page 76: 用Raspberry Pi學GPIO - 自己做遊戲機

76

BTN_PIN = 11

GPIO.setup(BTN_PIN, GPIO.IN)

previousStatus = None

try:

while True:

input = GPIO.input(BTN_PIN)

if input == GPIO.LOW and previousStatus == GPIO.HIGH:

print("Button pressed")

previousStatus = input

except KeyboardInterrupt:

print "Exception: KeyboardInterrupt"

finally:

GPIO.cleanup()

判斷條件 : 這次低 && 上次高

Page 77: 用Raspberry Pi學GPIO - 自己做遊戲機

77

DEMOpush_button_poll.py

$ cd ~/gpio-game-console

$ cd 04_1-push_button_poll

$ sudo python push_button_poll.py

Page 78: 用Raspberry Pi學GPIO - 自己做遊戲機

78

按一次出現兩次?這樣子對不對啊?

Page 79: 用Raspberry Pi學GPIO - 自己做遊戲機

79

● 機械式開關在切換過程中會有訊號彈跳現象 (雜訊 )

開關訊號的彈跳問題 (bounce)

http://120.101.72.1/Onechip/PPT/ 實習單元三 .ppt

理想訊號輸出

實際輸出訊號

Page 80: 用Raspberry Pi學GPIO - 自己做遊戲機

80

● 硬體方法:以 RC 電路或正回授的比較器電路解決

● 軟體方法:調整觸發的延遲時間● 不同的按鍵會有不同的延遲時間

解決彈跳問題 (de-bounce)

10ms - 20ms

Page 81: 用Raspberry Pi學GPIO - 自己做遊戲機

81

WAIT_TIME = 0.2

GPIO.setup(BTN_PIN, GPIO.IN)

previousStatus = None

previousTime = time.time()

currentTime = None

try:

while True:

input = GPIO.input(BTN_PIN)

currentTime = time.time()

if input == GPIO.LOW and \

previousStatus == GPIO.HIGH and \

(currentTime - previousTime) > WAIT_TIME:

previousTime = currentTime

print("Button pressed @"), time.ctime()

previousStatus = input

不反應在延遲時間內的觸發

Page 82: 用Raspberry Pi學GPIO - 自己做遊戲機

82

DEMOpush_button_debounce.py

$ cd ~/gpio-game-console

$ cd 04_2-push_button_debounce

$ sudo python push_button_debounce.py

Page 83: 用Raspberry Pi學GPIO - 自己做遊戲機

83

但是這個程式的 CPU 用量挺大的$ top -c

跑個按鍵偵測程式 CPU 使用率達 91.9% ( 如果使用 Pi 3 使用率約 2x%)

● PID:該程序的id

● COMMAND:該程序的完整指令

Page 84: 用Raspberry Pi學GPIO - 自己做遊戲機

84

● 送一個 KILL 的訊號吧 $ sudo kill -9 3449

如何結束程序?

● 按 q離開 top 指令

Page 85: 用Raspberry Pi學GPIO - 自己做遊戲機

85

● 輪詢 (polling)● SoC每隔一段時間檢查週邊硬體的資料

● 中斷 (interrupt)● 當週邊硬體的狀態改變時 ,對 SoC 發出中斷要求

輪詢與中斷

Page 86: 用Raspberry Pi學GPIO - 自己做遊戲機

86

● 建立回呼函數

● def mycallback()

● 綁定事件和回呼函數

● add_event_detect(gpio, # 對象

edge, # 觸發條件

callback,# 回呼函數

bouncetime)● 多個事件可以綁定同樣的回呼函數

中斷的程式寫法

source/py_gpio.c

Page 87: 用Raspberry Pi學GPIO - 自己做遊戲機

87

BTN_PIN = 11

WAIT_TIME = 200

GPIO.setup(BTN_PIN, GPIO.IN)

def mycallback(channel):

print("Button pressed")

try:

GPIO.add_event_detect(BTN_PIN, \

GPIO.FALLING, \

callback=mycallback, \

bouncetime=WAIT_TIME)

while True:

time.sleep(10)

finally:

GPIO.cleanup()

即使在 sleep狀態下也可立即回應

Page 88: 用Raspberry Pi學GPIO - 自己做遊戲機

88

DEMOpush_button_interrupt.py

$ cd ~/gpio-game-console

$ cd 04_3-push_button_interrupt

$ sudo python push_button_interrupt.py

Page 89: 用Raspberry Pi學GPIO - 自己做遊戲機

89

● 需要硬體或軟體(作業系統)的支援

● RPi.GPIO在版本0.5.0a有了中斷功能

● 加上add_event_detect()等機制

● RPi.GPIO以建立多執行緒方式實現中斷

● 程式開始執行時, 主執行序運行

● 當加入事件後,以epoll_create建立新的fd● 當事件觸發時,第二個執行序和主執行序溝通(回呼)● 程式碼可參考source/event_gpio.c

中斷的意義

source/py_gpio.c

Page 90: 用Raspberry Pi學GPIO - 自己做遊戲機

90

簡單的按鍵接法沒有錯 , 但是 ...

Page 91: 用Raspberry Pi學GPIO - 自己做遊戲機

91

GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def mycallback(channel):

print("Button pressed")

try:

GPIO.add_event_detect(BTN_PIN, \

GPIO.FALLING, \

callback=mycallback, \

bouncetime=WAIT_TIME)

while True:

time.sleep(10)

finally:

GPIO.cleanup()

要搭配內建的上拉電阻 (50k)

Page 92: 用Raspberry Pi學GPIO - 自己做遊戲機

92

DEMOpush_button_internal_pull_up.py

$ cd ~/gpio-game-console

$ cd 04_4-push_button_internal_pull_up

$ sudo python push_button_internal_pull_up.py

Page 93: 用Raspberry Pi學GPIO - 自己做遊戲機

93

實驗 5:傾斜開關

目的:認識不同的硬體

Page 94: 用Raspberry Pi學GPIO - 自己做遊戲機

94

傾斜開關 Tilt Switch

Page 95: 用Raspberry Pi學GPIO - 自己做遊戲機

95

線路圖SWITCH RPi第一腳 (RED) Pin11 (GPIO17)第二腳 (BLACK) Pin6 (Ground)

Page 96: 用Raspberry Pi學GPIO - 自己做遊戲機

96

DEMOtilt_switch.py

$ cd ~/gpio-game-console

$ cd 05-tilt_switch

$ sudo python tilt_switch.py

使用內建的上拉電阻

Page 97: 用Raspberry Pi學GPIO - 自己做遊戲機

97

實驗 6:蜂鳴器樂器

目的:聲音輸出

Page 98: 用Raspberry Pi學GPIO - 自己做遊戲機

98

● 發聲原理 :聲音是由振動產生 ,其頻率稱為音頻

● 蜂鳴器發聲原理 :電流 (6)通過電磁線圈 (3)產生磁場來驅動振動膜 (11)

● 人耳可聽到 20Hz - 20KHz

原理

http://www.itianer.com/diancishifengmingqigouzaoyuyuanlijieshao.html

Page 99: 用Raspberry Pi學GPIO - 自己做遊戲機

99

● 自激 (有源 ):只能發出同頻率的聲音

● 黑膠封裝 ,高低腳

● 他激 (無源 ): 需從外部輸入震盪方波發聲

● 綠色電路板 ,兩腳同長

● 腳位有正負之分 (看底板 )

蜂鳴器 Buzzer

http://www.buzzer-speaker.com/manufacturer/piezo%20buzzer.htm

自激式 他激式

Page 100: 用Raspberry Pi學GPIO - 自己做遊戲機

100

線路圖BUZZER RPi+(RED) Pin12 (GPIO18)- (BLACK) Pin6 (Ground)

Page 101: 用Raspberry Pi學GPIO - 自己做遊戲機

101

def buzz(pitch, duration) :

period = 1.0 / pitch

half_period = period / 2

cycles = int(duration * pitch)

for i in xrange(cycles) :

GPIO.output(buzzer_pin, GPIO.HIGH)

time.sleep(half_period)

GPIO.output(buzzer_pin, GPIO.LOW)

time.sleep(half_period)

while True :

pitch_s = raw_input("Enter Pitch (200 to 2000): ")

duration_s = raw_input("Enter Duration (seconde): ")

buzz(float(pitch_s), float(duration_s))

可發出不同頻率聲音

Page 102: 用Raspberry Pi學GPIO - 自己做遊戲機

102

DEMObuzzer.py

$ cd ~/gpio-game-console

$ cd 06_1-buzzer

$ sudo python buzzer.py

Page 103: 用Raspberry Pi學GPIO - 自己做遊戲機

103

● 標準 88 鍵鋼琴 ,每個音的頻率 :● 每段音階分為 12 個半音

● 每個音的頻率是前一個的 1.05946倍 ( )

鋼琴模擬

1

2

3

4

5

6

7

0 8

http://en.wikipedia.org/wiki/Piano_key_frequencies

122

Page 104: 用Raspberry Pi學GPIO - 自己做遊戲機

104

● 標準88鍵鋼琴 ,以第 49鍵A4為基準 (440Hz)● 各半音頻率如下:

● C5 (52th, DO): 523Hz● D5 (54th, RE): 587Hz● E5 (56th, ME): 659Hz● F5 (57th, FA): 698Hz● G5 (59th, SO): 784Hz● A5 (61th, LA): 880Hz● B5 (63th, SI): 988Hz

鋼琴頻率

http://en.wikipedia.org/wiki/Piano_key_frequencies

Page 105: 用Raspberry Pi學GPIO - 自己做遊戲機

105

線路圖RPiPin7 BuzzerPin11 DoPin12 RePin13 MePin15 FaPin16 SoPin18 LaPin22 Si

Page 106: 用Raspberry Pi學GPIO - 自己做遊戲機

106

DEMOpaino_buzzer.py

$ cd ~/gpio-game-console

$ cd 06_2-paino_buzzer

$ sudo python paino_buzzer.py

Page 107: 用Raspberry Pi學GPIO - 自己做遊戲機

107

實驗 7:人體紅外線感測器

目的:常見感測器使用

Page 108: 用Raspberry Pi學GPIO - 自己做遊戲機

108

Pyroelectric ("Passive") InfraRed SensorPIR 人體紅外線感測器

http://www.raspberrypi-spy.co.uk/2013/01/cheap-pir-sensors-and-the-raspberry-pi-part-1/

Page 109: 用Raspberry Pi學GPIO - 自己做遊戲機

109

使用示意圖

http://www.ladyada.net/learn/sensors/pir.html

Page 110: 用Raspberry Pi學GPIO - 自己做遊戲機

110

應用範例

http://www.ladyada.net/learn/sensors/pir.htmlhttp://totherails.blogspot.tw/2011/09/halloween-preparations.html

Page 111: 用Raspberry Pi學GPIO - 自己做遊戲機

111

元件說明

http://www.ladyada.net/learn/sensors/pir.html

Page 112: 用Raspberry Pi學GPIO - 自己做遊戲機

112

● 輸入電壓 :DC 3.3V - 24V ● 輸出電壓 :3.3V( 可直接接上 Raspberry Pi)● 延遲時間 (Tx):2.45秒 – 248秒

● 感應之後輸出維持的時間● 封鎖時間 (Ti):2.4 秒

● 感應輸出結束之後 ,再次觸發必須等待的時間

● 感應角度 :110度 x 70度● 感應距離 :3米 - 7 米

瞭解規格

Page 113: 用Raspberry Pi學GPIO - 自己做遊戲機

113

● 感測距離設定

● 順時針 :最高為 7米● 逆時針 :最小為 3米

● 延遲時間設定 (Tx)● 順時針 :最長為 248秒● 逆時針 :最短為 2.45秒

● 實際可調整時間要看 R10,C6,R9,C7而定

感測距離 /延遲時間設定

感測距離設定 延遲時間設定

Page 114: 用Raspberry Pi學GPIO - 自己做遊戲機

114

● 可重複觸發模式 (H)

● 不可重複觸發模式 (L)

觸發模式

H: 可重複觸發L: 不可重複觸發 (預設 )

感應 & 輸出

感應 & 等待 & 輸出

Page 115: 用Raspberry Pi學GPIO - 自己做遊戲機

115

線路圖

Page 116: 用Raspberry Pi學GPIO - 自己做遊戲機

116

PIR_PIN = 26

GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

def mycallback(channel):

print "Motion detected"

try:

GPIO.add_event_detect(PIR_PIN, GPIO.RISING, \

callback=mycallback, \

bouncetime=200)

while True:

time.sleep(1)

finally:

GPIO.cleanup()

再一次使用 interrupt 模式

Page 117: 用Raspberry Pi學GPIO - 自己做遊戲機

117

DEMOpir.py

$ cd ~/gpio-game-console

$ cd 07_1-pir

$ sudo python pir.py

觸發才拉高電位 ,因此用內建的下拉電阻

Page 118: 用Raspberry Pi學GPIO - 自己做遊戲機

118

加上警示的LED燈吧

Page 119: 用Raspberry Pi學GPIO - 自己做遊戲機

119

線路圖

Page 120: 用Raspberry Pi學GPIO - 自己做遊戲機

120

DEMOpeople_alarm_system.py

$ cd ~/gpio-game-console

$ cd 07_2-people_alarm_system

$ sudo python people_alarm_system.py

Page 121: 用Raspberry Pi學GPIO - 自己做遊戲機

121

LED_PIN = 12

PIR_PIN = 26

GPIO.setup(PIR_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

GPIO.setup(LED_PIN, GPIO.OUT)

def mycallback(channel):

print "Motion detected"

for i in xrange(3) :

GPIO.output(LED_PIN, GPIO.HIGH)

time.sleep(0.5)

GPIO.output(LED_PIN, GPIO.LOW)

time.sleep(0.5)

try:

GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=mycallback, bouncetime=200)

while True:

time.sleep(1)

偵測到人 , 燈閃 3 次

Page 122: 用Raspberry Pi學GPIO - 自己做遊戲機

122

實驗 8:超音波距離感測器

目的:根據規格撰寫程式

Page 123: 用Raspberry Pi學GPIO - 自己做遊戲機

123

● 聲音在 20°C (68°F) 的速度是 343公尺 /秒● 溫度每增加 1°,速度增加 0.6公尺/秒

測距離原理

http://en.wikipedia.org/wiki/Speed_of_soundhttps://www.modmypi.com/blog/hc-sr04-ultrasonic-range-sensor-on-the-raspberry-pi

Page 124: 用Raspberry Pi學GPIO - 自己做遊戲機

124

● 內建發射(40kHz)與接收電路

● 根據發射與接收的時間差計算距離

● 特殊功能:US-020(長距離)、US-100(溫度補償)

HC-SR04超音波距離感測器

http://coopermaa2nd.blogspot.tw/2012/09/hc-sr04.html

Page 125: 用Raspberry Pi學GPIO - 自己做遊戲機

125

● 避障 ,測距● 物體移動感測● 地鐵感測器

應用

http://letsmakerobots.com/robot/project/rock-crawlerhttps://www.dropbox.com/s/x0qdaq86rkc0zyv/MakerConf.pdf

Page 126: 用Raspberry Pi學GPIO - 自己做遊戲機

126

地鐵感測器

http://makezine.com/magazine/ultrasonic-train-detector-in-stockholm-subway/

Page 127: 用Raspberry Pi學GPIO - 自己做遊戲機

127

地鐵感測器

http://makezine.com/magazine/ultrasonic-train-detector-in-stockholm-subway/

Page 128: 用Raspberry Pi學GPIO - 自己做遊戲機

128

● 規格與時序圖

HC-SR04

http://coopermaa2nd.blogspot.tw/2012/09/hc-sr04.html

建議測量間隔 >60ms

Page 129: 用Raspberry Pi學GPIO - 自己做遊戲機

129

● TRIG腳位收到高電位 (3.3V)後發送超聲波

● ECHO腳位維持低電位 (0V),收到回應後拉到高電位 (5V)

● Raspberry Pi腳位的容忍電位為 3.3V

=> 將 ECHO腳位的 5V降壓為 3.3V左右

分壓電路計算

https://www.modmypi.com/blog/hc-sr04-ultrasonic-range-sensor-on-the-raspberry-pi=> R1=1K, R2 取 2K

Page 130: 用Raspberry Pi學GPIO - 自己做遊戲機

130

線路圖- 注意 1K, 2K 電阻

ULTRASONIC RPiVcc(RED) Pin2 (5V)Trig(YELLOW) Pin16 (GPIO23)Echo(PURPLE) Pin18 (GPIO24)Grnd(BLACK) Pin6 (Ground)

1k:棕黑黑棕

2k:紅黑黑棕

Page 131: 用Raspberry Pi學GPIO - 自己做遊戲機

131

v = 343 # (331 + 0.6*20)

def measure() :

GPIO.output(TRIGGER_PIN, GPIO.HIGH)

time.sleep(0.00001) # 10uS

GPIO.output(TRIGGER_PIN, GPIO.LOW)

pulse_start = time.time()

while GPIO.input(ECHO_PIN) == GPIO.LOW:

pulse_start = time.time()

while GPIO.input(ECHO_PIN) == GPIO.HIGH:

pulse_end = time.time()

t = pulse_end - pulse_start

d = t * v

d = d/2

return d*100

測量距離

Page 132: 用Raspberry Pi學GPIO - 自己做遊戲機

132

DEMOhc_sr04_measure_distance.py

$ cd ~/gpio-game-console

$ cd 08-hc_sr04_measure_distance

$ sudo python hc_sr04_measure_distance.py

Page 133: 用Raspberry Pi學GPIO - 自己做遊戲機

133

實驗 9:呼吸燈

目的:瞭解訊號模擬

Page 134: 用Raspberry Pi學GPIO - 自己做遊戲機

134

● 數位: 0 與 1的訊號

● 類比:連續的訊號

數位與類比

http://www.bitscope.com/software/blog/DJ/?p=DJ19A

Page 135: 用Raspberry Pi學GPIO - 自己做遊戲機

135

● 數位 :亮和不亮

● 類比 :亮 ,有點亮 ,有點不亮 ...,不亮

● 可是 GPIO腳位輸出都是固定值 ,怎麼辦?

從 LED 的角度來看

Page 136: 用Raspberry Pi學GPIO - 自己做遊戲機

136

● 旋轉式 ,滑動式

● 線性關係 (B 型 ),對數關係 (A型 )● 常見規格 :0 -10k Ohm(線性 )

可變電阻 Potentiometer(VR)

https://en.wikipedia.org/wiki/Potentiometer

接高電位

接低電位

滑動接點 (可變輸出 )

Page 137: 用Raspberry Pi學GPIO - 自己做遊戲機

137

利用可變電阻改變 LDE亮度

Page 138: 用Raspberry Pi學GPIO - 自己做遊戲機

138

有不使用額外硬體的方法嗎?

Page 139: 用Raspberry Pi學GPIO - 自己做遊戲機

139

● 是將類比信號轉為脈波的一種技術

● 改變工作比 (duty cycle)=改變電壓

脈寬調變 (Pulse-Width Modulation)

http://www.societyofrobots.com/schematics_h-bridgedes.shtml

Page 140: 用Raspberry Pi學GPIO - 自己做遊戲機

140

● 類比輸出電壓 =脈衝寬度 x高電位值

公式計算

http://www.protostack.com/blog/2011/06/atmega168a-pulse-width-modulation-pwm/

Page 141: 用Raspberry Pi學GPIO - 自己做遊戲機

141

● To create a PWM instance:

● p = GPIO.PWM(channel, frequency)

● To start PWM:

● p.start(dc) # dc is the duty cycle

● To change the duty cycle:

● p.ChangeDutyCycle(dc) # where 0.0 <= dc <= 100.0

● To stop PWM:

● p.stop()

GPIO.PWM()

http://sourceforge.net/p/raspberry-gpio-python/wiki/PWM/

Page 142: 用Raspberry Pi學GPIO - 自己做遊戲機

142

線路圖LED RPi長腳 (RED) Pin12 (GPIO18)短腳 (BLACK) Pin6 (Ground)

Page 143: 用Raspberry Pi學GPIO - 自己做遊戲機

143

LED_PIN = 12

● GPIO.setup(LED_PIN, GPIO.OUT)

pwm_led = GPIO.PWM(LED_PIN, 100)

● pwm_led.start(100)

● try:

● while True:

● duty_s = raw_input("Enter Brightness (0 to 100):")

● duty = int(duty_s)

● if duty >= 0 and duty <=100 :

● pwm_led.ChangeDutyCycle(duty)

● except KeyboardInterrupt:

● pwm_led.stop()

● GPIO.cleanup()

互動式的調光

Page 144: 用Raspberry Pi學GPIO - 自己做遊戲機

144

DEMOadjust_led_bright.py

$ cd ~/gpio-game-console

$ cd 09_1-adjust_led_bright

$ sudo python adjust_led_bright.py

Page 145: 用Raspberry Pi學GPIO - 自己做遊戲機

145

LED_PIN = 12

GPIO.setup(LED_PIN, GPIO.OUT)

pwm_led = GPIO.PWM(LED_PIN, 100)

pwm_led.start(0)

while True:

for dc in xrange(0, 101, 5):

pwm_led.ChangeDutyCycle(dc)

time.sleep(0.1)

time.sleep(0.5)

for dc in xrange(100, -1, -5):

pwm_led.ChangeDutyCycle(dc)

time.sleep(0.1)

time.sleep(0.5)

呼吸燈就是漸明漸亮

Page 146: 用Raspberry Pi學GPIO - 自己做遊戲機

146

● 兩者差異

● Software PWM是透過kernel做duty cycle的調整

● Hardware PWM是SoC透過DMA做調整● 使用時機

● 不需要精準時用Software PWM,例如LED調光● 需要低延遲時用Hardware PWM,例如伺服馬達

● Hardware PWM GPIO只有實體腳位Pin 12和Pin 33(Model B+以後)支援

● 內建pigpiod提供Hardware PWM函式呼叫

Software PWM vs. Hardware PWM

Page 147: 用Raspberry Pi學GPIO - 自己做遊戲機

147

DEMOpwm_led.py

$ cd ~/gpio-game-console

$ cd 09_2-pwm_led

$ sudo python pwm_led.py

Page 148: 用Raspberry Pi學GPIO - 自己做遊戲機

148

實驗10:光敏電阻

目的:類比訊號的讀取

Page 149: 用Raspberry Pi學GPIO - 自己做遊戲機

149

● 硫化鎘 (CdS) 或光敏電阻器 (LDR), 阻抗隨光落在表面的總量而轉變

● 光越強阻值越小 ,反之光越弱阻值則越大

● 應用:光控開關 ,電子玩具 ,工業控制

光敏電阻

http://www2.nkfust.edu.tw/~jlkuo2/31/a6.htm

Page 150: 用Raspberry Pi學GPIO - 自己做遊戲機

150

● Raspberry Pi沒有硬體的類比數位轉換器 (ADC)

類比訊號轉換為數位訊號

http://www.planetoftunes.com/digital-audio/how-do-analogue-to-digital-converters-work.html

IN ADC OUT

此ADC 的解析度為 4bits從 0000 到 1111(看 Y軸 )

Page 151: 用Raspberry Pi學GPIO - 自己做遊戲機

151

● 類比數位轉換器 (Analog to Digital Converter)● 8通道 ,10 bits解析度

● SPI協議

利用 MCP3008

Page 152: 用Raspberry Pi學GPIO - 自己做遊戲機

152

● 主從式架構 , 可一對多

● 四線同步序列資料協定

● SS:週邊選擇線 (CE)● SCK:序列時脈線 (SCLK)● MOSI: 主往從送

● MISO: 從往主送

Serial Peripheral Interface(SPI)

Page 153: 用Raspberry Pi學GPIO - 自己做遊戲機

153

● $ sudo raspi-config

啟用 Raspberry Pi 的 SPI

Page 154: 用Raspberry Pi學GPIO - 自己做遊戲機

154

開機就載入 SPI核心模組

Page 155: 用Raspberry Pi學GPIO - 自己做遊戲機

155

● 測試確認SPI模組已載入

● 安裝必要套件(如果前面已裝過,就不需再裝)● $ sudo apt-get update● $ sudo apt-get install -y python-dev python-pip

● $ sudo pip install spidev

SPI 使用前的確認

Page 156: 用Raspberry Pi學GPIO - 自己做遊戲機

156

線路圖MCP3008 RPiCLK Pin23 (SCLK)Din Pin19 (MOSI)Dout Pin21 (MISO)CS Pin24 (CE0)

Page 157: 用Raspberry Pi學GPIO - 自己做遊戲機

157

● SPI會用到的腳位是 MOSI,MISO,SCLK和 CE0/CE1

再看一次腳位定義

Page 158: 用Raspberry Pi學GPIO - 自己做遊戲機

158

spi = spidev.SpiDev()

spi.open(0,0) # (0,0)表示接到CE0腳位,對應到/dev/spidev0.0裝置檔

def ReadChannel(channel):

adc = spi.xfer2([1,(8+channel)<<4,0])

data = ((adc[1]&3) << 8) + adc[2]

return data

def ConvertVolts(data,places):

volts = (data * 3.3) / float(1023)

volts = round(volts,places)

return volts

light_channel = 0

delay = 1

while True:

light_level = ReadChannel(light_channel)

light_volts = ConvertVolts(light_level, 2)

print("Light: {} ({}V)".format(light_level,light_volts))

time.sleep(delay)

Page 159: 用Raspberry Pi學GPIO - 自己做遊戲機

159

程式要照硬體規格撰寫

Page 160: 用Raspberry Pi學GPIO - 自己做遊戲機

160

● input一次送三個bytes● # byte 1: the start bit (always 0x01)● # byte 2: configure bits● # byte 3: don't care

● spi.xfer2([1,(8+channel)<<4,0])

● Ch0 = 1000 0000● Ch1 = 1001 0000

了解 spi.xfer2() 的意義

0x01 don't careCh0/Ch1

Page 161: 用Raspberry Pi學GPIO - 自己做遊戲機

161http://wolfpaulus.com/

Page 162: 用Raspberry Pi學GPIO - 自己做遊戲機

162http://wolfpaulus.com/

Output也是一次回傳三個 bytes因為是 10bits 解析度 , 所以我們只取最後有用的 10bits

Page 163: 用Raspberry Pi學GPIO - 自己做遊戲機

163

DEMOphotoresistor.py

$ cd ~/gpio-game-console

$ cd 10-photoresistor

$ sudo python photoresistor.py

Page 164: 用Raspberry Pi學GPIO - 自己做遊戲機

164

實驗11:手做遊戲機之貪食蛇

目的:系統整合

Page 165: 用Raspberry Pi學GPIO - 自己做遊戲機

165

● 現況:用上下左右鍵控制● 目標:改為用搖桿控制

Bash 版之貪食蛇

http://bruxy.regnet.cz/linux/housenka/

Page 166: 用Raspberry Pi學GPIO - 自己做遊戲機

166

● 下載貪食蛇

● keyboard 控制

● 讀取搖桿的值

● 搖桿和 keyboard對應

● 開機就啟動按鍵搖桿對應程式

概念 &步驟

http://bruxy.regnet.cz/web/linux/EN/housenka-bash-game/http://www.linuxuser.co.uk/tutorials/emulate-a-bluetooth-keyboard-with-the-raspberry-pi

Page 167: 用Raspberry Pi學GPIO - 自己做遊戲機

167

搖桿 (joystick)

Page 168: 用Raspberry Pi學GPIO - 自己做遊戲機

168

● 3.3V-5V工作電壓

● 輸出形式:

● x,y軸 - 類比輸出

● z軸 - 數位輸出

XY雙軸搖桿

http://www.aliexpress.com/cheap/cheap-arduino-joystick.html

Page 169: 用Raspberry Pi學GPIO - 自己做遊戲機

169

線路圖

http://www.raspberrypi-spy.co.uk/2014/04/using-a-joystick-on-the-raspberry-pi-using-an-mcp3008/

Page 170: 用Raspberry Pi學GPIO - 自己做遊戲機

170

spi = spidev.SpiDev()

● spi.open(0,0)

● def ReadChannel(channel):

● adc = spi.xfer2([1,(8+channel)<<4,0])

● data = ((adc[1]&3) << 8) + adc[2]

● return data

● vrx_channel = 1

● vry_channel = 2

● while True:

● vrx_pos = ReadChannel(vrx_channel)

● vry_pos = ReadChannel(vry_channel)

● print("X : {} Y : {} ".format(vrx_pos,vry_pos))

● time.sleep(0.5)

Page 171: 用Raspberry Pi學GPIO - 自己做遊戲機

171

DEMOmcp3008_joystick

$ cd ~/gpio-game-console

$ cd 11_1-mcp3008_joystick

$ sudo python mcp3008_joystick.py

Page 172: 用Raspberry Pi學GPIO - 自己做遊戲機

172

搖桿如何和 keyboard對應?

Page 173: 用Raspberry Pi學GPIO - 自己做遊戲機

173

Linux 輸入與輸出的處理流程

https://en.wikipedia.org/wiki/Evdev

Page 174: 用Raspberry Pi學GPIO - 自己做遊戲機

174

Linux Input Subsystem

http://www.linuxjournal.com/article/6396

Page 175: 用Raspberry Pi學GPIO - 自己做遊戲機

175

● USB或 PS2 keyboard都是同一個 handler處理

● 我們可以加上 GPIO的 driver,讓 keyboard handler來接?

Linux Input Subsystem

http://www.linuxjournal.com/article/6396

USB Keyboard

PS2 Keyboard

Page 176: 用Raspberry Pi學GPIO - 自己做遊戲機

176

除了在 kernel space 做以外,

可以在 user space 做嗎?

Page 177: 用Raspberry Pi學GPIO - 自己做遊戲機

177

● evdev● Bindings to the Linux input handling subsystem

● python-evdev● provides bindings to the generic input event interface in Linux

● 安裝(如果前面已裝過, 就不需再裝)● $ sudo pip install evdev

python-evdev

https://pypi.python.org/pypi/evdev

Page 178: 用Raspberry Pi學GPIO - 自己做遊戲機

178

python-evdev keyboard examplefrom evdev import UInput, ecodes as e

ui = UInput()

ui.write(e.EV_KEY, e.KEY_H, 1) # KEY_H down

ui.write(e.EV_KEY, e.KEY_H, 0) # KEY_H up

ui.write(e.EV_KEY, e.KEY_E, 1)

ui.write(e.EV_KEY, e.KEY_E, 0)

ui.write(e.EV_KEY, e.KEY_L, 1)

ui.write(e.EV_KEY, e.KEY_L, 0)

ui.write(e.EV_KEY, e.KEY_L, 1)

ui.write(e.EV_KEY, e.KEY_L, 0)

ui.write(e.EV_KEY, e.KEY_O, 1)

ui.write(e.EV_KEY, e.KEY_O, 0)

ui.syn()

● ui.close()

Page 179: 用Raspberry Pi學GPIO - 自己做遊戲機

179

DEMOevdev_keyboard.py

$ cd ~/gpio-game-console

$ cd 11_2-evdev_keyboard

$ sudo python evdev_keyboard.py

Page 180: 用Raspberry Pi學GPIO - 自己做遊戲機

180

上下左右鍵與搖桿的對應

Page 181: 用Raspberry Pi學GPIO - 自己做遊戲機

181

上下左右鍵與搖桿的對應

- 觀察操作搖桿與畫面輸出值的關係

Page 182: 用Raspberry Pi學GPIO - 自己做遊戲機

182

vrx_channel = 1

while True:

vrx_pos = ReadChannel(vrx_channel)

if vrx_pos > 700 :

ui.write(e.EV_KEY, e.KEY_DOWN, 1)

ui.write(e.EV_KEY, e.KEY_UP, 0)

ui.syn()

elif vrx_pos < 200 :

ui.write(e.EV_KEY, e.KEY_DOWN, 0)

ui.write(e.EV_KEY, e.KEY_UP, 1)

ui.syn()

else :

ui.write(e.EV_KEY, e.KEY_DOWN, 0)

ui.write(e.EV_KEY, e.KEY_UP, 0)

ui.syn()

time.sleep(0.1)

Page 183: 用Raspberry Pi學GPIO - 自己做遊戲機

183

DEMOjoystick_mapping_keyboard.py

$ cd ~/gpio-game-console

$ cd 11_3-joystick_mapping_keyboard

$ sudo python joystick_mapping_keyboard.py

Page 184: 用Raspberry Pi學GPIO - 自己做遊戲機

184

● 第一個執行搖桿按鍵對應程式

● $ sudo python joystick_mapping_keyboard.py

用搖桿控制貪食蛇- 需要開啟兩個視窗

Page 185: 用Raspberry Pi學GPIO - 自己做遊戲機

185

● 第二個執行貪食蛇script● $ ./housenka.sh

用搖桿控制貪食蛇- 需要開啟兩個視窗

Page 186: 用Raspberry Pi學GPIO - 自己做遊戲機

186

試試看是否可以用搖桿控制貪食蛇

Page 187: 用Raspberry Pi學GPIO - 自己做遊戲機

187

好麻煩 !如何開機就執行 ?

Page 188: 用Raspberry Pi學GPIO - 自己做遊戲機

188

● 一次性的執行 , 可以放在 /etc/rc.local 裡

● 以服務的方式執行 ,需寫 systemd 設定檔

● 有畫面的程式前景執行 ,用 LXDE的 autostart

開機就執行?

Page 189: 用Raspberry Pi學GPIO - 自己做遊戲機

189

● 新增黃色字的部份

● $ sudo nano /etc/rc.local

sudo python /home/pi/gpio-game-console/11_3-joystick_mapping_keyboard/joystick_mapping_keyboard.py &

# Print the IP address

_IP=$(hostname -I) || true

if [ "$_IP" ]; then

printf "My IP address is %s\n" "$_IP"

fi

exit 0

開機就執行搖桿對應按鍵程式

Page 190: 用Raspberry Pi學GPIO - 自己做遊戲機

190

● 新增黃色字的部份

● $ nano ~/.config/lxsession/LXDE-pi/autostart

@lxpanel --profile LXDE-pi

@pcmanfm --desktop --profile LXDE-pi

@xscreensaver -no-splash

● @lxterminal -e /home/pi/gpio-game-console/11_3-joystick_mapping_keyboard/housenka.sh

● 設定完以後重開機試試看吧

進入桌面環境後就執行貪食蛇

Page 191: 用Raspberry Pi學GPIO - 自己做遊戲機

191

實驗13:模擬器

目的:完整度更高的遊戲機

Page 192: 用Raspberry Pi學GPIO - 自己做遊戲機

192

遊戲機 =硬體 + 遊戲

http://www.emulatorworld.com/

Page 193: 用Raspberry Pi學GPIO - 自己做遊戲機

193

● 模擬不同的硬體架構● 常見的模擬器:

● MAME (AdvanceMAME)● Nintendo Entertainment System (RetroArch)

● Super Nintendo Entertainment System (PiSNES)

● PC / x86 (rpix86)

Video Game System Emulators

https://en.wikipedia.org/wiki/List_of_video_game_emulators

Page 194: 用Raspberry Pi學GPIO - 自己做遊戲機

194

● 模擬大台電動玩具

MAME(Multiple Arcade Machine Emulator)

http://www.williamsamusements.co.uk/mame.html

Page 195: 用Raspberry Pi學GPIO - 自己做遊戲機

195

● 下載編譯好的binary

● $ cd ~● $ wget http://goo.gl/mN5zhS -O advmame● $ chmod 755 advmame● $ ./advmame

● 2.下載rom

● $ cd /home/pi/.advance/rom● Google搜尋AdvanceMAME suprmrio rom

● 3. 執行模擬器

● $ cd /home/pi● $ ./advmame suprmrio

AdvanceMAME

Page 196: 用Raspberry Pi學GPIO - 自己做遊戲機

196

● 搜尋MAME● http://www.emuparadise.me/

● 中英文對照● http://bbs.duowan.com/thread-41350071-1-1.html

● 經典遊戲● 超級瑪莉歐● 彈珠台● 小精靈● 坦克大作戰, 泡泡龍...

下載 ROM放到對應的目錄下

http://en.wikipedia.org/wiki/Nintendo_Entertainment_System

Page 197: 用Raspberry Pi學GPIO - 自己做遊戲機

197

搖桿 +按鍵的應用

MakerFaire 2014 Raspberry Jam

Page 198: 用Raspberry Pi學GPIO - 自己做遊戲機

198

線路圖

Page 199: 用Raspberry Pi學GPIO - 自己做遊戲機

199

超音波距離感測器的應用

● 手勢拉搖桿演算法範例:

1.握拳靠近感測器觸發

2.握拳平行向後 15cm

3. 手掌打開 =放開拉桿

Page 200: 用Raspberry Pi學GPIO - 自己做遊戲機

200

自製遊戲機- 機構外殼很重要

demo board 大台 gameboy 正面

大台 gameboy內裝

小台 gameboy 正面 小台 gameboy內裝 大台電動玩具

Page 201: 用Raspberry Pi學GPIO - 自己做遊戲機

201

DEMOgaming_console.py

$ cd ~/gpio-game-console

$ cd 13-gaming_console

$ sudo python gaming_console.py

Page 202: 用Raspberry Pi學GPIO - 自己做遊戲機

202

更多應用

Page 203: 用Raspberry Pi學GPIO - 自己做遊戲機

203http://makezine.com/2013/04/14/47-raspberry-pi-projects-to-inspire-your-next-build/

Page 204: 用Raspberry Pi學GPIO - 自己做遊戲機

204

Raspberry Pi Rocks the World

Thanks

Page 205: 用Raspberry Pi學GPIO - 自己做遊戲機

205

補充:自己編譯AdvanceMAME

Page 206: 用Raspberry Pi學GPIO - 自己做遊戲機

206

● 安裝gcc-4.8

● $ sudo apt-get install gcc-4.8● 下載advancemame-1.4.tar.gz

● http://www.advancemame.it/download● 安裝

● $ sudo apt-get install -y gcc-4.8 libsdl1.2-dev● $ tar zxvf advancemame-1.4.tar.gz● $ cd advancemame-1.4/● $ CC=gcc-4.8 GCC=g++-4.8 ./configure --disable-fb● $ make -j4● $ ./advmame

AdvanceMAME

Page 207: 用Raspberry Pi學GPIO - 自己做遊戲機

207

● 1.產生rc檔● $ cd /home/pi/advancemame-1.4● $ chmod 755 advmame● $ ./advmame

● 2.下載rom● $ cd /home/pi/.advance/rom

● 3. 執行模擬器

● $ cd /home/pi/advancemame-1.4● $ ./advmame suprmrio

執行模擬器

Page 208: 用Raspberry Pi學GPIO - 自己做遊戲機

208

補充: AdvanceMAME 性能調校

Page 209: 用Raspberry Pi學GPIO - 自己做遊戲機

209

● 修改解析度 , 改為 256x240x60● tab鍵進入選單 , 選擇 Video Mode, ESC離

我的 AdvanceMAME很慢?

Page 210: 用Raspberry Pi學GPIO - 自己做遊戲機

210

● 修改解析度 , 改為 256x240x60● tab鍵進入選單 , 選擇 Video Mode, ESC離

我的 AdvanceMAME很慢?

Page 211: 用Raspberry Pi學GPIO - 自己做遊戲機

211

● 修改解析度 ,改為 256x240x60● tab鍵進入選單 ,選擇 Video Mode, ESC離開

我的 AdvanceMAME很慢?

Page 212: 用Raspberry Pi學GPIO - 自己做遊戲機

212

補充: Raspberry Pi 的開機流程

Page 213: 用Raspberry Pi學GPIO - 自己做遊戲機

213

Linux 開機流程

http://goo.gl/taI5fw

Page 214: 用Raspberry Pi學GPIO - 自己做遊戲機

214http://myembeddedlinux.blogspot.tw/2013/05/raspberry-pi-boot-sequence.html

Pi 開機流程

Page 215: 用Raspberry Pi學GPIO - 自己做遊戲機

215

Raspbian Jessie Pi 開機流程

Page 216: 用Raspberry Pi學GPIO - 自己做遊戲機

216

使用者登入與進入桌面環境

http://linux.vbird.org/linux_basic/0320bash.php

Page 217: 用Raspberry Pi學GPIO - 自己做遊戲機

217

Debian 的演進

http://forums.debian.net/viewtopic.php?f=5&t=125562

Page 218: 用Raspberry Pi學GPIO - 自己做遊戲機

218

sysvinit, upstart, systemd

Page 219: 用Raspberry Pi學GPIO - 自己做遊戲機

219

● Systemd是 Jessie預設的初始化系統 , 包括

● 啟動系統與個人服務● 提供管理工具

核心載入後 , 交給 systemd處理

Page 220: 用Raspberry Pi學GPIO - 自己做遊戲機

220

systemd架構

https://pl.wikipedia.org/wiki/Systemd

Page 221: 用Raspberry Pi學GPIO - 自己做遊戲機

$ sudo nano /lib/systemd/system/my_systemd.service● [Unit]

Description=Add a New Systemd

[Service]

ExecStart=/home/pi/my_systemd.sh

[Install]

WantedBy=multi-user.target

$ sudo systemctl daemon-reload

新增 systemd 設定檔