Raspberry Piと1602LCDディスプレイで電光掲示板を作成

raspberry_pi_clockRaspberry Pi
raspberry_pi_clock

本記事の内容

  • Raspberry Pi、または、Raspberry Pi Picoと1602 LCDディスプレイモジュールで、駅でよく見かける電光掲示板(時刻表)を作製します。
  • 玄関に一台セットするだけで、これから乗る電車の発車時刻と行き先が分かるアイデアグッズの完成です。

はじめに

これまで写真を撮ったり気温を測ったり、「あまり使えなさそうなガラクタ」ばかり作ってきましたが、今度こそはガラクタにならないアイデア作品の紹介になります。

上述したように今回作製するのは、駅で見かける電光掲示板です。(正式名称は「発車標」だそうです。)

この発車標を駅までの所要時間分ずらして、家の玄関に置くだけで、後に乗る電車が分かるという優れものになります。

raspberry_pi_clock_1
raspberry_pi_clock_1

ちなみに私は東京メトロ千代田線の「北千住⇒代々木上原」を通勤に使っていますが、千代田線は行き先名がどれもこれも長すぎます!!!

漢字5文字の行き先だけで4駅もあり、どれも濁点だらけで、1602 LCDディスプレイ一行に収まらないんですよね、、、(代々木上原「ヨヨギウエハラ」、明治神宮前「メイジジングウマエ」、成城学園前「セイジョウガクエンマエ」、向ヶ丘遊園「ムコウガオカユウエン」)

これは適当に短縮して何とかしますが、他の路線ならもっと見やすく作製できるはずです。それでは作製ステップに入ります。

必要なもの

  • Raspberry Pi、または、Raspberry Pi Pico
  • 1602 LCDディスプレイモジュール
  • (Raspberry Piであれば、)ジャンプワイヤー4本
  • (Raspberry Pi Picoであれば)ユニバーサル基盤など

本記事では、Raspberry PiとRaspberry Pi Picoの両方で作製方法を解説します。

Raspberry Piは画面出力機能もあるので初めてでも扱いやすく、プログラミング工作初心者向けになりますまた、時刻も自動で取得できるので、設定が簡単です。

一方で、Raspberry Pi Picoはマイコンなので、中・上級者向けです。安価(550円)で低消費電力という魅力がありますが、時刻の取得機能がないので、時計がずれたら直す必要があります。

すなわち、Raspberry Pi経験者であればRaspberry Pi Picoを、初めてのプログラミング工作であればRaspberry Pi 4BやZERO 2を購入してRaspberry Piで作製することをお勧めします。

ディスプレイモジュールについては、Amazonでレビューが高かった「WayinTop 1602 LCD ディスプレイ」を最初に買いましたが、この商品はディスプレイとI2CシリアルI/Fが、はんだ付けされていません。

はんだ初心者が頑張ってくっつけてみましたが、基盤同士が接触してしまったせいか、ディスプレイが点灯しなくなってしまいました。。。はんだ付けはルーペや基盤固定台などを念頭に準備して行わないと、やはり素人には難しいです。

それゆえ、個人的には「HiLetgo 1602 LCDディスプレイモジュール」をおすすめします。はんだ付け済の商品であり、Amazonなら2個セット1400円と少しお得に購入できます。

Raspberry Pi Picoで作製する場合

配線とはんだ付け

Raspberry Pi Picoと1602 LCDディスプレイモジュールを以下の通り配線します。

raspberry_pi_clock_2
raspberry_pi_clock_2

Raspberry Pi Picoでの1602 LCDディスプレイモジュールの動作テスト

MicroPythonで1602 LCDディスプレイモジュールを使う方法は、この方の記事がとても分かりやすく参考になります。

要点のみピックアップすると、

  1. githubからpython_lcdをダウンロード
  2. Raspberry Pi Picoに「esp8266_i2c_lcd.py」と「lcd_api.py」をアップロード
  3. I2Cアドレスの確認(基本的にLCDのアドレスは39なので不要?)
  4. 以下のテストプログラムを実行
import time
import machine
from esp8266_i2c_lcd import I2cLcd

I2C_ADDR = 0x27
sda = machine.Pin(0)
scl = machine.Pin(1)

# I2C start
i2c = machine.I2C(0,sda=sda, scl=scl, freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, 2, 16)
lcd.putstr("It Works!\nHello World")

ちなみに、出荷時はディスプレイのコントラストが最低値で設定されているため、「バックライトは映っているが、文字が見えない」という場合は、背面のつまみを時計回りに回してみてください。

raspberry_pi_clock_3
raspberry_pi_clock_3

無事に文字が表示されれば成功です。

時刻表の変換とプログラムコードの作成

Raspberry Pi Picoはマイコンなので、datetime関数のような時刻の取得機能はありません。そのため、電源投入時の時刻をあらかじめ設定して、1分ごとにひたすらカウントアップさせて内部時計にします。

上手に型や関数を使うと奇麗なコードになるかもしれませんが、ずぼらなPython初心者は分刻みの時刻(clock)を内部時計としています。(1:00⇒60、1:05⇒65、1:10⇒70…、23:55⇒1435)

内部時計と同様に、電車の時刻表もExcelで分刻みの時刻に変換して、配列”departureclock[]”用に準備します。

発車時刻departureclock[]
05:09309
05:21321
05:32332

続いて、行き先(カタカナ)を定義します。カタカナのコードは、こちらの方が表にして下さっています。

行き先コード定義
代々木上原\xd6\xd6\xb7\xde\xb3\xb4\xca\xd7yoyogi
成城学園前\xbe\xb2\xbc\xde\xae\xb3\xb6\xde\xb8\xb4\xddseijou

あとは、行き先配列”to[]”を用意して、”departureclock[]”とセットに定義するだけです。

departureclock[]to[]
343yoyogi
352yoyogi
357yoyogi
362mukouga

実際のプログラムコードは以下の通りです。

import time
import machine
from esp8266_i2c_lcd import I2cLcd

I2C_ADDR = 0x27
sda = machine.Pin(0)
scl = machine.Pin(1)

# I2C start
i2c = machine.I2C(0,sda=sda, scl=scl, freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, 2, 16)

#行き先定義
yoyogi="\xd6\xd6\xb7\xde\xb3\xb4\xca\xd7"
seijou="\xbe\xb2\xbc\xde\xae\xb3\xb6\xde\xb8\xb4\xdd"
isehara="\xb2\xbe\xca\xd7"
honatsugi="\xce\xdd\xb1\xc2\xb7\xde"
kasumiga="\xb6\xbd\xd0\xb6\xde\xbe\xb7"
mukouga="\xd1\xba\xb3\xb6\xde\xb5\xb6"
meiji="\xd2\xb2\xbc\xde\xbc\xde\xdd\xb8\xde\xb3"
sagami="\xbb\xb6\xd0\xb5\xb5\xc9"

#時刻表定義
departureclock = [309,321,332,…]
to = [yoyogi,yoyogi,yoyogi,…]

#現在時刻(分換算)
clock = 1200

#n値(次発のインデックス)の算出
n = 0
while True:
    if departureclock[n] >= clock:
        break
    n +=1

while True:
    lcd.putstr(f'{departureclock[n]//60:02}'+f'{departureclock[n]%60:02}'+" "+to[n]+"\n")
    lcd.putstr(f'{departureclock[n+1]//60:02}'+f'{departureclock[n+1]%60:02}'+" "+to[n+1])
    time.sleep(60)
    lcd.clear()
    clock += 1

    #24時を過ぎたら、0時にリセット
    if clock > 1440:
        clock -= 1440
        n = 0
    
    #出発時刻を過ぎたら、次々発を次発に繰り上げ
    elif clock > departureclock[n]:
        n +=1

プログラムコードが長くなるので今回は割愛しますが、時計と交互に表示させたり、発車時刻になったら点滅させるなどの工夫を凝らしてもいいですね。

(2022年11月23日追記)

Raspberry Pi Picoには時刻の取得機能はありませんが、パソコンに繋がなくとも00:00からカウントアップする機能はあります。以下、簡易的に時刻を表示する機能の紹介になります。

Raspberry Piで作製する場合

配線

Raspberry Piと1602 LCDディスプレイは以下の通り配線します。見づらくて申し訳ありません。

Raspberry Piでの1602 LCDディスプレイモジュールの動作テスト

Raspberry Piで1602 LCDディスプレイモジュールを使うには、「設定」>「Raspberry Piの設定」>「インターフェィス」から「I2C」を有効にする必要があります。

該当項目を有効化します。

以降、ライブラリのダウンロードはこちらの方の記事を参考にしました。1602 LCDディスプレイモジュールのライブラリはRaspberry Pi Picoと同じくGitHubから頂いています。

時刻表の変換とプログラムコードの作成

Raspberry Piではdatetime関数が使えるので、時刻は常に正確な値を表示できます。

コードの大まかな構成はRaspberry Pi Picoと同じです。こちらも上手に型や関数を使うと奇麗になるかもしれませんが、Python初心者はHHMM(時間分分)で時刻表を変換しました。(5:09⇒509、5:21⇒521、5:32⇒532、…)

<!-- wp:code -->
<pre class="wp-block-code"><code><span class="fz-12px">from LCD1602I2C.LCD import LCD
import time
import datetime

lcd = LCD(2,0x27,True)

#行き先定義
yoyogi="\xd6\xd6\xb7\xde\xb3\xb4\xca\xd7"
…

#時刻表定義
departureclock = [509,521,532,…]
to = [yoyogi,yoyogi,yoyogi,…]

#n値(次発のインデックス)の算出
date = datetime.datetime.now()
n = 0
while True:
    if departureclock[n] >= date.hour*100+date.minute:
        break
    n +=1

while True:
    date = datetime.datetime.now()
    lcd.message(f'{departureclock[n]//100:02}'+":"+f'{departureclock[n]%100:02}'+" "+to[n],1)
    lcd.message(f'{departureclock[n+1]//100:02}'+":"+f'{departureclock[n+1]%100:02}'+" "+to[n+1],2)
    time.sleep(1)
    if date.hour*100+date.minute > departureclock[n]:
        n +=1</span></code></pre>
<!-- /wp:code -->

こちらで、毎秒ディスプレイが更新されて、次発と次々発の出発時刻が表示されます。

コメント

  1. なかじ より:

    こんにちは
    有意義なものプレゼンありがとうございます

    これのラズベリーパイPICOのプログラムをためしてみましたが以下のエラーが出てしましました
    アドバイスをお願いします

    Traceback (most recent call last):
    File “”, line 24, in
    NameError: name ‘…’ isn’t defined

    どうにかして電光掲示板つくりたいですよろしくおねがいします

  2. なかじ より:

    カタカナ表示はラズベリーパイピコでやる場合もArduinoのライブラリが必要なのでしょうか?

  3. なかじ より:

    先程の件あるコードを削除したら正常に動くようになりました
    最後まで正常に動作するかわかりませんが…

    現在時刻を切り替えて表示させたいのですがプログラムをどうやって作ればいいかわかりますでしょうか?よろしくお願いします

  4. なかじ より:

    #24時を過ぎたら、0時にリセット
    プログラムほとんどコピーで発射時刻と行き先を変えてプログラムを実行しました

    if clock > 1440:
    clock -= 1440
    n = 0

    これを打ち込んでるんですが表示が0時に戻って来なくそのまま最後の時刻の表示になってしまいます
    なにか解決策はないでしょうか?