树莓派GPIO开发(二)RGB模块-PWM调节


配置环境

系统:Raspbian11(官方64位)
设备:树莓派CM4

一、PWM简单介绍

全称:Pulse-width modulation,脉冲宽度调制,简单的数模转换方法

1.基本原理

脉冲宽度调制(PWM),是用脉冲信号对模拟信号进行近似的一 种技术,一般变换后脉冲的周期固定,但脉冲的工作周期 (Duty Cycle,即一个周期内高电平的比例)会依所需模拟信号的大小而改变,高电平所占比例越高,拟合的模拟信号的幅度越大

PWM 技术通过使用高分辨率计数器(调制频率)调制方波的占空比,从而实现对一个模拟信号的电平进行编码。

2.PWM 信号主要有两个参数:

(1)信号的周期长度(Period),通常用频率(Frequency)来描述。 Frequency = 1/ Period 。

(2)工作周期(Duty Cycle),该参数通常用占空比(Duty Ratio) 来描述,占空比就是高电平在一个周期所占的百分比。

3.PWM的优点

最大的优点是从处理器到被控对象之间的所有信号都是数字形式 的,无需再进行数模转换过程;

而且对噪声的抗干扰能力也大大增强,这使得 PWM 在通讯等信号传输行业得到大量应用的主要原因。

4.PWM使用条件

模拟信号能否使用 PWM 进行编码调制,仅依赖带宽,这即意味着只要有足够的带宽,任何模拟信号值均可以采用 PWM 技术进行调制编码,一般而言,负载需要的调制频率要高于 10Hz,在 实际应用中,频率约在 1kHz 到 200kHz 之间。

5.pwm调节电压

假设一个PWM信号,V = +5V,CLK = 13KHz,Duty = 50%,那么它输出的信号就可以看成是一个+2.5V的直流信号,占空比和电压成正比。

二、RGB模块简单介绍

R、G、B三个引脚电压的高低,决定了颜色的成分,而电压的高低由PWM进行控制。树莓派的通用GPIO都可以被设置为 PWM工作方式,普通引脚精度较低专用引脚精度较高,但是我们这里也用不着。(GPIO12、GPIO13、GPIO18、GPIO19可以实现硬件脉宽调制)

这里我用编号为11、13、15三个通用GPIO。

三、代码实现

#-*- coding: utf-8 -*  
import RPi.GPIO as GPIO
import time

class RGB_LED(object):
    def __init__(self,pin_R,pin_G,pin_B):
        self.pins = [pin_R,pin_G,pin_B]
        
        # 设置为输出引脚,初始化低电平,灯灭
        for pin in self.pins:
            GPIO.setup(pin, GPIO.OUT)   
            GPIO.output(pin, GPIO.LOW)
            
        # 用RPi.GPIO的PWM方法设置三个引脚为pwm对象,频率2000Hz
        self.pwm_R = GPIO.PWM(pin_R, 2000)  
        self.pwm_G = GPIO.PWM(pin_G, 2000)
        self.pwm_B = GPIO.PWM(pin_B, 2000)
    
        # 初始占空比为0
        self.pwm_R.start(0)      
        self.pwm_G.start(0)
        self.pwm_B.start(0)
	
    # 颜色转为占空比,颜色取值范围是(0,255),占空比取值范围是(0,100),就是 (颜色/255)*100
    def color2ratio(self,x,min_color,max_color,min_ratio,max_ratio):
        return (x - min_color) * (max_ratio - min_ratio) / (max_color - min_color) + min_ratio
	
    # 颜色设置
    def setColor(self,col):
        R_val,G_val,B_val = col # 把元组解包,赋值给变量
   
        R =self.color2ratio(R_val, 0, 255, 0, 100)
        G =self.color2ratio(G_val, 0, 255, 0, 100)
        B =self.color2ratio(B_val, 0, 255, 0, 100)
        
        # 改变占空比,使用RPI.GPIO的方法ChangeDutyCycle()
        self.pwm_R.ChangeDutyCycle(R)     
        self.pwm_G.ChangeDutyCycle(G)
        self.pwm_B.ChangeDutyCycle(B)
        
    # 对象销毁 
    def destroy(self):    
        self.pwm_R.stop() # 使用stop()方法,把PWM停止
        self.pwm_G.stop()
        self.pwm_B.stop() 
        for pin in self.pins:
            GPIO.output(pin, GPIO.HIGH)   # 把输出引脚全部拉高
        GPIO.cleanup()	  # 引脚清空,结束引脚的占用

if __name__ == "__main__":

    # 设置引脚编号模式
    GPIO.setmode(GPIO.BOARD)
    
    # 定义三个引脚 
    pin_R = 11
    pin_G = 13
    pin_B = 15
    
    # 定义 RGB_LED 对象
    m_RGB_LED = RGB_LED(pin_R,pin_G,pin_B)
    
    # 定义显示的颜色(R,G,B)
    colors = [(255,0,0),(0,255,0),(0,0,255),(255,255,0),(0,197,204),(192,255,62),(148,0,211),(118,238,0)];
    
    # 循环显示各种颜色
    try:
        while True:
            for col in colors:
                # 打印颜色
                print(col)
                # 设置颜色,使用了方法
                m_RGB_LED.setColor(col)
                # 延时
                time.sleep(3)
    except KeyboardInterrupt:
        print('\n Ctrl + C QUIT')   
    finally:
        m_RGB_LED.destroy()  # 对象销毁

代码我还补充了一些注释,小白应该也能看懂了。


相关推荐

相关