ラズパイPicoでNeoPixel、まずはシンプルに1個から後は応用でいろいろ試そう♪

ラズパイPicoでNeoPixel簡単制御

「Raspberry Pi Pico」でフルカラーLEDのNeoPixelを試そうとしたときに、流れるように点灯させたり、7色に変化させたり、いろんなパターンで点灯させるサンプルプログラムはたくさん見つかるけど、シンプルに1個を希望の色に点灯させるプログラムは意外と見つからない気がします・・・

1個点灯させる方法だけわかれば後は繰り返しや、好きなパターンで指定するだけなので、まずはシンプルに1個点灯する方法から、テープライトやドットマトリクスを好きなように点灯する方法まで詳しく紹介します。

スポンサーリンク

1.フルカラーLED NeoPixelとは

「NeoPixel」とはRGB(赤緑青)のフルカラーLEDの一種です。
単体でマイコンを内蔵しておりシリアル通信で点灯色を指定して使用します。

今回動作確認にも使用したNeoPixel WS2812B は下画像のようになります。

ラズパイPicoでNeoPixel簡単制御

電源とGND(0V)端子の他に制御信号用として入力、出力端子があります。
制御信号入力端子にはシリアルデータを入力します。RGB(赤緑青)3つのLEDの明るさをそれぞれ8bitで指定するため1つのNeoPixelの明るさを指定するために24bit(8bit × 3)の制御信号(シリアルデータ)を使用します。


複数のNeoPixelを制御するには下画像のように互いの制御信号入力端子と出力端子を数珠繋ぎに接続(カスケード接続)します。

ラズパイPicoでNeoPixel簡単制御

最初の1個目が24bitの制御信号を受け取ると、制御信号に応してRGBのLEDを点灯させ、それ以降のデータは次のNeoPixelへ出力します。
次のLEDも同様に24bitの制御信号を受け取り各LEDを点灯させた後、次のLEDへ制御信号を出力します。
これを連続的に行うことで複数のLEDの点灯色を個別に指定することができます。

制御信号はパルス状ですがON/OFFの判定はHigh/Lowではなくパルス幅でON(High時間580ns~1μs)/OFF(High時間220ns~380ns)を判定しています。(Low時間はどちらも580ns~1μs)

Low時間が280us以上続くとリセット信号と判断し、次のデータを待ちます。
制御信号でのRGBの指定はGRB(緑赤青)の順番に送信する必要があるため注意が必要です。

この制御信号を自力で作成するには手間がかかるため、各マイコンボードごとに簡単に制御できる仕組み(ライブラリ等)が提供されています。


ここでも簡単に制御できるようにライブラリ等を使用しているため、サンプルプログラムではこれらを使用するためのプログラムが多く書かれてますが、ほぼ同じ内容が書かれているため、これについては気にせずにそのままコピペして使用してください。

実際にNeoPixelの点灯色を指定するプログラムは少しだけでシンプルで単純なため、この部分をいろいろ変えながらNeoPixelを使いこなしていきましょう。

スポンサーリンク

2.配線図

「Raspberry Pi Pico」の端子配列は下画像のようになります。(公式サイトより抜粋

ラズパイ(Raspberry Pi) Pico 端子配列

今回は下画像のようにブレッドボードを使用して「ボタン」と「ボリューム」「ドットマトリクスLED(8×8)」を接続しました。

「ボタン」は「Rasoberry Pi Pico」のGP20とGND(0V)に接続「ボリューム」は両端に3V3(OUT)(3.3V)とGND(0V)に接続、真ん中の端子をGP28(ADC2)に接続しています。

「ドットマトリクスLED」は電源電圧+端子をVBUS(USBの5V)、ー端子をGND(0V)、IN(制御信号端子)をGP0に接続しています。

ラズパイPicoでNeoPixel簡単制御

LEDテープライト(LED60個を使用)はドットマトリクスと同じ配線のため、下画像のようにドットマトリクスLEDと交換して接続します。

ラズパイPicoでNeoPixel簡単制御

スポンサーリンク

3.サンプルプログラム①〜⑤の動作紹介

サンプルプログラム(コピペ)として「Python」と「C言語」の両方で ①〜⑤の5パターン用意しました。
それぞれのプログラムの動作は以下のようになります。


  ①シンプルに1個点灯

ドットマトリクスLEDを一個だけ好きな色に点灯させます。
余計なプログラムが書かれていないため、シンプルにNeoPixel 1個を点灯させるためだけの方法を知ることができます。

ラズパイPicoでNeoPixel簡単制御

  ②ボタンを押すたびに色変更

ボタンを押すたびに下画像のように白→赤→緑→青と変化させるプログラムです。

ラズパイPicoでNeoPixel簡単制御
ラズパイPicoでNeoPixel簡単制御
ラズパイPicoでNeoPixel簡単制御
ラズパイPicoでNeoPixel簡単制御

  ③ボリュームで色変更

AD(アナログ-デジタル)変換を使用してボリュームの電圧値を取得することで、ボリュームを回すごとにLEDの色が少しずつ変化していくプログラムです。
色が少しづつ変化していくため赤、緑、青だけでなく、下画像のような中間色のLEDの発光が確認できます。

ラズパイPicoでNeoPixel簡単制御
ラズパイPicoでNeoPixel簡単制御
ラズパイPicoでNeoPixel簡単制御

  ④LEDテープライト全点灯

NeoPixel 60個がテープ状に連なったテープライトを全て同じ色に点灯させます。
これについては1個点灯させるのとほぼ同じで「for文」を使用してLEDの数だけ連続的に色指定するだけです。

ラズパイPicoでNeoPixel簡単制御

  ⑤ドットマトリクスLEDを好きなパターンで点灯

ドットマトリクスLEDをお絵描き感覚で好きなパターン、好きな色で点灯させます。
今回は8×8のドットマトリクスLEDを使用しましたが、LEDの数が変わっても簡単に変更できます。

ラズパイPicoでNeoPixel簡単制御

4.Pythonサンプルプログラム

「Python」を使用したサンプルプログラムについて紹介します。
開発環境は「Thonny」を使用しました。


「Thonny」のインストールから使い方については以下のリンクで詳しく紹介しています。

ラズパイPico/PicoWの使い方を3つの開発環境Python、ArduinoIDE、PlatformIOで紹介
Raspberry Pi Pico/Pico Wの使い方を端子配列からPython(MicroPython)とC言語の開発環境、Lチカ方法まで紹介。PythonはTonny、C言語はArduinoIDEとPlatformIOの3種類で詳しく紹介します。

  ①シンプルに1個点灯

「Python」で「NeoPixel」をシンプルに1個点灯させるプログラムは以下のようになります。

コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

import array, time
from machine import Pin
import rp2

# NeoPixel WS2812Bの指定
NUM_LEDS = 1  # NeoPixelの数
LED_PIN = 0   # NeoPixel信号接続端子

# 以下はNeoPixelを使用するための設定、このまま書いておく ---------------------------
# NeoPixcel WS2812の制御タイミングに合わせたパルスを生成するための設定をアセンブラで指定
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
def ws2812():    
  T1 = 2
  T2 = 5
  T3 = 3
  wrap_target()
  label("bitloop")
  out(x, 1) .side(0) [T3 - 1]
  jmp(not_x, "do_zero") .side(1) [T1 - 1]
  jmp("bitloop") .side(1) [T2 - 1]
  label("do_zero")
  nop() .side(0) [T2 - 1]
  wrap()
# クラスStateMachineを使用して、正確なパルスを出力するための設定を行う
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(LED_PIN))
# 設定したクラスStateMachineを有効にして使えるようにする。
sm.active(1)
# LEDのRGBの値を指定する24bit(8bit x 3)の配列をNeoPixelの数で準備
ar = array.array("I", [0 for _ in range(NUM_LEDS)])

# NeoPixel点灯処理関数、このまま書いておく ------------------------------------
def drawpix(num, r, g, b):
  ar[num] = g << 16 | r << 8 | b  # NeoPixel制御パルス用の24bitデータを左ビットシフトとORで生成

# 以下に点灯させる処理を記入--------------------------------------------------
# 1個を白色点灯(複数ある場合は最初の1番目のみ点灯)
# 点灯させたいNeoPixelの番号(num)とRGB(赤緑青)の明るさを0〜255(30程でも十分明るい)で指定
drawpix(0, 10, 10, 10) # LED点灯処理関数呼び出し(num, R, G, B)

sm.put(ar, 8)   # 点灯実行(NeoPixel制御パルス出力)
time.sleep_ms(100)

 5〜7行目 35〜40行目がNeoPixelの色を指定するプログラムでそれ以外はNeoPixelを制御するために毎回使用するプログラムのためそのまま書いておきます。

NeoPixelの制御には別途作成した「drawpix」関数を呼び出して以下のように行います。

drawpix( NeoPixel番号, 赤設定値, 緑設定値, 青設定値) ; 

NeoPixcel番号:点灯させたいNeoPixelの番号を指定(1番目は0から始まる)
赤設定値:赤色LEDの明るさを0〜255の値で指定
緑設定値:緑色LEDの明るさを0〜255の値で指定
青設定値:青色LEDの明るさを0〜255の値で指定
※LEDの明るさの指定値は30程度で十分明るいです。

 40行目の「sm.put(ar, 8)」が実行されると制御信号が出力されて、NeoPixelが指定通りの色で点灯します。


  ②ボタンを押すたびに色変更

「Python」で1個のNeoPixelをボタンを押すたびに赤→緑→青→白と変更させるサンプルプログラムは以下のようになります。

コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

import array, time
from machine import Pin
import rp2

# NeoPixel WS2812Bの指定
NUM_LEDS = 1  # NeoPixelの数
LED_PIN = 0   # NeoPixel信号接続端子

# 以下はNeoPixelを使用するための設定、このまま書いておく ---------------------------
# NeoPixcel WS2812の制御タイミングに合わせたパルスを生成するための設定をアセンブラで指定
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
def ws2812():    
  T1 = 2
  T2 = 5
  T3 = 3
  wrap_target()
  label("bitloop")
  out(x, 1) .side(0) [T3 - 1]
  jmp(not_x, "do_zero") .side(1) [T1 - 1]
  jmp("bitloop") .side(1) [T2 - 1]
  label("do_zero")
  nop() .side(0) [T2 - 1]
  wrap()
# クラスStateMachineを使用して、正確なパルスを出力するための設定を行う
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(LED_PIN))
# 設定したクラスStateMachineを有効にして使えるようにする。
sm.active(1)
# LEDのRGBの値を指定する24bit(8bit x 3)の配列をNeoPixelの数で準備
ar = array.array("I", [0 for _ in range(NUM_LEDS)])

# NeoPixel点灯処理関数、このまま書いておく ------------------------------------
def drawpix(num, r, g, b):
  ar[num] = g << 16 | r << 8 | b  # NeoPixel制御パルス用の24bitデータを左ビットシフトとORで生成

# 以下に点灯させる処理を記入--------------------------------------------------
# 1個の色をボタンを押すたびに変更(複数ある場合は最初の1番目のみ使用)
btn = Pin(20, Pin.IN, Pin.PULL_UP)  # GP20を入力端子(プルアップ)に設定
cnt = 0     # ボタンON回数カウント用
state = False   # ボタン状態格納用

while True:
  # ボタン回数カウント
  if btn.value() == 0 and state == False:  # GP20がONでstateがFalseなら
    state = True    # stateをTrueに
    cnt = cnt + 1   # ボタン回数カウント+1
  if btn.value() == 1:   # GP20がOFFなら
    state = False   # stateをFalseに
  # ボタン回数カウントリセット
  if cnt == 4:  # ボタン回数カウントが4なら
    cnt = 0     # 0リセット
  # LED点灯処理
  if cnt == 0:    # cntが0なら白点灯
    drawpix(0, 10, 10, 10)  # LED点灯処理関数呼び出し(num, R, G, B)
  elif cnt == 1:  # cntが1なら赤点灯
    drawpix(0, 30, 0, 0)    # LED点灯処理関数呼び出し(num, R, G, B)
  elif cnt == 2:  # cntが2なら緑点灯
    drawpix(0, 0, 30, 0)    # LED点灯処理関数呼び出し(num, R, G, B)
  elif cnt == 3:  # cntが3なら青点灯
    drawpix(0, 0, 0, 30)    # LED点灯処理関数呼び出し(num, R, G, B)

  sm.put(ar, 8)   # 点灯実行(NeoPixel制御パルス出力)
  time.sleep_ms(100)  # 遅延時間

 5〜7行目 35〜61行目がNeoPixelの色を指定するプログラムでそれ以外はNeoPixelを制御するために毎回使用するプログラムのためそのまま書いておきます。

 37行目でボタンを接続しているGP20を入力端子に設定し「if文」を使用して、ボタンを押した回数に応じてNeoPixcelの色を指定しています。


  ③ボリュームで色変更

「Python」で外付けのボリュームを回転させることで1個のNeoPixelを赤〜緑〜青〜赤に変化させるサンプルプログラムは以下のようになります。

コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

import array, time
from machine import Pin
import rp2

# NeoPixel WS2812Bの指定
NUM_LEDS = 1  # NeoPixelの数
LED_PIN = 0   # NeoPixel信号接続端子

# 以下はNeoPixelを使用するための設定、このまま書いておく ---------------------------
# NeoPixcel WS2812の制御タイミングに合わせたパルスを生成するための設定をアセンブラで指定
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
def ws2812():    
  T1 = 2
  T2 = 5
  T3 = 3
  wrap_target()
  label("bitloop")
  out(x, 1) .side(0) [T3 - 1]
  jmp(not_x, "do_zero") .side(1) [T1 - 1]
  jmp("bitloop") .side(1) [T2 - 1]
  label("do_zero")
  nop() .side(0) [T2 - 1]
  wrap()
# クラスStateMachineを使用して、正確なパルスを出力するための設定を行う
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(LED_PIN))
# 設定したクラスStateMachineを有効にして使えるようにする。
sm.active(1)
# LEDのRGBの値を指定する24bit(8bit x 3)の配列をNeoPixelの数で準備
ar = array.array("I", [0 for _ in range(NUM_LEDS)])

# NeoPixel点灯処理関数、このまま書いておく ------------------------------------
def drawpix(num, r, g, b):
  bright = 0.1  # Neopixelの明るさ設定(MAX1.0)
  r = int(r * bright)   # 赤色LEDの値
  g = int(g * bright)   # 緑色LEDの値
  b = int(b * bright)   # 青色LEDの値
  ar[num] = g << 16 | r << 8 | b  # NeoPixel制御パルス用の24bitデータを左ビットシフトとORで生成

# 以下に点灯させる処理を記入--------------------------------------------------
# ADC設定
adc = machine.ADC(2)  # GP28(ADC2)をADC設定

while True: # ずっと繰り返し
  # アナログ入力処理
  adc_val = adc.read_u16()   # アナログ入力値取得(0〜65535)
  # ボリュームの値でLED色可変
  r = 0
  g = 0
  b = 0
  if adc_val <= 21845:     # アナログ値が21845より小さいなら赤、緑指定
    g = (adc_val / 85.6667)           # 緑を指定(0~255へ換算)
    r = 255 - g                       # 緑が明るくなったら赤を暗く
  elif adc_val > 21845 and adc_val <= 43690:  # アナログ値が21845以上43690より小さいなら赤、緑指定
    b = ((adc_val - 21845) / 85.6667) # 青を指定(0~255へ換算)
    g = 255 - b                       # 青が明るくなったら緑を暗く
  elif adc_val > 43690:  # アナログ値が21845以上なら青、赤指定
    r = ((adc_val -43690) / 85.6667)  # 赤を指定(0~255へ換算)
    b = 255 - r                       # 赤が明るくなったら青を暗く
  
  drawpix(0, r, g, b) # LED点灯処理

  sm.put(ar, 8)   # NeoPixel制御パルス出力
  time.sleep_ms(100)

 5〜7行目 39〜62行目がNeoPixelの色を指定するプログラムでそれ以外はNeoPixelを制御するために毎回使用するプログラムのためそのまま書いておきます。

ボリュームのAD変換値を3等分し、赤緑青の明るさ指定値に割り当てることで、ボリュームの変化に応じてNeoPixelの点灯色を変化させます。

AD変換値を0〜255に換算して、NeoPixelの赤緑青の明るさ指定値に使用しています。
このため明るさの指定値が最大255になり明るすぎる(電流が大きくなりすぎる)ため 33〜36行目の「bright = 0.1」を使用して明るさの倍率を小さく(1.0 → 0.1)しています。


  ④LEDテープライト全点灯

「Python」でLEDテープライトを全て同じ色に点灯させるサンプルプログラムは以下のようになります。

コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

import array, time
from machine import Pin
import rp2

# NeoPixel WS2812Bの指定
NUM_LEDS = 60  # NeoPixelの数
LED_PIN = 0    # NeoPixel信号接続端子

# 以下はNeoPixelを使用するための設定、このまま書いておく ---------------------------
# NeoPixcel WS2812の制御タイミングに合わせたパルスを生成するための設定をアセンブラで指定
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
def ws2812():    
  T1 = 2
  T2 = 5
  T3 = 3
  wrap_target()
  label("bitloop")
  out(x, 1) .side(0) [T3 - 1]
  jmp(not_x, "do_zero") .side(1) [T1 - 1]
  jmp("bitloop") .side(1) [T2 - 1]
  label("do_zero")
  nop() .side(0) [T2 - 1]
  wrap()
# クラスStateMachineを使用して、正確なパルスを出力するための設定を行う
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(LED_PIN))
# 設定したクラスStateMachineを有効にして使えるようにする。
sm.active(1)
# LEDのRGBの値を指定する24bit(8bit x 3)の配列をNeoPixelの数で準備
ar = array.array("I", [0 for _ in range(NUM_LEDS)])

# NeoPixel点灯処理関数、このまま書いておく ------------------------------------
def drawpix(num, r, g, b):
  ar[num] = g << 16 | r << 8 | b  # NeoPixel制御パルス用の24bitデータを左ビットシフトとORで生成

# 以下に点灯させる処理を記入--------------------------------------------------
# LEDテープライトを全て同じ色に点灯
# 全てのLEDのRGB(赤緑青)の明るさ0〜255(30程でも十分明るい)をfor文で連続で指定
for i in range(0, NUM_LEDS):
  drawpix(i, 10, 10, 10) # LED点灯処理関数呼び出し(num, R, G, B)

sm.put(ar, 8)   # 点灯実行(NeoPixel制御パルス出力)
time.sleep_ms(100)

 5〜7行目 35〜41行目がNeoPixelの色を指定するプログラムでそれ以外はNeoPixelを制御するために毎回使用するプログラムのためそのまま書いておきます。

「for文」を使用して全てのNeoPixelの色を連続的に指定しています。


  ⑤ドットマトリクスLEDを好きなパターンで点灯

「Python」でドットマトリクスLEDを好きなパターン、好きな色で点灯させるサンプルプログラムは以下のようになります。

コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

import array, time
from machine import Pin
import rp2

# NeoPixel WS2812Bの指定
NUM_LEDS = 64   # NeoPixelの数
LED_PIN = 0     # NeoPixel信号接続端子
MATRIX_LINE = 8 #  ドットマトリックスの行列の数を指定(8なら8×8)

# 以下はNeoPixelを使用するための設定、このまま書いておく --------------------------------
# NeoPixcel WS2812の制御タイミングに合わせたパルスを生成するための設定をアセンブラで指定
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
def ws2812():    
  T1 = 2
  T2 = 5
  T3 = 3
  wrap_target()
  label("bitloop")
  out(x, 1) .side(0) [T3 - 1]
  jmp(not_x, "do_zero") .side(1) [T1 - 1]
  jmp("bitloop") .side(1) [T2 - 1]
  label("do_zero")
  nop() .side(0) [T2 - 1]
  wrap()
# クラスStateMachineを使用して、正確なパルスを出力するための設定を行う
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(LED_PIN))
# 設定したクラスStateMachineを有効にして使えるようにする。
sm.active(1)
# LEDのRGBの値を指定する24bit(8bit x 3)の配列をNeoPixelの数で準備
ar = array.array("I", [0 for _ in range(NUM_LEDS)])

# NeoPixel点灯処理関数、このまま書いておく --------------------------------------------
def drawpix(num, r, g, b):
  ar[num] = g << 16 | r << 8 | b  # NeoPixel制御パルス用の24bitデータを左ビットシフトとORで生成

# 以下に点灯させる処理を記入----------------------------------------------------------
# ドットマトリックスの色パターンをお絵描き感覚で指定。
# LEDマトリクス表示指定配列(0:消灯、1以上:色指定配列で指定した色に指定(color配列1次要素番号))
matrix = [[0]* MATRIX_LINE]* MATRIX_LINE # ドットマトリックスの縦×横の数に合わせて2重配列を準備
# 以下の2重配列の点灯させたい場所に色番号を指定
matrix = [[3,3,3,0,0,3,3,3],
          [0,3,3,1,1,3,3,0],
          [0,1,1,2,2,1,1,0],
          [2,1,1,2,2,1,1,2],
          [1,2,2,1,1,2,2,1],
          [2,1,1,2,2,1,1,2],
          [0,1,1,2,2,1,1,0],
          [0,0,2,1,1,2,0,0]] # ラズベリー?

# 色指定配列(1次要素を色番号として表示する色を2次要素の3原色[赤、緑、青]で設定)
color_list = [[0]* 3]* 6  # 色格納配列(色数分のRGBの組み合わせを2次元配列で準備)
#     LED色: [[0:消灯] , [1:ピンク], [2:オレンジ], [3:グリーン], [4:パープル], [5:ホワイト]]
color_list = [[0, 0, 0], [50, 0, 5], [6, 1, 3], [5, 15, 0], [10, 0, 20], [10, 10, 10]]

# ドットマトリックスの縦横のLEDの色を2重ループで指定
num = 0;  # matrix配列の色番号格納用
for i in range(0, MATRIX_LINE):     # matrix 行ループ
  for j in range(0, MATRIX_LINE):   # matrix 列ループ
    num = matrix[i][j];   # matrix配列の色番号取得
    # matrix行ごと(0,8,16,24,32,40,48,56)に左から右へ色番号の色で表示
    drawpix((i * MATRIX_LINE) + j, color_list[num][0], color_list[num][1], color_list[num][2]) # LED点灯処理関数呼び出し

sm.put(ar, 8)   # NeoPixel制御パルス出力
time.sleep_ms(100)  # 遅延時間

 5〜8行目 36〜63行目がNeoPixelの色を指定するプログラムでそれ以外はNeoPixelを制御するために毎回使用するプログラムのためそのまま書いておきます。

 53行目color_list」配列で指定した色([赤,緑,青]で指定)の色番号を 41行目matrix」配列に記入することでその場所の色を指定することができます。

今回は8×8のドットマトリクスLEDを使用しましたが、数量(行列の数)が変わる場合は 8行目の「MATRIX_LINE」の設定値を変更して「matrix」配列の各要素の数も合わせて変更します。

5.C言語(ArduinoIDE)サンプルプログラム

「C言語」を使用したサンプルプログラムについて紹介します。
開発環境は「ArduinoIDE」を使用しました。
ライブラリとして「Adafruit_NeoPixel」を使用しているので、別途インストールしておいてください。


「ArduinoIDE」のインストールから使い方については以下のリンクで詳しく紹介しています。

ラズパイPico/Pico WのArduinoIDEインストール方法と初期設定、使い方紹介
Raspberry Pi Pico/Pico WのC言語での開発環境 ArduinoIDEのインストールから初期設定、使い方、Lチカでの動作確認まで詳しく紹介します。

ライブラリのインストール方法は以下のリンクを参考にしてください。

M5StackシリーズのためのArduino IDEのインストール方法と初期設定、使い方紹介
ArduinoIDEバージョン2のインストール方法から初期設定、スケッチ例の書き込み、コピペでの使い方まで詳しく紹介します。インストールはArduinoでも同じです。

  ①シンプルに1個点灯

「C言語」で「NeoPixel」をシンプルに1個点灯させるプログラムは以下のようになります。

コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

#include <Adafruit_NeoPixel.h>  // NeoPixel制御用ライブラリの準備

// NeoPixel WS2812Bの指定
#define NUM_LEDS  1  // NeoPixelの数
#define LED_PIN   0  // NeoPixel信号接続端子

// NeoPixcelライブラリの設定、このまま書いておく-----------------------
// NeoPixel用の stripオブジェクトを宣言(LEO_GRB + NEO_KHZ800 は NeoPixel WS2812 使用の場合の設定)
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// 初期設定、このまま書いておく --------------------------------------
void setup() {
  // NeoPixel(WS2812)初期設定
  strip.begin();      // NeoPixel初期化
  strip.show();       // NeoPixcelを全て消灯
  strip.setBrightness(255);  // 明るさ倍率設定 (RGB設定値 * 明るさ倍率、最大255)
}
// 以下に点灯させる処理を記入-----------------------------------------
// 1個を白色点灯(複数ある場合は最初の1番目のみ点灯)
void loop() {
  // 点灯させたいNeoPixelの番号(num)とRGB(赤緑青)の明るさを0〜255(30程でも十分明るい)で指定
  strip.setPixelColor(0, strip.Color(10, 10, 10)); // LED発光色指定(num,strip.Color(R,G,B))※RGB:0〜255

  strip.show(); // 点灯実行(NeoPixel制御パルス出力)
  delay(100);   // 遅延時間
}

 3〜5行目 18〜24行目がNeoPixelの色を指定するプログラムでそれ以外はNeoPixelを制御するために毎回使用するプログラムのためそのまま書いておきます。

NeoPixelの制御には「Adafruit_NeoPixel」ライブラリを使用して以下のように行います。

strip.setPixelColor( NeoPixel番号, strip.Color( 赤設定値, 緑設定値, 青設定値 ) ) ;

NeoPixcel番号:点灯させたいNeoPixelの番号を指定(1番目は0から始まる)
赤設定値:赤色LEDの明るさを0〜255の値で指定
緑設定値:緑色LEDの明るさを0〜255の値で指定
青設定値:青色LEDの明るさを0〜255の値で指定
※LEDの明るさの指定値は30程度で十分明るいです。

 24行目の「strip.show();」が実行されると制御信号が出力されて、NeoPixelが指定通りの色で点灯します。


  ②ボタンを押すたびに色変更

「C言語」で1個のNeoPixelをボタンを押すたびに赤→緑→青→白と変更させるサンプルプログラムは以下のようになります。

コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

#include <Adafruit_NeoPixel.h>  // NeoPixel制御用ライブラリの準備

// NeoPixel WS2812Bの指定
#define NUM_LEDS  1 // NeoPixelの数
#define LED_PIN   0 // NeoPixel信号接続端子

// 変数宣言
int cnt = 0;        // ボタンON回数カウント用
bool state = false; // ボタン状態格納用

// NeoPixcelライブラリの設定、このまま書いておく-----------------------
// NeoPixel用の stripオブジェクトを宣言(LEO_GRB + NEO_KHZ800 は NeoPixel WS2812 使用の場合の設定)
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// 初期設定、このまま書いておく --------------------------------------
void setup() {
  // NeoPixel(WS2812)初期設定
  strip.begin();              // NeoPixel初期化
  strip.show();               // NeoPixcelを全て消灯
  strip.setBrightness(255);   // 明るさ倍率設定 (RGB設定値 * 明るさ倍率、最大255)
  // 入力設定
  pinMode(20, INPUT_PULLUP);  // GP20を入力端子(プルアップ)に設定
}
// 以下に点灯させる処理を記入-----------------------------------------
// 1個のLEDの色をボタンを押すたびに変更(複数ある場合は最初の1番目のみ使用)
void loop() {
  // ボタン回数カウント
  if (digitalRead(20) == 0 && state == false) { // GP20がONでstateがfalseなら
    state = true; // stateをtrueに
    cnt++;        // ボタン回数カウント+1
  }
  if (digitalRead(20) == 1) {                   // GP20がOFFなら
    state = false;  // stateをfalseに
  }
  // ボタン回数カウントリセット
  if (cnt == 4) { // ボタン回数カウントが4なら
    cnt = 0;      // 0リセット
  }

  // LED点灯処理
  switch (cnt) {  // cntの値によって分岐処理
  case 0: // cntが0なら白点灯
    strip.setPixelColor(0, strip.Color(10, 10, 10)); // LED点灯処理
    break;
  case 1: // cntが1なら赤点灯
    strip.setPixelColor(0, strip.Color(30, 0, 0));  // LED点灯処理
    break;
  case 2: // cntが2なら緑点灯
    strip.setPixelColor(0, strip.Color(0, 30, 0));  // LED点灯処理
    break;
  case 3: // cntが3なら青点灯
    strip.setPixelColor(0, strip.Color(0, 0, 30));  // LED点灯処理
    break;
  }

  strip.show(); // NeoPixel 発光色更新
  delay(100);   // 遅延時間
}

 3〜5行目 24〜56行目がNeoPixelの色を指定するプログラムでそれ以外はNeoPixelを制御するために毎回使用するプログラムのためそのまま書いておきます。

 21,22行目でボタンを接続しているGP20を入力端子に設定し「switch文」を使用して、ボタンを押した回数に応じてNeoPixcelの色を指定しています。


  ③ボリュームで色変更

「C言語」で外付けのボリュームを回転させることで1個のNeoPixelを赤〜緑〜青〜赤に変化させるサンプルプログラムは以下のようになります。

コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

#include <Adafruit_NeoPixel.h>  // NeoPixel制御用ライブラリの準備

// NeoPixel WS2812Bの指定
#define NUM_LEDS  1 // NeoPixelの数
#define LED_PIN   0 // NeoPixel信号接続端子

// 変数宣言
int r = 0;    // 赤LED指示値
int g = 0;    // 緑LED指示値
int b = 0;    // 青LED指示値
float an_val; // AD変換値格納用

// NeoPixcelライブラリの設定、このまま書いておく-----------------------
// NeoPixel用の stripオブジェクトを宣言(LEO_GRB + NEO_KHZ800 は NeoPixel WS2812 使用の場合の設定)
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// 初期設定、このまま書いておく --------------------------------------
void setup() {
  // NeoPixel(WS2812)初期設定
  strip.begin();      // NeoPixel初期化
  strip.show();       // NeoPixcelを全て消灯
  strip.setBrightness(30);  // 明るさ倍率設定 (RGB設定値 * 明るさ倍率、最大255)
}
// 以下に点灯させる処理を記入-----------------------------------------
// 外付けボリュームからのAD変換の値でLEDの色を連続的に変更
void loop() {
  // アナログ入力処理
  an_val = analogRead(28);  //アナログ換算値(0~1024)取得

  //LED色可変
  if (an_val <= 341) {   //アナログ値が341以下なら赤、緑指定
    g = (an_val / 1.337);             //緑を指定(0~255へ換算)
    r = 255 - g;                      //緑が明るくなったら赤を暗く
  } else if (an_val > 341 && an_val <= 682) {
                //アナログ値が341より大きく682以下なら青、緑指定
    b = ((an_val - 341) / 1.337);     //青を指定(0~255へ換算)
    g = 255 - b;                      //青が明るくなったら緑を暗く
  } else if (an_val > 682) { //アナログ値が682より大きければ青、赤指定
    r = ((an_val -682) / 1.337);      //赤を指定(0~255へ換算)
    b = 255 - r;                      //赤が明るくなったら青を暗く
  }
  strip.setPixelColor(0, strip.Color(r, g, b));  // LED点灯処理

  strip.show(); // NeoPixel 発光色更新
  delay(100);   // 遅延時間
}

 3〜11行目 24〜44行目がNeoPixelの色を指定するプログラムでそれ以外はNeoPixelを制御するために毎回使用するプログラムのためそのまま書いておきます。

ボリュームのAD変換値を3等分し、赤緑青の明るさ指定値に割り当てることで、ボリュームの変化に応じてNeoPixelの点灯色を変化させます。

AD変換値を0〜255に換算して、NeoPixelの赤緑青の明るさ指定値に使用しています。
このため明るさの指定値が最大255になり明るすぎる(電流が大きくなりすぎる)ため 22行目の「strip.setBrightness(30);」を使用して明るさの倍率を小さく(255 → 30)しています。


  ④LEDテープライト全点灯

「C言語」でLEDテープライトを全て同じ色に点灯させるサンプルプログラムは以下のようになります。

コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

#include <Adafruit_NeoPixel.h>  // NeoPixel制御用ライブラリの準備

// NeoPixel WS2812Bの指定
#define NUM_LEDS  60  // NeoPixelの数
#define LED_PIN    0  // NeoPixel信号接続端子

// NeoPixcelライブラリの設定、このまま書いておく-----------------------
// NeoPixel用の stripオブジェクトを宣言(LEO_GRB + NEO_KHZ800 は NeoPixel WS2812 使用の場合の設定)
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// 初期設定、このまま書いておく --------------------------------------
void setup() {
  // NeoPixel(WS2812)初期設定
  strip.begin();      // NeoPixel初期化
  strip.show();       // NeoPixcelを全て消灯
  strip.setBrightness(255);  // 明るさ倍率設定 (RGB設定値 * 明るさ倍率、最大255)
}
// 以下に点灯させる処理を記入-----------------------------------------
// LEDテープライトを同じ色で全点灯
void loop() {
  // for文で全てのNeoPixelのRGB(赤緑青)の明るさを0〜255(30程でも十分明るい)で指定
  for (int i = 0; i < NUM_LEDS; i++) {
    strip.setPixelColor(i, strip.Color(30, 30, 30)); // LED発光色指定(num,strip.Color(R,G,B))※RGB:0〜255
  }
  strip.show(); // 点灯実行(NeoPixel制御パルス出力)
  delay(100);
}

 3〜5行目 18〜25行目がNeoPixelの色を指定するプログラムでそれ以外はNeoPixelを制御するために毎回使用するプログラムのためそのまま書いておきます。

「for文」を使用して全てのNeoPixelの色を連続的に指定しています。


⑤ドットマトリクスLEDを好きなパターンで点灯

「C言語」でドットマトリクスLEDを好きなパターン、好きな色で点灯させるサンプルプログラムは以下のようになります。

コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

#include <Adafruit_NeoPixel.h>  // NeoPixel制御用ライブラリの準備

// NeoPixel WS2812Bの指定
#define NUM_LEDS  64    // NeoPixelの数
#define LED_PIN    0    // NeoPixel信号接続端子
#define MATRIX_LINE  8  // ドットマトリックスの行列の数を指定(8なら8×8)

// NeoPixcelライブラリの設定、このまま書いておく-----------------------
// NeoPixel用の stripオブジェクトを宣言(LEO_GRB + NEO_KHZ800 は NeoPixel WS2812 使用の場合の設定)
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// 初期設定、このまま書いておく --------------------------------------
void setup() {
  // NeoPixel(WS2812)初期設定
  strip.begin();      // NeoPixel初期化
  strip.show();       // NeoPixcelを全て消灯
  strip.setBrightness(255);  // 明るさ倍率設定 (RGB設定値 * 明るさ倍率、最大255)
}
// 以下に点灯させる処理を記入-----------------------------------------
// ドットマトリックスの色パターンをお絵描き感覚で指定。
void loop() {
  // ドットマトリックスの縦×横の数に合わせて2重配列を準備
  // LEDマトリクス表示指定配列(0:消灯、1以上:色指定配列で指定した色に指定(color配列の1次要素番号))
  // 以下の2重配列の点灯させたい場所に色番号を指定
  int matrix[MATRIX_LINE][MATRIX_LINE] = {{3,3,3,0,0,3,3,3},
                                          {0,3,3,1,1,3,3,0},
                                          {0,1,1,2,2,1,1,0},
                                          {2,1,1,2,2,1,1,2},
                                          {1,2,2,1,1,2,2,1},
                                          {2,1,1,2,2,1,1,2},
                                          {0,1,1,2,2,1,1,0},
                                          {0,0,2,1,1,2,0,0}}; // ラズベリー?

  // 色指定配列(1次要素を色番号として表示する色を2次要素の3原色{赤、緑、青}で設定)
  //        LED色: {{0:消灯}  , {1:ピンク}, {2:ピンク(暗)}, {3:グリーン}, {4:パープル}, {5:ホワイト}}
  int color[][3] = {{0, 0, 0}, {50, 0, 5}, {6, 1, 3}, {5, 15, 0}, {10, 0, 20}, {10, 10, 10}};

  // ドットマトリックスの縦横のLEDの色を2重ループで指定
  int num = 0;  //matrix配列の色番号格納用
  for (int i = 0; i < MATRIX_LINE; i++) {     //matrix行ループ
    for (int j = 0; j < MATRIX_LINE; j++) {   //matrix列ループ
      num = matrix[i][j];           //matrix配列の色番号取得
      //matrixの行ごと(0,8,16,24,32,40,48,56)に左から右へ色番号の色で表示
      strip.setPixelColor(i * MATRIX_LINE + j, strip.Color(color[num][0], color[num][1], color[num][2])); // LED発光色指定
    }
  }
  strip.show(); // 点灯実行(NeoPixel制御パルス出力)
  delay(100);   //遅延時間
}

 3〜5行目 19〜45行目がNeoPixelの色を指定するプログラムでそれ以外はNeoPixelを制御するために毎回使用するプログラムのためそのまま書いておきます。

 36行目color」配列で指定した色([赤,緑,青]で指定)の色番号を 25行目matrix」配列に記入することでその場所の色を指定することができます。

今回は8×8のドットマトリクスLEDを使用しましたが、数量(行列の数)が変わる場合は 6行目の「MATRIX_LINE」の設定値を変更して「matrix」配列の各要素の数も合わせて変更します。

6.まとめ

フルカラーLEDのNoePixelを1個点灯させる方法から、テープライトの使い方やドットマトリクスLEDをお絵描き感覚で好きなパターンで点灯させる方法まで紹介しました。

NeoPixelはマイコン内蔵のフルカラーLEDで、24bitの制御信号で赤緑青の明るさを指定して使用します。
制御信号の生成は自力では大変なため、マイコンボードごとに用意されているライブラリ等を使用すると簡単に制御することができます。

まずは1個を点灯させる方法が確認できたら、あとは「For文」や「配列」を使用して連続的に指定するだけなので、NeoPixelを使い始めるときは、1個点灯させる方法を先に確認しておきましょう。

コメント

  1. justplaty より:

    初歩的な質問で恐れ入りますが、5VのNeoPixelと3.3Vのラズパイpicoをつなぐ中間にレベルシフターをかませる必要はありませんでしょうか? 現在作成途中で悩んでおります。

    • logikara より:

      コメントありがとうございます。
      レベルシフターなしでも動作は可能でしたが安定動作を考えるとあった方が良いです。

      WS2812Bのデータシートでは、制御信号のHighレベルは0.7Vddとなっていますので
      5Vの場合は 0.7×5で3.5Vとなり保証範囲外となります。
      ご使用のNeoPixelや数量、供給電源によっては動作しない可能性もありますのでレベルシフターをご使用するか
      NeoPixelが3.3V〜対応しておれば別電源(電流容量にご注意ください)で3.3Vを供給してご使用すると良いかと思います。

  2. justplaty より:

    ご教示大変ありがとうございました。引き続きこちらのサイトで勉強させていただきます。

タイトルとURLをコピーしました