树莓派 GPIO操作.1(Python版本)

2021-07-23 13:03:12 浏览数 (1)

今天的最后一篇文章,一共7篇,很久没有写这么满了。后面的硬件就不测试了,大概率是正确的,我只写源代码。而且这些代码放在Jetson Nano上面也是可以的。

源码都是主机上面写的,环境是Python3.7:

如图所示

先安装urllib3,我以前写爬虫是2

安装一些插件,教我做人

代码语言:javascript复制
https://copilot.github.com/

语言模式,就写Python

代码语言:javascript复制
import urllib
contens = urllib.urlopen("www.baidu.com/").read()
print(contens)

出错了

代码语言:javascript复制
from urllib.request import urlopen
webpage = urlopen('http://www.python.org')
print(webpage)

这个还算靠谱

代码语言:javascript复制
import sys
for(i, value) in enumerate(sys.argv):
    print("arg:%d %s" % (i, value))

这是它的第一种用法,直接读取命令行的数组

代码语言:javascript复制
python.exe .url.py a b c d

也可以这样执行

后面是捕获的参数

树莓派B

另一个引脚图

代码语言:javascript复制
https://pypi.org/project/RPi.GPIO/
代码语言:javascript复制
https://github.com/zhongzhi107/raspberry-pi-tutorials
代码语言:javascript复制
https://sourceforge.net/p/raspberry-gpio-python/code/ci/default/tree/

源文件是C的,应该是包装了Python的接口

C文件

py_gpio.py看上去都是C的实现,包装了一个接口

这样只能尽可能的快了,差不多够用吧

使用的方法是BCM

代码语言:javascript复制
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)

while (True):
    GPIO.output(18, True)
    time.sleep(0.5)
    GPIO.output(18, False)
    time.sleep(0.5)

LED闪烁的程序


用到了io和time,先设置IO的map方式,然后是引脚。接着死循环,交替的让18脚输出高低电平,中间是时间。

代码语言:javascript复制
sudo python xxxx.py

和内核态打交道,记得给sudo的权限,下面都是这样的运行方式

代码语言:javascript复制
import RPi.GPIO as GPIO
import time

buzzer_pin = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)


def buzz(pitch, duration):
    period = 1.0 / pitch
    delay = period / 2
    cycles = int(duration * pitch)
    for i in range(cycles):
        GPIO.output(buzzer_pin, True)
        time.sleep(delay)
        GPIO.output(buzzer_pin, False)
        time.sleep(delay)


while True:
    pitch_s = print("输入音高 (200 到 2000): ")
    pitch = float(pitch_s)
    duration_s = print("输入持续时间(秒):")
    duration = float(duration_s)
    buzz(pitch, duration)

蜂鸣器


原理是很简单,通过快速的改变18脚的开关状态来工作,延迟时间用音调计算而来。

产生动静的代码

代码语言:javascript复制
from Tkinter import *
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)


class App:

    def __init__(self, master):
        frame = Frame(master)
        frame.pack()
        self.check_var = BooleanVar()
        check = Checkbutton(frame, text='Pin 18',
                            command=self.update,
                            variable=self.check_var, onvalue=True, offvalue=False)
        check.grid(row=1)

    def update(self):
        GPIO.output(18, self.check_var.get())


root = Tk()
root.wm_title('On / Off Switch')
app = App(root)
root.geometry("200x50 0 0")
root.mainloop()

一个控制开关的GUI代码


需要掌握的知识有点多,先写写看。

写作思路

代码语言:javascript复制
import tkinter
top = tkinter.Tk()
# 进入消息循环
top.mainloop()

结果

代码语言:javascript复制
# Python3.x 导入方法
from tkinter import *
root = Tk()                     # 创建窗口对象的背景色
# 创建两个列表
li = ['C', 'python', 'php', 'html', 'SQL', 'java']
movie = ['CSS', 'jQuery', 'Bootstrap']
listb = Listbox(root)  # 创建两个列表组件
listb2 = Listbox(root)
for item in li:                 # 第一个小部件插入数据
    listb.insert(0, item)

for item in movie:              # 第二个小部件插入数据
    listb2.insert(0, item)

listb.pack()                    # 将小部件放置到主窗口中
listb2.pack()
root.mainloop()                 # 进入消息循环

要使用的部件

控件共有的属性

几何管理方式

代码语言:javascript复制
https://github.com/china-testing/python-api-tesing

一个py的api集成库

刚刚查资料看见的

代码语言:javascript复制
https://github.com/china-testing/python-api-tesing/blob/master/books.md
代码语言:javascript复制
https://china-testing.github.io/tk2.html

创建一个复选框

通过传递值,来改变复选框的状态

bool变量设置复选框的状态

传递的函数,在这里和硬件产生的关联

代码语言:javascript复制
https://zhuanlan.zhihu.com/p/75872830?from_voters_page=true

这里插个文章,还不错

代码语言:javascript复制
python -m tkinter

cmd输入这个会出现对话框

代码语言:javascript复制
https://tkdocs.com/tutorial/index.html

这个链接里面有大量的doc

代码语言:javascript复制
https://wxpython.org/Phoenix/docs/html/index.html

还有别的库

代码语言:javascript复制
https://wxpython.org/pages/overview/

有时间的去看吧

传递的command

我们使用到的组件

代码语言:javascript复制
https://tcl.tk/man/tcl8.6/TkCmd/ttk_checkbutton.htm

具体的参数

最后注意使用mainloop()不然不出现现窗口

定义了一个App的类,如果你有两个函数需要一起管理就考虑类吧


初始化的韩苏护创建一个check_var的成员变量,包含了一个bool的变量,未组件实现了变量选项。

保证了你鼠标点复选框的时候,变量的值会改变。

command的参数会在发生改变的似乎运行updata的函数,至于updata函数这不是有手就行。

代码语言:javascript复制
from Tkinter import *
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
pwm = GPIO.PWM(18, 500)
pwm.start(100)


class App:

    def __init__(self, master):
        frame = Frame(master)
        frame.pack()
        scale = Scale(frame, from_=0, to=100,
                      orient=HORIZONTAL, command=self.update)
        scale.grid(row=0)

    def update(self, duty):
        pwm.ChangeDutyCycle(float(duty))


root = Tk()
root.wm_title('PWM Power Control')
app = App(root)
root.geometry("200x50 0 0")
root.mainloop()

控制一个引脚的PWM输出,我又写了一个GUI


和上个写法一样,不过用了一个新的组件:

代码语言:javascript复制
https://tkdocs.com/tutorial/morewidgets.html#scale

就这个

同样写了App的类和一个update的函数,直接输出一个duty的参数控制

滑块变,执行update函数,然后回导致duty变,最后导致PWM的占空比变

代码语言:javascript复制
from Tkinter import *
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
GPIO.setup(23, GPIO.OUT)
GPIO.setup(24, GPIO.OUT)

pwmRed = GPIO.PWM(18, 500)
pwmRed.start(100)

pwmGreen = GPIO.PWM(23, 500)
pwmGreen.start(100)

pwmBlue = GPIO.PWM(24, 500)
pwmBlue.start(100)


class App:

    def __init__(self, master):
        frame = Frame(master)
        frame.pack()
        Label(frame, text='Red').grid(row=0, column=0)
        Label(frame, text='Green').grid(row=1, column=0)
        Label(frame, text='Blue').grid(row=2, column=0)
        scaleRed = Scale(frame, from_=0, to=100,
                         orient=HORIZONTAL, command=self.updateRed)
        scaleRed.grid(row=0, column=1)
        scaleGreen = Scale(frame, from_=0, to=100,
                           orient=HORIZONTAL, command=self.updateGreen)
        scaleGreen.grid(row=1, column=1)
        scaleBlue = Scale(frame, from_=0, to=100,
                          orient=HORIZONTAL, command=self.updateBlue)
        scaleBlue.grid(row=2, column=1)

    def updateRed(self, duty):
        pwmRed.ChangeDutyCycle(float(duty))

    def updateGreen(self, duty):
        pwmGreen.ChangeDutyCycle(float(duty))

    def updateBlue(self, duty):
        pwmBlue.ChangeDutyCycle(float(duty))


root = Tk()
root.wm_title('RGB LED Control')
app = App(root)
root.geometry("200x150 0 0")
root.mainloop()

趁热打铁,来个RGB的控制代码

一目了然对吧?

初始化三个脚

代码有点不好,没有用生成器写

和上面一样,注意运行的时候看你的RGB的类型

共阳极还是共阴极,如果是漫射型的会更好

代码语言:javascript复制
import RPi.GPIO as GPIO

pins = [18, 23, 24]

pin_led_states = [
    [1, 0, -1],  # A
    [0, 1, -1],  # B
    [-1, 1, 0],  # C
    [-1, 0, 1],  # D
    [1, -1, 0],  # E
    [0, -1, 1]  # F
]

GPIO.setmode(GPIO.BCM)


def set_pin(pin_index, pin_state):
    if pin_state == -1:
        GPIO.setup(pins[pin_index], GPIO.IN)
    else:
        GPIO.setup(pins[pin_index], GPIO.OUT)
        GPIO.output(pins[pin_index], pin_state)


def light_led(led_number):
    for pin_index, pin_state in enumerate(pin_led_states[led_number]):
        set_pin(pin_index, pin_state)


set_pin(0, -1)
set_pin(1, -1)
set_pin(2, -1)

while True:
    x = int(raw_input("Pin (0 to 5):"))
    light_led(x)

接着我们看一个有趣的东西,众所周知,IO脚和珍贵

那么如何用少的IO控制尽可能多的灯呢?



利用GPIO引脚在运行过程中可以随意改变输入输出的原理。我突然不想解释了,LED=n^2-n,10个脚可以控制90个LED。在上面的demo的里面是一次点亮一个,需要多个点亮是,将要点亮的led放数组,然后快速循环,来欺骗你的eye。

大纲

直接看这个配置,数组,不多。列表保存的GPIO

设置引脚

led灯

0 人点赞