文章目录
前言Jetson.GPIO安装可用引脚点亮LEDGPIO输出示例GPIO输入示例GPIO EventGPIO InterruptPWM微信公众号前言
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/
, 但还要配置环境什么的麻烦, 不如直接装一个:
## 先安装pip3sudo apt install python3-pip## 安装Jetson.GPIOsudo pip3 install Jetson.GPIO# Successfully installed Jetson.GPIO-2.0.4
如果直接输入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': {# Pre-test configuration, if boot-time pinmux doesn't set up PWM pins:# Set BOARD pin 18 as mux function PWM:# busybox devmem 0x2434090 32 0x401# Board mode pins'out_a': 18,'in_a': 19,'out_b': 21,'in_b': 22,'unimplemented_pins': (),# Other pin modes:'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 GPIOimport timeLED = 12def main():GPIO.setmode(GPIO.BOARD)GPIO.setup(LED, GPIO.OUT, initial=GPIO.LOW)curr_value = GPIO.LOWtry:while True:time.sleep(1)GPIO.output(LED, curr_value)curr_value ^= GPIO.HIGHfinally:GPIO.cleanup()if __name__=='__main__':main()
GPIO输入示例
文件gpio_input.py
:
import Jetson.GPIO as GPIOimport timeinput_pin = 12def main():GPIO.setmode(GPIO.BOARD)GPIO.setup(input_pin, GPIO.IN)prev_value = Nonetry: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 = valuetime.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 LOWPin 12 Value is HIGHPin 12 Value is LOWPin 12 Value is HIGH
下面关于interrupt, event, pwm的例子直接贴官方代码了.
GPIO Event
import Jetson.GPIO as GPIOimport time# Pin Definitons:led_pin = 12 # Board pin 12but_pin = 18 # Board pin 18def main():# Pin Setup:GPIO.setmode(GPIO.BOARD) # BOARD pin-numbering schemeGPIO.setup(led_pin, GPIO.OUT) # LED pin set as outputGPIO.setup(but_pin, GPIO.IN) # button pin set as input# Initial state for LEDs: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)# event received when button pressedprint("Button Pressed!")GPIO.output(led_pin, GPIO.HIGH)time.sleep(1)GPIO.output(led_pin, GPIO.LOW)finally:GPIO.cleanup() # cleanup all GPIOsif __name__ == '__main__':main()
注意GPIO.wait_for_edge
还可以设置超时时间:
# timeout is in millisecondsGPIO.wait_for_edge(channel, GPIO.RISING, timeout=500)
GPIO Interrupt
import Jetson.GPIO as GPIOimport time# Pin Definitions:led_pin_1 = 12led_pin_2 = 13but_pin = 18# blink LED 2 quickly 5 times when button presseddef 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():# Pin Setup:GPIO.setmode(GPIO.BOARD) # BOARD pin-numbering schemeGPIO.setup([led_pin_1, led_pin_2], GPIO.OUT) # LED pins set as outputGPIO.setup(but_pin, GPIO.IN) # button pin set as input# Initial state for LEDs:GPIO.output(led_pin_1, GPIO.LOW)GPIO.output(led_pin_2, GPIO.LOW)# GPIO.RISING, GPIO.FALLING or GPIO.BOTHGPIO.add_event_detect(but_pin, GPIO.FALLING, callback=blink, bouncetime=10)print("Starting demo now! Press CTRL+C to exit")try:while True:# blink LED 1 slowlyGPIO.output(led_pin_1, GPIO.HIGH)time.sleep(2)GPIO.output(led_pin_1, GPIO.LOW)time.sleep(2)finally:GPIO.cleanup() # cleanup all GPIOsif __name__ == '__main__':main()
注意其中的bouncetime
(单位ms)很好用, 可以保证这段时间内只触发一次, 避免重复触发, 消抖什么的还不错.
PWM
import Jetson.GPIO as GPIOimport timeoutput_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():# Pin Setup:# Board pin-numbering schemeGPIO.setmode(GPIO.BOARD)# set pin as an output pin with optional initial state of HIGHGPIO.setup(output_pin, GPIO.OUT, initial=GPIO.HIGH)p = GPIO.PWM(output_pin, 50)# 50Hzp.start(25)# 25% duty cycleprint("PWM running. Press CTRL+C to exit.")try:while True:# p.ChangeDutyCycle(dc) # where 0.0 <= dc <= 100.0time.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配置 这篇文章.
微信公众号
欢迎扫描二维码关注本人微信公众号, 及时获取或者发送给我最新消息:
如果觉得《Nvidia Xavier GPIO 输入输出 中断 PWM》对你有帮助,请点赞、收藏,并留下你的观点哦!