【树莓派4B学习】一、环境搭建、开机及登录树莓派4B
【树莓派4B学习】二、树莓派4B介绍与一些必要的软件安装配置
【树莓派4B学习】三、接入USB摄像头,搭建Python2.7.16+OpenCV3.2.0开发环境
【树莓派4B学习】四、使用USB摄像头和motion实现监控
【树莓派4B学习】五、树莓派4B的OpenCV基本操作
【树莓派4B学习】六、树莓派4BOpenCV的视频/摄像头基本操作
【树莓派4B学习】七、树莓派4B的GPIO基础操作

1 wiringPi和BCM和BOARD编码

1.1 管脚信息

树莓派上提供了一组GPIO(General Purpose Input Output,即通用输入/输出)接口,这些接口可以用于做一些电子相关的实验:控制一些硬件设备,如最常见的发光二极管、电机等,或者读取一些信号的状态,如开关、传感器等。这里需要注意的是,树莓派中的GPIO只支持数字输入输出,即1和0对应高电平3.3V和低电平0V,因此必要的时候可能需要数模转换。

树莓派中执行:
$gpio readall得到关于树莓派管脚的信息

RXD是Receive Data接收数据的引脚
TXD是Transmit Data发送数据的引脚

比如,BOARD编码中的37号引脚
在wiringPi 中的编码就是25号引脚
在BCM 中的编码就是26号引脚
它们的功能都是GPIO.25(通用输入输出管脚25)

在wiringPi中, 你要使用GPIO.25号管脚, 你就得驱动25
而在BCM中, 你要使用GPIO.25号管脚, 你就得驱动26

1.2 使用场合

BOARD编码和BCM一般都在python库中使用。

import RPi.GPIO as GPIO  //引入RPi.GPIO库
GPIO.setmode(GPIO.BCM) //设置引脚编号为BCM编码方式;
GPIO.setmode(GPIO.BOARD) //设置GPIO引脚为BOARD编码方式。

而wiringPi一般用于C++等平台。

LIBS += -lwiringPi
#include "wiringPi.h"
wiringPiSetup();

1.3 I2C总线

I2C总线介绍

SDA----串行数据线----Serial Data Line 
SCL-----串行控制线----Serial Control Line 
通过对SCL和SDA线高低电平时序的控制,来产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时,这两根线一般被上面所接的上拉电阻拉高,保持着高电平。

SDA在SCL 高电平期间由高电平跳变为低电平,然后由主机发送一个字节的数据.数据传送完毕,由主机发出停止信号,SDA在SCL 高电平期间由低电平跳变为高电平。

1.4 SPI总线

SPI详细解释
SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。

(1)MISO– Master Input Slave Output,主设备数据输入,从设备数据输出;(2)MOSI– Master Output Slave Input,主设备数据输出,从设备数据输入;

2 RPI.GPIO


2.1 参考资料

参考树莓派基础实验1:双色LED灯实验
参考树莓派基础实验2:RGB-LED实验
参考树莓派基础实验3:七彩LED灯闪烁实验
参考树莓派基础实验4:继电器实验
参考树莓派基础实验5:激光传感器实验
参考树莓派基础实验6:轻触开关按键实验
参考树莓派基础实验7:倾斜开关实验
参考树莓派基础实验8:振动开关实验
参考树莓派基础实验9:蜂鸣器实验
参考树莓派基础实验10:干簧管传感器实验
参考树莓派基础实验11:U型光电传感器实验
参考树莓派基础实验12:PCF8591模数转换器实验
参考树莓派基础实验13:雨滴探测传感器实验
参考树莓派基础实验14:PS2操纵杆实验
参考树莓派基础实验15:电位器传感器实验
参考树莓派基础实验16:霍尔传感器实验
参考树莓派基础实验17:温度传感器实验
参考树莓派基础实验18:声音传感器实验
参考树莓派基础实验19:光敏传感器实验
参考树莓派基础实验20:火焰报警传感器实验
参考树莓派基础实验21:烟雾报警传感器实验
参考树莓派基础实验22:红外遥控传感器实验
参考树莓派基础实验23:触摸开关传感器实验
参考树莓派基础实验24:超声波测距传感器实验
参考树莓派基础实验25:DS18B20温度传感器实验
参考树莓派基础实验26:旋转编码器实验
参考树莓派基础实验27:温湿度传感器DHT11 实验
参考树莓派基础实验28:红外避障传感器实验
参考树莓派基础实验29:I2C LCD1602实验
参考树莓派基础实验30:BMP180气压传感器实验
参考树莓派基础实验31:MPU6050陀螺仪加速度传感器实验
参考树莓派基础实验32:DS1302实时时钟模块实验
参考树莓派基础实验33:TCRT5000红外循迹传感器实验
参考树莓派基础实验34:L298N模块驱动直流电机实验
参考树莓派基础实验35:USB TO TTL模块实验
参考树莓派基础实验36:通用串口通信实验

2.2 SDK

import RPi.GPIO as GPIO

2.2.1 SDK说明PWM

class PWM(builtins.object)
Pulse Width Modulation class脉冲宽度调制
举例p_R = GPIO.PWM(11, 2000)  # 设置频率为 2KHz
*************************************************************
ChangeDutyCycle(...)
Change the duty cycle
更改占空比
(1)dutycycle
between 0.0 and 100.0
*************************************************************
ChangeFrequency(...)
Change the frequency
frequency - frequency in Hz (freq > 1.0)
*************************************************************
函数start(...)初始占空比
Start software PWM
(1)dutycycle
the duty cycle (0.0 to 100.0)
举例p_R.start(0) # 初始占空比为0
*************************************************************
函数stop(...)停止PWM
Stop software PWM

2.2.2 SDK说明静态函数

(1)函数setmode(…)

函数setmode(...)
Set up numbering mode to use for channels.
BOARD——Use Raspberry Pi board numbers
BCM————Use Broadcom GPIO 00..nn numbers

例如GPIO.setmode(GPIO.BOARD)
例如GPIO.setmode(GPIO.BCM)
(2)函数setup(…)

函数setup(...)
设置针脚模式
Set up a GPIO channel or list of channels with a direction
and (optional) pull/up down control
参数(1)channel
either board pin number or BCM number depending on which mode is set.
参数(2)direction
IN or OUT
参数(3)[pull_up_down]
PUD_OFF (default), PUD_UP or PUD_DOWN
参数(4)[initial]
Initial value for an output channel

例如GPIO.setup(11, GPIO.OUT)设置引脚模式为输出

有多种方式将GPIO的输入导入到程序中:
polling(轮询式 )轮询式如果程序在错误的时间读取值,可能会错过输入。
interrupt( 中断式 )( edge detection 边缘检测 )这里采用中断式。

如果您没有将输入引脚连接到任何东西,它将“浮动”。
换句话说,读取的值是未定义的,因为它没有连接到任何东西,直到你按下按钮或开关。
它可能会由于接收电源干扰而改变很大的值。

为了解决这个问题,我们使用一个向上拉或向下拉电阻器。
这样,就可以设置输入的默认值。
可以使用硬件或者软件实现上下拉电阻。
在硬件方式中,常常在输入通道与3.3V(上拉)或0V(下拉)之间使用10K电阻。
GPIO模块允许您在编程中这样配置:
例如GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
例如GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
(3)函数output(…)

函数output(...)
Output to a GPIO channel or list of channels
参数(1)channel
either board pin number or BCM number depending on which mode is set.
参数(2)value
0/1 or False/True or LOW/HIGH

例如GPIO.output(11, 1)高电平
例如GPIO.output(12, 0)低电平

(4)函数input(…)

函数input(...)
Input from a GPIO channel.
Returns HIGH=1=True or LOW=0=False
参数(1)channel
either board pin number or BCM number depending on which mode is set.

(5)捕捉引脚的电平改变
我们很多时候并不关心电平值, 而关心电平从低到高,或从高到低的变化(如编码器测速/按键按下弹开等), 为避免主程序忙于其它事情错过引脚的电平改变, 有两种方式:
wait_for_edge() 函数
event_detected() 函数
(5-1)函数wait_for_edge(…)

函数wait_for_edge(...)
Wait for an edge.
Returns the channel number or None on timeout.
参数(1)channel
either board pin number or BCM number depending on which mode is set.
参数(2)edge
RISING, FALLING or BOTH
参数(3)[bouncetime]
time allowed between calls to allow for switchbounce
参数(4)[timeout]
timeout in ms

wait_for_edge()函数是为了阻止程序的执行,直到检测到边缘为止。换句话说,等待按钮按下的示例可以改写成:
GPIO.wait_for_edge(channel, GPIO.RISING)

注意检测的边缘参数有:
GPIO.RISING,上升沿
GPIO.FALLING,下降沿
GPIO.BOTH, 升降沿
这样用几乎不占用CPU,如果你只希望在确定的时间段内查询,可以使用 timeout 参数:

#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)

(5-2)函数event_detected(…)

函数event_detected(...)
Returns True if an edge has occurred on a given GPIO.
You need to enable edge detection using add_event_detect() first.
(1)channel
either board pin number or BCM number depending on which mode is set.

event_detected()函数被设计用来与其他事物一起在循环中使用, 不同于polling轮询, 它不会在CPU忙于处理其他事物时错过输入状态的变化。 这使得使用Pygame 或 PyQt 时非常有用,因为其中有一个主循环监听和及时响应GUI事件的基础。

只要检测到指定参数的边缘事件(上升沿, 下降沿 或 升降沿)发生时,调用GPIO.event_detected(channel)的值就为"ture"(真)。

#Note that you can detect events for GPIO.RISING, GPIO.FALLING or GPIO.BOTH.
#add rising edge detection on a channel
GPIO.add_event_detect(channel, GPIO.RISING)
do_something()
if GPIO.event_detected(channel):print('Button pressed')

不过需要自己新建一个线程去循环检测event_detected()的值,还算是比较麻烦的。

可采用另一种办法轻松检测状态,这种方式是直接传入一个回调函数:GPIO通过在add_event_detect()函数中添加callback参数,RPI.GPIO为回调函数运行第二个线程。这意味着回调函数可以与主程序同时运行,以立即响应边缘。
(6)函数add_event_detect(…)

函数add_event_detect(...)
Enable edge detection events for a particular GPIO channel.
参数(1)channel
either board pin number or BCM number depending on which mode is set.
参数(2)edge
RISING, FALLING or BOTH
参数(3)[callback]
A callback function for the event (optional)
参数(4)[bouncetime]
Switch bounce timeout in ms for callback

例如这里添加了回调函数callback这个参数,就不需要GPIO.event_detected(channel)函数了。

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)

例如如果你想要不止一个回调函数:

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)
#请注意,在这种情况下,回调函数是按顺序运行的,而不是并发的。
#这是因为只有一个线程用于回调,其中每个回调都按照它们被定义的顺序运行。

由于存在开关抖动(用示波器可以看到),每次按下开关会调用多次回调函数,这不是我们希望的,有两种方式处理开关抖动:①在开关两个引脚之间添加一个0.1uF的电容。②软件消抖。③二者结合使用。
  使用软件消抖时, 给回调函数添加一个弹跳时间的参数( bouncetime= ), 弹跳时间(参照单片机可以为10~20ms)在ms级别, 下面的程序用200ms来消抖:

#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)

(7)函数add_event_callback(…)

函数add_event_callback(...)
Add a callback for an event already defined using add_event_detect()
参数(1)channel
either board pin number or BCM number depending on which mode is set.
参数(2)callback
a callback function

(8)函数remove_event_detect(…)

函数remove_event_detect(...)
Remove edge detection for a particular GPIO channel
参数(1)channel
either board pin number or BCM number depending on which mode is set.

由于某些原因, 你的程序可能不希望用边缘检测了,可以停止它们:
GPIO.remove_event_detect(channel)
(9)函数cleanup(…)

函数cleanup(...)
重置GPIO状态
Clean up by resetting all GPIO channels that have been used by this program to INPUT with no pullup/pulldown and no event detection
(1)[channel]
individual channel or list/tuple of channels to clean up.
Default - clean every channel that has been used.

例如GPIO.cleanup() # 释放资源

(10)函数getmode(…)

函数getmode(...)
Get numbering mode used for channel numbers.
Returns BOARD, BCM or None

(11)函数gpio_function(…)

函数gpio_function(...)
Return the current GPIO function (IN, OUT, PWM, SERIAL, I2C, SPI)
(1)channel
either board pin number or BCM number depending on which mode is set.

(12)函数setwarnings(…)

函数setwarnings(...)
Enable or disable warning messages

2.2.3 SDK说明DATA

DATA
BCM = 11
BOARD = 10
BOTH = 33
FALLING = 32
HARD_PWM = 43
HIGH = 1
I2C = 42
IN = 1
LOW = 0
OUT = 0
PUD_DOWN = 21
PUD_OFF = 20
PUD_UP = 22
RISING = 31
RPI_INFO = {'MANUFACTURER': 'Sony', 'P1_REVISION': 3, 'PROCESSOR': 'BC...
RPI_REVISION = 3
SERIAL = 40
SPI = 41
UNKNOWN = -1
VERSION = '0.7.0'FILE/usr/lib/python3/dist-packages/RPi/GPIO/__init__.py

2.2.4 SDK应用

(1)开发环境Thonny python IDE【python3.7.3】
(2)导入模块,设置常量、板载模式。
Raspberry Pi有三种引脚编号方法:Board根据引脚的物理位置编号;由C语言GPIO库wiringpi指定的编号;由BCM2837 SOC指定的编号。

import RPi.GPIO as GPIO   #导入控制GPIO的模块,RPi.GPIO
import time #导入时间模块,提供延时、时钟和其它时间函数
colors = [0xFF00, 0x00FF, 0x0FF0, 0xF00F]   #颜色列表
GPIO.setmode(GPIO.BOARD) #设置引脚编号模式为板载模式,即树莓派上的物理位置编号
#GPIO.setmode(GPIO.BCM) #或者为BCM模式

R、G、B均为255时就合成了白光,R、G、B均为0时就形成了黑色。
00000000–0x00–0
11111111–0xFF–255
(3)初始化LED灯,输入输出模式、初始电平、频率、占空比。

GPIO.setup(11, GPIO.OUT)   # 设置针脚模式为输出(或者输入GPIO.IN)
GPIO.output(11, GPIO.LOW) #设置针脚为低电平,关掉LED灯
GPIO.setup(12, GPIO.OUT)   # 设置针脚模式为输出(或者输入GPIO.IN)
GPIO.output(12, GPIO.LOW) #设置针脚为低电平,关掉LED灯p_R = GPIO.PWM(11, 2000)  # 设置频率为 2KHz
p_G = GPIO.PWM(12, 2000)  # 设置频率为 2KHzp_R.start(0) # 初始占空比为0(范围:0.0 <= dc <= 100.0,0为关闭状态)
p_G.start(0) # p.start(dc) dc代表占空比

PWM的频率决定了输出的数字信号on (1) 和 off(0 )的切换速度。频率越高,切换就越快。
占空比:指一串理想脉冲序列中,正脉冲的持续时间与脉冲总周期的比值。
(4)通过更改占空比调整各基色的亮度,进而设置LED的发光颜色。

#将颜色的刺激量转换为占空比对应的值
def map(x, in_min, in_max, out_min, out_max):return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_mindef setColor(col):   # 设置颜色#先“与”运算只保留自己颜色所在位的值有效#再“右移”运算将自己颜色所在位的值提取出来R_val = (col & 0xFF00) >> 8    G_val = (col & 0x00FF) >> 0#将颜色的刺激量转换为占空比对应的值R_val = map(R_val, 0, 255, 0, 100)   G_val = map(G_val, 0, 255, 0, 100)# 更改占空比,调整该颜色的亮度p_R.ChangeDutyCycle(R_val)     p_G.ChangeDutyCycle(G_val)

(5)处理

def loop():while True: #循环函数for col in colors:  #遍历颜色列表setColor(col) #设置颜色time.sleep(0.5) #延时0.5秒def destroy():p_R.stop()  #停止PWMp_G.stop()  #停止PWMGPIO.output(11, GPIO.LOW)  # 关掉所有led灯GPIO.output(12, GPIO.LOW)  # 关掉所有led灯GPIO.cleanup()  #重置GPIO状态
if __name__ == "__main__":try:   #用try-except代码块来处理可能引发的异常loop()except KeyboardInterrupt:  #用户中断(control+C),则执行destroy()函数destroy()

2.3 LED灯实验

2.3.1 小双色LED灯实验

树莓派学习笔记1:python控制双色LED灯
树莓派基础实验1:双色LED灯实验

实现红绿LED 灯交替闪亮,并间隔2秒。
注意:GPIO 输出High 电平为3.3v。
注意小双色LED灯引脚从上往下依次是:
-接地
Board11–R
Board12–G

# encoding=utf-8
import RPi.GPIO as GPIO
import timepins = {'pin_R':11, 'pin_G':12}  #引脚字典
sleep_time =2GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical location
for i in pins:GPIO.setup(pins[i], GPIO.OUT)   # Set pins' mode is outputGPIO.output(pins[i], GPIO.LOW) # Set pins to low(0V) to off leddef loop(): while True:GPIO.output(pins['pin_R'], GPIO.HIGH)   # give hightime.sleep(sleep_time)GPIO.output(pins['pin_R'], GPIO.LOW)  # give lowGPIO.output(pins['pin_G'], GPIO.HIGH)  # give hightime.sleep(sleep_time)GPIO.output(pins['pin_G'], GPIO.LOW)
def destroy():for i in pins:GPIO.output(pins[i], GPIO.LOW)    # Turn off all ledsGPIO.cleanup()if __name__ == "__main__":try:loop()except KeyboardInterrupt:destroy()

中断ctrl+c。

2.3.2 三色LED灯实验

红-绿-蓝-白,三色变换

import RPi.GPIO as GPIO   #导入控制GPIO的模块,RPi.GPIO
import time     #导入时间模块,提供延时、时钟和其它时间函数
GPIO.setmode(GPIO.BOARD) #设置引脚编号模式为板载模式,即树莓派上的物理位置编号GPIO.setup(11, GPIO.OUT)   # 设置针脚模式为输出(或者输入GPIO.IN)
GPIO.output(11, GPIO.LOW) #设置针脚为低电平,关掉LED灯
GPIO.setup(12, GPIO.OUT)   # 设置针脚模式为输出(或者输入GPIO.IN)
GPIO.output(12, GPIO.LOW) #设置针脚为低电平,关掉LED灯
GPIO.setup(13, GPIO.OUT)   # 设置针脚模式为输出(或者输入GPIO.IN)
GPIO.output(13, GPIO.LOW) #设置针脚为低电平,关掉LED灯#11-R
#12-G
#13-Bdef loop():while True:#Red       GPIO.output(11, GPIO.HIGH)GPIO.output(12, GPIO.LOW)GPIO.output(13, GPIO.LOW)time.sleep(1)   #延时0.5秒#Green       GPIO.output(11, GPIO.LOW)GPIO.output(12, GPIO.HIGH)GPIO.output(13, GPIO.LOW)time.sleep(1)   #延时0.5秒#Blue      GPIO.output(11, GPIO.LOW)GPIO.output(12, GPIO.LOW)GPIO.output(13, GPIO.HIGH)time.sleep(1)   #延时0.5秒#White      GPIO.output(11, GPIO.HIGH)GPIO.output(12, GPIO.HIGH)GPIO.output(13, GPIO.HIGH)time.sleep(1)   #延时0.5秒def destroy():GPIO.output(11, GPIO.LOW)    # 关掉所有led灯GPIO.output(12, GPIO.LOW)    # 关掉所有led灯GPIO.output(13, GPIO.LOW)    # 关掉所有led灯GPIO.cleanup()     #重置GPIO状态
if __name__ == "__main__":try:         #用try-except代码块来处理可能引发的异常loop()except KeyboardInterrupt: #如果中断(control+C),则执行destroy()函数destroy()

2.3.3 七彩LED灯实验

5v供电
“红线”连接7彩LED模块VCC端子S;
“黑线”连接7彩LED模块GND端子-。
7彩LED模块内置有控制灯闪烁的芯片,不需要编程,通电即可看到实验效果。

2.4 继电器实验

常闭——继电器被激活时断开,未激活时连接。
常开——继电器被激活时连接,未激活时断开。

board11——SIG 耦合对应 NC常闭——G
5V——DC+ 耦合对应COM——5V
GND——DC- 耦合对应 NO常开——R

注意小双色LED灯引脚从上往下依次是:
引脚-接地
引脚R
引脚G

import RPi.GPIO as GPIO
import timeRelayPin = 11    # pin11def setup():GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical locationGPIO.setup(RelayPin, GPIO.OUT)GPIO.output(RelayPin, GPIO.LOW)def loop():while True:print '...relayd on'GPIO.output(RelayPin, GPIO.LOW)#低电平时,继电器为初始状态time.sleep(0.5)                #常闭触点通电,绿灯亮print 'relay off...'GPIO.output(RelayPin, GPIO.HIGH)#高电平时,继电器为激活状态time.sleep(0.5)                 #常开触点通电,红灯亮def destroy():GPIO.output(RelayPin, GPIO.LOW)GPIO.cleanup()                     # Release resourceif __name__ == '__main__':     # Program start from heresetup()try:loop()# When 'Ctrl+C' is pressed, the child program destroy() will be  executed.except KeyboardInterrupt:  destroy()

2.5 激光传感器实验

引脚S接Board11
引脚-接GND

import RPi.GPIO as GPIO
import timeLedPin = 11    # pin11def setup():GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical locationGPIO.setup(LedPin, GPIO.OUT)   # Set LedPin's mode is outputGPIO.output(LedPin, GPIO.LOW) # Set LedPin LOW(0V) to off leddef loop():while True:print '...Laser off'GPIO.output(LedPin, GPIO.LOW)  # led offtime.sleep(0.5)print 'Laser on...'GPIO.output(LedPin, GPIO.HIGH) # led ontime.sleep(0.5)def destroy():GPIO.output(LedPin, GPIO.LOW))     # led offGPIO.cleanup()                     # Release resourceif __name__ == '__main__':     # Program start from heresetup()try:loop()# When 'Ctrl+C' is pressed, the child program destroy() will be  executed.except KeyboardInterrupt:  destroy()

2.6 开关实验

2.6.1 按键开关实验

按键模块引脚,从上往下依次是:
引脚S接Board11
引脚中间VCC接5V
引脚-接GND

小双色LED灯引脚,从上往下依次是:
引脚-接GND
引脚中间R接Board12
引脚G接Board13

import RPi.GPIO as GPIOBtnPin = 11
Rpin   = 12
Gpin   = 13def setup():GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical locationGPIO.setup(Gpin, GPIO.OUT)     # Set Green Led Pin mode to outputGPIO.setup(Rpin, GPIO.OUT)     # Set Red Led Pin mode to output# Set BtnPin's mode is input, and pull up to high level(3.3V)GPIO.setup(BtnPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)    GPIO.add_event_detect(BtnPin, GPIO.BOTH, callback=detect, bouncetime=200)def Led(x):         #控制双色LED灯闪烁的函数if x == 0:GPIO.output(Rpin, 1)  #红灯亮GPIO.output(Gpin, 0)  #绿灯灭if x == 1:GPIO.output(Rpin, 0)  #红灯灭GPIO.output(Gpin, 1)  #绿灯亮def Print(x):        #打印按键是否按下的提示消息if x == 0:print('    ***********************')print('    *   Button is down!   *')print('    ***********************')elif x == 1:print('    ***********************')print('    *   Button is up !   *')print('    ***********************')def detect(chn):Led(GPIO.input(BtnPin))    #控制双色LED灯闪烁Print(GPIO.input(BtnPin))  #打印按键是否按下的提示消息def loop():while True:pass  #pass 不做任何事情,一般用做占位语句。def destroy():GPIO.output(Gpin, GPIO.LOW)       # Green led offGPIO.output(Rpin, GPIO.LOW)       # Red led offGPIO.cleanup()                     # Release resourceif __name__ == '__main__':     # Program start from heresetup()try:loop()# When 'Ctrl+C' is pressed, the child program destroy() will be  executed.except KeyboardInterrupt:  destroy()

2.6.2 倾斜开关实验

带有金属球的球形倾斜开关。它用于检测小角度的倾斜。
倾斜模块引脚,从上往下依次是:
引脚S接Board11
引脚中间VCC接5V
引脚-接GND

小双色LED灯引脚,从上往下依次是:
引脚-接GND
引脚中间R接Board12
引脚G接Board13

import RPi.GPIO as GPIOTiltPin = 11
Rpin   = 12
Gpin   = 13def setup():GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical locationGPIO.setup(Gpin, GPIO.OUT)     # Set Green Led Pin mode to outputGPIO.setup(Rpin, GPIO.OUT)     # Set Red Led Pin mode to output# Set BtnPin's mode is input, and pull up to high level(3.3V)GPIO.setup(TiltPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)    GPIO.add_event_detect(TiltPin, GPIO.BOTH, callback=detect, bouncetime=200)def Led(x):        #控制双色LED灯闪烁的函数if x == 0:GPIO.output(Rpin, 1)  #红灯亮GPIO.output(Gpin, 0)  #绿灯灭if x == 1:GPIO.output(Rpin, 0)GPIO.output(Gpin, 1)def Print(x):  #打印按键是否倾斜的提示消息if x == 0:print('    *************')print('    *   Tilt!   *')print('    *************')def detect(chn):Led(GPIO.input(TiltPin))    #控制双色LED灯闪烁Print(GPIO.input(TiltPin))  #打印按键是否倾斜的提示消息
def loop():while True:passdef destroy():GPIO.output(Gpin, GPIO.LOW)       # Green led offGPIO.output(Rpin, GPIO.LOW)       # Red led offGPIO.cleanup()                     # Release resourceif __name__ == '__main__':     # Program start from heresetup()try:loop()# When 'Ctrl+C' is pressed, the child program destroy() will be  executed.except KeyboardInterrupt:  destroy()

2.6.3 震动开关实验

振动开关也称为弹簧开关或振动传感器,是一种电子开关。它会产生振动力,并将结果传送给电路装置,从而触发其工作。它包含以下部分:导电振动弹簧,开关主体,触发销和包装壳。
震动模块引脚,从上往下依次是:
引脚S接Board11
引脚中间VCC接5V
引脚-接GND

小双色LED灯引脚,从上往下依次是:
引脚-接GND
引脚中间R接Board12
引脚G接Board13

import RPi.GPIO as GPIO
import timeVibratePin = 11
Rpin   = 12
Gpin   = 13tmp = 0def setup():GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical locationGPIO.setup(Gpin, GPIO.OUT)     # Set Green Led Pin mode to outputGPIO.setup(Rpin, GPIO.OUT)     # Set Red Led Pin mode to outputGPIO.setup(VibratePin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set BtnPin's mode is input, and pull up to high level(3.3V)def Led(x): #控制双色LED灯闪烁的函数if x == 0:GPIO.output(Rpin, 1)  #红灯亮GPIO.output(Gpin, 0)    #绿灯灭if x == 1:GPIO.output(Rpin, 0)GPIO.output(Gpin, 1)def Print(x):   #打印按键是否切换开关的提示消息global tmpif x != tmp:if x == 0:print('    **********')print('    *     ON *')print('    **********')if x == 1:print('    **********')print('    * OFF    *')print('    **********')tmp = x
def loop():state = 0while True:if GPIO.input(VibratePin):  #每当振动产生时state = state + 1if state > 1:state = 0Led(state)Print(state)time.sleep(1)
def destroy():GPIO.output(Gpin, GPIO.LOW)       # Green led offGPIO.output(Rpin, GPIO.LOW)       # Red led offGPIO.cleanup()                     # Release resourceif __name__ == '__main__':     # Program start from heresetup()try:loop()# When 'Ctrl+C' is pressed, the child program destroy() will be  executed.except KeyboardInterrupt:  destroy()

2.6.4 迷你磁簧开关实验

磁簧开关(Reed Switch)也称之为干簧管,它是一个通过所施加的磁场操作的电开关。基本型式是将两片磁簧片密封在玻璃管内,两片虽重叠,但中间间隔有一小空隙。当外来磁场时将使两片磁簧片接触,进而导通。 一旦磁体被拉到远离开关,磁簧开关将返回到其原来的位置。可以用来计数或限制位置。

迷你磁簧模块引脚,从上往下依次是:
引脚S接Board11
引脚中间VCC接5V
引脚-接GND

小双色LED灯引脚,从上往下依次是:
引脚-接GND
引脚中间R接Board12
引脚G接Board13

import RPi.GPIO as GPIO
ReedPin = 11
Rpin = 12
Gpin = 13def setup():GPIO.setmode(GPIO.BOARD)  # Numbers GPIOs by physical locationGPIO.setup(Gpin, GPIO.OUT)  # Set Green Led Pin mode to outputGPIO.setup(Rpin, GPIO.OUT)  # Set Red Led Pin mode to output# Set BtnPin's mode is input, and pull up to high level(3.3V)GPIO.setup(ReedPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)GPIO.add_event_detect(ReedPin, GPIO.BOTH, callback=detect, bouncetime=200)
def Led(x): #控制双色LED灯闪烁的函数if x == 0:  #传感器输出低电平,干簧管簧片拉在一起,电路联通,红灯亮GPIO.output(Rpin, 1)GPIO.output(Gpin, 0)if x == 1:   #传感器输出高电平,干簧管簧片分开,电路断开,绿灯亮GPIO.output(Rpin, 0)GPIO.output(Gpin, 1)def Print(x):   #打印检测到磁性物质if x == 0:print('    ***********************************')print('    *   Detected Magnetic Material!   *')print('    ***********************************')def detect(chn):Led(GPIO.input(ReedPin))    #控制双色LED灯闪烁的函数Print(GPIO.input(ReedPin))  #打印检测到磁性物质print(GPIO.input(ReedPin)) #验证GPIO.input(ReedPin)的值
def loop():while True:passdef destroy():GPIO.output(Gpin, GPIO.LOW)  # Green led offGPIO.output(Rpin, GPIO.LOW)  # Red led offGPIO.cleanup()   # Release resourceif __name__ == '__main__':  # Program start from heresetup()try:loop()# When 'Ctrl+C' is pressed, the child program destroy() will be  executed.except KeyboardInterrupt:destroy()

2.7 蜂鸣器实验

蜂鸣器是音频信号装置,蜂鸣器可分为有源蜂鸣器和无源蜂鸣器。
有源蜂鸣器直接接上额定电源就可以连续发声;
无源蜂鸣器则和电磁扬声器一样,需要接在音频输出电路中才能周期性地振动发声。

有源蜂鸣器内置振荡源,所以通电时会发出声音。但无源蜂鸣器没有这种内置振荡源,所以如果使用直流信号,他不会发出轰鸣声;相反,你需要使用频率在2k到5k之间的方波来驱动它。由于有内置振荡电路,所以有源蜂鸣器通常比无源蜂鸣器昂贵。

2.7.1 有源蜂鸣器

引脚S接Board11
引脚中间VCC接3.3V
引脚-接GND
通过改变输入到蜂鸣器的信号电平,低电平是响,高电平是停止响来控制蜂鸣器。

import RPi.GPIO as GPIO
import timeBuzzer = 11    # pin11def setup(pin):global BuzzerPinBuzzerPin = pinGPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical locationGPIO.setup(BuzzerPin, GPIO.OUT)GPIO.output(BuzzerPin, GPIO.HIGH)def on():GPIO.output(BuzzerPin, GPIO.LOW)   #低电平是响
def off():GPIO.output(BuzzerPin, GPIO.HIGH)#高电平是停止响
def beep(x):    #响3秒后停止3秒on()time.sleep(x)off()time.sleep(x)def loop():while True:beep(3)def destroy():GPIO.output(BuzzerPin, GPIO.HIGH)GPIO.cleanup()                     # Release resourceif __name__ == '__main__':     # Program start from heresetup(Buzzer)try:loop()# When 'Ctrl+C' is pressed, the child program destroy() will be  executed.except KeyboardInterrupt:  destroy()

2.7.2 无源蜂鸣器

引脚S接Board11
引脚中间VCC接3.3V
引脚-接GND
使用无源蜂鸣器,只要输出不同频率的PWM波,即可发出不同的音符。不同的音符组合起来就是一个曲子了。

import RPi.GPIO as GPIO
import timeBuzzer = 11CL = [0, 131, 147, 165, 175, 196, 211, 248]          # C调低音符的频率列表,第一位为0是占位用,后面不使用#除0外,依次是1do、2re、3mi、4fa、5sol、6la、7si
CM = [0, 262, 294, 330, 350, 393, 441, 495]          # Frequency of Middle C notesCH = [0, 525, 589, 661, 700, 786, 882, 990]           # Frequency of High C notessong_0 = [CL[1], CL[2], CL[3], CL[4], CL[5], CL[6], CL[7],CM[1], CM[2], CM[3], CM[4], CM[5], CM[6], CM[7], CH[1], CH[2], CH[3], CH[4], CH[5], CH[6], CH[7] ]# song_0表示从低音do依次到高音si的音符列表
beat_0 = [2, 2, 2, 2, 2, 2, 2,                         2, 2, 2, 2, 2, 2, 2,  2, 2, 2, 2, 2, 2, 2  ]# song_0的节拍, 2表示2个1/8节拍。一个1/8节拍为0.5秒延迟。
song_1 = [CM[3], CM[5], CM[6], CM[3], CM[2], CM[3], CM[5], CM[6], CH[1], CM[6], CM[5], CM[1], CM[3], CM[2], CM[2], CM[3], CM[5], CM[2], CM[3], CM[3], CL[6], CL[6], CL[6], CM[1],CM[2], CM[3], CM[2], CL[7], CL[6], CM[1], CL[5] ]
# Notes of song1
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 ]
# Beats of song 1, 1 means 1/8 beats
song_2 = [CM[1], CM[1], CM[1], CL[5], CM[3], CM[3], CM[3], CM[1], CM[1], CM[3], CM[5], CM[5], CM[4], CM[3], CM[2], CM[2], CM[3], CM[4], CM[4], CM[3], CM[2], CM[3], CM[1], CM[1], CM[3], CM[2], CL[5], CL[7], CM[2], CM[1]]
# Notes of song2
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 ]
# Beats of song 2, 1 means 1/8 beats,0.5 seconddef setup():GPIO.setmode(GPIO.BOARD)  # Numbers GPIOs by physical locationGPIO.setup(Buzzer, GPIO.OUT) # Set pins' mode is outputglobal Buzz # Assign a global variable to replace GPIO.PWM Buzz = GPIO.PWM(Buzzer, 440)  # 440 is initial frequency.Buzz.start(50) # Start Buzzer pin with 50% duty ration
def loop():while True:#--------------------------------------------print('\n\n    Playing Low C notes...')for i in range(0, 7):         # Play song 0的C调低音音符Buzz.ChangeFrequency(song_0[i])# 根据歌曲的音符改变频率print(i)      #打印i的值time.sleep(beat_0[i] * 0.5)# 根据节拍列表每个音符延迟1秒,2 beats*0.5s=1sprint('\n\n    Playing Middle C notes...')for i in range(7, 14):         # Play song 0Buzz.ChangeFrequency(song_0[i]) # Change the frequency along the song noteprint(i)time.sleep(beat_0[i] * 0.5)     # delay a note for beat * 0.5sprint('\n\n    Playing High C notes...')for i in range(14, 21):         # Play song 0Buzz.ChangeFrequency(song_0[i]) # Change the frequency along the song noteprint(i)time.sleep(beat_0[i] * 0.5)     # delay a note for beat * 0.5sBuzz.ChangeFrequency(3)  #一首曲子结束,间隔3秒time.sleep(3)#--------------------------------------------print('\n    Playing song 1...')for i in range(0, len(song_1)):         # Play song 1Buzz.ChangeFrequency(song_1[i]) # Change the frequency along the song notetime.sleep(beat_1[i] * 0.5)     # delay a note for beat * 0.5sBuzz.ChangeFrequency(3) #一首曲子结束,间隔3秒time.sleep(3)                          #--------------------------------------------print('\n\n    Playing song 2...')for i in range(0, len(song_2)):         # Play song 1Buzz.ChangeFrequency(song_2[i]) # Change the frequency along the song notetime.sleep(beat_2[i] * 0.5)     # delay a note for beat * 0.5sBuzz.ChangeFrequency(3)time.sleep(3)
def destory():Buzz.stop()      # Stop the buzzerGPIO.output(Buzzer, 1) # Set Buzzer pin to HighGPIO.cleanup()  # Release resourceif __name__ == '__main__': # Program start from heresetup()try:loop()# When 'Ctrl+C' is pressed, the child program destroy() will be  executed.except KeyboardInterrupt:       destory()

2.8 土壤湿度传感器

土壤湿度检测模块如下:

首先,传感器模块选的是常见的YL-69,电阻型传感器,如上图。

YL-69有模拟输出(AO口)和数字输出(DO口),由于树莓派的GPIO只支持数字输出,所以AO口悬空。
将VCC连接物理接口2,
GND引脚连接物理接口14,
DO引脚连接物理接口40,对应的BCM编码为21。

电源连通之后,电源灯会亮起:

调节传感器上的旋钮(蓝色的菊花),这个是灵敏度的校准,也是个阈值,直到在干燥空气中不让DO-LED亮起。

倒一杯水,或者没有水的话,舔一下传感器的触角,DO-LED应该会亮起,这时候就校准好了。然后就能爆代码了!

这个传感器在干燥时候输出的是高电平,遇到水输出低电平。根据这个原理,把代码爆成这样:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import RPi.GPIO as GPIO
import timechannel = 21 #管脚40,参阅树莓派引脚图,物理引脚40对应的BCM编码为21GPIO.setmode(GPIO.BCM)
GPIO.setup(channel, GPIO.IN)while True:if GPIO.input(channel) == GPIO.LOW:print("土壤检测结果:潮湿")else:print("土壤检测结果:干燥")time.sleep(1)

运行,当把传感器触角放在空气和放在水中时,会显示不同的输出

2.9 温湿度传感器DHT11

DHT11温湿度传感器编程思路以及代码的实现
树莓派下DHT11温湿度传感器控制程序(python)

利用树莓派连接DHT11读取温湿度
参考Adafruit Python DHT现成包
参考树莓派与DHT11温度传感器的那些事儿
DHT11是一个数字传感器,由两个不同的传感器组成一个封装。该传感器包含一个NTC(负温度系数)温度传感器,一个电阻型湿度传感器和一个8位微控制器,用于转换来自这些传感器的模拟信号并产生数字输出。

NTC(Negative Temperature Coefficient)是指随温度上升电阻呈指数关系减小、具有负温度系数的热敏电阻现象和材料。

DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±5%RH, 温度±2℃,量程湿度20-90%RH, 温度0~50℃。

(2)DHT11和RaspberryPi接线图
将DHT11传感器的VCC和GND引脚连接到RaspberryPi的+5V和GND,然后将传感器的数据输出连接到GPIO4,即RaspberryPi的物理引脚7。


为何在树莓派上用dht11测温湿度得到的两个数值一直都是255?
按照时序要求来 255一看就是没按照时序 读数全是1 数据线根本没被启动才会读出来ff。

sudo apt-get update
sudo apt-get install build-essential python-dev
(1)从 GitHub 获取 Adafruit 库:
sudo git clone https://github.com/adafruit/Adafruit_Python_DHT.git
cd Adafruit_Python_DHT
(2)给 Python 2 和 Python 3 安装该库:
sudo python setup.py install
sudo python3 setup.py install

树莓派4b 使用dht11/dht22测温注意
由于下载的Adafruit_DHT驱动未支持4b处理器BCM2711,需在打开文件
/home/pi/Adafruit_Python_DHT/Adafruit_DHT/platform_detect.py

在代码段
elif match.group(1) == 'BCM2837':# Pi 3b+return 3
后添加如下代码段
elif match.group(1) == 'BCM2711':# Pi 4breturn 3
然后输入命令安装Adafruit Python DHT Sensor函数库
cd Adafruit_Python_DHT/
sudo python setup.py install
sudo python3 setup.py install

2.9.1 使用示例程序

Adafruit 提供了示例程序,运行下面的命令测试。

cd /home/pi
cd Adafruit_Python_DHT
cd examples
python AdafruitDHT.py 11 4

2.9.2 使用Adafruit库自定义Python程序

import Adafruit_DHT
# 设置传感器类型DHT11,DHT22或AM2302
sensor=Adafruit_DHT.DHT11
# Set GPIO sensor is connected to
gpio=4
# 读取15次,每次间隔2秒
humidity, temperature = Adafruit_DHT.read_retry(sensor, gpio)
if humidity is not None and temperature is not None:print('Temp={0:0.1f}*C  Humidity={1:0.1f}%'.format(temperature, humidity))
else:print('Failed to get reading. Try again!')

2.5 温度传感器DS18b20

参考树莓派+温度传感器实现室内温度监控


(1)允许单总线接口

$ sudo raspi-config
进入interfacing options
enable one-wire interface
重启

(2)完成接线
该模块使用的是单总线数字温度传感器 DS18B20,外界供电电压范围为 3.0 V 至 5.5 V,无需备用电源。
测量温度范围为-55 ° C 至+125 ℃ , 华氏相当于是67 ° F 到 257° F。
其中 -10 °C 至+85 ° C 范围内精度为±0.5 ° C 。

GND-----Board----9
DQ-------Board----7
VCC-----Board----1

(3)升级内核
$ sudo apt-get update
$ sudo apt-get upgrade

3 异常及解决

(1)树莓派4B gpio readall 出现Oops - unable to determine board type… model: 17
树莓派使用GPIO接口是基于wiringPi的。
解决方案:
$wget https://project-downloads.drogon.net/wiringpi-latest.deb
#sudo dpkg -i wiringpi-latest.deb

树莓派-5-GPIO的应用实验相关推荐

  1. 品味树莓派:GPIO Zero库使用入门

    文章目录 目的 基础说明 入门使用 LED PWMLED Button 更多入门例程 类基础说明 注意事项 总结 目的 树莓派有很多GPIO口可供用户使用,官方同时也提供了一些方式来操作这些IO口,其 ...

  2. 树莓派python gpio 模仿iic_Adafruit的树莓派教程:GPIO配置

    概览 树莓派最令人兴奋的特点之一是它有一个GPIO连接器可以用来接其他的硬件设备. GPIO连接器实际上是由许多不同类型的接口组成的: 真正的GPIO(General Purpose Input Ou ...

  3. 【树莓派C语言开发】实验02:RGB小灯

    文章目录 前言 1.实验器材 1.1树莓派运行库准备 2.元件接线 3.函数解释 3.1关于softPwmWrite的使用问题,大大的疑惑 4.代码样例 4.1初始化针脚 4.2颜色参数设置 4.3完 ...

  4. 【树莓派C语言开发】实验12:PCF8591模数转换器模块

    文章目录 前言 1.实验器材 2.实验原理 2.0 元件介绍 2.1 i2c总线 2.2 第一字节 2.3 控制字节 2.4 模块电路 2.5 电路接线 3.程序控制 3.1 在树莓派中开启I2C 3 ...

  5. 【树莓派C语言开发】实验03:七彩LED模块

    文章目录 前言 1.实验器材 2.实验接线 3.实验效果 结语 前言 学习太累,那就玩玩树莓派"陶冶情操"吧! 关注本专栏,和我一起学习树莓派开发板30+经典实验! C语言代码,0 ...

  6. 树莓派python控制gpio_树莓派的GPIO控制

    陈拓chentuo@ms.xab.ac.cn 2018.06.09/2018.06.10 从网上下载了几张精美的图片,感谢图片的制作者! 0. 概述 本文介绍树莓派 Zero W的GPIO控制,并用L ...

  7. 【树莓派C语言开发】实验10:干簧管传感器

    文章目录 前言 1.实验器材 2.实验原理 2.1电路图 2.2接线图 3.代码示例 3.1编译代码 3.1.1 GCC中-Wall指令的作用 3.2实验效果 结语 前言 好像没啥可以说的,直接开始进 ...

  8. 品味树莓派:GPIO口定义、电气特性、启动状态等基础说明

    文章目录 目录 GPIO口定义 电气特性 启动状态 总结 目录 树莓派相比成品化的电脑来说有很多独立的GPIO口可供开发使用,可以方便的实现很多实物相关的功能.本文将对树莓派开放给用户的GPIO口的针 ...

  9. 【树莓派C语言开发】实验07:倾斜开关模块

    文章目录 前言 1.实验器材 2.实验原理 2.1实验接线 2.2实物接线图 3.代码示例 3.1部分代码解释 去抖动操作 直接用`==`比较字符串 3.2 Linux编译运行代码 3.3运行效果 结 ...

  10. 实现在树莓派的GPIO接口上用跳线(短路帽)轻松选择启用或者禁用overlayfs影子系统

    前面我发过一篇blog说明如何使用overlayfs打造一个只读的不怕意外关机的树莓派Raspberry Pi. https://blog.csdn.net/zhufu86/article/detai ...

最新文章

  1. lua linux获取文件夹,Linux:删除目录下的文件的10种方法
  2. Buuctf(pwn)ciscn_2019_n_8
  3. 如何查询一个表中除某几个字段外其他所有的字段_一个小故事告诉你:如何写好数据分析报告?...
  4. python面试题库——3数据库和缓存
  5. 《软件工程》课程设计总结
  6. 回溯法之避免无用判断 UVA129 Krypton Factor困难的串
  7. redux-form V.7.4.2学习笔记(六)表单同步校验技术
  8. typescript-koa-postgresql 实现一个简单的rest风格服务器 —— 连接 postgresql 数据库...
  9. JavaScript:学习笔记(9)——Promise对象
  10. LeetCode 1913. 两个数对之间的最大乘积差
  11. 鸿蒙 自研内核 core b,华为平板将首次搭载鸿蒙OS 2.0系统:首次自研内核与构架...
  12. vscode之调试js
  13. linux安装软件常用命令
  14. 简单打开.swf文件
  15. C# Abp框架入门系列文章(一)
  16. 怎样训练左右手协调_吉他,左右手的协调,练习的方法原来这么简单!
  17. 凸函数二阶条件的理解及常见函数解析
  18. Discuz!您当前的访问请求当中含有非法字符,已经被系统拒绝解决办法
  19. 2023年全国最新二级建造师精选真题及答案26
  20. LPC1768 IAP写入bin格式程序不能启动的解决办法

热门文章

  1. 当代年轻人的生活仪式感有哪些。
  2. Linux Crontab定时执行脚本出错,但手动执行脚本正常原因及解决方案
  3. c语言程序导出到excel里,怎么将C语言的输出倒入Excel工作表
  4. 开源协议的优劣势比较
  5. 美国商标如何申请办理
  6. 宁做创业狼,不做打工狗-- -- 影响了数亿人的文章
  7. 工具集合 各种vip骚操作应有尽有,分享给大家
  8. centos7.6 安装NVIDIArtc2070显卡驱动
  9. Pandas模块:表计算与数据分析
  10. 计算机专业基础英语,计算机专业基础英语.ppt