Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

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

135 812 vues

Publié le

2019/11/05 投影片更新 ==> http://bit.ly/2NGodu2
===
用 Raspberry Pi 學 GPIO。
- 由淺入深,從 20 個實驗介紹 “數位/類比 x 輸入/輸出”。
- 硬體包括 Raspberry Pi,GPIO 遊戲機學習套件。
- 建議搭配 PL2303HXD 傳輸線和 EDIMAX 7811Un 無線網卡。

購買學習套件:
http://www.raspberrypi.com.tw/2557/gpio-game-console-starter-kit/

範例程式下載:
https://github.com/raspberrypi-tw/gpio-game-console

Publié dans : Technologie

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

  1. 1. 1 Raspberry Pi 遊戲機工作坊 - 從 GPIO 開始和世界連接 台灣樹莓派 <sosorry@raspberrypi.com.tw>
  2. 2. 姓名標示 — 非商業性 — 相同方式分享 CC (Creative Commons) 姓名標示 — 你必須給予 適當表彰、提供指向本授權 條款的連結,以及 指出(本作品的原始版本)是否已 被變更。你可以任何合理方式為前述表彰,但不得以 任何方式暗示授權人為你或你的使用方式背書。 非商業性 — 你不得將本素材進行商業目的之使 用。 相同方式分享 — 若你重混、轉換本素材,或依本 素材建立新素材,你必須依本素材的授權條款來 散布你的貢獻物。
  3. 3. 3 ● Element14 指定台灣地區 Raspberry Pi 獨家經銷商 about 台灣樹莓派 http://farnell.com/raspberrypi-consumer/approved-retailers.php?region=apac&MER=MER-LM-OB-RPICC-76315
  4. 4. ● 專注於 Raspberry Pi 應用與推廣 ● 舉辦社群聚會 / 工作坊 / 讀書會 / 黑客松 ● Website : ● https://www.raspberrypi.com.tw/ ● Facebook : ● 搜尋 RaspberryPi.Taiwan ● https://www.facebook.com/RaspberryPi.Taiwan about 台灣樹莓派
  5. 5. 5 ● COSCUP,MakerConf,PyCon 講者 ● 投影片 ● http://www.slideshare.net/raspberrypi- tw/presentations ● 程式碼 ● https://github.com/raspberrypi-tw 分享 x 社群
  6. 6. 6 ● Raspberry Pi 的 GPIO 介紹 ● 環境設定 ● 輸入 / 輸出 ● 數位 / 類比 ● 練習與實做 本次主題
  7. 7. 7 ● 了解電子電路原理 ● 學習如何根據規格撰寫控制程式 ● 親手完成遊戲機 目標
  8. 8. 8 ● $ sudo apt-get update ● $ sudo apt-get install -y python-dev python-pip libsdl1.2-dev x11vnc ● $ sudo pip install spidev evdev 安裝今日所需套件
  9. 9. 9 Raspberry Pi GPIO 介紹
  10. 10. 10 ● General Purpose Input Output ● GPIO 是一種可用軟體控制的數位訊號 什麼是 GPIO ? http://www.tek.com/datasheet/tps2000b-series-digital-storage-oscilloscopes-datasheet
  11. 11. 11 ● 決定是輸入還是輸出 ● 輸出:寫值到某根腳位 ● 輸入:從某根腳位讀值 ● 等待中斷 (interrupt) 的發生 ● 決定是正緣觸發還是負緣觸發 用軟體控制什麼 ?
  12. 12. 12 GPIO 腳位在哪裡? http://www.raspberrypi-spy.co.uk/ Pin1 Pin2 Pin25 Pin26 Pin3 Pin4Z Z 字型的腳位編號
  13. 13. 13 ● C ● C + wiringPi ● C# ● Ruby ● Perl ● Python ● Scratch ● Java Pi4J Library ● Shell script 如何控制 Raspberry Pi 的 GPIO ?
  14. 14. 14 Python + GPIO
  15. 15. 15 ● 變數 , 物件 , 型別 , 註解 ● 模組 ● 縮排 ● 迴圈 ● 條件判斷 ● 函式 Python 五分鐘速成
  16. 16. 16 ● 動態型別 (dynamic typing) # 這是註解 i = 3 # 變數 i 指到數字物件 3 i = [1, 2, 3, 4, 5] # 變數 i 指到串列物件 print i[2] # 印出串列中第三個元素 i = “abcde” # 變數 i 指到字串物件 print i[2] # 印出字串中第三個元素 變數 , 物件 , 型別 , 註解
  17. 17. 17 # import MODULE import RPi.GPIO # import MODULE as ALIAS import RPi.GPIO as GPIO 模組
  18. 18. 18 ● 用縮排取代大括號 ● 程式碼的區塊是用縮排分隔 ● 不使用 tab, 使用空白鍵 ● 常見縮排為 4 個空白鍵 縮排
  19. 19. 19 ● 自動迭代 (iterator) for i in xrange(start, stop[, step]) : process for i in xrange(0, 11, 5) : process 迴圈
  20. 20. 20 if condition_1: process_1 elif condition_2: process_2 else : process_3 process_4 條件判斷
  21. 21. 21 def function_name(): process def function_name(param_name): process def function_name(param_name = 3): process 函式
  22. 22. 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
  23. 23. 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
  24. 24. 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
  25. 25. 25 本套件相容於全系列 Raspberry Pi 購買套件: https://www.raspberrypi.com.tw/2557/
  26. 26. 26 數位輸出
  27. 27. 27 實驗 1 :硬體的 Hello World 目的:從硬體到軟體的思維
  28. 28. 28 ● 發光二極體 ● 單向導通 ● 省電 LED http://upload.wikimedia.org/wikipedia/commons/c/c8/5mm_Red_LED.jpg 長腳接正極 Vcc 短腳接負極 GND
  29. 29. 29 ● 電路組成元件 : 電源、導線、負載 ● 閉路 : 當三者形成一完整路徑 , 有電流經過電路 ● 歐姆定律 : 導體兩端的電壓與通過的電流成正比 ● V = I x R 電路一分鐘速成 I I V RV R I https://zh.wikipedia.org/wiki/ 电路
  30. 30. 30 Raspberry Pi + LED 直接插入嗎 ? 先看看規格吧
  31. 31. 31 ● VF : 順向電壓 ● IF : 在順向電壓下的最大電流 LED 的特性 https://learn.adafruit.com/all-about-leds/forward-voltage-and-kvl
  32. 32. 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 燒毀 如何解讀?
  33. 33. 33 電阻阻值計算 www.digikey.tw/tw/zht/mkt/5-band-resistors.html 四環:右側為金或銀 五環:前四環很靠近1K= 棕黑黑棕 ( 棕 ) 2K= 紅黑黑棕 ( 棕 )
  34. 34. 34 要接哪一個腳位?
  35. 35. 35 要接哪一個腳位? 目標:一隻腳接地 , 一隻腳給電
  36. 36. 36 線路圖 LED RPi 長腳 (RED) Pin12 (GPIO18) 短腳 (BLACK) Pin6 (Ground)
  37. 37. 37 麵包板的種類 https://goo.gl/JipVgH
  38. 38. 38 麵包板的使用 http://bugworkshop.blogspot.tw/2012/12/diy-breadboard.html 1. 藍色和綠色兩塊不通 2. 藍色水平相通 3. 紅色垂直相通 麵包板的內部結構
  39. 39. 39 使用麵包板方便多了 1k 電阻:棕黑黑棕 ( 棕 )
  40. 40. 40 使用麵包板方便多了
  41. 41. 41 ● 試試看這樣接 不會亮嗎? 因為你沒寫程式阿
  42. 42. 42 各腳位的意義 https://goo.gl/f2rPpN
  43. 43. 43 開始用 Python 控制 GPIO 吧
  44. 44. 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
  45. 45. 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 一個實際的範例
  46. 46. 46 DEMO led_on.py
  47. 47. 47 使用: nano < 檔名 , 例如 led_on.py> 離開: Ctrl + x > 令存新檔: y > 不存離開: n > 離開: Ctrl + c nano 編輯器使用
  48. 48. 48 ● $ cd < 目錄 > # 跳到 < 目錄 > ● $ cd .. # 回上一層 ● $ cd ~ # 回 < 家目錄 > ● $ pwd # 查看目前工作目錄 ● $ ls # 列出檔案與目錄 ● $ sudo reboot # 重開機 你必須知道的 Linux 指令
  49. 49. 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 可以用一般使用者身份執行 ) 執行方式
  50. 50. 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 的使用方法
  51. 51. 51 實驗 2 :控制 LED 閃爍 目的:熟悉 Python 語法
  52. 52. 52 一樣的線路圖 LED RPi 長腳 (RED) Pin12 (GPIO18) 短腳 (BLACK) Pin6 (Ground)
  53. 53. 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 跳出迴圈
  54. 54. 54 DEMO led_blink_warning.py $ cd ~/gpio-game-console $ cd 02_1-led_blink_warning $ sudo python led_blink_warning.py
  55. 55. 55 RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
  56. 56. 56 為什麼出現 Warning ?
  57. 57. 57 ● 在正常情況下執行完畢結束 ● 遇到錯誤跳出 ● 受到中斷停止 ( 收到終止訊號 , 例如 Ctrl+c) 程式何時會結束 ?
  58. 58. 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() 接住例外
  59. 59. 59 DEMO led_blink.py $ cd ~/gpio-game-console $ cd 02_2-led_blink $ sudo python led_blink.py
  60. 60. 60 實驗 3 :用 LED 做交通號誌 目的:結構化程式設計
  61. 61. 61 ● 紅 , 黃 , 綠燈依序亮燈 ● 紅燈亮 4 秒 , 黃燈亮 2 秒 , 綠燈亮 4 秒 設計一個紅綠燈 http://www.clipartbest.com/traffic-light-photo
  62. 62. 62 線路圖
  63. 63. 63 DEMO traffic_light_nonstructure.py $ cd ~/gpio-game-console $ cd 03_1-traffic_light_nonstructure $ sudo python traffic_light_nonstructure.py
  64. 64. 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() 把亮燈拿到外面
  65. 65. 65 DEMO traffic_light.py $ cd ~/gpio-game-console $ cd 03_2-traffic_light $ sudo python traffic_light.py
  66. 66. 66 數位輸入
  67. 67. 67 實驗 4 :讀取按鍵輸入 目的:了解硬體和軟體的差異
  68. 68. 68 ● 開關:按鍵式 , 滑動式 , 傾斜式 ... 按鍵 Button / 開關 Switch http://nicegear.co.nz/
  69. 69. 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
  70. 70. 70 按鍵的內部結構 http://www.ladyada.net/learn/arduino/lesson5.html ● 按下前 ● 長邊相連 (1&2,3&4) ● 短邊不相連 ● 按下後 ● 四點都通 1 2 3 4
  71. 71. 71 簡單的按鍵接法 BUTTON RPi 腳 1 Pin6 (Ground) 腳 3 Pin11 (GPIO17)
  72. 72. 72 ● Input 空接會讀到雜訊 問題在哪裡? 按鍵按下前未導通 , 讀到??按鍵按下後 , 讀到低電位
  73. 73. 73 更好的按鍵接法 http://geekgurldiaries.blogspot.tw/2012/12/part-2.html
  74. 74. 74 上拉電阻 http://playground.arduino.cc/CommonTopics/PullUpDownResistor - 還沒按下按鍵 - 按下按鍵時
  75. 75. 75 線路圖 BUTTON RPi 腳 1 Pin6 (Ground) 腳 3 Pin11 (GPIO17) Pin1 (3.3V) 1k 電阻
  76. 76. 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() 判斷條件 : 這次低 && 上次高
  77. 77. 77 DEMO push_button_poll.py $ cd ~/gpio-game-console $ cd 04_1-push_button_poll $ sudo python push_button_poll.py
  78. 78. 78 按一次出現兩次?這樣子對不對啊?
  79. 79. 79 ● 機械式開關在切換過程中會有訊號彈跳現象 ( 雜訊 ) 開關訊號的彈跳問題 (bounce) http://120.101.72.1/Onechip/PPT/ 實習單元三 .ppt 理想訊號輸出 實際輸出訊號
  80. 80. 80 ● 硬體方法:以 RC 電路或正回授的比較器電路解決 ● 軟體方法:調整觸發的延遲時間 ● 不同的按鍵會有不同的延遲時間 解決彈跳問題 (de-bounce) 10ms - 20ms
  81. 81. 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 不反應在延遲時間內的觸發
  82. 82. 82 DEMO push_button_debounce.py $ cd ~/gpio-game-console $ cd 04_2-push_button_debounce $ sudo python push_button_debounce.py
  83. 83. 83 但是這個程式的 CPU 用量挺大的 $ top -c 跑個按鍵偵測程式 CPU 使用率達 91.9% ( 如果使用 Pi 3 使用率約 2x%) ● PID: 該程序的 id ● COMMAND: 該程序的完整指令
  84. 84. 84 ● 送一個 KILL 的訊號吧 $ sudo kill -9 3449 如何結束程序? ● 按 q 離開 top 指令
  85. 85. 85 ● 輪詢 (polling) ● SoC 每隔一段時間檢查週邊硬體的資料 ● 中斷 (interrupt) ● 當週邊硬體的狀態改變時 , 對 SoC 發出中斷要求 輪詢與中斷
  86. 86. 86 ● 建立回呼函數 ● def mycallback() ● 綁定事件和回呼函數 ● add_event_detect(gpio, # 對象 edge, # 觸發條件 callback, # 回呼函數 bouncetime) ● 多個事件可以綁定同樣的回呼函數 中斷的程式寫法 source/py_gpio.c
  87. 87. 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 狀態下也可立即回應
  88. 88. 88 DEMO push_button_interrupt.py $ cd ~/gpio-game-console $ cd 04_3-push_button_interrupt $ sudo python push_button_interrupt.py
  89. 89. 89 ● 需要硬體或軟體 ( 作業系統 ) 的支援 ● RPi.GPIO 在版本 0.5.0a 有了中斷功能 ● 加上 add_event_detect() 等機制 ● RPi.GPIO 以建立多執行緒方式實現中斷 ● 程式開始執行時 , 主執行序運行 ● 當加入事件後 , 以 epoll_create 建立新的 fd ● 當事件觸發時 , 第二個執行序和主執行序溝通 ( 回呼 ) ● 程式碼可參考 source/event_gpio.c 中斷的意義 source/py_gpio.c
  90. 90. 90 簡單的按鍵接法沒有錯 , 但是 ...
  91. 91. 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)
  92. 92. 92 DEMO push_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
  93. 93. 93 實驗 5 :傾斜開關 目的:認識不同的硬體
  94. 94. 94 傾斜開關 Tilt Switch
  95. 95. 95 線路圖 SWITCH RPi 第一腳 (RED) Pin11 (GPIO17) 第二腳 (BLACK) Pin6 (Ground)
  96. 96. 96 DEMO tilt_switch.py $ cd ~/gpio-game-console $ cd 05-tilt_switch $ sudo python tilt_switch.py 使用內建的上拉電阻
  97. 97. 97 實驗 6 :蜂鳴器樂器 目的:聲音輸出
  98. 98. 98 ● 發聲原理 : 聲音是由振動產生 , 其頻率稱為音頻 ● 蜂鳴器發聲原理 : 電流 (6) 通過電磁線圈 (3) 產生 磁場來驅動振動膜 (11) ● 人耳可聽到 20Hz - 20KHz 原理 http://www.itianer.com/diancishifengmingqigouzaoyuyuanlijieshao.html
  99. 99. 99 ● 自激 ( 有源 ): 只能發出同頻率的聲音 ● 黑膠封裝 , 高低腳 ● 他激 ( 無源 ): 需從外部輸入震盪方波發聲 ● 綠色電路板 , 兩腳同長 ● 腳位有正負之分 ( 看底板 ) 蜂鳴器 Buzzer http://www.buzzer-speaker.com/manufacturer/piezo%20buzzer.htm 自激式 他激式
  100. 100. 100 線路圖 BUZZER RPi +(RED) Pin12 (GPIO18) - (BLACK) Pin6 (Ground)
  101. 101. 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)) 可發出不同頻率聲音
  102. 102. 102 DEMO buzzer.py $ cd ~/gpio-game-console $ cd 06_1-buzzer $ sudo python buzzer.py
  103. 103. 103 ● ● 標準 88 鍵鋼琴 , 每個音的頻率 : ● 每段音階分為 12 個半音 ● 每個音的頻率是前一個的 1.05946 倍 ( ) 鋼琴模擬 1 2 3 4 5 6 7 0 8 http://en.wikipedia.org/wiki/Piano_key_frequencies 12 2
  104. 104. 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
  105. 105. 105 線路圖 RPi Pin7 Buzzer Pin11 Do Pin12 Re Pin13 Me Pin15 Fa Pin16 So Pin18 La Pin22 Si
  106. 106. 106 DEMO paino_buzzer.py $ cd ~/gpio-game-console $ cd 06_2-paino_buzzer $ sudo python paino_buzzer.py
  107. 107. 107 實驗 7 :人體紅外線感測器 目的:常見感測器使用
  108. 108. 108 Pyroelectric ("Passive") InfraRed Sensor PIR 人體紅外線感測器 http://www.raspberrypi-spy.co.uk/2013/01/cheap-pir-sensors-and-the-raspberry-pi-part-1/
  109. 109. 109 使用示意圖 http://www.ladyada.net/learn/sensors/pir.html
  110. 110. 110 應用範例 http://www.ladyada.net/learn/sensors/pir.html http://totherails.blogspot.tw/2011/09/halloween-preparations.html
  111. 111. 111 元件說明 http://www.ladyada.net/learn/sensors/pir.html
  112. 112. 112 ● 輸入電壓 :DC 3.3V - 24V ● 輸出電壓 :3.3V( 可直接接上 Raspberry Pi) ● 延遲時間 (Tx):2.45 秒 – 248 秒 ● 感應之後輸出維持的時間 ● 封鎖時間 (Ti):2.4 秒 ● 感應輸出結束之後 , 再次觸發必須等待的時間 ● 感應角度 :110 度 x 70 度 ● 感應距離 :3 米 - 7 米 瞭解規格
  113. 113. 113 ● 感測距離設定 ● 順時針 : 最高為 7 米 ● 逆時針 : 最小為 3 米 ● 延遲時間設定 (Tx) ● 順時針 : 最長為 248 秒 ● 逆時針 : 最短為 2.45 秒 ● 實際可調整時間要看 R10,C6,R9,C7 而定 感測距離 / 延遲時間設定 感測距離設定 延遲時間設定
  114. 114. 114 ● 可重複觸發模式 (H) ● 不可重複觸發模式 (L) 觸發模式 H: 可重複觸發 L: 不可重複觸發 ( 預設 ) 感應 & 輸出 感應 & 等待 & 輸出
  115. 115. 115 線路圖
  116. 116. 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 模式
  117. 117. 117 DEMO pir.py $ cd ~/gpio-game-console $ cd 07_1-pir $ sudo python pir.py 觸發才拉高電位 , 因此用內建的下拉電阻
  118. 118. 118 加上警示的 LED 燈吧
  119. 119. 119 線路圖
  120. 120. 120 DEMO people_alarm_system.py $ cd ~/gpio-game-console $ cd 07_2-people_alarm_system $ sudo python people_alarm_system.py
  121. 121. 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 次
  122. 122. 122 實驗 8 :超音波距離感測器 目的:根據規格撰寫程式
  123. 123. 123 ● 聲音在 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
  124. 124. 124 ● 內建發射 (40kHz) 與接收電路 ● 根據發射與接收的時間差計算距離 ● 特殊功能 :US-020( 長距離 ) 、 US-100( 溫度補償 ) HC-SR04 超音波距離感測器 http://coopermaa2nd.blogspot.tw/2012/09/hc-sr04.html
  125. 125. 125 ● 避障 , 測距 ● 物體移動感測 ● 地鐵感測器 應用 http://letsmakerobots.com/robot/project/rock-crawler https://www.dropbox.com/s/x0qdaq86rkc0zyv/MakerConf.pdf
  126. 126. 126 地鐵感測器 http://makezine.com/magazine/ultrasonic-train-detector-in-stockholm-subway/
  127. 127. 127 地鐵感測器 http://makezine.com/magazine/ultrasonic-train-detector-in-stockholm-subway/
  128. 128. 128 ● 規格與時序圖 HC-SR04 http://coopermaa2nd.blogspot.tw/2012/09/hc-sr04.html 建議測量間隔 >60ms
  129. 129. 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
  130. 130. 130 線路圖 - 注意 1K, 2K 電阻 ULTRASONIC RPi Vcc(RED) Pin2 (5V) Trig(YELLOW) Pin16 (GPIO23) Echo(PURPLE) Pin18 (GPIO24) Grnd(BLACK) Pin6 (Ground) 1k: 棕黑黑棕 2k: 紅黑黑棕
  131. 131. 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 測量距離
  132. 132. 132 DEMO hc_sr04_measure_distance.py $ cd ~/gpio-game-console $ cd 08-hc_sr04_measure_distance $ sudo python hc_sr04_measure_distance.py
  133. 133. 133 實驗 9 :呼吸燈 目的:瞭解訊號模擬
  134. 134. 134 ● 數位: 0 與 1 的訊號 ● 類比:連續的訊號 數位與類比 http://www.bitscope.com/software/blog/DJ/?p=DJ19A
  135. 135. 135 ● 數位 : 亮和不亮 ● 類比 : 亮 , 有點亮 , 有點不亮 ..., 不亮 ● 可是 GPIO 腳位輸出都是固定值 , 怎麼辦? 從 LED 的角度來看
  136. 136. 136 ● 旋轉式 , 滑動式 ● 線性關係 (B 型 ), 對數關係 (A 型 ) ● 常見規格 :0 -10k Ohm( 線性 ) 可變電阻 Potentiometer(VR) https://en.wikipedia.org/wiki/Potentiometer 接高電位 接低電位 滑動接點 ( 可變輸出 )
  137. 137. 137 利用可變電阻改變 LDE 亮度
  138. 138. 138 有不使用額外硬體的方法嗎?
  139. 139. 139 ● 是將類比信號轉為脈波的一種技術 ● 改變工作比 (duty cycle)= 改變電壓 脈寬調變 (Pulse-Width Modulation) http://www.societyofrobots.com/schematics_h-bridgedes.shtml
  140. 140. 140 ● 類比輸出電壓 = 脈衝寬度 x 高電位值 公式計算 http://www.protostack.com/blog/2011/06/atmega168a-pulse-width-modulation-pwm/
  141. 141. 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/
  142. 142. 142 線路圖 LED RPi 長腳 (RED) Pin12 (GPIO18) 短腳 (BLACK) Pin6 (Ground)
  143. 143. 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() 互動式的調光
  144. 144. 144 DEMO adjust_led_bright.py $ cd ~/gpio-game-console $ cd 09_1-adjust_led_bright $ sudo python adjust_led_bright.py
  145. 145. 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) 呼吸燈就是漸明漸亮
  146. 146. 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
  147. 147. 147 DEMO pwm_led.py $ cd ~/gpio-game-console $ cd 09_2-pwm_led $ sudo python pwm_led.py
  148. 148. 148 實驗 10 :光敏電阻 目的:類比訊號的讀取
  149. 149. 149 ● 硫化鎘 (CdS) 或光敏電阻器 (LDR), 阻抗隨光落 在表面的總量而轉變 ● 光越強阻值越小 , 反之光越弱阻值則越大 ● 應用:光控開關 , 電子玩具 , 工業控制 光敏電阻 http://www2.nkfust.edu.tw/~jlkuo2/31/a6.htm
  150. 150. 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 軸 )
  151. 151. 151 ● 類比數位轉換器 (Analog to Digital Converter) ● 8 通道 ,10 bits 解析度 ● SPI 協議 利用 MCP3008
  152. 152. 152 ● 主從式架構 , 可一對多 ● 四線同步序列資料協定 ● SS: 週邊選擇線 (CE) ● SCK: 序列時脈線 (SCLK) ● MOSI: 主往從送 ● MISO: 從往主送 Serial Peripheral Interface(SPI)
  153. 153. 153 ● $ sudo raspi-config 啟用 Raspberry Pi 的 SPI
  154. 154. 154 開機就載入 SPI 核心模組
  155. 155. 155 ● 測試確認 SPI 模組已載入 ● 安裝必要套件 ( 如果前面已裝過 , 就不需再裝 ) ● $ sudo apt-get update ● $ sudo apt-get install -y python-dev python-pip ● $ sudo pip install spidev SPI 使用前的確認
  156. 156. 156 線路圖 MCP3008 RPi CLK Pin23 (SCLK) Din Pin19 (MOSI) Dout Pin21 (MISO) CS Pin24 (CE0)
  157. 157. 157 ● SPI 會用到的腳位是 MOSI,MISO,SCLK 和 CE0/CE1 再看一次腳位定義
  158. 158. 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)
  159. 159. 159 程式要照硬體規格撰寫
  160. 160. 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
  161. 161. 161 http://wolfpaulus.com/
  162. 162. 162 http://wolfpaulus.com/ Output 也是一次回傳三個 bytes 因為是 10bits 解析度 , 所以我們只取最後有用的 10bits
  163. 163. 163 DEMO photoresistor.py $ cd ~/gpio-game-console $ cd 10-photoresistor $ sudo python photoresistor.py
  164. 164. 164 實驗 11 :手做遊戲機之貪食蛇 目的:系統整合
  165. 165. 165 ● 現況:用上下左右鍵控制 ● 目標:改為用搖桿控制 Bash 版之貪食蛇 http://bruxy.regnet.cz/linux/housenka/
  166. 166. 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
  167. 167. 167 搖桿 (joystick)
  168. 168. 168 ● 3.3V-5V 工作電壓 ● 輸出形式: ● x,y 軸 - 類比輸出 ● z 軸 - 數位輸出 XY 雙軸搖桿 http://www.aliexpress.com/cheap/cheap-arduino-joystick.html
  169. 169. 169 線路圖 http://www.raspberrypi-spy.co.uk/2014/04/using-a-joystick-on-the-raspberry-pi-using-an-mcp3008/
  170. 170. 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)
  171. 171. 171 DEMO mcp3008_joystick $ cd ~/gpio-game-console $ cd 11_1-mcp3008_joystick $ sudo python mcp3008_joystick.py
  172. 172. 172 搖桿如何和 keyboard 對應?
  173. 173. 173 Linux 輸入與輸出的處理流程 https://en.wikipedia.org/wiki/Evdev
  174. 174. 174 Linux Input Subsystem http://www.linuxjournal.com/article/6396
  175. 175. 175 ● USB 或 PS2 keyboard 都是同一個 handler 處理 ● 我們可以加上 GPIO 的 driver, 讓 keyboard handler 來接? Linux Input Subsystem http://www.linuxjournal.com/article/6396 USB Keyboard PS2 Keyboard
  176. 176. 176 除了在 kernel space 做以外 , 可以在 user space 做嗎?
  177. 177. 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
  178. 178. 178 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()
  179. 179. 179 DEMO evdev_keyboard.py $ cd ~/gpio-game-console $ cd 11_2-evdev_keyboard $ sudo python evdev_keyboard.py
  180. 180. 180 上下左右鍵與搖桿的對應
  181. 181. 181 上下左右鍵與搖桿的對應 - 觀察操作搖桿與畫面輸出值的關係
  182. 182. 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)
  183. 183. 183 DEMO joystick_mapping_keyboard.py $ cd ~/gpio-game-console $ cd 11_3-joystick_mapping_keyboard $ sudo python joystick_mapping_keyboard.py
  184. 184. 184 ● 第一個執行搖桿按鍵對應程式 ● $ sudo python joystick_mapping_keyboard.py 用搖桿控制貪食蛇 - 需要開啟兩個視窗
  185. 185. 185 ● 第二個執行貪食蛇 script ● $ ./housenka.sh 用搖桿控制貪食蛇 - 需要開啟兩個視窗
  186. 186. 186 試試看是否可以用搖桿控制貪食蛇
  187. 187. 187 好麻煩 ! 如何開機就執行 ?
  188. 188. 188 ● 一次性的執行 , 可以放在 /etc/rc.local 裡 ● 以服務的方式執行 , 需寫 systemd 設定檔 ● 有畫面的程式前景執行 , 用 LXDE 的 autostart 開機就執行?
  189. 189. 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 %sn" "$_IP" fi exit 0 開機就執行搖桿對應按鍵程式
  190. 190. 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 ● 設定完以後重開機試試看吧 進入桌面環境後就執行貪食蛇
  191. 191. 191 實驗 13 :模擬器 目的:完整度更高的遊戲機
  192. 192. 192 遊戲機 = 硬體 + 遊戲 http://www.emulatorworld.com/
  193. 193. 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
  194. 194. 194 ● 模擬大台電動玩具 MAME(Multiple Arcade Machine Emulator) http://www.williamsamusements.co.uk/mame.html
  195. 195. 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
  196. 196. 196 ● 搜尋 MAME ● http://www.emuparadise.me/ ● 中英文對照 ● http://bbs.duowan.com/thread-41350071-1-1.html ● 經典遊戲 ● 超級瑪莉歐 ● 彈珠台 ● 小精靈 ● 坦克大作戰 , 泡泡龍 ... 下載 ROM 放到對應的目錄下 http://en.wikipedia.org/wiki/Nintendo_Entertainment_System
  197. 197. 197 搖桿 + 按鍵的應用 MakerFaire 2014 Raspberry Jam
  198. 198. 198 線路圖
  199. 199. 199 超音波距離感測器的應用 ● 手勢拉搖桿演算法範例: 1. 握拳靠近感測器觸發 2. 握拳平行向後 15cm 3. 手掌打開 = 放開拉桿
  200. 200. 200 自製遊戲機 - 機構外殼很重要 demo board 大台 gameboy 正面 大台 gameboy 內裝 小台 gameboy 正面 小台 gameboy 內裝 大台電動玩具
  201. 201. 201 DEMO gaming_console.py $ cd ~/gpio-game-console $ cd 13-gaming_console $ sudo python gaming_console.py
  202. 202. 202 更多應用
  203. 203. 203 http://makezine.com/2013/04/14/47-raspberry-pi-projects-to-inspire-your-next-build/
  204. 204. 204 Raspberry Pi Rocks the World Thanks
  205. 205. 205 補充:自己編譯 AdvanceMAME
  206. 206. 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
  207. 207. 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 執行模擬器
  208. 208. 208 補充: AdvanceMAME 性能調校
  209. 209. 209 ● 修改解析度 , 改為 256x240x60 ● tab 鍵進入選單 , 選擇 Video Mode, ESC 離 開 我的 AdvanceMAME 很慢?
  210. 210. 210 ● 修改解析度 , 改為 256x240x60 ● tab 鍵進入選單 , 選擇 Video Mode, ESC 離 開 我的 AdvanceMAME 很慢?
  211. 211. 211 ● 修改解析度 , 改為 256x240x60 ● tab 鍵進入選單 , 選擇 Video Mode, ESC 離開 我的 AdvanceMAME 很慢?
  212. 212. 212 補充: Raspberry Pi 的開機流程
  213. 213. 213 Linux 開機流程 http://goo.gl/taI5fw
  214. 214. 214 http://myembeddedlinux.blogspot.tw/2013/05/raspberry-pi-boot-sequence.html Pi 開機流程
  215. 215. 215 Raspbian Jessie Pi 開機流程
  216. 216. 216 使用者登入與進入桌面環境 http://linux.vbird.org/linux_basic/0320bash.php
  217. 217. 217 Debian 的演進 http://forums.debian.net/viewtopic.php?f=5&t=125562
  218. 218. 218 sysvinit, upstart, systemd
  219. 219. 219 ● Systemd 是 Jessie 預設的初始化系統 , 包括 ● 啟動系統與個人服務 ● 提供管理工具 核心載入後 , 交給 systemd 處理
  220. 220. 220 systemd 架構 https://pl.wikipedia.org/wiki/Systemd
  221. 221. $ 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 設定檔

×