デアゴ ミレニアムファルコン作製記 Episode 054 [Raspberry Piで多数のLEDの制御ができた!]

デアゴ ファルコン
この記事は約10分で読めます。

これまで作ってきた電飾回路は、ほとんどPICの出力ピン1本に対して、PICの出力電圧5.0Vの範囲で発光できるLEDの本数(白・青は1本、その他は2~3本)をつなげる感じで作っていました。

たくさんのLEDを接続する方法

コクピット、廊下照明、船倉については、ホログラムチェステーブルやコンピュータ類に加えて、どうやら間接照明や点検口下など、組み上げていくうちに必要なLEDがどんどん増えています。

更に、タラップ昇降などこの先も電流を多く消費するような仕組みも追加される予定のため、配布された電池ボックス(1.5V×単三電池4本=6.0V)から取れる電流を考えると、力不足感が否めません。

昇圧コンバータによる10個直列接続

先日動作確認を行った、10個のLEDを直列接続を可能とする昇圧コンバータモジュールでの実装は、割とすんなりできました。

 

ただし、この接続だと、10個の点滅は同時に点灯・消灯を行うことしかできません。

 

 

IMG_7449

例えば、廊下の照明などに用途があります。

 

8ビットシフトレジスタで、机上論理で無制限のLED制御が可能

PICを複数のPICを用いてLEDの数を増やすことはできますが、PIC同士の連携など考えると回路が複雑になってしまいます。

先日入手してRaspberry piの入門書を見ていたところ、SN74HC595NというIC(8ビットシフトレジスタ)を使えば、より多くのLEDを制御できる事を知りました。

誤解を恐れずだいたいの動きを説明すると、8ビットシフトレジスタは、8つの端子のON/OFFが制御できるICチップです。これを連結して接続することで、実質的にプログラムから多数のLEDを別々に制御することが可能になります。

こちらのサイト様も参考になります。

 

さっそく部品を取り寄せ、やってみました。

2つのレジスタを連結し、電源を除くとRaspberry側の端子を3つ使うだけで、8×2、16個のLEDをプログラム(Raspberryの推奨のPython使用)から自由にコントロールできるようになりました。

これは、コクピット・船倉、廊下、外殻のポジションランプ、クチバシのライト等、すべてをRaspberry Piからコントロールできる事を意味します。

10連LEDや既に作り上げたPICに対しては、このシフトレジスタからのHIGHの信号をこれらのスイッチとして認識させれば良いと考えています。

更に、Raspberry Piをサーバとして動作させればスマホからの操作も可能となります。

なので、ファルコンにRaspberry piが仕込めるかどうかは分かってませんが、面白そうなので突っ走ってます。

あと、この動画ではRaspberry piの3.3VポートからLEDの電源を確保していますが、将来的には不足してしまうため、別の方法(外部から電源を確保する)を模索中です。

 

外部電源の取得(7/16 19:30追記)

16番PIN(Vcc)への電源供給を、ACアダプター(5.0V 1.0A)から供給したら、うまく動きました。

回路図は次の様になりました。

RaspberryPi+SN74HC595N

  • 抵抗は、全て330Ω
  • Vccへ、外部電源(5.0V 1.0A)のACアダプタを接続

 

このように、SN74HC595Nを直列に接続していくことで多数ののLEDが増設でき、しかも点滅制御も可能になります。

 

ランダム点滅プログラム(Python)

とりあえず、プログラムを貼っときます。コメントアウトした変数、LEDdata99(99は1~16)に置き換えると、1個が流れるように光るパターンに変更できます。

レジスタの格納順序が逆になるため、配列を逆から見たパターンがセットされるため、ループ内の変数は、後ろ側からセットしています。これは直感的でないので、反転するプログラムがあると楽かも。後日の課題とします。

import RPi.GPIO as GPIO
from time import sleep

def sendLEDdata(data, ser, rclk, srclk):
    n = len(data)

    GPIO.output(rclk, GPIO.LOW)
    GPIO.output(srclk, GPIO.LOW)

    for i in range(n):
        if data[i] == 1:
            GPIO.output(ser, GPIO.HIGH)
        else:
            GPIO.output(ser, GPIO.LOW)

        GPIO.output(srclk, GPIO.HIGH)
        GPIO.output(srclk, GPIO.LOW)

    GPIO.output(rclk, GPIO.HIGH)
    GPIO.output(rclk, GPIO.LOW)

SER = 25
RCLK = 24
SRCLK = 23

GPIO.setmode(GPIO.BCM)
GPIO.setup(SER, GPIO.OUT)
GPIO.setup(RCLK, GPIO.OUT)
GPIO.setup(SRCLK, GPIO.OUT)

#LEDdata1 = [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
#LEDdata2 = [0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
#LEDdata3 = [0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0]
#LEDdata4 = [0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0]
#LEDdata5 = [0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0]
#LEDdata6 = [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0]
#LEDdata7 = [0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0]
#LEDdata8 = [0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0]
#LEDdata9 = [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0]
#LEDdata10 =[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0]
#LEDdata11 =[0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0]
#LEDdata12 =[0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0]
#LEDdata13 =[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
#LEDdata14 =[0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
#LEDdata15 =[0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0]
#LEDdata16 =[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]


LEDdata1 = [1,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0]
LEDdata2 = [0,1,0,0,0,0,0,0,1,1,0,1,1,0,0,0]
LEDdata3 = [0,0,1,0,0,0,0,1,0,0,0,0,0,1,1,1]
LEDdata4 = [0,1,0,1,0,0,0,0,1,0,1,0,1,1,0,1]
LEDdata5 = [0,1,0,0,1,0,0,0,0,0,0,0,1,0,1,1]
LEDdata6 = [0,0,0,0,0,1,0,0,0,1,1,0,0,1,0,0]
LEDdata7 = [0,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0]
LEDdata8 = [0,1,0,1,1,0,0,1,0,1,1,1,0,1,0,0]
LEDdata9 = [0,0,0,1,1,0,0,0,1,0,0,1,1,1,0,0]
LEDdata10 =[1,1,1,0,0,0,0,1,0,1,0,1,1,0,0,0]
LEDdata11 =[0,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0]
LEDdata12 =[0,0,0,1,0,0,0,0,1,0,0,1,1,0,0,0]
LEDdata13 =[1,1,0,0,1,1,0,0,1,0,0,0,1,0,0,0]
LEDdata14 =[0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0]
LEDdata15 =[0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0]
LEDdata16 =[0,0,1,0,0,0,1,0,0,0,0,0,1,1,1,1]


try:
    while True:
        sendLEDdata(LEDdata16, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata15, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata14, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata13, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata12, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata11, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata10, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata9, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata7, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata6, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata5, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata4, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata3, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata2, SER, RCLK, SRCLK)
        sleep(.05)
        sendLEDdata(LEDdata1, SER, RCLK, SRCLK)
        sleep(.05)

except KeyboardInterrupt:
    pass

GPIO.cleanup()

 

ファルコン本体の方は。。。ちょっと放置してます。

。。。明日は作業台の日曜大工をしてるかも(/・ω・)/

 

Raspberry Pi 参考書籍

幾つか関連書籍を見比べた結果、下記2冊が解説が丁寧で、順だってスキルを習得するのに良いと思いました。本ブログの内容は、「実例で学ぶ~」の方に記載されています。

 

 

 

コメント

  1. 6jiro より:

    こんばんは!

    正直な所プログラム読み込めないのですが^^;とりあえずはLEDdataの配列をあたかも一つのPICで扱っているような感じで扱えるんですね〜。
    なかなか楽しいですね〜。私の場合は何個かのPICもしくはAVRをそれぞれのパートに仕込んでそこの部分専用で処理させていこうと思っていましたが、機会があればこういったものも勉強してみようと思いました^^。
    あせんちゅさんはホント勉強熱心ですね!素晴らしいと思います!

    ラズベリーパイはbluetoothも使えるのは魅力ですね〜。赤外線リモコンの場合表面のどこかにあの受信機を仕込まないといけませんからね〜。

  2. >6jiroさん
    こんばんは!
    このプログラムは書籍のサンプルをちょっと弄っただけで、0,1の羅列のところは演習っぽくベタ書きな状態です。

    分かりにくい説明ですが、このICはレジスタを二つ持っていて、

    [1,0,0,0,0,0,0,0]という配列を、FirstInでコマンドを発行してシフトレジスタに押しこむと、

    [1 ]
    [0,1 ]
    [0,0,1 ]


    [0,0,0,0,0,0,0,1]
    逆に格納されます。この状態で、シフトレジスタからストレージレジスタに転記するコマンドを掛けると、一気に8つの0,1(low,high)状態になる仕組みの様です。

    2つ繋げることで、レジスタからあふれたビットがその隣のICに転記されていくイメージになります。

    プログラムはこのパターンを16個作って0.2秒の待ちを掛けています。

    ちゃんとLEDの数分の配列を持たせないと、あふれた分のパターンが普通に次のLEDに乗っかって2巡目からは複写したように動いてしまいます(笑)

    赤外線LEDだとどっかに受光部を露出させないといけないですが、BluetoothかWi-FiでWeb経由だとシームレスにできますね。

    かずさんも始められたArduinoの方は扱える電流も大きく、電圧も5.0Vなので、ファルコンにはこっちがいいかも、と思ったりしてます。

    。。。といいながら、Arduinoは放置状態ですw

  3. 6jiro より:

    こんにちは!

    詳しいせつめありがとうございます!
    プログラムとご説明頂いたことでなんとなくイメージができました。
    なんか面白いですね。
    レッサーかずさんもArduinoを始められたみたいで、みなさんの本気具合がよくわかりますよね〜!

    • >6jiroさん

      こんにちは!
      理解できたらシンプルなパーツだと思いました。
      バケツリレーでLow, Highを渡してって、最後まで行き渡ったら一斉にどん!

      ですね。

  4. LsKaz より:

    こんばんは〜

    シフトレジスタいいですね〜
    LED出力用ピンが足りなくて、
    困ってたのですが灯台下暗し(^_^;)
    正に解決作が書かれてますました(笑)
    リンク先はarduinoだし実験キットにもシフトレジスタ入ってました♪

    • >かずさん

      おはようございます!
      電子工作を趣味とされている方からすれば何てことないお話なのかもしれませんが、日々新たな発見ができて新鮮でいいですね。

      もう、この歳になると知らないものは知らんと開き直って吸収していきたいと思いますw

      キットにも入ってましたか!数珠つなぎにしたら幾らでもいけそうなので、たくさん繋ぎましょう~

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