树莓派 GPIO操作.1(Python版本)
今天的最后一篇文章,一共7篇,很久没有写这么满了。后面的硬件就不测试了,大概率是正确的,我只写源代码。而且这些代码放在Jetson Nano上面也是可以的。
源码都是主机上面写的,环境是Python3.7:
如图所示
先安装urllib3,我以前写爬虫是2
安装一些插件,教我做人
https://copilot.github.com/
语言模式,就写Python
import urllib
contens = urllib.urlopen("www.baidu.com/").read()
print(contens)
出错了
from urllib.request import urlopen
webpage = urlopen('http://www.python.org')
print(webpage)
这个还算靠谱
import sys
for(i, value) in enumerate(sys.argv):
print("arg:%d %s" % (i, value))
这是它的第一种用法,直接读取命令行的数组
python.exe .\url.py a b c d
也可以这样执行
后面是捕获的参数
树莓派B+
另一个引脚图
https://pypi.org/project/RPi.GPIO/
https://github.com/zhongzhi107/raspberry-pi-tutorials
https://sourceforge.net/p/raspberry-gpio-python/code/ci/default/tree/
源文件是C的,应该是包装了Python的接口
C文件
py_gpio.py看上去都是C的实现,包装了一个接口
这样只能尽可能的快了,差不多够用吧
使用的方法是BCM
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脚输出高低电平,中间是时间。
sudo python xxxx.py
和内核态打交道,记得给sudo的权限,下面都是这样的运行方式
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脚的开关状态来工作,延迟时间用音调计算而来。
产生动静的代码
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代码
需要掌握的知识有点多,先写写看。
写作思路
import tkinter
top = tkinter.Tk()
# 进入消息循环
top.mainloop()
结果
# 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() # 进入消息循环
要使用的部件
控件共有的属性
几何管理方式
https://github.com/china-testing/python-api-tesing
一个py的api集成库
刚刚查资料看见的
https://github.com/china-testing/python-api-tesing/blob/master/books.md
https://china-testing.github.io/tk2.html
创建一个复选框
通过传递值,来改变复选框的状态
bool变量设置复选框的状态
传递的函数,在这里和硬件产生的关联
https://zhuanlan.zhihu.com/p/75872830?from_voters_page=true
这里插个文章,还不错
python -m tkinter
cmd输入这个会出现对话框
https://tkdocs.com/tutorial/index.html
这个链接里面有大量的doc
https://wxpython.org/Phoenix/docs/html/index.html
还有别的库
https://wxpython.org/pages/overview/
有时间的去看吧
传递的command
我们使用到的组件
https://tcl.tk/man/tcl8.6/TkCmd/ttk_checkbutton.htm
具体的参数
最后注意使用mainloop()不然不出现现窗口
定义了一个App的类,如果你有两个函数需要一起管理就考虑类吧
初始化的韩苏护创建一个check_var的成员变量,包含了一个bool的变量,未组件实现了变量选项。
保证了你鼠标点复选框的时候,变量的值会改变。
command的参数会在发生改变的似乎运行updata的函数,至于updata函数这不是有手就行。
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
和上个写法一样,不过用了一个新的组件:
https://tkdocs.com/tutorial/morewidgets.html#scale
就这个
同样写了App的类和一个update的函数,直接输出一个duty的参数控制
滑块变,执行update函数,然后回导致duty变,最后导致PWM的占空比变
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的类型
共阳极还是共阴极,如果是漫射型的会更好
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灯