DesignSpark Electrical Logolinkedin
菜单 搜寻
提问问题

[第一次用Jetson nano 就上手]使用40 pin GPIO(繁體)

上篇文章教大家在Jetson Nano上使用攝影機和OpenCV,這篇則會帶著大家操作Jetson Nano上的GPIO腳位,想要一起嘗試的朋友可以點我取得NVIDIA Jetson Nano Developer Kit!

作者 吳怡庭
難度 簡單
材料表
  • NVIDIA Jetson Nano Developer Kit
  • 5V4A變壓器
  • 64GB Samsung micro SD卡
  • 外接螢幕(HDMI接頭)
  • USB鍵盤
  • USB滑鼠
  • USB Wi-Fi dongle (也可使用有線網路)
  • 麵包板
  • 杜邦線 數條
  • 四腳按鈕
  • LED燈
  • I2C LCD螢幕(本文使用I2C LCD 1602)

 

一、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

電阻色碼計算器:https://www.digikey.tw/zh/resources/conversion-calculators/conversion-calculator-resistor-color-code-4-band

I2C LCD函式庫:https://www.circuitbasics.com/raspberry-pi-i2c-lcd-set-up-and-programming/

下载

CAVEDU Education is devoted into robotics education and maker movement since 2008, and is intensively active in teaching fundamental knowledge and skills. We had published many books for readers in all ages, topics including App Inventor, Lego robot and IoT (Arduino / Raspberry Pi). Please check CAVEDU's website for more information: http://www.cavedu.com, http://www.appinventor.tw

17 Apr 2020, 2:02