Slide 1

Slide 1 text

1 Raspberry Pi 遊戲機工作坊 - 從 GPIO 開始和世界連接 台灣樹莓派

Slide 2

Slide 2 text

姓名標示 — 非商業性 — 相同方式分享 CC (Creative Commons) 姓名標示 — 你必須給予 適當表彰、提供指向本授權 條款的連結,以及 指出(本作品的原始版本)是否已 被變更。你可以任何合理方式為前述表彰,但不得以 任何方式暗示授權人為你或你的使用方式背書。 非商業性 — 你不得將本素材進行商業目的之使 用。 相同方式分享 — 若你重混、轉換本素材,或依本 素材建立新素材,你必須依本素材的授權條款來 散布你的貢獻物。

Slide 3

Slide 3 text

3 ● Raspberry Pi 官方經銷商 ● 專注 Raspberry Pi 應用與推廣 , 舉辦社群活動 關於我們

Slide 4

Slide 4 text

4 ● COSCUP,MakerConf,PyCon,HKOSCon 講者 ● 投影片 ● https://speakerdeck.com/piepie_tw ● 程式碼 ● https://github.com/piepie-tw 分享 x 教學

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

6 ● Raspberry Pi GPIO 介紹 ● 環境設定 ● 輸入 / 輸出 ● 數位 / 類比 ● 練習與實做 本次主題

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

8 ● 硬體:Raspberry Pi 4B ● 作業系統:2021-05-07-raspios-buster-armhf-full.img ● 為了可以使用USB 轉TTL 傳輸線 ● 修改/boot/config.txt, 新增三行 – dtoverlay=pi3-miniuart-bt – core_freq=250 – enable_uart=1 ● 修改/boot/cmdline.txt, 將quiet splash 的quiet 移除 今日環境 刪除 quiet 新增三行

Slide 9

Slide 9 text

9 ● $ sudo apt-get update ● $ sudo apt-get install -y python3-dev python3-pip libsdl1.2-dev vim ● $ sudo pip3 install spidev evdev 安裝今日所需套件

Slide 10

Slide 10 text

10 Raspberry Pi GPIO 介紹

Slide 11

Slide 11 text

11 ● General Purpose Input Output ● GPIO 是一種可用軟體控制的數位訊號 什麼是 GPIO ? http://www.tek.com/datasheet/tps2000b-series-digital-storage-oscilloscopes-datasheet

Slide 12

Slide 12 text

12 ● 決定是輸入還是輸出 ● 輸出:寫值到某根腳位 ● 輸入:從某根腳位讀值 ● 等待中斷 (interrupt) 的發生 ● 決定是正緣觸發還是負緣觸發 用軟體控制什麼 ?

Slide 13

Slide 13 text

13 GPIO 腳位在哪裡? http://www.raspberrypi-spy.co.uk/ Pin1 Pin2 Pin25 Pin26 Pin3 Pin4 Z Z 字型的腳位編號

Slide 14

Slide 14 text

14 ● GPIO 高電位輸出為 3.3V ● GPIO 容忍輸入電位為 3.3V ● 單一 Pin 輸出電流為 3mA-16mA ● 全部 Pin 輸出總和小於 50mA ● GPIO 輸入低電位為小於 0.8V, 高電位為大於 1.3V 幾個 GPIO 的數字 https://www.scribd.com/doc/101830961/GPIO-Pads-Control2

Slide 15

Slide 15 text

15 ● C ● C + wiringPi ● C# ● Ruby ● Perl ● Python ● Scratch ● Java Pi4J Library ● Shell script 如何控制 Raspberry Pi 的 GPIO ?

Slide 16

Slide 16 text

16 ● 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

Slide 17

Slide 17 text

17 Python + GPIO

Slide 18

Slide 18 text

18 ● 變數 , 物件 , 型別 , 註解 ● 模組 ● 縮排 ● 迴圈 ● 條件判斷 ● 函式 Python3 五分鐘速成

Slide 19

Slide 19 text

19 ● 動態型別 (dynamic typing) # 這是註解 i = 3 # 變數 i 指到數字物件 3 i = [1, 2, 3, 4, 5] # 變數 i 指到串列物件 print(i[2]) # 印出串列中第三個元素 i = "abcde" # 變數 i 指到字串物件 print(i[2]) # 印出字串中第三個元素 變數 , 物件 , 型別 , 註解

Slide 20

Slide 20 text

20 # import MODULE import RPi.GPIO # import MODULE as ALIAS import RPi.GPIO as GPIO 模組

Slide 21

Slide 21 text

21 ● 用縮排取代大括號 ● 程式碼的區塊是用縮排分隔 ● 不使用 tab, 使用空白鍵 ● 常見縮排為 4 個空白鍵 縮排

Slide 22

Slide 22 text

22 ● 自動迭代 (iterator) for i in range(start, stop[, step]): process for i in range(0, 11, 5): print(i) 迴圈

Slide 23

Slide 23 text

23 if condition_1: process_1 elif condition_2: process_2 else: process_3 process_4 條件判斷

Slide 24

Slide 24 text

24 def function_name(): process def function_name(param_name): process def function_name(param_name = 3): process 函式

Slide 25

Slide 25 text

25 ● 1. 存成檔案以後 , 用 python 執行 ● $ nano test.py ● $ python3 test.py ● 2. 進到互動模式 , 可直接看輸出結果 ● $ python3 Python 3.5.3 (default, Sep 27 2018, 17:25:39) ● [GCC 6.3.0 20170516] on linux ● Type "help", "copyright", "credits" or "license" for more information. >>> 兩種執行 Python 的方法

Slide 26

Slide 26 text

26 電子入門套件 ● 紅/ 黃/ 綠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

Slide 27

Slide 27 text

27 本套件相容於全系列 Raspberry Pi 購買 : https://www.piepie.com.tw/2557/

Slide 28

Slide 28 text

28 數位輸出

Slide 29

Slide 29 text

29 實驗 1: 硬體的 Hello World 目的 : 從硬體到軟體的思維

Slide 30

Slide 30 text

30 ● 發光二極體 ● 單向導通 ● 省電 LED http://upload.wikimedia.org/wikipedia/commons/c/c8/5mm_Red_LED.jpg 長腳接正極 Vcc 短腳接負極 GND

Slide 31

Slide 31 text

31 ● 電路組成元件 : 電源、導線、負載 ● 閉路 : 當三者形成一完整路徑 , 有電流經過電路 ● 歐姆定律 : 導體兩端的電壓與通過的電流成正比 ● V = I x R 電路一分鐘速成 I I V R V R I https://zh.wikipedia.org/wiki/ 电路

Slide 32

Slide 32 text

32 Raspberry Pi + LED 直接插入嗎 ? 先看看規格吧

Slide 33

Slide 33 text

33 ● V F : 順向電壓 ● I F : 在順向電壓下的安全電流 LED 的特性 https://learn.adafruit.com/all-about-leds/forward-voltage-and-kvl

Slide 34

Slide 34 text

34 ● 在順向電壓下一般的 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 燒毀 如何解讀?

Slide 35

Slide 35 text

35 電阻阻值計算 www.digikey.tw/tw/zht/mkt/5-band-resistors.html 四環:右側為金或銀 五環:前四環很靠近 1K= 棕黑黑棕 ( 棕 ) 2K= 紅黑黑棕 ( 棕 )

Slide 36

Slide 36 text

36 要接哪一個腳位?

Slide 37

Slide 37 text

37 要接哪一個腳位? 目標 : 一隻腳接地 , 一隻腳給電

Slide 38

Slide 38 text

38 線路圖 LED RPi 長腳 (RED) Pin12 (GPIO18) 短腳 (BLACK) Pin6 (Ground) 1k 電阻 : 棕黑黑棕 ( 棕 )

Slide 39

Slide 39 text

39 線路圖 LED RPi 長腳 (RED) Pin12 (GPIO18) 短腳 (BLACK) Pin6 (Ground) 1k 電阻 : 棕黑黑棕 ( 棕 )

Slide 40

Slide 40 text

40 麵包板的種類 https://goo.gl/JipVgH

Slide 41

Slide 41 text

麵包板的使用 https://www.slideshare.net/eoinbrazil/imediaarduino08

Slide 42

Slide 42 text

42 使用麵包板方便多了 1k 電阻 LED RPi 長腳 (RED) Pin12 (GPIO18) 短腳 (BLACK) Pin6 (Ground)

Slide 43

Slide 43 text

43 ● 試試看這樣接 不會亮嗎? 因為你沒寫程式阿

Slide 44

Slide 44 text

44 各腳位的意義 https://goo.gl/f2rPpN

Slide 45

Slide 45 text

45 開始用 Python 控制 GPIO 吧

Slide 46

Slide 46 text

46 ● 載入模組 (Import module) ● 選擇編號系統 (Define pin numbering) ● 定義腳位 (Setup up a channel) ● 讀取輸入 / 寫入輸出 (Input/Output) ● 清理 (Cleanup) Python Code 基本流程 http://code.google.com/p/raspberry-gpio-python/wiki/BasicUsage

Slide 47

Slide 47 text

47 #!/usr/bin/python3 ● 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 一個實際的範例 以下都是使用別名 (alias)

Slide 48

Slide 48 text

48 DEMO led_on.py $ python3 led_on.py

Slide 49

Slide 49 text

49 使用 :nano < 檔名 , 例如 led_on.py> 離開 :Ctrl + x > 令存新檔 :y > 不存離開 :n > 離開 :Ctrl + c nano 編輯器使用

Slide 50

Slide 50 text

50 $ cd ~ $ git clone https://github.com/piepie-tw/gpio-game-console $ cd ~/gpio-game-console $ cd 01-led_on $ python3 led_on.py 讀寫 GPIO 會存取 /dev/mem, 需 root 權限 (2015-09-24 以後的 image 可以用一般使用者身份執行 ) 執行方式

Slide 51

Slide 51 text

51 ● 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 的使用方法

Slide 52

Slide 52 text

52 實驗 2: 控制 LED 閃爍 目的 : 熟悉 Python 語法

Slide 53

Slide 53 text

53 一樣的線路圖 LED RPi 長腳 (RED) Pin12 (GPIO18) 短腳 (BLACK) Pin6 (Ground) 1k 電阻

Slide 54

Slide 54 text

54 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 跳出迴圈

Slide 55

Slide 55 text

55 DEMO led_blink_warning.py $ cd ~/gpio-game-console $ cd 02_1-led_blink_warning $ python3 led_blink_warning.py

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

57 為什麼出現 Warning ?

Slide 58

Slide 58 text

58 ● 在正常情況下執行完畢結束 ● 遇到錯誤跳出 ● 受到中斷停止 ( 收到終止訊號 , 例如 Ctrl+c) 程式何時會結束 ?

Slide 59

Slide 59 text

59 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() 接住例外

Slide 60

Slide 60 text

60 DEMO led_blink.py $ cd ~/gpio-game-console $ cd 02_2-led_blink $ python3 led_blink.py

Slide 61

Slide 61 text

61 實驗 3: 用 LED 做交通號誌 目的 : 結構化程式設計

Slide 62

Slide 62 text

62 ● 紅 , 黃 , 綠燈依序亮燈 ● 紅燈亮 4 秒 , 黃燈亮 2 秒 , 綠燈亮 4 秒 設計一個紅綠燈 http://www.clipartbest.com/traffic-light-photo

Slide 63

Slide 63 text

63 線路圖

Slide 64

Slide 64 text

64 DEMO traffic_light_nonstructure.py $ cd ~/gpio-game-console $ cd 03_1-traffic_light_nonstructure $ python3 traffic_light_nonstructure.py

Slide 65

Slide 65 text

65 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() 把亮燈拿到外面

Slide 66

Slide 66 text

66 DEMO traffic_light.py $ cd ~/gpio-game-console $ cd 03_2-traffic_light $ python3 traffic_light.py

Slide 67

Slide 67 text

67 數位輸入

Slide 68

Slide 68 text

68 實驗 4: 讀取按鍵輸入 目的 : 了解硬體和軟體的差異

Slide 69

Slide 69 text

69 ● 開關:按鍵式 , 滑動式 , 傾斜式 ... 按鍵 Button / 開關 Switch http://nicegear.co.nz/

Slide 70

Slide 70 text

70 ● 常開 (normally open, N.O.) ● 常閉 (normally close, N.C.) 按鍵 Button / 開關 Switch http://www.engineersgarage.com/sites/default/files/imagecache/Original/wysiwyg_imageupload/4214/Switch-2_0.jpg

Slide 71

Slide 71 text

71 按鍵的內部結構 http://www.ladyada.net/learn/arduino/lesson5.html ● 按下前 ● 長邊相連 (1&2,3&4) ● 短邊不相連 ● 按下後 ● 四點都通 1 2 3 4

Slide 72

Slide 72 text

72 簡單的按鍵接法 BUTTON RPi 腳 1 Pin6 (Ground) 腳 3 Pin11 (GPIO17)

Slide 73

Slide 73 text

73 ● Input 空接會讀到雜訊 問題在哪裡? 按鍵按下前未導通 , 讀到?? 按鍵按下後 , 讀到低電位

Slide 74

Slide 74 text

74 更好的按鍵接法 ( 上拉電阻 ) http://geekgurldiaries.blogspot.tw/2012/12/part-2.html

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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() 判斷條件 : 這次低 && 上次高

Slide 77

Slide 77 text

77 DEMO push_button_poll.py $ cd ~/gpio-game-console $ cd 04_1-push_button_poll $ python3 push_button_poll.py

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

79 ● 機械式開關在切換過程中會有訊號彈跳現象 ( 雜訊 ) 開關訊號的彈跳問題 (bounce) http://120.101.72.1/Onechip/PPT/ 實習單元三 .ppt 理想訊號輸出 實際輸出訊號

Slide 80

Slide 80 text

80 ● 硬體方法 : 以 RC 電路或正回授的比較器電路解決 ● 軟體方法 : 調整觸發的延遲時間 ● 不同的按鍵會有不同的延遲時間 解決彈跳問題 (de-bounce) 10ms - 20ms

Slide 81

Slide 81 text

81 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) > 0.2: previousTime = currentTime print("Button pressed”) previousStatus = input 不反應在延遲時間內的觸發

Slide 82

Slide 82 text

82 DEMO push_button_debounce.py $ cd ~/gpio-game-console $ cd 04_2-push_button_debounce $ python3 push_button_debounce.py

Slide 83

Slide 83 text

83 ● 先以背景方式執行單一程式 ( 加上 &) ● $ python3 push_button_debounce.py & 如何看系統效能? PID

Slide 84

Slide 84 text

84 ● 先以背景方式執行單一程式 ( 加上 &) ● $ python3 push_button_debounce.py & ● 再看整體系統使用狀況 ( 按 q 離開 ) ● $ top -c 如何看系統效能? PID

Slide 85

Slide 85 text

85 在 top 指令中止程序 在 top 指令中按 k 輸入要中止的程序 PID 輸入 KILL 訊號 9 中止程序

Slide 86

Slide 86 text

86 使用 ps 指令查詢程序 使用 ps aux | grep python3 搜尋程序 使用指令 kill 送出中止訊號 9 給程序 再次使用 ps aux 已經沒有該程序了

Slide 87

Slide 87 text

87 ● 輪詢 (polling) ● SoC 每隔一段時間檢查週邊硬體的資料 ● 中斷 (interrupt) ● 當週邊硬體的狀態改變時 , 對 SoC 發出中斷要求 輪詢與中斷

Slide 88

Slide 88 text

88 ● 建立回呼函數 ● def mycallback() ● 綁定事件和回呼函數 ● add_event_detect(gpio, # 對象 edge, # 觸發條件 callback,# 回呼函數 bouncetime) ● 多個事件可以綁定同樣的回呼函數 中斷的程式寫法 source/py_gpio.c

Slide 89

Slide 89 text

89 BTN_PIN = 11 GPIO.setup(BTN_PIN, GPIO.IN) def mycallback(channel): print("Button pressed") try: GPIO.add_event_detect(BTN_PIN, \ GPIO.FALLING, \ callback=mycallback, \ bouncetime=200) while True: time.sleep(10) finally: GPIO.cleanup() 即使在 sleep 狀態下也可立即回應

Slide 90

Slide 90 text

90 DEMO push_button_interrupt.py $ cd ~/gpio-game-console $ cd 04_3-push_button_interrupt $ python3 push_button_interrupt.py

Slide 91

Slide 91 text

91 ● 需要硬體或軟體 ( 作業系統 ) 的支援 ● RPi.GPIO 在版本 0.5.0a 有了中斷功能 ● 加上 add_event_detect() 等機制 ● RPi.GPIO 以建立多執行緒方式實現中斷 ● 程式開始執行時 , 主執行序運行 ● 當加入事件後 , 以 epoll_create 建立新的 fd ● 當事件觸發時 , 第二個執行序和主執行序溝通 ( 回呼 ) ● 程式碼可參考 source/event_gpio.c 中斷的意義 source/py_gpio.c

Slide 92

Slide 92 text

92 簡單的按鍵接法沒有錯 , 但是 ... BUTTON RPi 腳 1 Pin6 (Ground) 腳 3 Pin11 (GPIO17)

Slide 93

Slide 93 text

93 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)

Slide 94

Slide 94 text

94 DEMO push_button_internal_pull_up.py $ cd ~/gpio-game-console $ cd 04_4-push_button_internal_pull_up $ python3 push_button_internal_pull_up.py

Slide 95

Slide 95 text

95 實驗 5: 傾斜開關 目的 : 認識不同的硬體

Slide 96

Slide 96 text

96 傾斜開關 Tilt Switch

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

98 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)

Slide 99

Slide 99 text

99 DEMO tilt_switch.py $ cd ~/gpio-game-console $ cd 05-tilt_switch $ python3 tilt_switch.py 使用內建的上拉電阻

Slide 100

Slide 100 text

100 實驗 6: 蜂鳴器樂器 目的 : 聲音輸出

Slide 101

Slide 101 text

101 ● 發聲原理 : 聲音是由振動產生 , 其頻率稱為音頻 ● 蜂鳴器發聲原理 : 電流 (6) 通過電磁線圈 (3) 產生 磁場來驅動振動膜 (11) ● 人耳可聽到 20Hz - 20KHz 原理 http://www.itianer.com/diancishifengmingqigouzaoyuyuanlijieshao.html

Slide 102

Slide 102 text

102 ● 自激 ( 有源 ): 只能發出同頻率的聲音 ● 黑膠封裝 , 高低腳 ● 他激 ( 無源 ): 需從外部輸入震盪方波發聲 ● 綠色電路板 , 兩腳同長 ● 腳位有正負之分 ( 看底板 ) 蜂鳴器 Buzzer http://www.buzzer-speaker.com/manufacturer/piezo%20buzzer.htm 自激式 他激式

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

104 def buzz(pitch, duration) : period = 1.0 / pitch half_period = period / 2 cycles = int(duration * pitch) for i in range(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 = input("Enter Pitch (200 to 2000): ") duration_s = input("Enter Duration (seconde): ") buzz(float(pitch_s), float(duration_s)) 可發出不同頻率聲音

Slide 105

Slide 105 text

105 DEMO buzzer.py $ cd ~/gpio-game-console $ cd 06_1-buzzer $ python3 buzzer.py

Slide 106

Slide 106 text

106 ● ● 標準 88 鍵鋼琴 , 每個音的頻率 : ● 每段音階分為 12 個半音 ● 每個音的頻率是前一個的 1.05946 倍 ( ) 鋼琴模擬 1 2 3 4 5 6 7 0 8 http://en.wikipedia.org/wiki/Piano_key_frequencies 12 2

Slide 107

Slide 107 text

107 ● 標準 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

Slide 108

Slide 108 text

108 線路圖 RPi Pin7 Buzzer Pin11 Do Pin12 Re Pin13 Me Pin15 Fa Pin16 So Pin18 La Pin22 Si

Slide 109

Slide 109 text

109 DEMO paino_buzzer.py $ cd ~/gpio-game-console $ cd 06_2-paino_buzzer $ python3 paino_buzzer.py

Slide 110

Slide 110 text

110 實驗 7: 人體紅外線感測器 目的 : 常見感測器使用

Slide 111

Slide 111 text

111 Pyroelectric ("Passive") InfraRed Sensor PIR 人體紅外線感測器 http://www.raspberrypi-spy.co.uk/2013/01/cheap-pir-sensors-and-the-raspberry-pi-part-1/

Slide 112

Slide 112 text

112 使用示意圖 http://www.ladyada.net/learn/sensors/pir.html

Slide 113

Slide 113 text

113 應用範例 http://www.ladyada.net/learn/sensors/pir.html http://totherails.blogspot.tw/2011/09/halloween-preparations.html

Slide 114

Slide 114 text

114 元件說明 http://www.ladyada.net/learn/sensors/pir.html

Slide 115

Slide 115 text

115 ● 輸入電壓 :DC 3.3V - 24V ● 輸出電壓 :3.3V( 可直接接上 Raspberry Pi) ● 延遲時間 (Tx):2.45 秒 – 248 秒 ● 感應之後輸出維持的時間 ● 封鎖時間 (Ti):2.4 秒 ● 感應輸出結束之後 , 再次觸發必須等待的時間 ● 感應角度 :110 度 x 70 度 ● 感應距離 :3 米 - 7 米 瞭解規格

Slide 116

Slide 116 text

116 ● 感測距離設定 ● 順時針 : 最高為 7 米 ● 逆時針 : 最小為 3 米 ● 延遲時間設定 (Tx) ● 順時針 : 最長為 248 秒 ● 逆時針 : 最短為 2.45 秒 ● 實際可調整時間要看 R10,C6,R9,C7 而定 感測距離 / 延遲時間設定 感測距離設定 延遲時間設定

Slide 117

Slide 117 text

117 ● 可重複觸發模式 (H) ● 不可重複觸發模式 (L) 觸發模式 H: 可重複觸發 L: 不可重複觸發 ( 預設 ) 感應 & 輸出 感應 & 等待 & 輸出

Slide 118

Slide 118 text

118 線路圖 Pin26

Slide 119

Slide 119 text

119 PIR_PIN = 26 GPIO.setup(PIR_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 模式

Slide 120

Slide 120 text

120 DEMO pir.py $ cd ~/gpio-game-console $ cd 07_1-pir $ python3 pir.py 觸發才拉高電位 , 因此用內建的下拉電阻

Slide 121

Slide 121 text

121 加上警示的 LED 燈吧

Slide 122

Slide 122 text

122 線路圖 1k 電阻 Pin26

Slide 123

Slide 123 text

123 DEMO people_alarm_system.py $ cd ~/gpio-game-console $ cd 07_2-people_alarm_system $ python3 people_alarm_system.py

Slide 124

Slide 124 text

124 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 range(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 次

Slide 125

Slide 125 text

125 實驗 8: 超音波距離感測器 目的 : 根據規格撰寫程式

Slide 126

Slide 126 text

126 ● 聲音在 20°C (68°F) 的速度是 343 公尺 / 秒 ● 溫度每增加 1°, 速度增加 0.6 公尺 / 秒 測距離原理 http://en.wikipedia.org/wiki/Speed_of_sound https://www.modmypi.com/blog/hc-sr04-ultrasonic-range-sensor-on-the-raspberry-pi

Slide 127

Slide 127 text

127 ● 內建發射 (40kHz) 與接收電路 ● 根據發射與接收的時間差計算距離 ● 特殊功能 :US-020( 長距離 ) 、 US-100( 溫度補償 ) HC-SR04 超音波距離感測器 http://coopermaa2nd.blogspot.tw/2012/09/hc-sr04.html

Slide 128

Slide 128 text

128 ● 避障 , 測距 ● 物體移動感測 ● 地鐵感測器 應用 http://letsmakerobots.com/robot/project/rock-crawler https://www.dropbox.com/s/x0qdaq86rkc0zyv/MakerConf.pdf

Slide 129

Slide 129 text

129 地鐵感測器 http://makezine.com/magazine/ultrasonic-train-detector-in-stockholm-subway/

Slide 130

Slide 130 text

130 地鐵感測器 http://makezine.com/magazine/ultrasonic-train-detector-in-stockholm-subway/

Slide 131

Slide 131 text

131 ● 規格與時序圖 HC-SR04 http://coopermaa2nd.blogspot.tw/2012/09/hc-sr04.html 建議測量間隔 >60ms

Slide 132

Slide 132 text

132 ● 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

Slide 133

Slide 133 text

133 注意 1K, 2K 電阻 ULTRASONIC RPi Vcc(RED) Pin2 (5V) Trig(YELLOW) Pin16 (GPIO23) Echo(PURPLE) Pin18 (GPIO24) Grnd(BLACK) Pin6 (Ground) 1k: 棕黑黑棕 2k: 紅黑黑棕 Vcc Gnd Echo Trig 這是背面

Slide 134

Slide 134 text

134 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 = None pulse_end = None 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 測量距離

Slide 135

Slide 135 text

135 DEMO hc_sr04_measure_distance.py $ cd ~/gpio-game-console $ cd 08-hc_sr04_measure_distance $ python3 hc_sr04_measure_distance.py

Slide 136

Slide 136 text

136 看看準不準?

Slide 137

Slide 137 text

137 實驗 9: 呼吸燈 目的 : 瞭解訊號模擬

Slide 138

Slide 138 text

138 ● 數位 :0 與 1 的訊號 ● 類比 : 連續的訊號 數位與類比 http://www.bitscope.com/software/blog/DJ/?p=DJ19A

Slide 139

Slide 139 text

139 ● 數位 : 亮和不亮 ● 類比 : 亮 , 有點亮 , 有點不亮 ..., 不亮 ● 可是 GPIO 腳位輸出都是固定值 , 怎麼辦? 從 LED 的角度來看

Slide 140

Slide 140 text

140 ● 旋轉式 , 滑動式 ● 線性關係 (B 型 ), 對數關係 (A 型 ) ● 常見規格 :0 -10k Ohm( 線性 ) 可變電阻 Potentiometer(VR) https://en.wikipedia.org/wiki/Potentiometer 接高電位 接低電位 滑動接點 ( 可變輸出 )

Slide 141

Slide 141 text

141 利用可變電阻改變 LED 亮度

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

143 ● 是將數位信號轉為脈波的一種技術 ● 頻率不變 + 改變工作週期 , 使整體平均電壓值改變 ● 改變工作週期 (duty cycle)= 改變平均電壓 脈寬調變 (Pulse-Width Modulation) http://wiki.csie.ncku.edu.tw/embedded/PWM

Slide 144

Slide 144 text

144 ● 輸出總功率 = 脈衝寬度 ( 時間 )x 高電位值 公式計算 http://www.protostack.com/blog/2011/06/atmega168a-pulse-width-modulation-pwm/

Slide 145

Slide 145 text

145 ● 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/

Slide 146

Slide 146 text

146 線路圖 LED RPi 長腳 (RED) Pin12 (GPIO18) 短腳 (BLACK) Pin6 (Ground) 1k 電阻

Slide 147

Slide 147 text

147 LED_PIN = 12 ● GPIO.setup(LED_PIN, GPIO.OUT) pwm_led = GPIO.PWM(LED_PIN, 100) ● pwm_led.start(0) ● ● try: ● while True: ● duty_s = 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() 互動式的調光

Slide 148

Slide 148 text

148 DEMO adjust_led_bright.py $ cd ~/gpio-game-console $ cd 09_1-adjust_led_bright $ python3 adjust_led_bright.py

Slide 149

Slide 149 text

149 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 range(0, 101, 5): pwm_led.ChangeDutyCycle(dc) time.sleep(0.1) time.sleep(0.5) for dc in range(100, -1, -5): pwm_led.ChangeDutyCycle(dc) time.sleep(0.1) time.sleep(0.5) 呼吸燈就是漸明漸亮

Slide 150

Slide 150 text

150 DEMO pwm_led.py $ cd ~/gpio-game-console $ cd 09_2-pwm_led $ python3 pwm_led.py

Slide 151

Slide 151 text

151 ● 兩者差異 ● Software PWM 是透過 kernel 做 duty cycle 的調整 ● Hardware PWM 是 SoC 透過 DMA 做調整 ● 使用時機 ● 不需要精準時用 Software PWM, 例如 LED 調光 ● 需要低延遲時用 Hardware PWM, 例如伺服馬達 ● Hardware PWM GPIO 只有 GPIO12(Pin32), GPIO13(Pin33), GPIO18(Pin12), GPIO19(Pin35) ● 目前已經內建 pigpio 提供 Hardware PWM 函式呼叫 Software PWM vs. Hardware PWM

Slide 152

Slide 152 text

152 實驗 10: 光敏電阻 目的 : 類比訊號的讀取

Slide 153

Slide 153 text

153 ● 硫化鎘 (CdS) 或光敏電阻器 (LDR), 阻抗隨光落 在表面的總量而轉變 ● 光越強阻值越小 , 反之光越弱阻值則越大 ● 應用 : 光控開關 , 電子玩具 , 工業控制 光敏電阻 http://www2.nkfust.edu.tw/~jlkuo2/31/a6.htm

Slide 154

Slide 154 text

154 ● 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 軸 )

Slide 155

Slide 155 text

155 ● 類比數位轉換器 (Analog to Digital Converter) ● 8 通道 ,10 bits 解析度 ● SPI 協議 利用 MCP3008

Slide 156

Slide 156 text

156 ● 主從式架構 , 可一對多 ● 四線同步序列資料協定 ● SS: 週邊選擇線 (CE) ● SCK: 序列時脈線 (SCLK) ● MOSI: 主往從送 ● MISO: 從往主送 Serial Peripheral Interface(SPI) https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus SPI Master SCLK MOSI MISO SS1 SS2 SS3 SPI Slave SCLK MOSI MISO SS SPI Slave SCLK MOSI MISO SS SPI Slave SCLK MOSI MISO SS

Slide 157

Slide 157 text

157 ● $ sudo raspi-config 啟用 Raspberry Pi 的 SPI

Slide 158

Slide 158 text

158 ● $ sudo raspi-config 啟用 Raspberry Pi 的 SPI

Slide 159

Slide 159 text

159 ● $ sudo raspi-config 啟用 Raspberry Pi 的 SPI

Slide 160

Slide 160 text

160 ● 測試確認 SPI 模組已載入 ● $ ls /dev/spi* ● 安裝必要套件 ( 如果前面已裝過 , 就不需再裝 ) ● $ sudo apt-get update ● $ sudo apt-get install -y python-dev ● $ sudo pip install spidev SPI 使用前的確認

Slide 161

Slide 161 text

161 線路圖 MCP3008 RPi CLK Pin23 (SCLK) Din Pin19 (MOSI) Dout Pin21 (MISO) CS Pin24 (CE0) 缺口朝左 1k 電阻

Slide 162

Slide 162 text

162 ● SPI 會用到的腳位是 MOSI,MISO,SCLK 和 CE0/CE1 再看一次腳位定義

Slide 163

Slide 163 text

163 spi = spidev.SpiDev() spi.open(0,0) # (0,0)表示接到CE0腳位,對應到/dev/spidev0.0裝置檔 spi.max_speed_hz = 1800000 # 10kHz to 3.6 MHz ● ● 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)

Slide 164

Slide 164 text

164 程式要照硬體規格撰寫

Slide 165

Slide 165 text

165 ● 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 care Ch0/Ch1

Slide 166

Slide 166 text

166 http://wolfpaulus.com/

Slide 167

Slide 167 text

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

Slide 168

Slide 168 text

168 DEMO photoresistor.py $ cd ~/gpio-game-console $ cd 10-photoresistor $ python3 photoresistor.py

Slide 169

Slide 169 text

169 再透過分壓電路回推光敏電阻阻值 光越強,電壓值越低

Slide 170

Slide 170 text

170 實驗 13: 模擬器 目的 : 系統整合

Slide 171

Slide 171 text

171 遊戲機 = 硬體 + 遊戲 http://www.emulatorworld.com/

Slide 172

Slide 172 text

172 ● 模擬不同的硬體架構 ● 常見的模擬器: ● 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

Slide 173

Slide 173 text

173 ● 模擬大台電動玩具 MAME(Multiple Arcade Machine Emulator) http://www.williamsamusements.co.uk/mame.html

Slide 174

Slide 174 text

174 ● RFB 協定 + 螢幕畫面分享及遠端操作軟體 ● 與作業系統無關 , 可跨平台使用 ● Client/Server 架構 用 Virtual Network Computing 看畫面 Raspberry Pi 當 VNC Server Laptop/PC 當 VNC client

Slide 175

Slide 175 text

175 ● $ sudo raspi-config 開啟 VNC Server 服務

Slide 176

Slide 176 text

176 ● $ sudo raspi-config 開啟 VNC Server 服務

Slide 177

Slide 177 text

177 ● $ sudo raspi-config 開啟 VNC Server 服務

Slide 178

Slide 178 text

178 ● 下載 realvnc viewer https://www.realvnc.com/en/connect/download/viewer x11vnc Client 安裝 port 和 x11vnc 相同

Slide 179

Slide 179 text

179

Slide 180

Slide 180 text

180 先不要更新

Slide 181

Slide 181 text

181 ● 下載編譯好的binary(已下載) ● $ cd ~ ● $ wget http://bit.ly/2OnUMwh -O ~/advmame ● $ chmod 755 advmame ● $ ./advmame ● 2.下載ROM(已下載) ● $ cd ~ ● $ wget http://bit.ly/2K1dhUb -O ~/.advance/rom/suprmrio.zip ● 3. 執行模擬器(還沒做) ● $ cd ~ ● $ ./advmame suprmrio 在 VNC 下執行 AdvanceMAME 大寫的英文 " 歐 "

Slide 182

Slide 182 text

182 ● 搜尋 MAME ● http://www.emuparadise.me/ ● 中英文對照 ● http://bbs.duowan.com/thread-41350071-1-1.html ● 經典遊戲 ● 超級瑪莉歐 ● 彈珠台 ● 小精靈 ● 坦克大作戰 , 泡泡龍 ... 下載 ROM 放到對應的目錄下 http://en.wikipedia.org/wiki/Nintendo_Entertainment_System

Slide 183

Slide 183 text

183 ● $ cd ~ ● $ ./advmame suprmrio ● 按 'o' 'k' 進入畫面 ● 按 '5' 投錢 ● 按 '1' 開始 ● 左邊 'ctrl' 是加速 ● 左邊 'alt' 是跳 ● 按 'esc' 是離開 使用模擬器

Slide 184

Slide 184 text

184 ● 執行模擬器 , 使用 keyboard 控制 ● 讀取 GPIO 搖桿的值 ● 讓 GPIO 搖桿和 keyboard 對應 ● 開機就啟動按鍵與 keyboard 對應程式 ● 開機就啟動模擬器 遊戲機製作步驟 http://www.linuxuser.co.uk/tutorials/emulate-a-bluetooth-keyboard-with-the-raspberry-pi

Slide 185

Slide 185 text

185 搖桿 (joystick)

Slide 186

Slide 186 text

186 ● 3.3V-5V 工作電壓 ● 輸出形式: ● x,y 軸 - 類比輸出 ● z 軸 - 數位輸出 XY 雙軸搖桿 http://www.aliexpress.com/cheap/cheap-arduino-joystick.html

Slide 187

Slide 187 text

187 http://www.raspberrypi-spy.co.uk/2014/04/using-a-joystick-on-the-raspberry-pi-using-an-mcp3008/ +5V MS VRY VRX GND

Slide 188

Slide 188 text

188 spi = spidev.SpiDev() ● spi.open(0,0) ● spi.max_speed_hz = 1800000 ● ● 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)

Slide 189

Slide 189 text

189 DEMO mcp3008_joystick $ cd ~/gpio-game-console $ cd 11_1-mcp3008_joystick $ python3 mcp3008_joystick.py

Slide 190

Slide 190 text

190 觀察結果

Slide 191

Slide 191 text

191 搖桿如何和 keyboard 對應?

Slide 192

Slide 192 text

192 Linux 輸入與輸出的處理流程 https://en.wikipedia.org/wiki/Evdev

Slide 193

Slide 193 text

193 Linux Input Subsystem http://www.linuxjournal.com/article/6396

Slide 194

Slide 194 text

194 ● USB 或 PS2 keyboard 都是同一個 handler 處理 ● 我們可以加上 GPIO 的 driver, 讓 keyboard handler 來接? Linux Input Subsystem http://www.linuxjournal.com/article/6396 USB Keyboard PS2 Keyboard

Slide 195

Slide 195 text

195 除了在 kernel space 做以外 , 可以在 user space 做嗎?

Slide 196

Slide 196 text

196 ● evdev(event device) ● 是 linux kenel 的通用輸入事件介面 , 可從 driver 產 生原始的 input event, 並透過 /dev/input/ 發送事件 ● python-evdev ● 和 evdev 的 user space 實做 uinput 綁定 , 提供 python 介面的呼叫來發送 input event ● 安裝 ( 如果前面已裝過 , 就不需再裝 ) ● $ sudo pip install evdev python-evdev https://pypi.python.org/pypi/evdev

Slide 197

Slide 197 text

197 python-evdev keyboard example from 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()

Slide 198

Slide 198 text

198 DEMO evdev_keyboard.py $ cd ~/gpio-game-console $ cd 11_2-evdev_keyboard $ sudo python3 evdev_keyboard.py 需要有 root 權限才能發送鍵盤事件

Slide 199

Slide 199 text

199 看不到結果嗎?

Slide 200

Slide 200 text

200 用 VNC 連進去開終端機看結果

Slide 201

Slide 201 text

201 上下左右鍵與搖桿的對應

Slide 202

Slide 202 text

202 上下左右鍵與搖桿的對應 - 觀察操作搖桿與畫面輸出值的關係

Slide 203

Slide 203 text

203 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)

Slide 204

Slide 204 text

204 DEMO joystick_mapping_keyboard.py $ cd ~/gpio-game-console $ cd 11_3-joystick_mapping_keyboard $ sudo python3 joystick_mapping_keyboard.py

Slide 205

Slide 205 text

205 搖桿 + 按鍵的應用 MakerFaire 2014 Raspberry Jam

Slide 206

Slide 206 text

206 線路圖 Pin7 Pin12

Slide 207

Slide 207 text

207 DEMO gaming_console.py $ cd ~/gpio-game-console $ cd 13-gaming_console $ sudo python3 gaming_console.py

Slide 208

Slide 208 text

208 ● 第一個執行超級瑪莉 (x11vnc) ● $ cd ~ ● $ ./advmame suprmrio 用搖桿控制超級瑪莉 - 需要開啟兩個視窗 從 x11vnc 連線後執行超級瑪莉 ( 顯示畫面 )

Slide 209

Slide 209 text

209 ● 第二個執行搖桿按鍵對應程式(serial 或ssh) ● $ cd ~/gpio-game-console/13-gaming_console ● $ sudo python3 gaming_console.py 用搖桿控制超級瑪莉 從 serial 或 ssh 連線後執行搖桿按鍵對應程式

Slide 210

Slide 210 text

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

Slide 211

Slide 211 text

211 ● 一次性的執行 , 可以放在 /etc/rc.local 裡 ● 以服務的方式執行 , 需寫 systemd 設定檔 ● 有畫面的程式前景執行 , 用 LXDE 的 autostart 開機就執行?

Slide 212

Slide 212 text

212 ● $ sudo nano /etc/rc.local ● 新增黃色字的部份 sudo python3 /home/pi/gpio-game-console/13- gaming_console/gaming_console.py & # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi exit 0 開機就執行搖桿對應按鍵程式 這是同一行

Slide 213

Slide 213 text

213 ● $ nano ~/.config/lxsession/LXDE-pi/autostart 或是 ● $ sudo nano /etc/xdg/lxsession/LXDE-pi/autostart ● 新增黃色字的部份 @lxpanel --profile LXDE-pi @pcmanfm --desktop --profile LXDE-pi @xscreensaver -no-splash @lxterminal -e /home/pi/advmame suprmrio ● 設定完以後重開機試試看吧 進入桌面環境後就執行超級瑪莉

Slide 214

Slide 214 text

214 超音波距離感測器的應用 ● 手勢拉搖桿演算法範例: 1. 握拳靠近感測器觸發 2. 握拳平行向後 15cm 3. 手掌打開 = 放開拉桿

Slide 215

Slide 215 text

215 自製遊戲機 - 機構外殼很重要 demo board 大台 gameboy 正面 大台 gameboy 內裝 小台 gameboy 正面 小台 gameboy 內裝 大台電動玩具

Slide 216

Slide 216 text

216 Raspberry Pi Rocks the World Thanks

Slide 217

Slide 217 text

217 補充:自己編譯 AdvanceMAME

Slide 218

Slide 218 text

218 ● 安裝 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

Slide 219

Slide 219 text

219 ● 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 執行模擬器

Slide 220

Slide 220 text

220 補充: AdvanceMAME 性能調校

Slide 221

Slide 221 text

221 ● 修改解析度 , 改為 256x240x60 ● tab 鍵進入選單 , 選擇 Video Mode, ESC 離開 我的 AdvanceMAME 很慢?

Slide 222

Slide 222 text

222 ● 修改解析度 , 改為 256x240x60 ● tab 鍵進入選單 , 選擇 Video Mode, ESC 離開 我的 AdvanceMAME 很慢?

Slide 223

Slide 223 text

223 ● 修改解析度 , 改為 256x240x60 ● tab 鍵進入選單 , 選擇 Video Mode, ESC 離開 我的 AdvanceMAME 很慢?