Python 物联网入门指南(三)(2)

简介: Python 物联网入门指南(三)

Python 物联网入门指南(三)(1)https://developer.aliyun.com/article/1507199

它是如何工作的…

这次,当我们设置 GPIO 引脚时,我们将与关机按钮连接的引脚定义为输入,与 LED 连接的引脚定义为输出。我们打开 LED 以指示系统正在运行。

通过将DEBUG标志设置为True,我们可以测试脚本的功能,而不会导致实际关闭(通过读取终端消息);我们只需要确保在实际使用脚本时将DEBUG设置为False

我们进入一个while循环,并每秒检查引脚,以查看 GPIO 引脚是否设置为LOW(即检查开关是否被按下);如果是,我们就进入doShutdown()函数。

程序将等待三秒,然后再次测试按钮是否仍然被按下。如果按钮不再被按下,我们将返回到之前的while循环。但是,如果在三秒后它仍然被按下,程序将闪烁 LED 并触发关闭(还会使用flite提供音频警告)。

当我们对脚本的运行状态感到满意时,我们可以禁用DEBUG标志(将其设置为False),并将脚本添加到crontab中。crontab是一个在后台运行的特殊程序,允许我们在系统启动时(@reboot)安排程序和操作的特定时间、日期或周期性。这使得脚本可以在每次树莓派上电时自动启动。当我们按住关机按钮超过三秒时,它会安全地关闭系统并进入低功耗状态(LED 在此之前会关闭,表明很快就可以拔掉电源)。要重新启动树莓派,我们简单地拔掉电源;这将重新启动系统,当树莓派加载完成时,LED 会亮起。

还有更多…

我们可以通过添加额外的功能并利用额外的 GPIO 连接(如果可用)来进一步扩展这个示例。

重置和重新启动树莓派

树莓派上有用于安装复位标头的孔(在树莓派 3/2 上标有RUN,在树莓派 1 型 A 和 B Rev 2 上标有P6)。复位引脚允许使用按钮而不是每次都拔掉微型 USB 连接器来重置设备的电源:

树莓派复位标头-左边是树莓派 A/B 型(Rev2),右边是树莓派 3

要使用它,您需要将一根导线或引脚排焊接到树莓派上,并连接一个按钮(或每次在两个孔之间短暂触碰一根导线)。或者,我们可以扩展我们之前的电路,如下图所示:

受控关闭电路布局和复位按钮

我们可以将这个额外的按钮添加到我们的电路中,它可以连接到复位标头(这是树莓派 3 上最靠近中间的孔,其他型号上最靠近边缘的孔)。当暂时将此引脚拉低连接到地(例如旁边的孔或 GPIO 标头的第 6 引脚等其他地点),将重置树莓派并允许它在关闭后再次启动。

添加额外功能

由于现在脚本一直监视关机按钮,我们可以同时添加额外的按钮/开关/跳线来监视。这将允许我们通过改变输入来触发特定程序或设置特定状态。以下示例允许我们轻松地在自动 DHCP 网络(默认网络设置)和使用直接 IP 地址之间进行切换,就像第一章“使用树莓派 3 计算机入门”中的“直接连接到笔记本电脑或计算机”配方中使用的那样。

将以下组件添加到上一个电路中:

  • 一个 470 欧姆电阻
  • 两个带跳线连接器的引脚头(或者,可选地,一个开关)
  • 面包板导线(实心线)

在添加了上述组件之后,我们的受控关机电路现在如下所示:

受控关机电路布局、复位按钮和跳线引脚

在上一个脚本中,我们添加了一个额外的输入来检测LAN_SWA引脚的状态(我们添加到电路中的跳线引脚),使用以下代码:

LAN_SWA = 11    #2 

确保在gpio_setup()函数中设置为输入(带上拉电阻)使用以下代码:

GPIO.setup(LAN_SWA,GPIO.IN,pull_up_down=GPIO.PUD_UP) 

添加一个新的功能来在 LAN 模式之间切换并读取新的 IP 地址。doChangeLAN()函数检查LAN_SWA引脚的状态是否自上次调用以来发生了变化,如果是,则将网络适配器设置为 DHCP,或者相应地设置直接 LAN 设置(如果可用,则使用flite来朗读新的 IP 设置)。最后,设置 LAN 为直接连接会导致 LED 在该模式激活时缓慢闪烁。使用以下代码来实现这一点:

def doChangeLAN(direct): 
  if(DEBUG):print("Direct LAN: %s" % direct) 
  if GPIO.input(LAN_SWA) and direct==True: 
    if(DEBUG):print("LAN Switch OFF") 
    cmd="sudo dhclient eth0" 
    direct=False 
    GPIO.output(LED,1) 
  elif GPIO.input(LAN_SWA)==False and direct==False: 
    if(DEBUG):print("LAN Switch ON") 
    cmd="sudo ifconfig eth0 169.254.69.69" 
    direct=True 
  else: 
    return direct 
  if(DEBUG==False):os.system(cmd) 
  if(SNDON):os.system("hostname -I | flite") 
  return direct 

添加另一个函数flashled(),每次调用时切换 LED 的状态。该函数的代码如下:

def flashled(ledon): 
  if ledon: 
    ledon=False 
  else: 
    ledon=True 
  GPIO.output(LED,ledon) 
  return ledon

最后,我们调整主循环,也调用doChangeLAN(),并使用结果决定是否使用ledon调用flashled()来跟踪 LED 的上一个状态。main()函数现在应该更新如下:

def main(): 
  gpio_setup() 
  GPIO.output(LED,1) 
  directlan=False 
  ledon=True 
  while True: 
    if(DEBUG):print("Waiting for >3sec button press") 
    if GPIO.input(SHTDWN_BTN)==False: 
       doShutdown() 
    directlan= doChangeLAN(directlan) 
    if directlan: 
      flashled(ledon) 
    time.sleep(1) 

GPIO 键盘输入

我们已经看到了如何监视 GPIO 上的输入来启动应用程序和控制树莓派;然而,有时我们需要控制第三方程序。使用uInput库,我们可以模拟键盘(甚至鼠标移动)来控制任何程序,使用我们自己的自定义硬件。

有关使用uInput的更多信息,请访问tjjr.fi/sw/python-uinput/

准备工作

执行以下步骤安装uInput

  1. 首先,我们需要下载uInput

您需要使用以下命令从 GitHub 下载uInput Python 库(约 50 KB):

wget https://github.com/tuomasjjrasanen/python-uinput/archive/master.zip
unzip master.zip

该库将解压缩到一个名为python-uinput-master的目录中。

  1. 完成后,可以使用以下命令删除 ZIP 文件:
rm master.zip  
  1. 使用以下命令安装所需的软件包(如果已经安装了它们,apt-get命令将忽略它们):
sudo apt-get install python3-setuptools python3-dev
sudo apt-get install libudev-dev  
  1. 使用以下命令编译和安装uInput
cd python-uinput-master
sudo python3 setup.py install
  1. 最后,使用以下命令加载新的uinput内核模块:
sudo modprobe uinput  

为了确保在启动时加载,我们可以使用以下命令将uinput添加到modules文件中:

sudo nano /etc/modules  

在文件中新建一行并保存(Ctrl + X, Y)。

  1. 使用以下设备创建以下电路:
  • 面包板(半尺寸或更大)
  • 7 根 DuPont 母对公排线
  • 六个按钮
  • 6 个 470 欧姆电阻
  • 面包板导线(实心线)

GPIO 键盘电路布局

键盘电路也可以通过将组件焊接到 Vero 原型板(也称为条板)中,制成永久电路,如下图所示:

GPIO 键盘 Pi 硬件模块这个电路可以从PiHardware.com购买成套焊接套件。

  1. 通过将适当的按钮与适当的引脚相匹配,将电路连接到树莓派 GPIO 引脚,如下表所示:
按钮 GPIO 引脚
GND 6
v B_DOWN 22
< B_LEFT 18
^ B_UP 15
> B_RIGHT 13
1 B_1 11
2 B_2 7

如何做…

创建一个名为gpiokeys.py的脚本,如下所示:

#!/usr/bin/python3 
#gpiokeys.py 
import time 
import RPi.GPIO as GPIO 
import uinput 
#HARDWARE SETUP 
# GPIO 
# 2[==G=====<=V==]26[=======]40 
# 1[===2=1>^=====]25[=======]39 
B_DOWN  = 22    #V 
B_LEFT  = 18   #< 
B_UP    = 15   #^ 
B_RIGHT = 13   #> 
B_1  = 11   #1 
B_2  = 7   #2 
DEBUG=True 
BTN = [B_UP,B_DOWN,B_LEFT,B_RIGHT,B_1,B_2] 
MSG = ["UP","DOWN","LEFT","RIGHT","1","2"] 
#Setup the DPad module pins and pull-ups 
def dpad_setup(): 
  #Set up the wiring 
  GPIO.setmode(GPIO.BOARD) 
  # Setup BTN Ports as INPUTS 
  for val in BTN: 
    # set up GPIO input with pull-up control 
    #(pull_up_down can be: 
    #    PUD_OFF, PUD_UP or PUD_DOWN, default PUD_OFF) 
    GPIO.setup(val, GPIO.IN, pull_up_down=GPIO.PUD_UP) 
def main(): 
  #Setup uinput 
  events = (uinput.KEY_UP,uinput.KEY_DOWN,uinput.KEY_LEFT, 
           uinput.KEY_RIGHT,uinput.KEY_ENTER,uinput.KEY_ENTER) 
  device = uinput.Device(events) 
  time.sleep(2) # seconds 
  dpad_setup() 
  print("DPad Ready!") 
  btn_state=[False,False,False,False,False,False] 
  key_state=[False,False,False,False,False,False] 
  while True: 
    #Catch all the buttons pressed before pressing the related keys 
    for idx, val in enumerate(BTN): 
      if GPIO.input(val) == False: 
        btn_state[idx]=True 
      else: 
        btn_state[idx]=False 
    #Perform the button presses/releases (but only change state once) 
    for idx, val in enumerate(btn_state): 
      if val == True and key_state[idx] == False: 
        if DEBUG:print (str(val) + ":" + MSG[idx]) 
        device.emit(events[idx], 1) # Press. 
        key_state[idx]=True 
      elif val == False and key_state[idx] == True: 
        if DEBUG:print (str(val) + ":!" + MSG[idx]) 
        device.emit(events[idx], 0) # Release. 
        key_state[idx]=False 
    time.sleep(.1) 
try: 
  main() 
finally: 
  GPIO.cleanup() 
#End 

它是如何工作的…

首先,我们导入uinput并定义键盘按钮的接线。对于BTN中的每个按钮,我们将它们启用为输入,并启用内部上拉。

接下来,我们设置uinput,定义我们想要模拟的键,并将它们添加到uinput.Device()函数中。我们等待几秒钟,以便uinput初始化,设置初始按钮和键状态,并启动我们的main循环。

main循环分为两个部分:第一部分检查按钮并记录btn_state中的状态,第二部分将btn_state与当前的key_state数组进行比较。这样,我们可以检测到btn_state的变化,并调用device.emit()来切换键的状态。

为了让我们能够在后台运行此脚本,我们可以使用&运行它,如下所示

以下命令:

sudo python3 gpiokeys.py &  

&字符允许命令在后台运行,因此我们可以继续使用命令行运行其他程序。您可以使用fg将其带回前台,或者如果有多个命令正在运行,则可以使用%1%2等。使用jobs获取列表。

您甚至可以通过按下Ctrl + Z将进程/程序暂停以进入命令提示符,然后使用bg恢复它(这将使其在后台运行)。

更多信息…

我们可以使用uinput来为其他程序提供硬件控制,包括那些需要鼠标输入的程序。

生成其他按键组合

您可以在文件中创建几种不同的键映射以支持不同的程序。例如,events_z80键映射对于像Fuse这样的光谱模拟器非常有用(浏览raspi.tv/2012/how-to-install-fuse-zx-spectrum-emulator-on-raspberry-pi获取更多详细信息)。events_omx键映射适用于使用以下命令控制通过 OMXPlayer 播放的视频:

omxplayer filename.mp4  

您可以使用-k参数获取omxplayer支持的键列表。

用新的键映射替换定义events列表的行,并通过以下代码将它们分配给事件来选择不同的键:

events_dpad = (uinput.KEY_UP,uinput.KEY_DOWN,uinput.KEY_LEFT, 
              uinput.KEY_RIGHT,uinput.KEY_ENTER,uinput.KEY_ENTER) 
events_z80 = (uinput.KEY_Q,uinput.KEY_A,uinput.KEY_O, 
             uinput.KEY_P,uinput.KEY_M,uinput.KEY_ENTER) 
events_omx = (uinput.KEY_EQUAL,uinput.KEY_MINUS,uinput.KEY_LEFT, 
             uinput.KEY_RIGHT,uinput.KEY_P,uinput.KEY_Q) 

您可以在input.h文件中找到所有的KEY定义;您可以使用less命令查看它(按Q退出),如下所示:

less /usr/include/linux/input.h  

模拟鼠标事件

uinput库可以模拟鼠标和操纵杆事件,以及键盘按键。要使用按钮模拟鼠标,我们可以调整脚本以使用鼠标事件(以及定义mousemove来设置移动的步长),使用以下代码:

MSG = ["M_UP","M_DOWN","M_LEFT","M_RIGHT","1","Enter"] 
events_mouse=(uinput.REL_Y,uinput.REL_Y, uinput.REL_X, 
             uinput.REL_X,uinput.BTN_LEFT,uinput.BTN_RIGHT) 
mousemove=1 

我们还需要修改按钮处理以提供连续移动,因为我们不需要跟踪鼠标键的状态。为此,请使用以下代码:

#Perform the button presses/releases 
#(but only change state once) 
for idx, val in enumerate(btn_state): 
  if MSG[idx] == "M_UP" or MSG[idx] == "M_LEFT": 
    state = -mousemove 
  else: 
    state = mousemove 
  if val == True: 
    device.emit(events[idx], state) # Press. 
  elif val == False: 
    device.emit(events[idx], 0) # Release. 
time.sleep(0.01) 

多路复用的彩色 LED

本章的下一个示例演示了一些看似简单的硬件如果通过软件控制可以产生一些令人印象深刻的结果。为此,我们将回到使用 RGB LED。我们将使用五个 RGB LED,这些 LED 被布线,以便我们只需要使用八个 GPIO 引脚来控制它们的红色、绿色和蓝色元素,使用一种称为硬件多路复用的方法(请参阅本食谱的硬件多路复用子部分中的更多信息部分)。

准备工作

您将需要以下图片中显示的 RGB LED 模块:

PiHardware.com 的 RGB LED 模块

正如您在上面的照片中所看到的,来自pihardware.com/的 RGB LED 模块带有 GPIO 引脚和杜邦母对母电缆用于连接。虽然有两组从 1 到 5 标记的引脚,但只需要连接一侧。

或者,您可以使用五个共阳极 RGB LED、3 个 470 欧姆电阻和一个 Vero 原型板(或大型面包板)来重新创建自己的电路。电路将如下图所示:

RGB LED 模块的电路图严格来说,我们应该在这个电路中使用 15 个电阻(每个 RGB LED 元件一个),这样可以避免 LED 共用同一个电阻的干扰,并且在一起开启时也会延长 LED 的寿命。然而,使用这种方法只有轻微的优势,特别是因为我们打算独立驱动每个 RGB LED,以实现多种颜色效果。

您需要将电路连接到树莓派 GPIO 引脚头,连接方式如下:

RGB LED 1 2 3 4
Rpi GPIO 引脚 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40
Rpi GPIO 引脚 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39
RGB LED 5 R G B

如何做到这一点…

创建rgbled.py脚本,并执行以下步骤:

  1. 导入所有所需的模块,并使用以下代码定义要使用的值:
#!/usr/bin/python3 
#rgbled.py 
import time 
import RPi.GPIO as GPIO 
#Setup Active states 
#Common Cathode RGB-LEDs (Cathode=Active Low) 
LED_ENABLE = 0; LED_DISABLE = 1 
RGB_ENABLE = 1; RGB_DISABLE = 0 
#HARDWARE SETUP 
# GPIO 
# 2[=====1=23=4==]26[=======]40 
# 1[===5=RGB=====]25[=======]39 
#LED CONFIG - Set GPIO Ports 
LED1 = 12; LED2 = 16; LED3 = 18; LED4 = 22; LED5 = 7 
LED = [LED1,LED2,LED3,LED4,LED5] 
RGB_RED = 11; RGB_GREEN = 13; RGB_BLUE = 15 
RGB = [RGB_RED,RGB_GREEN,RGB_BLUE] 
#Mixed Colors 
RGB_CYAN = [RGB_GREEN,RGB_BLUE] 
RGB_MAGENTA = [RGB_RED,RGB_BLUE] 
RGB_YELLOW = [RGB_RED,RGB_GREEN] 
RGB_WHITE = [RGB_RED,RGB_GREEN,RGB_BLUE] 
RGB_LIST = [RGB_RED,RGB_GREEN,RGB_BLUE,RGB_CYAN, 
            RGB_MAGENTA,RGB_YELLOW,RGB_WHITE] 
  1. 定义使用以下代码设置 GPIO 引脚的函数:
def led_setup(): 
  '''Setup the RGB-LED module pins and state.''' 
  #Set up the wiring 
  GPIO.setmode(GPIO.BOARD) 
  # Setup Ports 
  for val in LED: 
    GPIO.setup(val, GPIO.OUT) 
  for val in RGB: 
    GPIO.setup(val, GPIO.OUT) 
  led_clear()
  1. 使用以下代码定义我们的实用程序函数来帮助控制 LED:
def led_gpiocontrol(pins,state): 
  '''This function will control the state of 
  a single or multiple pins in a list.''' 
  #determine if "pins" is a single integer or not 
  if isinstance(pins,int): 
    #Single integer - reference directly 
    GPIO.output(pins,state) 
  else: 
    #if not, then cycle through the "pins" list 
    for i in pins: 
      GPIO.output(i,state) 
def led_activate(led,color): 
  '''Enable the selected led(s) and set the required color(s) 
  Will accept single or multiple values''' 
  #Enable led 
  led_gpiocontrol(led,LED_ENABLE) 
  #Enable color 
  led_gpiocontrol(color,RGB_ENABLE) 
def led_deactivate(led,color): 
  '''Deactivate the selected led(s) and set the required 
  color(s) will accept single or multiple values''' 
  #Disable led 
  led_gpiocontrol(led,LED_DISABLE) 
  #Disable color 
  led_gpiocontrol(color,RGB_DISABLE) 
def led_time(led, color, timeon): 
  '''Switch on the led and color for the timeon period''' 
  led_activate(led,color) 
  time.sleep(timeon) 
  led_deactivate(led,color) 
def led_clear(): 
  '''Set the pins to default state.''' 
  for val in LED: 
    GPIO.output(val, LED_DISABLE) 
  for val in RGB: 
    GPIO.output(val, RGB_DISABLE) 
def led_cleanup(): 
  '''Reset pins to default state and release GPIO''' 
  led_clear() 
  GPIO.cleanup()
  1. 创建一个测试函数来演示模块的功能:
def main(): 
  '''Directly run test function. 
  This function will run if the file is executed directly''' 
  led_setup() 
  led_time(LED1,RGB_RED,5) 
  led_time(LED2,RGB_GREEN,5) 
  led_time(LED3,RGB_BLUE,5) 
  led_time(LED,RGB_MAGENTA,2) 
  led_time(LED,RGB_YELLOW,2) 
  led_time(LED,RGB_CYAN,2)  
if __name__=='__main__': 
  try: 
    main() 
  finally: 
    led_cleanup() 
#End 

它是如何工作的…

首先,我们通过定义所需的状态来定义硬件设置,以便根据使用的 RGB LED(共阳极)的类型来启用禁用LED。如果您使用的是共阳极设备,只需颠倒启用禁用状态。

接下来,我们定义 GPIO 映射到引脚,以匹配我们之前进行的接线。

我们还通过组合红色、绿色和/或蓝色来定义一些基本的颜色组合,如下图所示:

LED 颜色组合

我们定义了一系列有用的函数,首先是led_setup(),它将把 GPIO 编号设置为GPIO.BOARD,并定义所有要用作输出的引脚。我们还调用一个名为led_clear()的函数,它将把引脚设置为默认状态,所有引脚都被禁用。

这意味着 LED 引脚 1-5(每个 LED 的共阳极)被设置为HIGH,而 RGB 引脚(每种颜色的单独阳极)被设置为LOW

我们创建一个名为led_gpiocontrol()的函数,它将允许我们设置一个或多个引脚的状态。isinstance()函数允许我们测试一个值,看它是否匹配特定类型(在本例中是单个整数);然后我们可以设置单个引脚的状态,或者遍历引脚列表并设置每个引脚的状态。

接下来,我们定义两个函数,led_activate()led_deactivate(),它们将启用和禁用指定的 LED 和颜色。最后,我们定义led_time(),它将允许我们指定 LED、颜色和开启时间。

我们还创建led_cleanup()来将引脚(和 LED)重置为默认值,并调用GPIO.cleanup()来释放正在使用的 GPIO 引脚。

这个脚本旨在成为一个库文件,因此我们将使用if __name__=='__main__'检查,只有在直接运行文件时才运行我们的测试代码:

通过检查__name__的值,我们可以确定文件是直接运行的(它将等于__main__),还是被另一个 Python 脚本导入的。

这使我们能够定义一个特殊的测试代码,只有在直接加载和运行文件时才执行。如果我们将此文件作为另一个脚本中的模块包含,那么此代码将不会被执行。

与以前一样,我们将使用try/finally来允许我们始终执行清理操作,即使我们提前退出。

为了测试脚本,我们将设置 LED 依次以各种颜色点亮。

还有更多…

我们可以通过一次打开 RGB LED 的一个或多个部分来创建几种不同的颜色。然而,通过一些巧妙的编程,我们可以创建整个颜色谱。此外,我们可以似乎同时在每个 LED 上显示不同的颜色。

硬件复用

LED 需要在阳极侧施加高电压,在阴极侧施加低电压才能点亮。电路中使用的 RGB LED 是共阳极的,因此我们必须在 RGB 引脚上施加高电压(3V3),在阴极引脚上施加低电压(0V)(分别连接到每个 LED 的 1 到 5 引脚)。

阴极和 RGB 引脚状态如下:

阴极和 RGB 引脚状态

因此,我们可以启用一个或多个 RGB 引脚,但仍然控制点亮哪个 LED。我们启用我们想要点亮的 LED 的引脚,并禁用我们不想点亮的引脚。这使我们可以使用比控制每个 RGB 线需要的引脚少得多的引脚。

显示随机图案

我们可以向我们的库中添加新的函数以产生不同的效果,例如生成随机颜色。以下函数使用randint()来获取 1 到颜色数量之间的值。我们忽略任何超出可用颜色数量的值,以便我们可以控制 LED 关闭的频率。执行以下步骤以添加所需的函数:

  1. 使用以下代码将random模块中的randint()函数添加到rgbled.py脚本中:
from random import randint
  1. 现在使用以下代码添加led_rgbrandom()
def led_rgbrandom(led,period,colors): 
   ''' Light up the selected led, for period in seconds, 
   in one of the possible colors. The colors can be 
   1 to 3 for RGB, or 1-6 for RGB plus combinations, 
   1-7 includes white. Anything over 7 will be set as 
   OFF (larger the number more chance of OFF).'''  
  value = randint(1,colors) 
  if value < len(RGB_LIST): 
    led_time(led,RGB_LIST[value-1],period) 
  1. main()函数中使用以下命令创建一系列

闪烁 LED:

for i in range(20): 
  for j in LED: 
    #Select from all, plus OFF 
    led_rgbrandom(j,0.1,20) 

混合多种颜色

到目前为止,我们只在一个或多个 LED 上一次显示一种颜色。如果考虑电路的接线方式,您可能会想知道我们如何让一个 LED 同时显示一种颜色,而另一个显示不同的颜色。简单的答案是我们不需要-我们只是快速地做到这一点!

我们所需要做的就是一次显示一种颜色,但来回变换,变换得如此之快,以至于颜色看起来像两种颜色的混合(甚至是三种红/绿/蓝 LED 的组合)。幸运的是,树莓派等计算机可以很容易地做到这一点,甚至允许我们组合 RGB 元素以在所有五个 LED 上制作多种颜色。执行以下步骤来混合颜色:

  1. rgbled.py脚本的顶部添加组合颜色定义,在混合颜色的定义之后,使用以下代码:
#Combo Colors 
RGB_AQUA = [RGB_CYAN,RGB_GREEN] 
RGB_LBLUE = [RGB_CYAN,RGB_BLUE] 
RGB_PINK = [RGB_MAGENTA,RGB_RED] 
RGB_PURPLE = [RGB_MAGENTA,RGB_BLUE] 
RGB_ORANGE = [RGB_YELLOW,RGB_RED] 
RGB_LIME = [RGB_YELLOW,RGB_GREEN] 
RGB_COLORS = [RGB_LIME,RGB_YELLOW,RGB_ORANGE,RGB_RED, 
              RGB_PINK,RGB_MAGENTA,RGB_PURPLE,RGB_BLUE, 
              RGB_LBLUE,RGB_CYAN,RGB_AQUA,RGB_GREEN] 

上述代码将提供创建我们所需的颜色组合,RGB_COLORS提供了对颜色的平滑过渡。

  1. 接下来,我们需要创建一个名为led_combo()的函数来处理单个或多个颜色。该函数的代码如下:
def led_combo(pins,colors,period): 
  #determine if "colors" is a single integer or not 
  if isinstance(colors,int): 
    #Single integer - reference directly 
    led_time(pins,colors,period) 
  else: 
    #if not, then cycle through the "colors" list 
    for i in colors: 
      led_time(pins,i,period) 
  1. 现在我们可以创建一个新的脚本rgbledrainbow.py,以利用我们rgbled.py模块中的新功能。rgbledrainbow.py脚本将如下所示:
#!/usr/bin/python3 
#rgbledrainbow.py 
import time 
import rgbled as RGBLED 
def next_value(number,max): 
  number = number % max 
  return number 
def main(): 
  print ("Setup the RGB module") 
  RGBLED.led_setup() 
  # Multiple LEDs with different Colors 
  print ("Switch on Rainbow") 
  led_num = 0 
  col_num = 0 
  for l in range(5): 
    print ("Cycle LEDs") 
    for k in range(100): 
      #Set the starting point for the next set of colors 
      col_num = next_value(col_num+1,len(RGBLED.RGB_COLORS)) 
      for i in range(20):  #cycle time 
        for j in range(5): #led cycle 
          led_num = next_value(j,len(RGBLED.LED)) 
          led_color = next_value(col_num+led_num, 
                                 len(RGBLED.RGB_COLORS)) 
          RGBLED.led_combo(RGBLED.LED[led_num], 
                           RGBLED.RGB_COLORS[led_color],0.001) 
    print ("Cycle COLORs")         
    for k in range(100): 
      #Set the next color 
      col_num = next_value(col_num+1,len(RGBLED.RGB_COLORS)) 
      for i in range(20): #cycle time 
        for j in range(5): #led cycle 
          led_num = next_value(j,len(RGBLED.LED)) 
          RGBLED.led_combo(RGBLED.LED[led_num], 
                           RGBLED.RGB_COLORS[col_num],0.001) 
  print ("Finished") 
if __name__=='__main__': 
  try: 
    main() 
  finally: 
    RGBLED.led_cleanup() 
#End 

main()函数将首先循环遍历 LED,将RGB_COLORS数组中的每种颜色设置在所有 LED 上。然后,它将循环遍历颜色,在 LED 上创建彩虹效果:

在五个 RGB LED 上循环显示多种颜色

使用视觉持久性编写消息

视觉持续性POV)显示可以产生一种几乎神奇的效果,通过快速来回移动一行 LED 或在圆圈中移动 LED 来在空中显示图像。这种效果的原理是因为您的眼睛无法调整得足够快,以分离出单独的闪光,因此您观察到一个合并的图像(显示的消息或图片):

!使用 RGB LED 的视觉持续性

Python 物联网入门指南(三)(3)https://developer.aliyun.com/article/1507201

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
相关文章
|
3天前
|
Linux 开发工具 Python
初学者从无到有的Python语言如何入门,这份Python学习路线赶紧带走_python 从无到(1)
初学者从无到有的Python语言如何入门,这份Python学习路线赶紧带走_python 从无到(1)
初学者从无到有的Python语言如何入门,这份Python学习路线赶紧带走_python 从无到(1)
|
3天前
|
物联网 Python
2024年Python最全信息技术导论——物联网技术习题整理(1),Python面试题库
2024年Python最全信息技术导论——物联网技术习题整理(1),Python面试题库
2024年Python最全信息技术导论——物联网技术习题整理(1),Python面试题库
|
3天前
|
数据采集 算法 Python
2024年Python最全python基础入门:高阶函数,小米面试编程题
2024年Python最全python基础入门:高阶函数,小米面试编程题
|
3天前
|
存储 数据采集 数据挖掘
真正零基础Python入门:手把手教你从变量和赋值语句学起
真正零基础Python入门:手把手教你从变量和赋值语句学起
|
4天前
|
数据挖掘 数据处理 Python
【Python DataFrame 专栏】Python DataFrame 入门指南:从零开始构建数据表格
【5月更文挑战第19天】本文介绍了Python数据分析中的核心概念——DataFrame,通过导入`pandas`库创建并操作DataFrame。示例展示了如何构建数据字典并转换为DataFrame,以及进行数据选择、添加修改列、计算统计量、筛选和排序等操作。DataFrame适用于处理各种规模的表格数据,是数据分析的得力工具。掌握其基础和应用是数据分析之旅的重要起点。
【Python DataFrame 专栏】Python DataFrame 入门指南:从零开始构建数据表格
|
5天前
|
网络协议 网络架构 Python
Python 网络编程基础:套接字(Sockets)入门与实践
【5月更文挑战第18天】Python网络编程中的套接字是程序间通信的基础,分为TCP和UDP。TCP套接字涉及创建服务器套接字、绑定地址和端口、监听、接受连接及数据交换。UDP套接字则无连接状态。示例展示了TCP服务器和客户端如何使用套接字通信。注意选择唯一地址和端口,处理异常以确保健壮性。学习套接字可为构建网络应用打下基础。
20 7
|
6天前
|
Python
10个python入门小游戏,零基础打通关,就能掌握编程基础_python编写的入门简单小游戏
10个python入门小游戏,零基础打通关,就能掌握编程基础_python编写的入门简单小游戏
|
8天前
|
Python 索引 C语言
Python3从零基础到入门(2)—— 运算符-3
Python3从零基础到入门(2)—— 运算符
|
8天前
|
Python
Python3从零基础到入门(2)—— 运算符-2
Python3从零基础到入门(2)—— 运算符
Python3从零基础到入门(2)—— 运算符-2
|
8天前
|
Python C语言 存储
Python3从零基础到入门(2)—— 运算符-1
Python3从零基础到入门(2)—— 运算符
Python3从零基础到入门(2)—— 运算符-1