文章目录
- 前言
- Jetson.GPIO安装
- 可用引脚
- 点亮LED
- GPIO输出示例
- GPIO输入示例
- GPIO Event
- GPIO Interrupt
- PWM
- 微信公众号
前言
Nvidia Jetson AGX Xavier 硬件相关
这篇讲到Xavier的40Pin扩展口和树莓派的40Pin扩展口类似, 本节就操作下GPIO. 方便起见, 再贴一下引脚映射:
RPi.GPIO 官方使用文档翻译
Jetson.GPIO
的API
和树莓派的RPi.GPIO
是一样的, 可以去参考我这篇之前的翻译文章.
Jetson.GPIO安装
NVIDIA/jetson-gpio, 这个Github
仓库写的很详细, Jetson TX1, TX2, AGX Xavier和Nano的载板
默认都提供了40Pin的扩展口, 可以通过Jetson.GPIO
这个Python
库进行GPIO
的操作, 和树莓派的RPi.GPIO
有相同的API
. 虽然Nvidia已经自带了jetson-gpio
: /opt/nvidia/jetson-gpio/
, 但还要配置环境什么的麻烦, 不如直接装一个:
sudo apt install python3-pip
sudo pip3 install Jetson.GPIO
如果直接输入python3
, 然后import Jetson.GPIO as GPIO
, 会提示权限不够:
raise RuntimeError("The current user does not have permissions set to "
RuntimeError: The current user does not have permissions set to access the library functionalites. Please configure permissions or use the root user to run this
涉及到硬件操作的, 用sudo
开头, 直接sudo python3
, 输入import Jetson.GPIO as GPIO
, 就可以了.
可用引脚
jetson-gpio/samples/test_all_apis.py
文件列出了各个Jetson板子测试的引脚, 以Xavier
为例:
'JETSON_XAVIER': {
'out_a': 18,
'in_a': 19,
'out_b': 21,
'in_b': 22,
'unimplemented_pins': (),
'cvm_pin': 'MCLK05',
'tegra_soc_pin': 'SOC_GPIO42',
'all_pwms': (13, 15, 18),
},
尽量用引脚 12, 13, 15, 18, 其它引脚没有测试, 有兴趣的对好原理图后, 可以试试, 留言给我.
点亮LED
首先把J514跳线帽设置为3.3V, 这样GPIO12通过了电平转换芯片TXB0108, 这里用12引脚作为输出驱动一颗LED, 连接方式:
Pin12 -> +LED- -> 4.7K电阻 -> GND(Pin14)
位置如图:
终端:
sudo python3
>>> import Jetson.GPIO as GPIO
>>> GPIO.setmode(GPIO.BOARD)
>>> LED = 12
>>> GPIO.setup(LED, GPIO.OUT)
>>> GPIO.output(LED, GPIO.HIGH)
然后就可以看到LED亮了, 继续输入 GPIO.output(LED, GPIO.LOW)
可以关闭LED.
GPIO.setmode(GPIO.BOARD)
设置的是引脚编号, GPIO.BOARD
这种编号方式和本文最上面图中引脚编号是一样的, Pin12就是图中的12引脚I2S2_CLK
, 其实编号共有4种方式: GPIO.BOARD, GPIO.BCM, GPIO.CVM, GPIO.TEGRA_SOC or None
, 详细解释:
The first two correspond to the modes provided by the RPi.GPIO library, i.e BOARD and BCM which refer to the pin number of the 40 pin GPIO header and the Broadcom SoC GPIO numbers respectively. The remaining two modes, CVM and TEGRA_SOC use strings instead of numbers which correspond to signal names on the CVM/CVB connector and the Tegra SoC respectively.
GPIO.setup(LED, GPIO.OUT)
就是设置引脚为输出, 同样的GPIO.setup(channel, GPIO.IN)
表示设置输入, 还可以初始化设置为输出高GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)
, 也可以对多个通道同时设置:
# add as many as channels as needed. You can also use tuples: (18,12,13)
channels = [18, 12, 13]
GPIO.setup(channels, GPIO.OUT)
GPIO.output(LED, GPIO.HIGH)
设置LED引脚为高电平, 这样LED就亮了.
最后, 不用的话, 最好clean up
一下, 让引脚回到默认状态:
GPIO.cleanup(LED)
上面Github的samples
文件夹里面有许多输入, 输出, PWM, 按键, 中断的例子, 可以好好参考一下.
GPIO输出示例
创建文件gpio_out.py
, 使用sudo python3 gpio_out.py
运行可以看到LED
每隔1s变换一次状态:
import Jetson.GPIO as GPIO
import time
LED = 12
def main():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LED, GPIO.OUT, initial=GPIO.LOW)
curr_value = GPIO.LOW
try:
while True:
time.sleep(1)
GPIO.output(LED, curr_value)
curr_value ^= GPIO.HIGH
finally:
GPIO.cleanup()
if __name__=='__main__':
main()
GPIO输入示例
文件gpio_input.py
:
import Jetson.GPIO as GPIO
import time
input_pin = 12
def main():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(input_pin, GPIO.IN)
prev_value = None
try:
while True:
value = GPIO.input(input_pin)
if value != prev_value:
if value == GPIO.HIGH:
value_str = "HIGH"
else:
value_str = "LOW"
print("Pin {} Value is {}".format(input_pin,value_str))
prev_value = value
time.sleep(1)
finally:
GPIO.cleanup()
if __name__=='__main__':
main()
然而, 只在12引脚成功, 在11和15引脚失败:
xavier@xavier-c:~/Documents/jetson-gpio/samples$ sudo python3 gpio_input.py
Pin 12 Value is LOW
Pin 12 Value is HIGH
Pin 12 Value is LOW
Pin 12 Value is HIGH
下面关于interrupt, event, pwm的例子直接贴官方代码了.
GPIO Event
import Jetson.GPIO as GPIO
import time
led_pin = 12
but_pin = 18
def main():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(led_pin, GPIO.OUT)
GPIO.setup(but_pin, GPIO.IN)
GPIO.output(led_pin, GPIO.LOW)
print("Starting demo now! Press CTRL+C to exit")
try:
while True:
print("Waiting for button event")
GPIO.wait_for_edge(but_pin, GPIO.FALLING)
print("Button Pressed!")
GPIO.output(led_pin, GPIO.HIGH)
time.sleep(1)
GPIO.output(led_pin, GPIO.LOW)
finally:
GPIO.cleanup()
if __name__ == '__main__':
main()
注意GPIO.wait_for_edge
还可以设置超时时间:
GPIO.wait_for_edge(channel, GPIO.RISING, timeout=500)
GPIO Interrupt
import Jetson.GPIO as GPIO
import time
led_pin_1 = 12
led_pin_2 = 13
but_pin = 18
def blink(channel):
print("Blink LED 2")
for i in range(5):
GPIO.output(led_pin_2, GPIO.HIGH)
time.sleep(0.5)
GPIO.output(led_pin_2, GPIO.LOW)
time.sleep(0.5)
def main():
GPIO.setmode(GPIO.BOARD)
GPIO.setup([led_pin_1, led_pin_2], GPIO.OUT)
GPIO.setup(but_pin, GPIO.IN)
GPIO.output(led_pin_1, GPIO.LOW)
GPIO.output(led_pin_2, GPIO.LOW)
GPIO.add_event_detect(but_pin, GPIO.FALLING, callback=blink, bouncetime=10)
print("Starting demo now! Press CTRL+C to exit")
try:
while True:
GPIO.output(led_pin_1, GPIO.HIGH)
time.sleep(2)
GPIO.output(led_pin_1, GPIO.LOW)
time.sleep(2)
finally:
GPIO.cleanup()
if __name__ == '__main__':
main()
注意其中的bouncetime
(单位ms)很好用, 可以保证这段时间内只触发一次, 避免重复触发, 消抖什么的还不错.
PWM
import Jetson.GPIO as GPIO
import time
output_pins = {
'JETSON_XAVIER': 18,
'JETSON_NANO': 33,
}
output_pin = output_pins.get(GPIO.model, None)
if output_pin is None:
raise Exception('PWM not supported on this board')
def main():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(output_pin, GPIO.OUT, initial=GPIO.HIGH)
p = GPIO.PWM(output_pin, 50)
p.start(25)
print("PWM running. Press CTRL+C to exit.")
try:
while True:
time.sleep(1)
finally:
p.stop()
GPIO.cleanup()
if __name__ == '__main__':
main()
注意PWM
的限制:
The Jetson.GPIO library supports PWM only on pins with attached hardware PWM controllers. Unlike the RPi.GPIO library, the Jetson.GPIO library does not implement Software emulated PWM. Jetson Nano supports 2 PWM channels, and Jetson AGX Xavier supports 3 PWM channels. Jetson TX1 and TX2 do not support any PWM channels.
The system pinmux must be configured to connect the hardware PWM controlller(s) to the relevant pins. If the pinmux is not configured, PWM signals will not reach the pins!
这么看来, pwm用起来还是有点难度的, 需要修改pinmux
, 具体可参考 JETSON NANO PWM配置 这篇文章.
微信公众号
欢迎扫描二维码关注本人微信公众号, 及时获取或者发送给我最新消息:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)