入坑树莓派-02-LED灯控制

入坑树莓派-02-LED灯控制

1.单色LED灯

点亮单色LED灯无需安装任何库,直接shell命令行就行。

这几个LED灯都连接在树莓派的GPIO(General-Purpose Input/Output)端口上:

端口明细如下:

通过翻阅扩展版的资料,我们了解到这几个灯连接在这几个端口上(即上图中NAME中的GPIO17,不是上图中的Pin17):

这样,我们就能通过控制这几个GPIO端口的电平高低来实现控制LED的亮和灭了。

控制GPIO的电平,用shell命令就能实现。

cd /sys/class/gpio/
echo 17 > export # 打开端口17
echo out > gpio17/direction # 将端口17设置为电平输出模式
echo 1 > gpio17/value # 将端口17设置为高电平

执行上述代码后,我们发现红色LED灯已经点亮了:

要想关掉也很简单,把端口17置为低电平即可(最后,如果17端口不用的话,可以直接关掉):

echo 0 > gpio17/value # 将端口17设置为低电平
echo 17 > unexport

同理,我们可以分别控制其他端口,来达到控制其他LED灯的目的。

用程序也能控制。

python版本:

import RPi.GPIO as GPIO
import time

# LED GPIO端口 17
LED_PIN = 17

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

# 设置端口为输出模式
GPIO.setup(LED_PIN, GPIO.OUT)

# 电平设置为高,点亮LED,1秒后关闭
GPIO.output(LED_PIN, GPIO.HIGH)
time.sleep(1)
GPIO.output(LED_PIN, GPIO.LOW)

C语言版本:

#include <bcm2835.h>
#include <stdio.h>

// gcc -o blink blink.c -lbcm2835

#define PIN_R 17  // 红色LED灯GPIO端口
#define PIN_Y 27  // 黄
#define PIN_G 22  // 绿
#define PIN_B 5   // 蓝

int main(int argc, char **argv)
{
    if (!bcm2835_init())
      return 1;

    bcm2835_gpio_fsel(PIN_R, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(PIN_Y, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(PIN_G, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(PIN_B, BCM2835_GPIO_FSEL_OUTP);
    while (1)
    {
        bcm2835_gpio_write(PIN_R, HIGH); // 开灯
        bcm2835_delay(50);
        bcm2835_gpio_write(PIN_R, LOW);  // 关灯
        bcm2835_gpio_write(PIN_Y, HIGH);
        bcm2835_delay(50);
        bcm2835_gpio_write(PIN_Y, LOW);
        bcm2835_gpio_write(PIN_G, HIGH);
        bcm2835_delay(50);
        bcm2835_gpio_write(PIN_G, LOW);
        bcm2835_gpio_write(PIN_B, HIGH);
        bcm2835_delay(50);
        bcm2835_gpio_write(PIN_B, LOW);
    }
    bcm2835_close();
    return 0;
}

注意:C语言需要安装函数库文件,从这里下载编译安装即可:

tar czvf bcm2835-1.73.tar.gz
cd bcm2835-1.73
./configure
make -j
make install

*树莓派的SOC是博通(Broadcom)的,因此需安装博通官方提供的函数库。

2.全彩LED灯

接下来我们控制这几个灯:

这几个灯是有型号的,叫:WS2812,控制它们需要安装一个特殊的函数库rpi_ws281x,使用下面的命令安装他们:

pip install rpi_ws281x

然后运行示例程序即可看到跑马灯的效果:

import time
from rpi_ws281x import Adafruit_NeoPixel, Color

# LED 灯条配置
LED_COUNT      = 6      	# 灯珠数量
LED_PIN        = 12      	# GPIO引脚
LED_FREQ_HZ    = 800000  	# LED信号频率(通常都是800KHz)
LED_DMA        = 10       	# 用于产生信号的DMA信道
LED_BRIGHTNESS = 2    		# 亮度:0最低,255最高
LED_INVERT     = False   	# 是否反转信号

strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS)

while True:
	strip.begin()
	# 顺序点亮,蓝色渐变
	for i in range(0, LED_COUNT):
		strip.setPixelColor(i, 	 Color(0,0,255))
		strip.setPixelColor(i-1, Color(0,0,200))
		strip.setPixelColor(i-2, Color(0,0,150))
		strip.setPixelColor(i-3, Color(0,0,100))
		strip.setPixelColor(i-4, Color(0,0,50))
		strip.setPixelColor(i-5, Color(0,0,0))
		strip.show()
		time.sleep(0.05)
	#逆序,绿色
	for i in range(0, LED_COUNT):
		strip.setPixelColor(LED_COUNT-i, Color(0,255,0))
		strip.show()
		time.sleep(0.05)
	#再逆序,红色
	for i in range(0,LED_COUNT):
		strip.setPixelColor(i, Color(255,0,0))
		strip.show()
		time.sleep(0.05)

3.呼吸灯

呼吸灯是这个:

控制这个灯,比前面的几个麻烦些。

首先,它需要在树莓派上开启I2C总线(使用raspi-config命令):

然后需要安装两个库:

# 安装
apt-get install i2c-tools
apt-get install python-smbus
# 赋权
usermod -aG i2c root

执行下面的命令就可以看到连接在I2C总线的元件地址了:

可以看到有两个地址,其中0x48就是我们要点亮的LED地址了,0x3c是OLD屏幕,我们将在下一篇文章中用到。

然后运行示例程序即可看到效果:

import smbus
import time

addr = 0x48 #LED的I2C总线地址
cmd  = 0x40

bus = smbus.SMBus(1)

bright = 0 # 亮度:0~255
while True:
    bus.write_byte_data(addr, cmd, bright)
    bright += 1
    if bright == 255:
        bright = 0
    time.sleep(0.003)

C语言版本的代码:

#include <bcm2835.h>
#include <unistd.h>

// gcc -o breathled breathled.c -lbcm2835

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return -1;

    bcm2835_i2c_begin();
    bcm2835_i2c_setSlaveAddress(0x48);  // 通信地址
    bcm2835_i2c_set_baudrate(10000);    // 波特率

    char busbuf[2] = {0, 0};
    unsigned char bright = 0;
    unsigned char direct = 1;
    while(1)
    {
        busbuf[0] = 0x40;       // LED灯的地址
        busbuf[1] = bright;     // 灯的亮度

        bcm2835_i2c_write(busbuf, 2);
        bcm2835_delay(5);

        if (direct)
            ++bright;
        else
            --bright;

        if (bright == 0 || bright == 255)
            direct = direct ? 0 : 1;
    }

    bcm2835_i2c_end();
    bcm2835_close();

    return 0;
}

补充知识:I2C和smbus

其实,控制这个呼吸灯之所以复杂,是因为它用的是模拟信号,而树莓派的GPIO只能输出电信号,将电信号转换为模拟信号需要一个芯片,我们用的是扩展板中PCF8591芯片,上述代码其实就是通过I2C总线将树莓派的电信号传递给PCF8591芯片,然后由其将数字信号转换为模拟信号,以点亮LED灯。

附:PCF8591芯片位置

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注