2021年11月29日月曜日

RaspberyPi でフルカラーLEDを制御してみた

RaspberyPi でフルカラーLEDを制御してみた

概要

PWM を使ってフルカラーLEDでいろんな色を点滅させてみました

環境

  • RaspberryPi4 8GRAM
  • RaspberryPiOS 5.10.17 armv7l
  • Python 2.7.16
    • pigpio 1.78

サンプルコード

後述でポイントを紹介しています
処理の概要はコメントにて記載しています

  • vim test_full_color_led.py
# -*- coding: utf-8 -*-
"""フルカラーのLEDを制御するモジュール."""
import RPi.GPIO as GPIO
import time
import logging

from logging import getLogger


class FullColorLEDTest():
    """フルカラーのLEDをテストするクラス."""

    # 各ピン定義
    RED = 11
    GREEN = 12
    BLUE = 13

    def __init__(self):
        """ピンを初期化します."""
        logging.basicConfig(level=logging.INFO)
        self.logger = getLogger(__name__)
        # RGB のカラーコードをここに記載します
        self.colors = [
            # red, green, blue, yellow, purple, cyan になります
            0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF
        ]
        pin_def = {
            self.RED: 2000,  # red
            self.GREEN: 2000,  # green
            self.BLUE: 5000,  # blue
        }
        GPIO.setmode(GPIO.BOARD)
        # 制御するピンを管理するdict
        self.pins = {
            self.RED: None,
            self.GREEN: None,
            self.BLUE: None,
        }
        # 各ピンの初期化
        for pin_num, freq in pin_def.items():
            GPIO.setup(pin_num, GPIO.OUT)
            pin = GPIO.PWM(pin_num, freq)
            pin.start(0)
            self.pins[pin_num] = pin
        self.logger.info('Started pwm pins for a full color led.')

    def calc_duty(self, x, in_min, in_max, out_min, out_max):
        """デューティー比を計算します."""
        return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

    def blink_color(self, col):
        """各ピンに色を設定し指定の色を光らせます."""
        # 左ビットシフト
        red = (col & 0x110000) >> 16
        green = (col & 0x001100) >> 8
        blue = (col & 0x000011) >> 0
        # デューティー比に変換 (0-100)
        red = self.calc_duty(red, 0, 255, 0, 100)
        green = self.calc_duty(green, 0, 255, 0, 100)
        blue = self.calc_duty(blue, 0, 255, 0, 100)
        # ピンにデューティー比を設定
        self.pins[self.RED].ChangeDutyCycle(red)
        self.pins[self.GREEN].ChangeDutyCycle(green)
        self.pins[self.BLUE].ChangeDutyCycle(blue)

    def blink(self):
        """フルカラーLEDを点滅させます."""
        try:
            self.logger.info('Started blinking a full color led.')
            while True:
                for col in self.colors:
                    self.blink_color(col)
                    time.sleep(0.5)
        except KeyboardInterrupt:
            pass
        finally:
            self.cleanup()

    def cleanup(self):
        """クリーンアップ処理を実行します."""
        for pin in self.pins.values():
            pin.stop()
        GPIO.cleanup()
        self.logger.info('The pin cleanup process was completed.')


if __name__ == "__main__":
    test = FullColorLEDTest()
    test.blink()

説明

今回使用したフルカラーLEDは赤青緑で3ピン必要になるのでピンを管理する dict を準備しました (この辺りはクラスにしてもいいかも)

ピンの情報と周波数も別途 dict で定義しています

init でピンの初期化を行ったあとは blink で各カラーを順番に点滅させます
点滅させたい色は self.colors で定義していので他の色を点滅させたい場合はここに追加していきます

定義したカラーコードを実際にはデューティー比に変換する必要があります
それは calc_duty で行っておりカラーコードを 0 から 100 の範囲に変換する処理を行っています

あとは変換した値を ChangeDutyCycle で各ピンに対して設定して上げれば OK です

回路

  • 11 -> 赤のピン
  • 12 -> 緑のピン
  • 13 -> 青のピン
  • 6 (GND) -> カソード

に接続するだけです
各色を管理するピンは 220 オームの抵抗を挟んで接続しています

動作確認

  • python test_full_color_led.py

で実行しましょう
以下のように順番に点滅すれば成功です

最後に

フルカラーLED と PWM を使えば好きな色の LED を光らせることができます
少しお値段が高いのが難点ですが便利です

各ピンの出力周波数に関しては参考にさせていただいたサイトの値をそのまま拝借しているだけなのでフルカラーLED の種類によっては調整の必要があるかもしれません

参考サイト

0 件のコメント:

コメントを投稿