前言:因为本人之前是学习硬件出身,所以对该jeston nano的开发先从硬件控制开始。
2 硬件控制
2.1 环境配置
Jetson TX1,TX2,AGX Xavier和Nano开发板包含一个40引脚GPIO接头,类似于Raspberry Pi中的40引脚接头。可以使用Jetson GPIO Library包中提供的Python库来控制这些GPIO的数字输入和输出。该库与Raspberry Pi的RPi.GPIO库具有相同的API,以便提供一种将Raspberry Pi上运行的应用程序移动到Jetson板的简便方法。
首先我们需要下载GPIO依赖,教程上给出的指令是
git clone https://github.com/NVIDIA/jetson-gpio
意为从英伟达github仓库下载配置的库,国内直接连接git速度非常满。上不上去全靠运气,所以我们这里先用另外一台有tizi的电脑把文件下载下来。
将下载下来的文件解压,使用传输介质(U盘)拷贝到nano系统的一个自定义文件夹下,并按照官网的知识输入如下的指令。
sudo python3 setup.py install
运行的结果如下图所示,没有报错,说明GPIO的驱动已经安装成功了。
使用前,还需要创建一个 gpio 组,把你的当前的账号加到这个组,并赋予使用权限,把下面的文件拷贝到规则当中。这个要根据文件的位置进行指令的更改,也可以直接使用UI界面手动拷贝
sudo groupadd -f -r gpio
sudo usermod -a -G gpio user_name
sudo cp /***/jetson-gpio/lib/python/Jetson/GPIO/99-gpio.rules /etc/udev/rules.d/
为了使新规则生效,您需要通过运行以下命令重新引导或重新加载udev规则
sudo udevadm control --reload-rules && sudo udevadm trigger
注意: user_name 是你使用的用户名,比如说 jetson
1.2 测试基本功能
nano的引脚定义如下图所示下是Jetson Nano正视管脚图。可见Jetson Nano中GPIO的各个管脚功能,具有Sysfs GPIO的管脚都可以作为通用输入输出管脚。其余管脚可以在name下面看到各自功能,具有通信功能的可看到查询地址或串口名称等信息。可见nano没有timer、ADC、DAC等资源,当然这些问题都可以用串口接一个STM32来解决。所以主要需要进行的是串口的开发。
我们首先测试基本的GPIO功能,在之前拷贝的文件夹中有一个叫做samples的文件夹,我们使用如下指令跑其中的历程。
sudo python3 simple_input.py
运行程序后,可以看到终端打印信息, 默认情况下 Pin18 的值是低电平,找一个杜邦线将第 12号引脚连到 3.3V,可以看到读取的值变成了 HIGH,如果连到 GND,会显示 LOW。
这个历程的源如下,我们逐进行分析。
import RPi.GPIO as GPIO
import time
# Pin Definitions
input_pin = 18 # BCM pin 18, BOARD pin 12
def main():
prev_value = None
# Pin Setup:
GPIO.setmode(GPIO.BCM) # BCM pin-numbering scheme from Raspberry Pi
GPIO.setup(input_pin, GPIO.IN) # set pin as an 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()
首先是导包,这个点英伟达官网的说明是下面第三行的导包模式,但同时也说明了第一行和第三行的导包方式是一样的。英伟达的原话如下“This way, you can refer to the module as GPIO throughout the rest of the application. The module can also be imported using the name RPi.GPIO instead of Jetson.GPIO for existing code using the RPi library.”
import RPi.GPIO as GPIO
import time
import Jetson.GPIO as GPIO
在之后进入到主函数中,先调用函数GPIO.setmode(XXX)参变量有四种选择方式,这个采用的是BCM编码模式。BCM模式下的引脚编码并不是引脚本身的位置号码,引脚本身的位置号码要使用第一中调用方式。这里的18即板子上的12引脚。英伟达的原话如下“The Jetson GPIO library provides four ways of numbering the I/O pins. 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.setmode(GPIO.BOARD)
GPIO.setmode(GPIO.BCM)
GPIO.setmode(GPIO.CVM)
GPIO.setmode(GPIO.TEGRA_SOC)
同时如果需要查询目前使用的模式可以使用如下的指令
mode = GPIO.getmode()
之后进行GPIO通道模式的选择,一下两条指令分别可以将GPIO设置成输入或者输出模式,只能是这两个模式中的一种。这里相对STM32简化了GPIO的推挽输出和开漏输出,上下拉电阻的配置等等。能否查看修改这些待到后面再进行查证。
GPIO.setup(channel, GPIO.IN)
GPIO.setup(channel, GPIO.OUT)
可以初始化的时候同时幅值
GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)
也可以同时初始多个GPIO
channels = [18, 12, 13]GPIO.setup(channels, GPIO.OUT)
下面是一个try结构,while true一直在运行整个程序,并且中了time.sleep作为延时,该结构使用轮询的方式进行GPIO的查询,每当电平跳变的时候进行输出。效率比较低,阵阵的应用场景应该使用中断的方式。
Value=GPIO.input(channel)
GPIO.output(channel, state)
最后执行finally释放了所有初始化过的GPIO。At the end of the program, it is good to clean up the channels so that all pins are set in their default state. To clean up all channels used, call:
GPIO.cleanup()