你觉得这篇文章怎么样? 帮助我们为您提供更好的内容。
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/