「土日で完成! 趣味のラズパイ」
土日で完成! 趣味のラズパイ ラズパイを使ってデジタル時計を作る
筆者のPCデスク周りには、時計がありません。Windows PCであれば右下に時刻が表示されるので、それを利用してもよいのですが、もう少し目立つ位置に、はっきりと表示される時計が欲しいもの。それならば安い置き時計を買えばいいのでは? という方もいるかもしれませんが、そこは「土日で完成」連載。ラズパイを使ってデジタル時計を表示させるのはいかがでしょうか。
また筆者の性格として「1秒でも時計が遅れるのは許せん」というものがあります。電波時計以外の時計は起動し続けると時間が狂っていきますが、ラズパイであればPCと同様にNTPサービスと同期して正確な時刻を表示させることも可能です。それならいっそ、ラズパイをNTPサーバーにしてもよいでしょうし、もっと踏み込んでGPSを搭載して時間を同期させてみてはいかがでしょうか。これであればネットワークにつながっていなくても正確な時刻を得られます。そこで今回から3回にわたって、ラズパイデジタル時計の作成、NTPサーバーの立て方、GPSとの連携について解説していこうと思います。
土日で完成! 趣味のラズパイ
第16回 ラズパイとChatGPTで遊ぼう——圧電ブザーで音を鳴らす
第15回 ラズパイとChatGPTで遊ぼう——気温/湿度/気圧を測定する
第14回 ChatGPTで遊ぼう——ラズパイで作ったデジタル時計に天気情報も表示させる
第13回 ラズパイとChatGPTで遊ぼう——液晶時計を作る
第12回 ラズパイとChatGPTで遊ぶ——その1:Lチカさせてみる
第11回 ラズパイをブリッジモードで使って、Wi-Fi接続する
第10回 ラズパイをWi-Fiルーターにする
特別編 【実機レビュー】よりパワフルになったRaspberry Pi 5を検証!
第9回 VolumioでラズパイからSpotifyやradikoを楽しむ
第8回 ラズパイで音楽プレーヤー「Volumio」を楽しむ
第7回 GPSを導入して正確な時刻を刻む
第6回 ラズパイをNTPサーバーにする
第5回 ラズパイを使ってデジタル時計を作る
第4回 Raspberry Pi Camera Module 3を使って見守りカメラを作る
第3回 BME680の測定データを小型ディスプレイに表示させる
第2回 空気質センサー「BME680」で空気汚染度を測る
第1回 ラズパイ工作の基本! 気温と湿度、気圧を計測する
一覧ページへ
ところでラズパイを使って時間を表示させられるディスプレイはたくさんあります。以前紹介した、コントローラーにSO1602を搭載したディスプレイを使うのでももちろんかまいません。しかしSO1602のディスプレイを使う場合は、文字の表示形式が決まっていて変化が乏しく、あまり面白みがありません。
そこで今回は128×64ピクセルのエリアで自由に描画できる有機ELディスプレイ(OLED)を使ってみましょう。ディスプレイは秋月電子通商で販売されている「0.96インチ 128×64ドット有機ELディスプレイ(OLED) 白色」(以下、SSD1306)を使用します。価格は580円(税込)です。
SSD1306をラズパイに接続する
まずはSSD1306をラズパイと接続します。I2Cで利用しますので、ラズパイの1番ピンにSSD1306のVCCを接続し、GNDにラズパイのGND端子(6番ピンなど)を接続。SDAを3番ピン、SCLを5番ピンに接続しましょう。接続にはブレッドボードを利用します。
このあと、デスクトップ環境であればメニューにある「設定」→「Raspberry Piの設定」から、CUI環境であれば「sudo raspi-config」と入力して「Interface Options」で「I2C」を選んで「はい」を選び、I2Cを有効にします。このあたりは「今さらきけない『ラズパイってなんですか?』」連載の「第4回 ラズパイを使う準備って何をしたらいいですか」と「第5回 GPIOって何ですか? 機能や役割は?」でも解説していますので参考にしてください。
ラズパイと接続してI2Cを有効にしたら、ラズパイが認識しているか確かめます。確かめるのは「i2cdetect」というコマンドです。以下のように入力してください。
$ i2cdetect -y 1
すると以下のように表示されます。
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
縦横の表示ですが、縦がアドレスの上位桁、横が下位桁になります。SSD1306は「0x3c」のアドレスを持ちますので、「3c」と表示されれば認識されています。表示されない場合は接触不良を疑うか、もしかしたら製品が壊れているかもしれません。ブレッドボードでの動作はちょっとした接触不良を起こすこともありますので、一度全て取り外し、接続し直すのも1つの手です。
表示させるモジュールをインストールする
では続いてSSD1306に文字を表示させるためのモジュールをインストールしましょう。「Luma.OLED」というモジュールが公開されていますので、これを利用します。以下の手順でインストールします。
$ sudo pip3 install luma.oled
これに続いて、表示させるフォントをインストールします。フォントはいろいろありますが、今回は「Noto」というGoogleが公開しているフォントを利用します。以下のコマンドでインストールしましょう。
$ sudo apt install fonts-noto
ここまでくれば文字を表示するための準備は終了です。今度はPythonのプログラムを記述していきます。内容は以下の通りです。「clocktest.py」などのファイル名で記述しましょう。プログラミングについては「第10回 ラズパイでLチカって何ですか」に解説していますので参考にしてください。Windowsで記述したファイルをラズパイに転送する方法については「第8回 『Windowsでラズパイを使う』って何ですか」で解説しています。
#!usr/bin/env python # -*- coding: utf-8 -*- from luma.core.interface.serial import i2c from luma.oled.device import ssd1306 from luma.core.render import canvas from PIL import ImageFont import time import datetime serial = i2c(port=1, address=0x3C) device = ssd1306(serial) I2C_ADDR = 0x3c FONT_PATH = "/usr/share/fonts/truetype/noto/NotoSans-Regular.ttf" font_month = ImageFont.truetype(FONT_PATH, 15, encoding = 'unic') font_time = ImageFont.truetype(FONT_PATH, 29, encoding='unic') try: while True: with canvas (device) as draw: now = datetime.datetime.now() today_n = now.date().strftime("%Y/%m/%d(%a)") time_n = now.time().strftime("%H:%M:%S") draw.text((8, 0), today_n, font=font_month, fill=255) draw.text((4, 16), time_n, font=font_time, fill=255) device.show() time.sleep(0.01) except KeyboardInterrupt: device.hide()
プログラムを記述してラズパイに転送したら、ターミナルから以下のコマンドを入力してプログラムを動かしましょう。
$ python clocktest.py
すると下の画像のように表示されます。Ctrl+Cを入力するとプログラムを終了し、画面から表示が消えます。
起動すると同時にプログラムを動かしたい場合は、「rc.local」というファイルにコマンドを記述すればOKです。nanoでrc.localを開きましょう。
$ sudo nano /etc/rc.local
ファイルを開いたら以下の場所にコマンドを記述します。「ユーザー名」は自分のユーザー名を入力しましょう。特に変更をしていない場合は「/home/pi」となっています。
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi python /home/(ユーザー名)/clocktest.py # ←ここに追加 exit 0
ここまででラズパイを使ったデジタル時計が完成しました。次はNTPサーバーを立てることにします。