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
相关文章
|
7天前
|
数据采集 存储 XML
Python爬虫定义入门知识
Python爬虫是用于自动化抓取互联网数据的程序。其基本概念包括爬虫、请求、响应和解析。常用库有Requests、BeautifulSoup、Scrapy和Selenium。工作流程包括发送请求、接收响应、解析数据和存储数据。注意事项包括遵守Robots协议、避免过度请求、处理异常和确保数据合法性。Python爬虫强大而灵活,但使用时需遵守法律法规。
|
7天前
|
Python
深入理解Python装饰器:从入门到实践####
本文旨在通过简明扼要的方式,为读者揭开Python装饰器的神秘面纱,从基本概念、工作原理到实际应用场景进行全面解析。不同于常规的摘要仅概述内容概要,本文将直接以一段精炼代码示例开篇,展示装饰器如何优雅地增强函数功能,激发读者探索兴趣,随后深入探讨其背后的机制与高级用法。 ####
37 11
|
4天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
|
4天前
|
机器学习/深度学习 数据挖掘 Python
Python编程入门——从零开始构建你的第一个程序
【10月更文挑战第39天】本文将带你走进Python的世界,通过简单易懂的语言和实际的代码示例,让你快速掌握Python的基础语法。无论你是编程新手还是想学习新语言的老手,这篇文章都能为你提供有价值的信息。我们将从变量、数据类型、控制结构等基本概念入手,逐步过渡到函数、模块等高级特性,最后通过一个综合示例来巩固所学知识。让我们一起开启Python编程之旅吧!
|
4天前
|
存储 Python
Python编程入门:打造你的第一个程序
【10月更文挑战第39天】在数字时代的浪潮中,掌握编程技能如同掌握了一门新时代的语言。本文将引导你步入Python编程的奇妙世界,从零基础出发,一步步构建你的第一个程序。我们将探索编程的基本概念,通过简单示例理解变量、数据类型和控制结构,最终实现一个简单的猜数字游戏。这不仅是一段代码的旅程,更是逻辑思维和问题解决能力的锻炼之旅。准备好了吗?让我们开始吧!
|
10天前
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
45 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
|
3天前
|
设计模式 缓存 开发框架
Python中的装饰器:从入门到实践####
本文深入探讨了Python中装饰器的工作原理与应用,通过具体案例展示了如何利用装饰器增强函数功能、提高代码复用性和可读性。读者将学习到装饰器的基本概念、实现方法及其在实际项目开发中的实用技巧。 ####
16 3
|
7天前
|
机器学习/深度学习 数据采集 数据可视化
Python在数据科学中的应用:从入门到实践
本文旨在为读者提供一个Python在数据科学领域应用的全面概览。我们将从Python的基础语法开始,逐步深入到数据处理、分析和可视化的高级技术。文章不仅涵盖了Python中常用的数据科学库,如NumPy、Pandas和Matplotlib,还探讨了机器学习库Scikit-learn的使用。通过实际案例分析,本文将展示如何利用Python进行数据清洗、特征工程、模型训练和结果评估。此外,我们还将探讨Python在大数据处理中的应用,以及如何通过集成学习和深度学习技术来提升数据分析的准确性和效率。
|
6天前
|
机器学习/深度学习 数据挖掘 开发者
Python编程入门:理解基础语法与编写第一个程序
【10月更文挑战第37天】本文旨在为初学者提供Python编程的初步了解,通过简明的语言和直观的例子,引导读者掌握Python的基础语法,并完成一个简单的程序。我们将从变量、数据类型到控制结构,逐步展开讲解,确保即使是编程新手也能轻松跟上。文章末尾附有完整代码示例,供读者参考和实践。
|
6天前
|
人工智能 数据挖掘 程序员
Python编程入门:从零到英雄
【10月更文挑战第37天】本文将引导你走进Python编程的世界,无论你是初学者还是有一定基础的开发者,都能从中受益。我们将从最基础的语法开始讲解,逐步深入到更复杂的主题,如数据结构、面向对象编程和网络编程等。通过本文的学习,你将能够编写出自己的Python程序,实现各种功能。让我们一起踏上Python编程之旅吧!