Uncategorized

【ラズパイ初心者】#4 流れるLEDを作る

流れるLEDを作ろう

前回はボタンでLEDの制御をしました。

今回は、複数のLEDを制御して流れるLEDを作ってみます。流れるウィンカーみたいな感じ。

Amazonで買ったfreenoveのスターターセットを使います。その中のLED bar graphというのを使うのですが、これは10個のLEDが組み込まれたものです。2列のピンがそれぞれ対になっていて、使い方としては通常の単一LEDと同じです。

用意するもの

  • raspberry pi pico 2w
  • USB ケーブル
  • ブレッドボード
  • ジャンパーワイヤー×11
  • LED bar graph
  • 抵抗220Ω×10

回路作成

それではチュートリアルの完成図や回路図を見ながら回路を作っていきます。

まずはLED barをraspberry pi pico2wの隣にセットします。真ん中の溝をまたぐような形でセットしてください。

次にジャンパーワイヤーでpico2wとLED barの上側を繋いでいきます。pico側の使うピンは上の図をよくみてくださいね。GPIOの16,17,18,19,20,21,22,26,27,28です。

ジャンパーワイヤーを挿す時、隣同士に10個挿すのは狭くてやりかったので、こんな感じで交互に挿してみました。

次は抵抗を付けていきます。LED barの下側から、−のエリアに抵抗を繋いでいきます。こうすることで抵抗を−エリアにまとめることができるので、GNDに繋ぐ配線が1本で済みます。抵抗の向きは揃えておくと美しいです。足の曲げ方が適当なのは許してください。笑

最後に、−エリアからpico2wのGNDへ配線します。このGNDはどこでも大丈夫です。四角に囲ってあるピンがGNDです。

これで回路完成です!

プログラムの作成

次はプログラムを作成していきます。

まずは、raspberry pi pico2wをパソコンに繋いで、freenoveのチュートリアルフォルダから03.1_Flowinglight.pyをThonnyで開きます。

こんな感じのプログラムが開けるので、raspberry pi pico2wに名前をつけて保存します。ファイル名は03_1_FlowingLight.pyとしました。

これで準備完了です。では動かしてみましょう!

できました!せっかくなので、プログラムを少しいじってみます。

time.sleep_ms(100)の100ところを4ヶ所全て10にしてみました。

動きがめちゃくちゃ早くなりましたね。

300にすると、かなりゆっくりになりました。

帰りだけ早くしちゃったり。(行きは300で帰りは50)

自由にスピードに変えることができますね。皆さんもぜひ自分で作って色々スピード変えて試してみてください!

失敗例

成功するまでに何度か失敗しているので共有しておきます。

  1. LEDが点かない
  2. 1ヶ所だけLEDが点かない

①はLED barの向きが逆になっていたのが原因でした。チュートリアルの注意書きにも、向きがランダムなので点かなかったら向きを変えてくださいと書いてありました。

②は抵抗をいじっていたら直ったので、抵抗の接触が悪かったのが原因でした。他にも抵抗の足が別の抵抗の足に接触していたらうまくLEDが点きませんでしたので、そのあたりを試してみてください。

プログラム解説

from machine import Pin
import time

pins = [16, 17, 18, 19, 20, 21, 22, 26, 27, 28]
def showLed():
    for pin in pins:
        print(pin)
        led = Pin(pin, Pin.OUT)
        led.value(1)
        time.sleep_ms(300)
        led.value(0)
        time.sleep_ms(300)        
    for pin in reversed(pins):
        print(pin)
        led = Pin(pin, Pin.OUT)
        led.value(1)
        time.sleep_ms(50)
        led.value(0)
        time.sleep_ms(50)
          
while True:
    showLed()

from machine import Pin

→machineモジュールの中のPinをインポートして入出力ピンを使えるようにしている。

import time

→timeをインポートして、時間の調整ができる能力をセットしている。

pins=[16,17,18,19,20,21,22,26,27,28]

→pinsという名前の変数に数字のリストを代入している。ここのピンを使うよということ。

def showLed()

→showLedという関数を定義している。定義しておくことで、後で関数を呼び出すときにもう1回コードを書かなくて済む。

for pin in pins:

→pinsというリスト内の数字(ピン番号)を一つずつ取り出してpinという変数に入れて処理を繰り返す。

print(pin)

→今使っているピンを表示する。Thonnyのシェルのところに表示される

led=Pin(pin,Pin.OUT)

→そのピンを出力モードに設定

led.value(1)

→LEDを点灯

time.sleep_ms(300)

→300ミリ秒待つ

led.value(0)

→LEDを消灯

for pin in reversed(pins):

→pinsのリストの順番を逆にしてループする

While True:

→ずっと繰り返して実行する

showLed()

→showLedという関数を実行する

おまけ(ボタンで制御)

これを前回のボタンと組み合わせて、ボタンでスタート・ストップしてみようかな。

ボタンの配置は、#3の時のものを参考にこんな感じで配線してみました。

プログラムをどうしたらいいのか分からなくて、AIに聞いてみました。

最初に上のプログラムをAIに見せたら、流れるLEDであることは理解してくれました。次に、このプログラムをボタンでスタートストップしたいとAIに聞いてみました。言われた通りにプログラムを作成してやってみましたが、ボタンを押してもスタートしませんでした。

この結果もAIに報告すると、次はボタンだけ作動するかの確認用プログラムが送られてきました。次はそれでやってみたのですが、ボタンの反応はありませんでした。

ここで手が止まったのですが、ボタンの入力のコードのところがこれまでの入力方法と違っているのが気になりました。

button = Pin(13, Pin.IN, Pin.PULL_UP)

なんかこんな感じでPULL_UPというのがついていました。今までこんなものはつけたことがなかったので、消してみました。

すると、ボタンでのスタートができるようになりました!

ですが、ボタンでのストップができませんでした。

この状況をAIに報告したら、改善されたプログラムが送られて来ました。どうやら、一通りLEDの動きが終わったタイミングでしたかストップの入力を受け入れるタイミングがない状態だったみたいです。LEDが流れている間でもボタンの状態をチェックして、ボタンが押されたらLEDを止めるプログラムに変更してみました。

これでストップもできました!ストップの時は気持ち長押ししないと反応しないけど、まあいいか。

プログラム紹介

from machine import Pin
import time

pin_numbers = [16, 17, 18, 19, 20, 21, 22, 26, 27, 28]
leds = [Pin(pin, Pin.OUT) for pin in pin_numbers]
button = Pin(13, Pin.IN)

running = False
last_button_state = 1

def check_button():
    global running, last_button_state
    current = button.value()
    if last_button_state == 1 and current == 0:
        running = not running
        print("状態切り替え:", "スタート" if running else "ストップ")
        time.sleep_ms(200)
    last_button_state = current

def showLed():
    for led in leds:
        if not running:
            break
        led.value(1)
        time.sleep_ms(300)
        led.value(0)
        time.sleep_ms(300)
        check_button()
    for led in reversed(leds):
        if not running:
            break
        led.value(1)
        time.sleep_ms(50)
        led.value(0)
        time.sleep_ms(50)
        check_button()

while True:
    check_button()
    if running:
        showLed()

pin_numbersとかledsはAIによって省略するために定義されています。

running〜

LEDの動作中かどうかを示す。

last_button_state

前回のボタン状態を記録している。ボタンの状態が切り替わりを検知してスタート・ストップを切り替えたい。

def check_button〜

ボタンの状態をチェックする関数を定義している。ボタンが押された瞬間を検知してrunningを切り替えている。

showLed〜

最初のプログラムとほとんどおなじ。各点灯の間にボタンチェックを入れているので、どのタイミングでもボタンで止められるようになっている。

while True〜

常にボタンをチェックして、runningがTRUEの時にshowLedを実行するというループ。

ABOUT ME
よしお
ラズパイ初心者です。 プログラミングも初心者ですが、ラズパイで電子工作にチャレンジしています。
CTAサンプル

これはCTAサンプルです。
内容を編集するか削除してください。