嘿!您似乎在 United States,您想使用我们的 English 网站吗?
Switch to English site
Skip to main content

[第一次用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为风扇连接的脚位。其他脚位功能请参考下图。

01_2c97a460d0543fd95eaa769853462d751dd15a93.png

图片来源:NVIDIA Jetson Nano User Guide

而这次我们要使用的是J41脚位,也就是我们常说的GPIO脚位,从下图中可看到40支针脚,并且旁边板子上也注明了3.3V、5V、GND脚位。(有些比较早出厂的板子上误把10和12号脚位印成6和8,之后就修改成正确的编号了)

0215_72b42c18671f83021a80b6db7c86b0ba38dd8765.jpg

Jetson Nano的GPIO脚位说明可参考下表,基本上和Raspberry Pi的脚位差不多。

0327_ebd7f06f462279471458fbbe0e1b81296ea9e1ab.png

表格来源: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,以此类推。

0414_a7f8c87abbc371b52064f0fe0eb7c2441fc8d694.jpg

为求方便,您也可以使用下表对照。

0523_b766478be8cde06680c9a7d147df712a5a0a00e1.png

二、安装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加文件名的指令执行程序,或是将程序代码复制、贴上再执行。

0621_144b270e2d2b28d05ee6b831941e3ed23adb198d.png

1.数位讯号输入(simple_input.py)

此范例使用面包板、杜邦线、四脚按钮、电阻。

其中我们使用330奥姆±10%的电阻,电阻上4个环的颜色分别为橘、橘、棕、银。如果您忘记自己的电阻是几奥姆,网络上也有很多方便的电阻色码计算器可以使用。

接线方式如下图所示,按钮1脚接到pin1(3.3V),3脚接到pin12(也就是程序中接受讯号的脚位),4脚接到电阻及pin14(GND)。

0725_a65bd55a8ce320ae41213a86b292fcf384fef24f.png

程序代码如下,此范例可侦测输入为高电位或低电位,并将数值显示出来。

# 汇入函式库
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)。

0820_c6916c65dd3b670024edd79bdeeddb9dd7e5ca0f.png

程序代码如下,此范例以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)。

0918_b6e9bd3cf2ee671b9389f4806ecebc5a8dfe0766.png

程序代码如下,此范例会读取按钮的数值来控制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(下图橘线)。1034_184d49d28648b1f8a93a2966592e931b66b0e79f.png

成功通电的话后方的I2C板子会亮起蓝灯。

1140_017b0d53ec02b77bea66b7c3f2ed376db40b09fc.jpg

在terminal中输入以下指令,安装I2C的函式库,再查询I2C的位址。

sudo apt-get install libi2c-dev i2c-tools
sudo i2cdetect -y -r 1

1240_e26c333cae7cbe1ef25170233456c025dab97a8f.png

上图中显示出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)

执行程序后屏幕就会出现文字啰!

1330_c68012e407414aa68a1861536d223a624d43a0c2.jpg

小提醒:如果您的屏幕没有显示画面,可能需要调整屏幕亮度,请使用螺丝起子转动后方旋钮调整。

1429_ec4098e07cd17b0c0929284d559cbc241d2a3cbe.png

修改参数为以下格式,可将文字位置设定到第2行、第3栏开始。

mylcd.lcd_display_string("Jetson Nano", 2,3)

1525_ff90587e3548f526cd938bcf5d79093971a8c137.jpg

搭配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 Deep Learning, edge computing, App Inventor, IoT and robotics. Please check CAVEDU's website for more information: http://www.cavedu.com, http://www.appinventor.tw
DesignSpark Electrical Logolinkedin