Nvidia Jetson Nano利用GPIO控制传感器
作者:Sun zi chao     发布时间:2022-07-24 07:40:00    阅读次数:15
如何在Nvdia Jetson Nano上利用GPIO控制外置传感器,我在网上收集了相关的资料,方便今后使用。

一、安装方法

	pip3 install Jetson.GPIO

二、控制传感器程序

1.rgb实验

import Jetson.GPIO as GPIO
import time

red_pin = 17
green_pin = 18
blue_pin = 27


# 初始化程序
def init_setup():
    GPIO.setmode(GPIO.BCM)    # 采用实际的物理管脚给GPIO口
    GPIO.setwarnings(False)     # 去除GPIO口警告
    GPIO.setup([red_pin,green_pin,blue_pin], GPIO.OUT, initial=0)   # 设置Pin模式为输出模式,low

# 关闭RGB-LED灯
def all_off():
    GPIO.output(red_pin, GPIO.LOW)    #  设置Pin管脚为低电平(0V)关闭LED
    GPIO.output(green_pin, GPIO.LOW)
    GPIO.output(blue_pin, GPIO.LOW)

def destroy():
    all_off()  # 关闭RGB-LED灯
    GPIO.cleanup()  # 释放资源

def red_on():
    GPIO.output(red_pin,GPIO.HIGH)
    GPIO.output(green_pin,GPIO.LOW)
    GPIO.output(blue_pin,GPIO.LOW)

def green_on():
    GPIO.output(red_pin,GPIO.LOW)
    GPIO.output(green_pin,GPIO.HIGH)
    GPIO.output(blue_pin,GPIO.LOW)

def blue_on():
    GPIO.output(red_pin,GPIO.LOW)
    GPIO.output(green_pin,GPIO.LOW)
    GPIO.output(blue_pin,GPIO.HIGH)

def all_on():
    GPIO.output(red_pin,GPIO.HIGH)
    GPIO.output(green_pin,GPIO.HIGH)
    GPIO.output(blue_pin,GPIO.HIGH)


init_setup() # 初始化设置函数

if __name__ == '__main__':
    try:
        while 1:
            inp = input('input command: ')
            if inp == 'r':
                red_on()
            elif inp == 'g':
                green_on()
            elif inp == 'b':
                blue_on()
            elif inp == 'a':
                all_on()
            elif inp == 'e':
                destroy()
                break
    except KeyboardInterrupt:
        destroy()

2.七彩灯实验

# 导入树莓Pi GPIO库
import RPi.GPIO as GPIO
# 从time模块导入sleep函数
from time import sleep

# 定义七彩灯控制管脚
Led_pin = 25
# 暂时忽略警告
GPIO.setwarnings(False)
# 设置GPIO模式作为 GPIO.BCM
GPIO.setmode(GPIO.BCM)
# 将七彩LED引脚作为输出引脚,并将初始值设置为HIGH(打开)
GPIO.setup(Led_pin, GPIO.OUT,initial=GPIO.HIGH)

def destroy():
    GPIO.output(Led_pin, GPIO.LOW)
    GPIO.cleanup()

try:
    while 1:
        pass
except KeyboardInterrupt:
    destroy()

3.OLED实验

import time

import Adafruit_SSD1306

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

# 128x32显示器,硬件I2C:
disp = Adafruit_SSD1306.SSD1306_128_32(rst=None, i2c_bus=1, gpio=1)

# 初始化库。
disp.begin()
# 清除显示内容
disp.clear()
disp.display()

#为绘图创建空白图像。
#确保为1位颜色创建模式为“1”的图像(单色)
width = disp.width
height = disp.height
image = Image.new('1', (width, height))

# 载入默认字体
font = ImageFont.load_default()

# 获取要在图像上绘制的绘图对象。
draw = ImageDraw.Draw(image)

def oled_main(text):
    try:
        while True:
            # 画一个黑色填充框清除图像。
            draw.rectangle((0,0,width,height), outline=0, fill=0)
            draw.text((50,10),text,font=font,fill=255)

            # 显示图像。
            disp.image(image)
            disp.display()
            time.sleep(3)
    except KeyboardInterrupt:
        disp.clear()
        disp.display()

if __name__ == '__main__':
    oled_main('ZLTech')


4.有源蜂鸣器实验

import RPi.GPIO as GPIO
import time

pin = 6    # 有源蜂鸣器管脚定义

# GPIO设置函数
def init_setup():
    GPIO.setmode(GPIO.BCM)  # 采用实际的物理管脚给GPIO口
    GPIO.setwarnings(False)   # 关闭GPIO警告提示
    GPIO.setup(pin, GPIO.OUT, initial=0)  # 设置有源蜂鸣器管脚为输出模式

#  打开蜂鸣器
def beep_on():
    GPIO.output(pin, GPIO.HIGH)  # 蜂鸣器为高电平触发,所以使能蜂鸣器让其发声

# 关闭蜂鸣器
def beep_off():
    GPIO.output(pin, GPIO.LOW) # 蜂鸣器设置为低电平,关闭蜂鸟器

# 控制蜂鸣器鸣叫
def beep(x):
    beep_on()     # 打开蜂鸣器控制
    time.sleep(x)  # 延时时间
    beep_off()    # 关闭蜂鸣器控制
    time.sleep(x)   # 延时时间

# 循环函数
def loop():
    while True:
        beep(0.5) # 控制蜂鸣器鸣叫,延时时间为500mm

def destroy():
    GPIO.output(pin, GPIO.LOW) # 关闭蜂鸣器鸣叫
    GPIO.cleanup()  # 释放资源


# 程序入口
if __name__ == '__main__': 
    init_setup() # 设置GPIO管脚
    try:  # 检测异常
        loop()      # 调用循环函数
    except KeyboardInterrupt:  # 当按下Ctrl+C时,将执行destroy()子程序
        destroy()    # 释放资源


5.无源蜂鸣器实验

import RPi.GPIO as GPIO
import time

output_pin = 33  # 无源蜂鸣器管脚

# 音谱定义
Tone_CL = [0, 131, 147, 165, 175, 196, 211, 248] # 低C音符的频率
Tone_CM = [0, 262, 294, 330, 350, 393, 441, 495] # 中C音的频率
Tone_CH = [0, 525, 589, 661, 700, 786, 882, 990] # 高C音符的频率

# 第一首歌音谱
song_1 = [ Tone_CM[3], Tone_CM[5], Tone_CM[6], Tone_CM[3], Tone_CM[2], Tone_CM[3], Tone_CM[5], Tone_CM[6], 
                                    Tone_CH[1], Tone_CM[6], Tone_CM[5], Tone_CM[1], Tone_CM[3], Tone_CM[2], Tone_CM[2], Tone_CM[3], 
                                    Tone_CM[5], Tone_CM[2], Tone_CM[3], Tone_CM[3], Tone_CL[6], Tone_CL[6], Tone_CL[6], Tone_CM[1],
                                    Tone_CM[2], Tone_CM[3], Tone_CM[2], Tone_CL[7], Tone_CL[6], Tone_CM[1], Tone_CL[5] ]

# 第1首歌的节拍,1表示1/8拍
beat_1 = [ 1, 1, 3, 1, 1, 3, 1, 1,
                                   1, 1, 1, 1, 1, 1, 3, 1, 
                                   1, 3, 1, 1, 1, 1, 1, 1, 
                                   1, 2, 1, 1, 1, 1, 1, 1, 
                                   1, 1, 3]

# 第二首歌音谱
song_2 = [Tone_CM[1], Tone_CM[1], Tone_CM[1], Tone_CL[5], Tone_CM[3], Tone_CM[3], Tone_CM[3], Tone_CM[1],
                                   Tone_CM[1], Tone_CM[3], Tone_CM[5], Tone_CM[5], Tone_CM[4], Tone_CM[3], Tone_CM[2], Tone_CM[2], 
                                   Tone_CM[3], Tone_CM[4], Tone_CM[4], Tone_CM[3], Tone_CM[2], Tone_CM[3], Tone_CM[1], Tone_CM[1], 
                                   Tone_CM[3], Tone_CM[2], Tone_CL[5], Tone_CL[7], Tone_CM[2], Tone_CM[1]]

# 第2首歌的节拍,1表示1/8拍
beat_2 = [ 1, 1, 2, 2, 1, 1, 2, 2, 
                                   1, 1, 2, 2, 1, 1, 3, 1, 
                                   1, 2, 2, 1, 1, 2, 2, 1, 
                                   1, 2, 2, 1, 1, 3 ]

# GPIO设置函数
def init_setup():
    GPIO.setmode(GPIO.BOARD)        # 采用实际的物理管脚给GPIO口
    GPIO.setwarnings(False)         # 关闭GPIO警告提示
    GPIO.setup(output_pin, GPIO.OUT, initial=GPIO.HIGH) # 设置无源蜂鸣器管脚为输出模式
    global pwm_key     # 指定一个全局变量来替换gpi.pwm
    pwm_key = GPIO.PWM(output_pin, 440) # 设置初始频率为440
    pwm_key.start(50)    # 按50%工作定额启动蜂鸣器引脚。

# 循环函数
def loop():
    while True:
        #    播放第一首歌音乐
        for i in range(1, len(song_1)):     # 播放第一首歌
            pwm_key.ChangeFrequency(song_1[i]) # 设置歌曲音符的频率
            time.sleep(beat_1[i] * 0.5)     # 延迟一个节拍* 0.5秒的音符
        time.sleep(1)       # 等待下一首歌。
        #    播放第二首歌音乐 
        for i in range(1, len(song_2)):     # 播放第二首歌
            pwm_key.ChangeFrequency(song_2[i]) # 设置歌曲音符的频率
            time.sleep(beat_2[i] * 0.5)     # 延迟一个节拍* 0.5秒的音符

# 释放资源函数
def destory():
    pwm_key.stop()  # 停止蜂鸣器
    GPIO.output(output_pin, 1)  # 设置蜂鸣器管脚为高电平
    GPIO.cleanup()   # 释放资源

# 程序入口
if __name__ == '__main__':
    init_setup()
    try:
        loop()
    except KeyboardInterrupt:   # 当按下Ctrl+C时,将执行destroy()子程序
        destory()      # 释放资源


6.按键控制有源蜂鸣器

import RPi.GPIO as GPIO
import time

key = 26
#key = 19
beep_pin = 6

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

def on():
    GPIO.output(beep_pin, 1)

def off():
    GPIO.output(beep_pin, 0)

def destroy():
    off()
    GPIO.cleanup()

def test(ver):
    if ver == 0:
        on()
    else:
        off()

if __name__ == '__main__':
    try:
        GPIO.setup(key, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.setup(beep_pin, GPIO.OUT, initial=0)
        while 1:
            GPIO.setup(key, GPIO.IN)

            ver = GPIO.input(key)
            GPIO.setup(key, GPIO.OUT, initial=1)
            test(ver)
    except KeyboardInterrupt:
        destroy()

7.超声波实验

import RPi.GPIO as GPIO
import time
import OLED

TRIG_pin = 11  # 超声波模块Trig控制管脚, BCM 17 18
ECHO_pin = 12  # 超声波模块Echo控制管脚

# 超声波模块初始化工作
def init_setup():
    GPIO.setmode(GPIO.BOARD)      # 采用实际的物理管脚给GPIO口
    GPIO.setwarnings(False)       # 忽略GPIO操作注意警告
    GPIO.setup(TRIG_pin, GPIO.OUT) # Tring设置为输出模式
    GPIO.setup(ECHO_pin, GPIO.IN)  # Echo设置为输入模式

# 超声波计算距离函数
def distance():
    GPIO.output(TRIG_pin, 0)  # 开始起始
    time.sleep(0.000002)  # 延时2us
    GPIO.output(TRIG_pin, 1)  # 超声波启动信号,延时10us
    time.sleep(0.00001)    # 发出超声波脉冲
    GPIO.output(TRIG_pin, 0)  # 设置为低电平

    while GPIO.input(ECHO_pin) == 0: # 等待回传信号
        us_a = 0
    us_time1 = time.time()      # 获取当前时间
    while GPIO.input(ECHO_pin) == 1: # 回传信号截止信息
        us_a = 1
    us_time2 = time.time()     # 获取当前时间
    during = us_time2 - us_time1          # 转换微秒级的时间

    # 声速在空气中的传播速度为340m/s, 超声波要经历一个发送信号和一个回波信息
    # 计算公式如下所示:
    return during * 340 / 2 * 100        # 求出距离

# 循环函数
def loop():
    while True:
        us_dis = distance()   # 获取超声波计算距离
        OLED.oled_main(us_dis+'cm')       # 打印超声波距离值
        time.sleep(0.3)  # 延时300ms 

# 资源释放函数
def destroy():
    GPIO.cleanup() # 释放资源

# 程序入口
if __name__ == "__main__":
    init_setup() # 调用初始化函数
    try:
        loop() # 调用循环函数
    except KeyboardInterrupt: # 当按下Ctrl+C时,将执行destroy()子程序
        destroy() # 释放资源
    else:
        pass


8.光敏实验

import PCF8591 as ADC
import RPi.GPIO as GPIO
import time

DO_pin = 17     # 光敏传感器管脚
GPIO.setmode(GPIO.BCM) # 管脚映射,采用BCM编码
GPIO.setwarnings(False)

# 初始化工作
def init_setup():
    ADC.setup(0x48)      # 设置PCF8591模块地址
    GPIO.setup(DO_pin, GPIO.IN) # 光敏传感器,设置为输入模式

# 循环函数
def loop():
    #status = 1 # 状态值
    # 无限循环
    while True:
        print ('Photoresistor Value: ', ADC.read(0)) # 读取AIN0的值,获取光敏模拟量值
        time.sleep(0.2)          # 延时200ms

# 程序入口
if __name__ == '__main__':
    try:
        init_setup() # 地址设置
        loop()  # 调用无限循环
    except KeyboardInterrupt: 
        pass


9.PCF8591实验

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 说明:这是一个PCF8591模块的程序。
#      警告:模拟输入不能超过3.3V!
# 在这个程序中,我们使用电位计进行模拟输入和控制一个模拟电压
# 的LED灯,你可以导入这个程序到另一个程序中使用:
# import PCF8591 as ADC
# ADC.Setup(Address)  # 通过 sudo i2cdetect -y -1 可以获取到IIC的地址
# ADC.read(channal)    # 通道选择范围为0-3
# ADC.write(Value)    # 值的范围为:0-255
#####################################################
import smbus
import time

# 对应比较旧的版本如RPI V1 版本,则 "bus = smbus.SMBus(0)"
bus = smbus.SMBus(1)

#通过 sudo i2cdetect -y -1 可以获取到IIC的地址
def setup(Addr):
    global address
    address = Addr

# 读取模拟量信息
def read(chn): #通道选择,范围是0-3之间
    try:
        if chn == 0:
            bus.write_byte(address,0x40)
        if chn == 1:
            bus.write_byte(address,0x41)
        if chn == 2:
            bus.write_byte(address,0x42)
        if chn == 3:
            bus.write_byte(address,0x43)
        bus.read_byte(address) # 开始进行读取转换
    except Exception as e:
        print ("Address: %s" % address)
        print (e)
    return bus.read_byte(address)

# 模块输出模拟量控制,范围为0-255
def write(val):
    try:
        temp = val # 将数值赋给temmp 变量
        temp = int(temp) # 将字符串转换为整型
        # 在终端上打印temp以查看,否则将注释掉
        bus.write_byte_data(address, 0x40, temp)
    except Exception as e:
        print ("Error: Device address: 0x%2X" % address)
        print (e)

if __name__ == "__main__":
    setup(0x48)
    while True:
        print ('AIN0 = ', read(0))
        print ('AIN1 = ', read(1))
        tmp = read(0)
        tmp = tmp*(255-125)/255+125 # 低于125时LED不会亮,所以请将“0-255”转换为“125-255”
        write(tmp)
#        time.sleep(0.3)


10.PCF8591控制

# 由于Jetson Nano GPIO 口不带模拟量输出,所以可以扩展出模拟量输入模块
import PCF8591 as ADC
import time

# 模块地址设置
def init_setup():
    ADC.setup(0x48)  # 设置PCF8591模块地址

# 无限循环
def loop():
    while True:
        print ("AIN0=%d"%ADC.read(0)) #读取AIN0的数值,插上跳线帽之后,采用的是内部的电位器
        time.sleep(0.5)
        ADC.write(ADC.read(0)) # 控制AOUT输出电平控制LED灯

# 异常处理函数
def destroy():
    ADC.write(0) #AOUT输出为0

#程序入口
if __name__ == "__main__":
    try:
        init_setup() #地址设置
        loop()    # 调用无限循环
    except KeyboardInterrupt:
        destroy() #释放AOUT端口


11.MPU6050实验

# 说明:驱动三轴加速度、陀螺仪姿态传感器
import smbus                    # 导入I2C的SMBus模块
from time import sleep          # 导入延时函数

# 一些MPU6050寄存器及其地址
PWR_MGMT_1   = 0x6B
SMPLRT_DIV   = 0x19
CONFIG       = 0x1A
GYRO_CONFIG  = 0x1B
INT_ENABLE   = 0x38
ACCEL_XOUT_H = 0x3B
ACCEL_YOUT_H = 0x3D
ACCEL_ZOUT_H = 0x3F
GYRO_XOUT_H  = 0x43
GYRO_YOUT_H  = 0x45
GYRO_ZOUT_H  = 0x47

# MPU 6050 初始化工作
def MPU_Init():
    # 写入抽样速率寄存器
    zl_bus.write_byte_data(device_address, SMPLRT_DIV, 7)
    # 写入电源管理寄存器
    zl_bus.write_byte_data(device_address, PWR_MGMT_1, 1)
    # 写入配置寄存器
    zl_bus.write_byte_data(device_address, CONFIG, 0)
    # 写入陀螺配置寄存器
    zl_bus.write_byte_data(device_address, GYRO_CONFIG, 24)
    # 写中断使能寄存器
    zl_bus.write_byte_data(device_address, INT_ENABLE, 1)

# 读取MPU6050数据寄存器
def read_data(addr):
    # 加速度值和陀螺值为16位
    high = zl_bus.read_byte_data(device_address, addr)
    low =  zl_bus.read_byte_data(device_address, addr+1)
    # 连接更高和更低的值
    value = ((high << 8) | low)
    # 从mpu6050获取有符号值
    if(value > 32768):
        value = value - 65536
    return value
 
zl_bus = smbus.SMBus(1)    # 或bus = smbus.SMBus(0)用于较老的版本板
device_address = 0x68   # MPU6050设备地址
MPU_Init()             # 初始化MPU6050
# 打印提示信息
print ("init ok")

# 无限循环
while True:
    # 读取加速度计原始值
    acc_x = read_data(ACCEL_XOUT_H)
    acc_y = read_data(ACCEL_YOUT_H)
    acc_z = read_data(ACCEL_ZOUT_H)

    # 读陀螺仪原始值
    gyro_x = read_data(GYRO_XOUT_H)
    gyro_y = read_data(GYRO_YOUT_H)
    gyro_z = read_data(GYRO_ZOUT_H)

    # 全刻度范围+/- 250度℃,根据灵敏度刻度系数
    Ax = acc_x/16384.0
    Ay = acc_y/16384.0
    Az = acc_z/16384.0

    Gx = gyro_x/131.0
    Gy = gyro_y/131.0
    Gz = gyro_z/131.0

    # 打印出MPU相关信息
    print ("Gx=%.2f" %Gx, u'\u00b0'+ "/s", "\tGy=%.2f" %Gy, u'\u00b0'+ "/s", "\tGz=%.2f" %Gz, u'\u00b0'+ "/s", "\tAx=%.2f g" %Ax, "\tAy=%.2f g" %Ay, "\tAz=%.2f g" %Az)
    sleep(1)  # 延时1s


桂ICP备11003301号-1 公安备案号:45040302000027 Copyright @ 2021- 2022 By Sun zi chao

阅读统计: 1.93W 文章数量: 76 运行天数: 416天 返回cmnsoft