🐝

ESP32-C3M-TRYでLEDを点滅(Lちか)させる

に公開

はじめに

この記事ではマイクロファン ラボのESP32-C3M-TRYとMicropythonを使用してオンボードLED(青色)とRGB LED(カラーLED)の操作について解説します。

オンボードLEDはESP32本体の右側にひとつ、RGB LEDはOLEDの右側に3つあります。

ESP32-C3-TRY
画像引用元:https://www.microfan.jp/wp-content/uploads/2023/06/ESP32-C3M-TRY-2.jpg

必要に応じて以下の資料を参照して下さい。
ESP32-C3M-TRYに関する詳細ページ
https://www.microfan.jp/2023/06/esp32-c3m-try/

ESP32-C3M-TRYマニュアル(PDFファイル)
https://www.microfan.jp/document/ESP32-C3M-TRY-R1-20230701.pdf

MicropythonのmachineモジュールPin(I/O ピンの制御)クラスの日本語ドキュメント
https://micropython-docs-ja.readthedocs.io/ja/latest/library/machine.Pin.html

LEDとは

LED(Light Emitting Diode、発光ダイオード)は、電流を流すことによって光を発する半導体素子です。

LEDの特徴

  • エネルギー効率:LEDは非常にエネルギー効率が高く、同じ明るさを得るために必要な電力が従来の電球(白熱電球や蛍光灯)よりも少なくて済みます。
  • 長寿命:LEDは非常に長寿命で、数万時間以上持つことが一般的です。これは白熱電球や蛍光灯に比べて大きな利点です。
  • 小型化:LEDは非常に小さく、薄型デザインが可能なので、ディスプレイや照明機器に広く使用されています。
  • 瞬時点灯:LEDは点灯に時間がかからず、瞬時に明るくなります。これにより、特に交通信号やディスプレイなどでの利用に便利です。
  • 耐久性:衝撃に強く、壊れにくいため、移動機器や屋外環境でも使用されやすいです。

LEDの用途

  • 照明:家庭用照明、商業用照明、街灯などに使われています。
  • ディスプレイ:テレビ、モニター、スマートフォンのスクリーン、デジタルサイネージに広く使用。
  • 車両のライト:自動車のヘッドライトやテールライト。
  • 交通信号:LED信号機が多くの国で使われています。

LEDの詳細

LEDの詳細については以下のサイト(Wikipedia)を参照して下さい。
https://ja.wikipedia.org/wiki/発光ダイオード

GPIOとは

GPIO(General Purpose Input/Output)は、コンピュータやマイクロコントローラに搭載されている汎用の入出力ピンのことです。
GPIOピンは、外部デバイスとマイクロコントローラやプロセッサを接続するためのインターフェースとして使用されます。
GPIOを使用することにより、さまざまなデバイスやセンサー、アクチュエータ(モーター、LED、ボタンなど)と直接やり取りをすることができます。

GPIOのモード

GPIOのモードには、一般的に次のものがあります。

入力モード: GPIOピンを外部信号を受け取るために使用します。このモードでは、スイッチやセンサーからの信号をCPUに伝える役割を果たします。入力モードでは、ピンは通常ハイインピーダンス(Hi-Z)状態になり、外部からの信号を受け取ることができます。

出力モード: GPIOピンを外部デバイスを制御するために使用します。例えば、LEDを点灯させたり、モーターを駆動させたりする際に利用されます。出力モードには、以下の2つの構成があります:

アナログモード: 一部のGPIOピンはアナログ信号を処理するために設定でき、アナログ入力を受け取ることができます。このモードは、センサーからのアナログ信号をデジタル信号に変換する際に使用されます。

ハイインピーダンスモード: 出力が無効になり、ピンが外部回路に影響を与えない状態です。このモードは、他のデバイスと信号を共有する際に重要です。

オンボードLEDの制御

サンプルプログラム1

次のサンプルプログラムはオンボードLEDを点灯させて3秒後に消灯するものです。

onboard1.py
# オンボードLEDの点滅
# onboard.py

# ハードウエア制御のモジュールをインポートする
import machine

# timeモジュールをインポートする
import time

# オンボードLEDはD0(GPIO0)に接続されている
LED = 0

# インスタンス(オブジェクト)を作成
led = machine.Pin(LED, machine.Pin.OUT)

# ledをONにしてLEDを点灯
led.on()

# 3秒間ONの状態を保持する
time.sleep(3)

# LEDを消灯
led.off()

サンプルプログラム2

onboard2.py
# オンボードLEDを10回点滅させる
# onboard2.py

# ハードウエア制御のモジュールをインポートする
import machine

# timeモジュールをインポートする
import time

# オンボードLEDはD0(GPIO0)に接続されている
LED = 0

# インスタンス(オブジェクト)を作成
led = machine.Pin(LED, machine.Pin.OUT)

# 1秒ごとにLEDの点灯、消灯を10回繰り返す
for n in range(10):
    # LED点灯
    led.on()

    # 1秒間ONの状態を保持する
    time.sleep(1)

    # LEDを消灯
    led.off()
    
    # 1秒間OFFの状態を保持する
    time.sleep(1)

RGB LED(カラーLED)の制御

RGB LED(カラーLED)とは

RGB LEDは光の三原色である赤(R)、緑(G)、青(B)のLEDが一つのパッケージに入ったものです。
それぞれのLEDの明るさを組み合わせることによってフルカラー(コントロールするGPIOの分解能によります)で表示できます。

下図のように、RGBがそれぞれ100%と0%(ONとOFF)だと2×2×2=8通りの組み合わせの色(全てが消灯していることも含めて)が表現できます。

例えば、RとGがONでBがOFFだと黄色に光ります。BとRがONでGがOFFだとマゼンタ(ピンク)に光り、BとGがONでRがOFFだとシアン(水色)に光ります。

Alt光の三原色
画像引用元: https://ezu-ken.com/three-primary-colors-o

RGB LEDのそれぞれのLEDの明るさをPWMを使ってコントロールできると、さらに多くの色の組み合わせを表現することができます。

例えば、R、G、BそれぞれのLEDが0%から100%までの間を256通りずつ明るさを変えることができるとすると、
256×256×256=約1,677万色となります。(それぞれ0から255までの256通りが3色)

ESP32-C3M-TRYのRGB LED

ESP32-C3M-TRYには、WS2812(NeoPixel)タイプのカラーLEDが3個搭載されています。
このLEDはLED1個ずつにICチップが搭載されていてLEDの色や明るさを細かくコントロールすることができます。
NeoPixel LEDがテープ状に多数接続されたNeoPixel RGBテープLEDなども販売されています。

ESP32-C3M-TRYでRGB LEDの制御

ESP32-C3M-TRYでは3個のNeoPixel LEDがGPIO38に接続されています。
Micropytonで制御するためにはneopixelモジュールをインポートする必要があります。

WS2812/NeoPixel LEDのドキュメントは以下のURLで参照できます。
https://micropython-docs-ja.readthedocs.io/ja/latest/library/neopixel.html#module-neopixel

サンプルプログラム3

以下のサンプルコードはマニュアルhttps://www.microfan.jp/document/ESP32-C3M-TRY-R1-20230701.pdf)より引用し、編集しました。(PDFのままのコードだと動きません)
rgbという名前でNeoPixelのインスタンスを作成しています。
一つ目の引数(Pin(10, Pin.OUT))はGPIO10を出力モードとし、二つ目の引数はLEDの数を表しています。
rgb[0]が左側(OLEDに近い側)のLED、rgb[1]が真ん中のLED、rgb[2]が右側のLEDを表します。
それぞれのR、G、Bのリストになっており、0から255の範囲で発色の強さを与えます。
一般的には

rgb[index] = (R, G, B)

のような記述になります。

rgb_led1.py
from machine import Pin # machineモジュールからPinクラスをインポートする
from neopixel import NeoPixel # neopixelモジュールからNeoPixelクラスをインポートする
# NeoPixel の初期化
rgb = NeoPixel(Pin(10, Pin.OUT), 3) # D10 に3個のLED
# 各LED の色の設定と表示
rgb[0] = (50,0,0) # LED3: 赤
rgb[1] = (0,50,0) # LED4: 緑
rgb[2] = (0,0,50) # LED5: 青
rgb.write() # 色の設定を全てのLED の表示に反映

サンプルプログラム4

次のプログラムはサンプルプログラム3を点灯、消灯を10回繰り返すようにしたものです。

rgb_led2.py
from machine import Pin
from neopixel import NeoPixel
from time import sleep

# NeoPixel の初期化
rgb = NeoPixel(Pin(10, Pin.OUT), 3) # D38 に3個の LED

# 10回繰り返す
for n in range(10):
    # 各 LED の色の設定と表示
    rgb[0] = (50,0,0) # LED3: 赤
    rgb[1] = (0,50,0) # LED4: 緑
    rgb[2] = (0,0,50) # LED5: 青
    rgb.write() # 色の設定を全ての LED の表示に反映
    sleep(1)
    
    # 各 LED を消灯する
    rgb[0] = (0,0,0) # LED3: 赤
    rgb[1] = (0,0,0) # LED4: 緑
    rgb[2] = (0,0,0) # LED5: 青
    rgb.write() # 色の設定を全ての LED の表示に反映
    sleep(1)

サンプルプログラム5

サンプルプログラム4のRGB LEDを制御する部分を関数にして簡素化してみました。

rgb_led3.py
from machine import Pin
from neopixel import NeoPixel
from time import sleep

# LEDの点灯パターン
led_value = [(50, 0, 0), (0, 50, 0), (0, 0, 50)]

             
# NeoPixel の初期化
rgb = NeoPixel(Pin(10, Pin.OUT), 3) # D38 に3個の LED

# RGB LEDを制御する関数(LEDの番号、パターンをタプルで与える)
def rgb_led(led_no, value):
    rgb[led_no] = value
    rgb.write()
    

# 10回繰り返す
for count in range(10):
    # 何回目を実行しているか表示
    print(count)
    # 各LEDの色の設定と点灯(rgb_led()関数をよぶ)
    for num in range(3):
        rgb_led(num, led_value[num])    
    sleep(1)
    
    # すべて消灯
    for num in range(3):
        rgb_led(num, (0, 0, 0))

    sleep(1)

サンプルプログラム6

次のプログラムはRGB LEDをランダムな色で点灯させるサンプルコードです。
led_valueというリストにrandint()を使って0から50の値で、3つそれぞれのLEDにランダムな値のRGBのタプルをセットしています。

rgb_led4.py
# RGB LEDをランダムに点灯させ
# May 1st 2025

from machine import Pin
from neopixel import NeoPixel
from time import sleep
from random import randint

# NeoPixel の初期化
rgb = NeoPixel(Pin(10, Pin.OUT), 3) # D38 に3個の LED

# RGB LEDを制御する関数(LEDの番号、パターンをタプルで与える)
def rgb_led(led_no, value):
    rgb[led_no] = value
    rgb.write()
    

# 無限に繰り返す
while True:
    # リストを初期化
    led_value = []
    # 50未満の値でランダムな色を設定してled_valueリストにセット
    for n in range(3):
        # リストに値を追加
        led_value.append((randint(0,50),randint(0,50),randint(0,50)))
    
    # 出来上がったリストを表示
    print(led_value)
        
    # 各LEDの色の設定と点灯(rgb_led()関数をよぶ)
    for num in range(3):
        rgb_led(num, led_value[num])    
    sleep(0.1)

サンプルプログラム7

CTRL-CやThonnyのSTOPボタンでプログラムを停止させるとLEDが点灯したままになるので、これらのイベントが発生した場合はすべてのLEDをtry exceptを使って消灯するようにしました。

rgb_led5.py
# RGB LEDをランダムに点灯させ、CTRL-CやSTOPボタンが押されたら消灯する
# May 1st 2025

from machine import Pin
from neopixel import NeoPixel
from time import sleep
from random import randint

# NeoPixel の初期化
rgb = NeoPixel(Pin(10, Pin.OUT), 3) # D38 に3個の LED

# RGB LEDを制御する関数(LEDの番号、パターンをタプルで与える)
def rgb_led(led_no, value):
    rgb[led_no] = value
    rgb.write()


# CTRL-Cが押されたり、STOPボタンが押されたらLEDをすべて消灯する
try:
    # 通常はこの無限ループを繰り返す
    # 無限に繰り返す
    while True:
        led_value = []
        # 50未満の値でランダムな色を設定してled_valueリストにセット
        for n in range(3):
            led_value.append((randint(0,50),randint(0,50),randint(0,50)))
        print(led_value)
            
        # 各LEDの色の設定と点灯(rgb_led()関数をよぶ)
        for num in range(3):
            rgb_led(num, led_value[num])    
        sleep(0.1)

# CTRL-CやSTOPボタンが押されたらLEDをすべて消灯する
except KeyboardInterrupt:
    # すべて消灯
    for num in range(3):
        rgb_led(num, (0, 0, 0))

演習問題

  1. 日本の一般的な信号機は左から緑、黄、赤となっています。赤を3秒、次に赤を消して黄色を1秒、次に黄色を消して赤を3秒点灯するプログラムを作成して下さい。(ファイル名:RGB-ex1.py)

  2. RGBの順に左から右に流れるような表示されるプログラムを作成して下さい。(ファイル名:RGB-ex2.py)

  3. サンプルプログラム7を書き換えて、LEDがそれぞれランダムな色でランダムな間隔で点灯したり相当したりする(どのようなパターンにするかは自分でアイデアを出して下さい)プログラムを作成して下さい。(ファイル名:RGB-ex3.py)

Discussion