树莓派瞎玩~7~RPi.GPIOのWIKI文档

树莓派瞎玩~7~RPi.GPIOのWIKI文档

  • RPiGPIO Python Module
  • RPiGPIO module basics
    • Importing the module
    • Pin numbering
    • Warnings
    • Setup up a channel
    • Setup more than one channel
    • Input
    • Output
    • Output to several channels
    • Cleanup
    • RPi Board Information and RPiGPIO version
  • Inputs
    • Pull up Pull down resistors
    • Testing inputs polling
    • Interrupts and Edge detection
      • wait_for_edge function
      • event_detected function
      • Threaded callbacks
      • Switch debounce
      • Remove event detection
  • GPIO Outputs
  • Using PWM in RPiGPIO
  • gpio_functionchannel


本文翻译的是树莓派中RPi.GPIO模块的WIKI,每个章节分别对应下表页面。

Title Last Update By Last Updated
Home Ben Croston (croston) 2014-10-11
BasicUsage Ben Croston (croston) 2016-01-01
Inputs Ben Croston (croston) 2016-02-09
Outputs Ben Croston (croston) 2014-11-11
PWM Ben Croston (croston) 2013-12-21
Checking function of GPIO channels Ben Croston (croston) 2015-02-18

RPi.GPIO Python Module

在开始使用RPi.GPIO模块时,这里的实例是值得阅读的。

安装说明见这里

BCM2835型号片上系统和树莓派的详细技术参数见这里


RPi.GPIO module basics

Importing the module

可以用以下语句导入RPi.GPIO模块

import RPi.GPIO as GPIO

这样,你可以在脚本中后面的部分使用GPIO来指代RPi.GPIO模块。

同时,你可以检查是否模块是否导入成功:

try:
    import RPi.GPIO as GPIO
except RuntimeError:
    print("Error importing RPi.GPIO!  This is probably because you need superuser privileges.  You can achieve this by using ‘sudo‘ to run your script")

Pin numbering

在RPi.GPIO中,同时支持树莓派上的两种GPIO引脚编号。第一种编号是BOARD编号,这和树莓派电路板上的物理引脚编号相对应。使用这种编号的好处是,你的硬件将是一直可以使用的,不用担心树莓派的版本问题。因此,在电路板升级后,你不需要重写连接器或代码。

第二种编号是BCM规则,是更底层的工作方式,它和Broadcom的片上系统中信道编号相对应。在使用一个引脚时,你需要查找信道号和物理引脚编号之间的对应规则。对于不同的树莓派版本,编写的脚本文件也可能是无法通用的。

你可以使用下列代码(强制的)指定一种编号规则:

GPIO.setmode(GPIO.BOARD)
  # or
GPIO.setmode(GPIO.BCM)

下面代码将返回被设置的编号规则

mode = GPIO.getmode()

所有可能的返回模式包括GPIO.BOARDGPIO.BCMNone

Warnings

由于在树莓派上,可能有多个脚本或电路控制着GPIO模块。如果RPi.GRIO检测到一个引脚已经被设置成了非默认值,那么你将看到一个警告信息。你可以通过下列代码禁用警告:

GPIO.setwarnings(False)

Setup up a channel

在使用一个引脚前,你需要设置这些引脚作为输入还是输出。配置一个引脚为输入的代码如下:

GPIO.setup(channel, GPIO.IN)

(此处的channel取决与上文设置的编号规则(BOARD/BCM))

有关输入引脚的更多信息见这里.

配置一个引脚为输出的代码如下:

GPIO.setup(channel, GPIO.OUT)

(此处的channel取决与上文设置的编号规则(BOARD/BCM))

你也可以为输出的引脚同时指定初始值。

GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)

Setup more than one channel

你可以使用一次函数调用初始化多个引脚(要求0.5.8以上版本)。例如:

chan_list = [11,12]    # add as many channels as you want!
                       # you can tuples instead i.e.:
                       #   chan_list = (11,12)
GPIO.setup(chan_list, GPIO.OUT)

Input

读取一个GPIO引脚值的代码如下:

GPIO.input(channel)

(此处的channel取决与上文设置的编号规则(BOARD/BCM))。低电平返回0 / GPIO.LOW / False,高电平返回1 / GPIO.HIGH / True

Output

设置一个GPIO引脚的输出状态,代码如下:

GPIO.output(channel, state)

(此处的channel取决与上文设置的编号规则(BOARD/BCM))。状态可以设置为0 / GPIO.LOW / False / 1 / GPIO.HIGH / True

Output to several channels

你可以使用一次函数调用设置多个引脚的输出值(要求0.5.8以上版本)。例如:

chan_list = [11,12]                             # also works with tuples
GPIO.output(chan_list, GPIO.LOW)                # sets all to GPIO.LOW
GPIO.output(chan_list, (GPIO.HIGH, GPIO.LOW))   # sets first HIGH and second LOW

Cleanup

在程序的最后,释放掉使用的资源是一个好的习惯。在使用RPi.GPIO模块中,也是这样。将用到的所有的输入都设置回没有上拉下拉电阻的输入,可以避免因为短接引脚而偶然的损坏树莓派。注意,GPIO.cleanup()只会释放掉脚本中使用的GPIO引脚,并会清除设置的引脚编号规则。

你可以使用下列代码释放脚本中使用的引脚:

GPIO.cleanup()

如果在退出程序时,不想将脚本中使用的所有引脚都释放,而是保留其中的一部分。你可以释放一个或一组引脚。

GPIO.cleanup(channel)
GPIO.cleanup( (channel1, channel2) )
GPIO.cleanup( [channel1, channel2] )

RPi Board Information and RPi.GPIO version

获取关于树莓派的信息:

GPIO.RPI_INFO

获取树莓派版本的信息:

GPIO.RPI_INFO[‘P1_REVISION‘]
GPIO.RPI_REVISION    (deprecated)

获取RPi.GPIO的版本:

GPIO.VERSION

Inputs

你可以通过多种方式获得GPIO引脚的值。最简单原始的方式是每隔一段时间检查输入的信号值,这种方式被称为轮询。如果你的程序读取的时机错误,则很可能会丢失输入信号。轮询是在循环中执行的,这种方式比较占用处理器资源。另一种响应GPIO输入的方式是使用中断(边缘检测),这里的边缘是指信号从高到低的变换(下降沿)或从低到高的变换(上升沿)。

Pull up / Pull down resistors

如果输入引脚处于悬空状态,引脚的值将是漂动的。换句话说,读取到的值是未知的,因为它并没有被连接到任何的信号上,直到按下一个按钮或开关。由于干扰的影响,输入的值可能会反复的变化。

我们可以通过硬件或软件两种方式为引脚连接一个上拉电阻或下拉电阻,这样,就会为输入引脚设置一个默认值,从而解决这个抖动问题。你可以使用硬件方式,将10K的电阻连接到输入引脚和3.3V电源之间(称为上拉电阻),或连接在输入引脚和0V的底线之间(成为下拉电阻)。也可以通过RPi.GPIO模块配置Broadcom的片上系统,实现为引脚连接一个上拉或下拉电阻。

GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
  # or
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

(此处的channel取决与上文设置的编号规则(BOARD/BCM))

Testing inputs (polling)

你可以在某一时刻获取输入信号的值:

if GPIO.input(channel):
    print(‘Input was HIGH‘)
else:
    print(‘Input was LOW‘)

下面代码给出了使用轮询的方式,来等待按钮按下:

while GPIO.input(channel) == GPIO.LOW:
    time.sleep(0.01)  # wait 10 ms to give CPU chance to do other things

(此处假设按下按钮将使得输入信号从低电平转换为高电平)

Interrupts and Edge detection

边缘是指信号状态的改变,从低到高(上升沿)或从高到低(下降沿)。通常情况下,我们更关心于输入状态的该边而不是输入信号的值。这种状态的该边被称为事件。

当你的程序正在忙于其他事情时,下面提供了几种方式使你的程序可以捕获到按钮的按下事件:

  • wait_for_edge() 函数
  • event_detected() 函数
  • 当边沿被检测时,回调一个线程函数

wait_for_edge() function

wait_for_edge()被用于阻止程序的继续执行,直到检测到一个边沿。也就是说,上文中等待按钮按下的实例可以改写为:

GPIO.wait_for_edge(channel, GPIO.RISING)

你可以检测这些边沿,GPIO.RISING / GPIO.FALLING / GPIO.BOTH。利用中断的好处是,它占用的CPU资源是可以忽略不计的,因此CPU有更多的资源可以做其他的事情。

如果你只是想在一个确定时间内等待边沿,则可以设置超时参数:

# wait for up to 5 seconds for a rising edge (timeout is in milliseconds)
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000)
if channel is None:
    print(‘Timeout occurred‘)
else:
    print(‘Edge detected on channel‘, channel)

event_detected() function

event_detected()函数可以在循环中和其他代码一起使用,和轮询方式不同的是,在CPU忙于其他事情时,并不会错过输入状态的改变。在使用Pygame或PyQt时,通常有一个主循环来监听和及时的响应GUI事件,此时该函数是很有用的。

GPIO.add_event_detect(channel, GPIO.RISING)  # add rising edge detection on a channel
do_something()
if GPIO.event_detected(channel):
    print(‘Button pressed‘)

你可以检测这些边沿,GPIO.RISING / GPIO.FALLING / GPIO.BOTH

Threaded callbacks

RPi.GPIO为回调函数另外开启一个线程。这意味这回调函数可以和你的主程序同时运行,及时的对边沿做出响应。例如:

def my_callback(channel):
    print(‘This is a edge event callback function!‘)
    print(‘Edge detected on channel %s‘%channel)
    print(‘This is run in a different thread to your main program‘)

GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback)  # add rising edge detection on a channel
...the rest of your program...

如果你想设置多个回调函数,可以这样:

def my_callback_one(channel):
    print(‘Callback one‘)

def my_callback_two(channel):
    print(‘Callback two‘)

GPIO.add_event_detect(channel, GPIO.RISING)
GPIO.add_event_callback(channel, my_callback_one)
GPIO.add_event_callback(channel, my_callback_two)

注意,这种情况下,回调函数将按照他们被定义的顺序的执行,不会同时执行,因为这里只有一个线程用于执行回调函数。(小白注:是按照add的顺序还是定义的顺序?原文:This is because there is only one thread used for callbacks, in which every callback is run, in the order in which they have been defined.)

Switch debounce

你可能注意到当你按下一次按钮时,回调函数可能会被调用多次。产生这个结果的原因被成为开关抖动。下面有几种方式可以应对开关抖动:

  • 加入 0.1uF 的电容
  • 软件去抖
  • 上两种方式的组合

在指定回调函数时,你可以加入bouncetime=参数来使用软件去抖,回跳时间的单位是毫秒。例如

# add rising edge detection on a channel, ignoring further edges for 200ms for switch bounce handling
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback, bouncetime=200)

GPIO.add_event_callback(channel, my_callback, bouncetime=200)

Remove event detection

出于某些原因,当你的程序不在需要检测边沿事件时,可以使用下面的代码停止检测:

GPIO.remove_event_detect(channel)

GPIO Outputs

1. 使用RPi.GPIO设置引脚为输出(正如这里描述的)

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)

2. 将输出值设置为高电平:

GPIO.output(12, GPIO.HIGH)
 # or
GPIO.output(12, 1)
 # or
GPIO.output(12, True)

3. 将输出值设置为低电平:

GPIO.output(12, GPIO.LOW)
 # or
GPIO.output(12, 0)
 # or
GPIO.output(12, False)

4. 同时设置多个输出引脚的值:

chan_list = (11,12)
GPIO.output(chan_list, GPIO.LOW) # all LOW
GPIO.output(chan_list, (GPIO.HIGH,GPIO.LOW))  # first LOW, second HIGH

5. 在程序的最后释放资源:

GPIO.cleanup()

注意,你可以使用Input()函数读取一个输出引脚的状态并将其作为输出值,例如:

GPIO.output(12, not GPIO.input(12))

Using PWM in RPi.GPIO

创建一个PWM实例:

p = GPIO.PWM(channel, frequency)

开始脉宽调制:

p.start(dc)   # where dc is the duty cycle (0.0 <= dc <= 100.0)

更改调制频率:

p.ChangeFrequency(freq)   # where freq is the new frequency in Hz

更改占空比:

p.ChangeDutyCycle(dc)  # where 0.0 <= dc <= 100.0

停止输出PWM波:

p.stop()

注意,当实例变量p超出作用域时,也会停止输出PWM波。

下面的例子将会使LED灯以两秒的速度闪烁:

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)

p = GPIO.PWM(12, 0.5)
p.start(1)
input(‘Press return to stop:‘)   # use raw_input for Python 2
p.stop()
GPIO.cleanup()

下面的例子使一个LED逐渐的变亮和变暗:

import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)

p = GPIO.PWM(12, 50)  # channel=12 frequency=50Hz
p.start(0)
try:
    while 1:
        for dc in range(0, 101, 5):
            p.ChangeDutyCycle(dc)
            time.sleep(0.1)
        for dc in range(100, -1, -5):
            p.ChangeDutyCycle(dc)
            time.sleep(0.1)
except KeyboardInterrupt:
    pass
p.stop()
GPIO.cleanup()

gpio_function(channel)

返回一个GPIO信道的功能。

例如:

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
func = GPIO.gpio_function(pin)

函数将返回下列值中的一个

GPIO.IN / GPIO.OUT / GPIO.SPI / GPIO.I2C / GPIO.HARD_PWM / GPIO.SERIAL / GPIO.UNKNOWN


时间: 2024-11-06 23:16:55

树莓派瞎玩~7~RPi.GPIOのWIKI文档的相关文章

Retrofit 简介 wiki 文档

简介 Type-safe HTTP client for Android and Java by Square, Inc. GitHub主页:https://github.com/square/retrofit/ WIKI    官网&简易教程 JAR包 依赖与混淆 Retrofit requires at minimum Java 7 or Android 2.3. Snapshots of the development version are available in Sonatype's

Solr Wiki文档

相比ElasticSearch,Solr的文档详尽丰富,同时也显得冗余啰嗦. Solr的官方文档有两个地方: Solr官方教程 Solr社区维基 本文主要列出一些Solr Wiki中的主要讨论主题,方便查阅: SolrJ 主要讲解Solr Java客户端的使用方法,版本比较老. SolrSchema.xml 主要讲解SolrSchema.xml相关配置. Solr中文分词 Solr自带多语言分词工具,主要是CJKTokenizer和SmartChineseTokenizer,基本上跟Lucene

转:全志A20 GPIO 总结文档

链接: http://blog.csdn.net/chwenj/article/details/42190745 /* * author:          [email protected] * Agreement:       GPL. */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>

使用Git Wiki 管理文档时,文档编写的基本用法

自己初次接触GitLab,通过百度和自己查找资料,了解了一部分.在自己的工作中,主要用到GitLab的Wiki文档版本管理能力.我总结了一小部分文本编辑需要用到的东西. 一.文本的排版 为了让文本/文档的结构清晰明了,我们需要一下标题结构和文本格式.Wiki 主要的文本编辑语法用到的是Markdown.Markdown语法兼容HTML,可以直接在文档里用HTML撰写,只是有一些区块元素<div><table><pre><p>等标签,必须在前后加空行与其他内容

基于alibaba开源的分布式数据同步系统安装配置文档otter之环境配置

otter项目开源地址:https://github.com/alibaba/otter canal项目开源地址:https://github.com/alibaba/canal 我们的用这个系统的背景:主要是做异地容灾,可是我们需要的现网的数据需要同步到容灾区.   工作原理: 原理描述: 1.基于Canal开源产品,获取数据库增量日志数据. 什么是Canal, 请点击 2.典型管理系统架构,manager(web管理)+node(工作节点) a. manager运行时推送同步配置到node节

基于Nutch&amp;Solr定向采集解析和索引搜索的整合技术指南文档

基于Nutch&Solr定向采集解析和索引搜索的整合技术指南文档 内容来源于开源项目: http://git.oschina.net/xautlx/nutch-ajax https://github.com/xautlx/nutch-ajax 如何阅读本文档 本教程文档原始基于Markdown编写,如果你熟悉Markdown文件及相关工具使用,可以直接通过Markdown阅读或编辑工具查看本教程.md格式文件. 由于Markdown语法暂时没有目录支持,如果希望以目录导航方式查看文档,可参考如下

Spring Boot:整合Swagger在线文档

综合概述 spring-boot作为当前最为流行的Java web开发脚手架,越来越多的开发者选择用其来构建企业级的RESTFul API接口.这些接口不但会服务于传统的web端(b/s),也会服务于移动端.在实际开发过程中,这些接口还要提供给开发测试进行相关的白盒测试,那么势必存在如何在多人协作中共享和及时更新API开发接口文档的问题. 假如你已经对传统的wiki文档共享方式所带来的弊端深恶痛绝,那么尝试一下Swagger2 方式,一定会让你有不一样的开发体验. 使用 Swagger 集成文档

SpringBoot + Swagger2 自动生成API接口文档

spring-boot作为当前最为流行的Java web开发脚手架,相信越来越多的开发者会使用其来构建企业级的RESTFul API接口.这些接口不但会服务于传统的web端(b/s),也会服务于移动端.在实际开发过程中,这些接口还要提供给开发测试进行相关的白盒测试,那么势必存在如何在多人协作中共享和及时更新API开发接口文档的问题. 假如你已经对传统的wiki文档共享方式所带来的弊端深恶痛绝,那么尝试一下Swagger2 方式,一定会让你有不一样的开发体验: 功能丰富 :支持多种注解,自动生成接

【玩转开源】BananaPi R2——移植RPi.GPIO 到 R2

1. 首先给大家介绍一下什么是RPi.GPIO. 简单去讲,RPi.GPIO就是一个运行在树莓派开发板上可以通过Python去控制GPIO的一个中间件. 现在我这边做了一个基础功能的移植,接下来大家可以跟着我去学习一下RPi.GPIO是如何通过Python去实现控制开发板上的GPIO的. 2. 看一下效果图: 2.1 硬件实物运行效果 2.2 执行Python脚本打印的log 3. 那么RPi.GPIO在R2上是如何使用的呢? 3.1 首先在R2上面运行一个Ubuntu镜像,然后下载代码:git