树莓派pythongpio编程_树莓派 GPIO 编程
树莓派包含GPIO接口,可以跟很多种硬件进行连接,给我们扩展树莓派的功能提供了很多方便的接口。
那么,什么是GPIO接口呢?
GPIO的定义
GPIO是(General Purpose Input Output)的缩写,也就是通用输入输出,是一种常见的硬件接口,用以表示开关量。
下图列出列树莓派全系列的图片,其中的针脚就是GPIO接口:
树莓派GPIO针脚的定义
常见的 Raspberry Pi 接口数量分为两种一种 26针 一种 40 针,根据自己手里的 Pi 即可,我这里的是3代Model B+,针脚的定义如下:
GND表示接地
带V表示电源
绿色的GPIO.*就是我们可以用来编程的针脚。
其他的接口:TxD/RxD是一组,串口通讯用的,和另外一个树莓派(或其他支持串口通讯的模块)对接(TxD接对方的RxD,Rxd接对方的TxD)设置一样的波特率,可以串口通讯。SDA/SCL是一组,IIC协议通讯用的,接另外一个树莓派(或arduino,支持IIC的模块等等),支持iic协议的,通过iic协议通讯MOSI、MISO、SCLK, CE0, CE1 是SPI通讯协议用的,接个使用SPI通讯的模块就靠它了 来源知乎
反正如果你不是很擅长硬件,也不打算扎根硬件的话,无视他们好了。
可以连接树莓派后,通过命令打印出针脚的定义:
1gpio readall
不知道是我的系统太久,还是我外界的扩展板不支持,这里并没有输出针脚编号,只是说不是支持的型号:
1
2
3
4
5
6
7Unable to determine hardware version. I see: Hardware: BCM2835
,
- expecting BCM2708 or BCM2709.
If this is a genuine Raspberry Pi then please report this
to projects@drogon.net. If this is not a Raspberry Pi then you
are on your own as wiringPi is designed to support the
Raspberry Pi ONLY.
不过没关系,不影响我们的测试。
树莓派的扩展板
这里用的是一个集成的扩展板,这样就不用再额外接引线了。
扩展板的针脚示意图:
python GPIO
该库更确切的名称为raspberry-gpio-python,树莓派官方资料中推荐且容易上手。python GPIO是一个小型的python库,可以帮助用户完成raspberry相关IO口操作。但是python GPIO库还没有支持SPI、I2C或者1-wire等总线接口。除了python GPIO之外,还有众多的python扩展库(例如webiopi),毫无疑问的说python非常适合树莓派,树莓派也非常适合python。
两种针脚编号
BOARD编号
这和树莓派电路板上的物理引脚编号相对应。使用这种编号的好处是,你的硬件将是一直可以使用的,不用担心树莓派的版本问题。因此,在电路板升级后,你不需要重写连接器或代码。
BCM规则
是更底层的工作方式,它和Broadcom的片上系统中信道编号相对应。在使用一个引脚时,你需要查找信道号和物理引脚编号之间的对应规则。对于不同的树莓派版本,编写的脚本文件也可能是无法通用的。
你可以使用下列代码(强制的)指定一种编号规则:
1GPIO.setmode(GPIO.BOARD) # orGPIO.setmode(GPIO.BCM)
下面代码将返回被设置的编号规则
1mode = GPIO.getmode()
警告
如果RPi.GRIO检测到一个引脚已经被设置成了非默认值,那么你将看到一个警告信息。你可以通过下列代码禁用警告:
1GPIO.setwarnings(False)
引脚设置
在使用一个引脚前,你需要设置这些引脚作为输入还是输出。配置一个引脚的代码如下:
将引脚设置为输入模式1GPIO.setup(channel, GPIO.IN)
将引脚设置为输出模式1GPIO.setup(channel, GPIO.OUT)
为输出的引脚设置默认值1GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)
释放
一般来说,程序到达最后都需要释放资源,这个好习惯可以避免偶然损坏树莓派。释放脚本中使用的引脚:
1GPIO.cleanup()
注意,GPIO.cleanup()只会释放掉脚本中使用的GPIO引脚,并会清除设置的引脚编号规则。
实验1 控制LED灯闪亮
要想点亮一个 LED 灯或者驱动某个设备,都需要给它们电流和电压,这个步骤也很简单,设置引脚的输出状态就可以了,代码如下:
1> GPIO.output(channel, state)
状态可以设置为:
0 / GPIO.LOW / False
1 / GPIO.HIGH / True
如果编码规则为,GPIO.BOARD,那么channel就是对应引脚的数字。
如果想一次性设置多个引脚,可使用下面的代码:
1
2chan_list = [11,12]
GPIO.output(chan_list, GPIO.LOW)GPIO.output(chan_list, (GPIO.HIGH, GPIO.LOW))
你还可以使用Input()函数读取一个输出引脚的状态并将其作为输出值,例如:
1GPIO.output(12, not GPIO.input(12))
我们也常常需要读取引脚的输入状态,获取引脚输入状态如下代码:
1GPIO.input(channel)
低电平返回
0 / GPIO.LOW / False
高电平返回
1 / GPIO.HIGH / True
如果输入引脚处于悬空状态,引脚的值将是漂动的。换句话说,读取到的值是未知的,因为它并没有被连接到任何的信号上,直到按下一个按钮或开关。由于干扰的影响,输入的值可能会反复的变化。 使用如下代码可以解决问题:
1
2GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
需要注意的是,上面的读取代码只是获取当前一瞬间的引脚输入信号。
如果需要实时监控引脚的状态变化,可以有两种办法。最简单原始的方式是每隔一段时间检查输入的信号值,这种方式被称为轮询。如果你的程序读取的时机错误,则很可能会丢失输入信号。轮询是在循环中执行的,这种方式比较占用处理器资源。另一种响应GPIO输入的方式是使用中断(边缘检测),这里的边缘是指信号从高到低的变换(下降沿)或从低到高的变换(上升沿)。
轮询方式1
2while GPIO.input(channel) == GPIO.LOW:
pass
边缘检测
边缘是指信号状态的改变,从低到高(上升沿)或从高到低(下降沿)。通常情况下,我们更关心于输入状态的该边而不是输入信号的值。这种状态的该边被称为事件。 先介绍两个函数:
wait_for_edge() 函数
wait_for_edge()被用于阻止程序的继续执行,直到检测到一个边沿。也就是说,上文中等待按钮按下的实例可以改写为:
1
2
3
4
5channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000)
if channel is None:
print('Timeout occurred')
else:
print('Edge detected on channel', channel)
add_event_detect() 函数
该函数对一个引脚进行监听,一旦引脚输入状态发生了改变,调用event_detected()函数会返回true,如下代码:
1
2
3
4GPIO.add_event_detect(channel, GPIO.RISING) # add rising edge detection on a channeldo_something()
# 下面的代码放在一个线程循环执行。
if GPIO.event_detected(channel):
print('Button pressed')
上面的代码需要自己新建一个线程去循环检测event_detected()的值,还算是比较麻烦的。
不过可采用另一种办法轻松检测状态,这种方式是直接传入一个回调函数:
1
2
3
4
5
6def 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)
如果你想设置多个回调函数,可以这样:
1
2
3
4
5
6
7
8
9def 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)
注意:回调触发时,并不会同时执行回调函数,而是根据设置的顺序调用它们。
说了这么多,下面我们开始正式点亮我们的LED灯:
编写一个python脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#coding:utf-8
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# 控制LED 闪亮
led = 12
GPIO.setup(led, GPIO.OUT)
try:
while(True):
print '亮'
GPIO.output(led, 1)
time.sleep(1)
print '灭'
GPIO.output(led, 0)
time.sleep(1)
except Exception as e:
print(e)
finally:
GPIO.cleanup()
上传到树莓派上,然后运行:
实验2 获取开关信号
实验1 是利用的轮询的方式实现的,这个实验中,我们将要实现获取开关信号的变化,利用边缘检测的方式。
由扩展板的线路图可知,我们这里的按钮有3个,对应的BCM编码分别是 17,18,27.
我们这里使用17作为开关。
轮询的方式
先给出轮询的方式,代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# coding:utf-8
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# 检测开关
# 3个集成开关的位置 17,18,27 默认为1 按下后信号为0
swtich = 17
GPIO.setup(swtich, GPIO.IN, GPIO.PUD_DOWN)
try:
while(True):
if GPIO.input(swtich) == True:
print '获取开关1信号:%s' % GPIO.input(swtich)
time.sleep(1)
except Exception as e:
print(e)
finally:
GPIO.cleanup()
输出:
1
2
3
4
5
6
7
8
9
10获取开关1信号:1
获取开关1信号:1
获取开关1信号:1
获取开关1信号:1
获取开关1信号:1
获取开关1信号:0
获取开关1信号:0
获取开关1信号:0
获取开关1信号:1
获取开关1信号:1
信号0的时候就是我们按下按钮的时候,不过这里因为是轮询,所以有可能回取不到值,就是我们按下按钮的一刻,树莓派并未获取到这个变化。
边缘检测的方式
利用边缘检测的方式能够方便的检测到开关变化:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25# coding:utf-8
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# 检测开关
# 3个集成开关的位置 17,18,27 默认为1 按下后信号为0
switch = 17
GPIO.setup(switch, GPIO.IN, GPIO.PUD_DOWN)
def my_callback(channel):
print('按下按钮...')
GPIO.add_event_detect(switch, GPIO.FALLING, callback=my_callback)
try:
while(True):
time.sleep(1)
except Exception as e:
print(e)
finally:
GPIO.cleanup()
输出:
1
2
3
4
5
6
7按下按钮...
按下按钮...
按下按钮...
按下按钮...
按下按钮...
按下按钮...
按下按钮...
OK,希望能帮到正在看文章的你 (^_^)
树莓派pythongpio编程_树莓派 GPIO 编程相关推荐
- 树莓派pythongpio编程_树莓派gpio接口及编程方法
树莓派现在越来越火,网上树莓派的资料也越来越多.树莓派源自英国,国外嵌入式开源领域具有良好的分享精神,树莓派各种集成库也层出不穷,下面详细介绍一下树莓派gpio接口及编程方法. GPIO基本介绍 GP ...
- python硬件编程_树莓派c语言 设置并使用树莓派进行Python和C语言编程 - 硬件设备 - 服务器之家...
树莓派c语言 设置并使用树莓派进行Python和C语言编程 发布时间:2017-03-01 来源:服务器之家 设置并使用树莓派进行Python和C语言编程 (下) Python部落组织翻译, 禁止转载 ...
- java函数式编程_说说函数式编程的那些事
今天这篇文章我们主要来聊聊函数式编程的思想. 函数式编程有用吗? 什么是函数式编程? 函数式编程的优点. 总所周知 JavaScript 是一种拥有很多共享状态的动态语言,慢慢的,代码就会积累足够的复 ...
- 树莓派蓝屏_树莓派刷写Windows 10 ARM版后成功运行桌面程序
微软在2015年时推出Windows 10 IoT物联网版供树莓派系列以及其他单板电脑安装和部署更多的应用程序. 不过树莓派系列设备本身都是使用博通的ARM处理器,所以也只能运行Windows 10商 ...
- java面向方面编程_面向方面编程的介绍----基本概念
面向对象的编程中常用的概念是:继承.封装.多态.在面向方面的编程中常使用的概念是:advices/interceptors, introductions, metadata, and pointcut ...
- 函数式编程和面向对象式编程_比较函数式编程,命令式编程和面向对象的编程
函数式编程和面向对象式编程 As Oracle Corporation has introduced some Functional constructs in Java SE 8, now-a-da ...
- python最简单的图形编程_图形化编程、Python、Java、C++到底哪个适合你?
近两年,学习编程的热潮一波接一波,编程语言也是五花八门.盒子姐姐找到了一份2019年编程语言热度排行榜,其中,Java.C语言和Python高居榜首. 有些小伙伴就要问啦,编程语言这么多,区别在哪里呢 ...
- 树莓派wifi探针_树莓派重新开始|搭建博客、网盘、流媒体与离线下载服务
树莓派重新开始|搭建博客.网盘.流媒体与离线下载服务 在折腾了一段时间的树莓派后,逐渐确定了自己对树莓派的使用有以下需求: 博客服务器 文件同步 流媒体服务器 离线下载 话不多说,重新开始. 准备工作 ...
- python编程狮的在线编程_「Python编程狮-零基础学Python」をApp Storeで
Python编程狮是W3Cschool编程狮旗下专门为零基础Python编程爱好者打造的一款入门工具App,致力于帮助初学者入门,轻松迈入编程世界.学Python,从这里开始! [零基础也能学]初学者 ...
- 常州儿童学机器人编程_常州幼儿编程机器人
常州幼儿编程机器人 来源:教育联展网 编辑:佚名 发布时间:2019-07-08 少儿编程的发展前景 18年4月28日,全球首部人工智能普教教材--<人工智能基础>(高中版)在 ...
最新文章
- 上手机器学习,从搞懂这十大经典算法开始
- html如何去掉有无标题点,HTML中,如何去掉某个元素下的一些特殊标签?
- SQLSERVER查询数据库所有表名及行数
- 一个杯子帮你理解软件测试
- matlab曲线图导出,从Matlab的Figure中导出数据的办法
- 有符号char和无符号char
- 动态加载Asp.net分页控件
- linux系统notebook,RedNotebook——Linux环境桌面日记本
- 领域驱动设计核心概念
- 【数据艺术科技1】基于pyhon的高维数据可视化。(1、2维)
- MySQL5及更高版本的jar包下载(jdbc)及常见问题解决
- 关于Odoo盘盈成本和计价法的讨论
- Freertos中空闲任务的重要性
- C#实现批量高斯投影正算、反算
- 18.03.21 继承作业
- html电气自动化专业学吗,电气工程及其自动化难学吗 适合哪些人学
- node_modules中出现.staging文件夹
- ROS Gazebo Ros Control 及 Controller运用
- 从入门到精通,Java学习路线导航(附学习资源)
- 谁说程序员不好找对象,网友:站出来,绝对不打死你!
热门文章
- Redmine基础:中文设定方法与常见问题对应
- 重装linux系统删除旧系统_什么是重装系统?工控机重装系统的几种方法
- 六、数据结构设计-栈与队列
- oracle12g与12c,oracle 11g和12c一样的sql查询结果不一样
- ENSP防火墙进入web登陆界面
- 应用统计学学什么科目_科目二:学什么?考什么?怎么练?最详细的解答来了!...
- “2012中国年度天使投资人”蔡文胜:彻底拥抱新趋势
- 使用javascript实现简单的龟兔赛跑小游戏
- 2019世界区块链大会·乌镇首日精彩观点集锦
- Django ORM获取字段的verbose_name