上一篇實(shí)現(xiàn)了樹莓派的第一個(gè)基礎(chǔ)實(shí)驗(yàn)——點(diǎn)亮雙色LED燈,并了解了樹莓派GPIO的基本用法。如果你已經(jīng)成功完成過樹莓派雙色LED燈實(shí)驗(yàn),并且對(duì)深入樹莓派玩法有更多的興趣的話,那么我們進(jìn)一步嘗試點(diǎn)亮一個(gè)更加絢麗的LED燈:RGB三基色LED燈。
一、介紹
RGB-LED模塊可以發(fā)出各種顏色的光。紅色,綠色和藍(lán)色的三個(gè)LED被封裝到透明或半透明塑料外殼中,并帶有四個(gè)引腳。紅色,綠色和藍(lán)色三原色可以按照亮度混合并組合各種顏色,因此可以通過控制電路使RGB-LED發(fā)出彩色光。
二、組件
Raspberry Pi 4b主板*1
樹莓派電源*1
40P軟排線*1
RGB-LED模塊*1
面包板*1
跳線若干
三、實(shí)驗(yàn)原理
在本實(shí)驗(yàn)中,我們將使用PWM技術(shù)來控制RGB的亮度。
脈沖寬度調(diào)制(PWM)是一種通過數(shù)字方式獲取模擬結(jié)果的技術(shù)。數(shù)字控制用于創(chuàng)建方波,信號(hào)在高電平和低電平之間切換。這種開關(guān)模式,可以通過改變信號(hào)持續(xù)的時(shí)間部分,與信號(hào)關(guān)閉的時(shí)間來模擬全開(5V)和關(guān)(0V)之間的電壓。“有效”的持續(xù)時(shí)間稱為脈沖寬度。要獲得不同的模擬值,可以更改或調(diào)節(jié)脈沖寬度。如果你使用的LED重復(fù)此開關(guān)模式足夠快,得到信號(hào)好像是0到5V之間的穩(wěn)定電壓,控制LED的亮度。
四、實(shí)驗(yàn)步驟
建立電路,按照如下表格連線:
樹莓派 | T形轉(zhuǎn)接板 | RGB-LED燈模塊 |
---|---|---|
GND | GND | GND |
GPIO0 | GPIO17 | R |
GPIO1 | GPIO18 | G |
GPIO2 | GPIO27 | B |
#!/usr/bin/env python #告訴Linux本文件是一個(gè)Python程序
import RPi.GPIO as GPIO #導(dǎo)入控制GPIO的模塊,RPi.GPIO
import time #導(dǎo)入時(shí)間模塊,提供延時(shí)、時(shí)鐘和其它時(shí)間函數(shù)
colors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF] #顏色列表
R = 11 #定義物理針腳號(hào)
G = 12
B = 13
#初始化程序
def setup(Rpin, Gpin, Bpin):
global pins # 在函數(shù)內(nèi)部聲明被其修飾的變量是全局變量
global p_R, p_G, p_B
pins = {'pin_R': Rpin, 'pin_G': Gpin, 'pin_B': Bpin}
GPIO.setmode(GPIO.BOARD) # 設(shè)置引腳編號(hào)模式為板載模式,即樹莓派上的物理位置編號(hào)
for i in pins:
GPIO.setup(pins[i], GPIO.OUT) # 設(shè)置針腳模式為輸出(或者輸入GPIO.IN)
GPIO.output(pins[i], GPIO.LOW) # Set pins to low(0 V) to off led
p_R = GPIO.PWM(pins['pin_R'], 2000) # set Frequece to 2KHz
p_G = GPIO.PWM(pins['pin_G'], 1999)
p_B = GPIO.PWM(pins['pin_B'], 5000)
p_R.start(0) # Initial duty Cycle = 0(leds off)
p_G.start(0)
p_B.start(0)
def map(x, in_min, in_max, out_min, out_max): #將顏色的刺激量轉(zhuǎn)換為占空比對(duì)應(yīng)的值。
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
def off():
for i in pins:
GPIO.output(pins[i], GPIO.LOW) # Turn off all leds
def setColor(col): # For example : col = 0x112233
R_val = (col & 0xff0000) > > 16 # 先“與”運(yùn)算 只保留自己顏色所在位的值有效
G_val = (col & 0x00ff00) > > 8 # 再“右移”運(yùn)算 將自己顏色所在位的值提取出來
B_val = (col & 0x0000ff) > > 0
R_val = map(R_val, 0, 255, 0, 100) # 將顏色的刺激量轉(zhuǎn)換為占空比對(duì)應(yīng)的值
G_val = map(G_val, 0, 255, 0, 100)
B_val = map(B_val, 0, 255, 0, 100)
p_R.ChangeDutyCycle(R_val) # 更改占空比,調(diào)整該顏色的亮度
p_G.ChangeDutyCycle(G_val)
p_B.ChangeDutyCycle(B_val)
#循環(huán)函數(shù)
def loop():
while True:
for col in colors:
setColor(col)
time.sleep(1)
#資源釋放
def destroy():
p_R.stop() #Turn off PWM
p_G.stop()
p_B.stop()
off() # Turn off all leds
GPIO.cleanup() #重置GPIO狀態(tài)
#程序入口
if __name__ == "__main__":
try: #用try-except代碼塊來處理可能引發(fā)的異常
setup(R, G, B) #調(diào)用初始化設(shè)置LED燈的函數(shù)
loop() #調(diào)用循環(huán)函數(shù)
except KeyboardInterrupt: #如果遇用戶中斷(control+C),則執(zhí)行destroy()函數(shù)
destroy() #調(diào)用清除LED狀態(tài)的函數(shù)