你觉得这篇文章怎么样? 帮助我们为您提供更好的内容。
Thank you! Your feedback has been received.
There was a problem submitting your feedback, please try again later.
你觉得这篇文章怎么样?
上篇文章教大家在Jetson Nano上使用攝影機和OpenCV,這篇則會帶著大家操作Jetson Nano上的GPIO腳位,想要一起嘗試的朋友可以點我取得NVIDIA Jetson Nano Developer Kit!
作者 | 吳怡庭 |
難度 | 簡單 |
材料表 |
|
一、Jetson Nano的40引腳GPIO
大家拿到Jetson Nano後可以看到有許多pin腳,例如這篇文章中提過使用直流電源時需要在J48接上jumper,或是J15為風扇連接的腳位。其他腳位功能請參考下圖。
圖片來源:NVIDIA Jetson Nano User Guide
而這次我們要使用的是J41腳位,也就是我們常說的GPIO腳位,從下圖中可看到40支針腳,並且旁邊板子上也註明了3.3V、5V、GND腳位。(有些比較早出廠的板子上誤把10和12號腳位印成6和8,之後就修改成正確的編號了)
Jetson Nano的GPIO腳位說明可參考下表,基本上和Raspberry Pi的腳位差不多。
表格來源:https://www.jetsonhacks.com/nvidia-jetson-nano-j41-header-pinout/
而Jetson Nano也和Raspberry Pi一樣,只能做數位訊號的輸入輸出,如果想要控制類比訊號,需要自行外接擴充板。
Jetson Nano預設提供四種模式:BOARD、BCM、CVM和TEGRA_SOC,其中BOARD和BCM常用在Python使用,BOARD代表板子上顯示的編號,Jetson Nano底部則印有對應的BCM編號,左下為pin1,右下為pin2,以此類推。
為求方便,您也可以使用下表對照。
二、安裝GPIO套件
您可以在terminal中輸入以下指令,安裝Jetson Nano 官方提供的GPIO函式庫。
sudo apt-get install python-pip
sudo pip install Jetson.GPIO
官方的github也提供了函式庫資料以及一些簡單的範例,所以您也可以輸入以下指令安裝git、複製GPIO函式庫並進行安裝。
sudo apt-get install git-all
git clone https://github.com/NVIDIA/jetson-gpio.git
cd jetson-gpio
sudo python3 setup.py install
github中的lib/python為GPIO的函式庫;如果您使用中遇到bug,可以使用.github/ISSUE_TEMPLATE中bug_report.md的格式回報給官方知道;samples中則有各種基礎範例供大家參考。
三、數位訊號輸入、輸出
注意:實作中請避免讓Jetson Nano短路,可能會導致系統重啟或是其他狀況產生。
程式範例來源自官方github:https://github.com/NVIDIA/jetson-gpio/tree/master/samples
可在terminal中使用cd加上資料夾路徑的指令移動到samples資料夾,並使用python3加檔名的指令執行程式,或是將程式碼複製、貼上再執行。
1.數位訊號輸入(simple_input.py)
此範例使用麵包板、杜邦線、四腳按鈕、電阻。
其中我們使用330歐姆±10%的電阻,電阻上4個環的顏色分別為橘、橘、棕、銀。如果您忘記自己的電阻是幾歐姆,網路上也有很多方便的電阻色碼計算器可以使用。
接線方式如下圖所示,按鈕1腳接到pin1(3.3V),3腳接到pin12(也就是程式中接受訊號的腳位),4腳接到電阻及pin14(GND)。
程式碼如下,此範例可偵測輸入為高電位或低電位,並將數值顯示出來。
# 匯入函式庫
import RPi.GPIO as GPIO
import time
# 設定腳位數值
input_pin = 18 # BCM pin 18, BOARD pin 12
def main():
prev_value = None
# Pin 腳位設置
GPIO.setmode(GPIO.BCM) # 設置為BCM模式(您也可以自行改為BOARD模式)
GPIO.setup(input_pin, GPIO.IN) # 設置輸入的腳位為input_pin
print("Starting demo now! Press CTRL+C to exit")
try:
# 偵測輸入為高電位或低電位
while True:
value = GPIO.input(input_pin)
if value != prev_value:
if value == GPIO.HIGH:
value_str = "HIGH"
else:
value_str = "LOW"
print("Value read from pin {} : {}".format(input_pin,
value_str))
prev_value = value
time.sleep(1)
finally:
GPIO.cleanup()
if __name__ == '__main__':
main()
執行程式後就會呈現以下結果,terminal上會印出讀取到的數值。
2.數位訊號輸出(simple_out.py)
此範例使用麵包板、杜邦線、LED。
接線方式如下圖所示,LED燈長腳接到pin12(也就是傳送訊號的腳位),短腳接到pin14(GND)。
程式碼如下,此範例以1秒的間隔輸出高、低電位,控制LED燈閃爍。
import RPi.GPIO as GPIO
import time
output_pin = 18
def main():
# 設置為BCM模式
GPIO.setmode(GPIO.BCM)
# 將腳位設定為輸出,並預設為輸出高電位
GPIO.setup(output_pin, GPIO.OUT, initial=GPIO.HIGH)
print("Starting demo now! Press CTRL+C to exit")
curr_value = GPIO.HIGH
try:
while True:
# 每隔1秒鐘切換
time.sleep(1)
print("Outputting {} to pin {}".format(curr_value, output_pin))
GPIO.output(output_pin, curr_value)
curr_value ^= GPIO.HIGH
finally:
GPIO.cleanup()
if __name__ == '__main__':
main()
程式開始執行就會看到閃爍的LED燈囉!
3.使用按鈕控制LED燈(button_led.py)
此範例使用麵包板、杜邦線、四腳按鈕、電阻、LED。
以上兩個範例若是都執行成功,就可以試著使用按鈕控制LED燈亮、滅。
接線方式如下圖所示,按鈕1腳接到pin1(3.3V),3腳接到pin18,4腳接到pin20(GND),LED燈長腳接到pin12(也就是傳送訊號的腳位),短腳接到pin14(GND)。
程式碼如下,此範例會讀取按鈕的數值來控制LED燈為亮或暗。
import RPi.GPIO as GPIO
import time
# 設定pin18讀取按鈕數值,再用pin12輸出高、低電位
led_pin = 12
but_pin = 18
def main():
prev_value = None
GPIO.setmode(GPIO.BOARD) # 設定為BOARD模式
GPIO.setup(led_pin, GPIO.OUT) # 設定led_pin為輸出
GPIO.setup(but_pin, GPIO.IN) # 設定but_pin為輸入
# 將LED燈的電位初始化為低電位
GPIO.output(led_pin, GPIO.LOW)
print("Starting demo now! Press CTRL+C to exit")
try:
while True:
curr_value = GPIO.input(but_pin)
if curr_value != prev_value:
GPIO.output(led_pin, not curr_value)
prev_value = curr_value
print("Outputting {} to Pin {}".format(curr_value, led_pin))
time.sleep(1)
finally:
GPIO.cleanup() # cleanup all GPIO
if __name__ == '__main__':
main()
程式執行結果如下方所示,也可以將程式中GPIO.output(led_pin, not curr_value) 的not去掉,就可以達到相反的效果了。
四、I2C LCD 螢幕
I2C(Inter-Integrated Circuit)是一種IC之間的通訊協定,應用I2C的電子零件會使用SDA(串列資料)和SCL(串列時脈)來傳輸。
Jetson Nano的pin3、pin5、pin27、pin28為I2C的SDA和SCL腳位,以下範例使用I2C LCD 1602螢幕,1602代表的是16*2,也就是螢幕上每行有16欄位,總共2行,每個欄位中僅能放入一個字元,並且不支援中文字。
接線方式如下圖所示,GND接到pin6(下圖黑線)、VCC接到pin4(下圖紅線)、SDA接到pin3(下圖藍線)、SCL接到pin5(下圖橘線)。
成功通電的話後方的I2C板子會亮起藍燈。
在terminal中輸入以下指令,安裝I2C的函式庫,再查詢I2C的位址。
sudo apt-get install libi2c-dev i2c-tools
sudo i2cdetect -y -r 1
上圖中顯示出3f,即代表I2C的位址為0x3f。
在terminal中輸入以下指令安裝smbus。
pip install smbus
在寫程式前我們需要先找可以使用的函式庫,由於Jetson Nano的GPIO設計和Raspberry Pi大致相同,所以也可以找Raspberry Pi的範例。
函式庫來源於:https://www.circuitbasics.com/raspberry-pi-i2c-lcd-set-up-and-programming/
您可以從上方網址內複製程式碼,或是從這篇文章的附檔下載I2C_LCD_driver.py。
其中一行程式碼為ADDRESS = 0x3f,請記得更改成先前查詢到的位址!
在terminal輸入以下指令,安裝I2C_LCD_driver函式庫
sudo python3 I2C_LCD_drive.py install
安裝完成後就可以寫程式來控制螢幕啦!
# 匯入I2C_LCD_driver函式庫
import I2C_LCD_driver
mylcd = I2C_LCD_driver.lcd()
# 在第1行的位置顯示字串Jetson Nano
mylcd.lcd_display_string("Jetson Nano", 1)
執行程式後螢幕就會出現文字囉!
小提醒:如果您的螢幕沒有顯示畫面,可能需要調整螢幕亮度,請使用螺絲起子轉動後方旋鈕調整。
修改參數為以下格式,可將文字位置設定到第2行、第3欄開始。
mylcd.lcd_display_string("Jetson Nano", 2,3)
搭配lcd_clear()清除畫面和time.sleep()延遲幾秒就可以達到螢幕閃爍的效果,如以下程式。
import time
import I2C_LCD_driver
mylcd = I2C_LCD_driver.lcd()
while True:
mylcd.lcd_display_string("Blinking!!!!!!")
time.sleep(1)
mylcd.lcd_clear()
time.sleep(1)
網站中還有一些小實作,例如跑馬燈、顯示特殊符號等,各位也可以自行實作看看。
最後帶大家自製數位時鐘,程式碼如下,其中%Y代表年份、%m代表月份、%d代表日期、%H代表小時、%M代表分鐘、%S代表秒。
import I2C_LCD_driver
import datetime
import time
# 設定格式日期和時間的格式
DATE_FORMAT = '%Y-%m-%d'
TIME_FORMAT = '%H:%M:%S'
mylcd = I2C_LCD_driver.lcd()
while True:
# 宣告DATE和TIME變數為從datetime函式獲取的系統時間,並指定印出格式
DATE = datetime.datetime.now().strftime(DATE_FORMAT)
TIME = datetime.datetime.now().strftime(TIME_FORMAT)
# 螢幕印出日期和時間,並將格式調整為置中
mylcd.lcd_display_string(DATE, 1,3)
mylcd.lcd_display_string(TIME, 2,4)
# 設定0.1秒更新一次,可修改參數自行調整畫面更新的頻率
time.sleep(0.1)
本次的教學就到這邊,大家都學會使用GPIO了嗎?未來我們還會有更多實作分享,感興趣的朋友歡迎關注我們!
看完文章想要使用Jetson Nano實作的朋友可以點此取得Jetson Nano開發套件。
資料來源&相關連結:
jetson-gpio github:https://github.com/NVIDIA/jetson-gpio
I2C LCD函式庫:https://www.circuitbasics.com/raspberry-pi-i2c-lcd-set-up-and-programming/