主にこの記事に書いてある情報
エラーへの対応法について(解決できたわけではないですが載せてます)
はじめに(今回すること)
2023年今年最後の投稿。
1年が早かった。
総括とかそういうのはしない。
僕の部屋の置時計はずれています。(スマートウォッチと比べても18分ぐらいずれているのが分かりますね。)
だから、ラズパイで電波時計を作りたくなったわけです。
ラズパイケースからの引っ越し
まず引っ越さなければならない。
ケースに入っているので、他のデバイス機器との接続ができない状況だから。(最近は冷却ファンの音もうるさくなり夜とか気になるようになってきた😢)
購入したものはこちら(ブラックフライデーで1,999円だった)
中身はこんな感じ
説明書はあるけど、英語。だけどイラストで何とかできると思う。
まず、アクリルの台。
防護フィルムをはがす。(結構はがしにくい)
次にねじを止めていく。
ラズパイをケースから外す。(これが一番大変だった…。)
赤丸の4か所にネジがあるのでこれを外す。
このネジが硬すぎてドライバーではびくともしなかった…。
一応、新しいドライバーや、ネジをとりやすくする滑り止めや、ネジをとるペンチみたいなものも買ったけど使えたのはネジをとるペンチのみ。
右上の赤丸のネジは狭すぎてペンチは使えず。
で、もともとも持っていたニッパー(以下左)で外せた。ネジを切らないように力加減に気を付けて外せた。
土台にラズパイを設置するためのねじを設置し、ラズパイを配置。
冷却ファンを別のアクリル板に固定
で、重ねて完成
電波時計
LCD部分(物理部分)
LCDは以下のスターターキットに入っていました。
これもブラックフライデーで安く買いました。
ラズパイ側の設定
I2Cを有効化する必要がある。
以下のコマンドで、「そのようなファイルやディレクトリはありません」と出てくると有効化されていない。
$ ls /dev/*i2c*
ls: '/dev/*i2c*' にアクセスできません: そのようなファイルやディレクトリはありません
設定画面を開く。
sudo raspi-config
設定画面から「Interfacing Options」→「I2C」を選択し、有効にする。
Visual Studio Codeのコンソールからsshでラズベリーパイに接続しても、以下のように設定画面に行ける。
再度確認すると有効になっていた。
$ ls /dev/*i2c*
/dev/i2c-1
I2Cデバイスを検出する。
$ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3f
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
python部分(コード部分)
完成したコードから載せます。
import smbus
import time
from datetime import datetime, timezone, timedelta
LCD_ADDR = 0x3f # アドレス(★上記の確認で3fが出たので、ここには3fを設定している それぞれの結果で適宜変えてね)
LCD_WIDTH = 16 # LCDの文字数
LCD_BACKLIGHT = 0x08 # バックライトの設定
# HD44780コマンド
LCD_CLEAR_DISPLAY = 0x01
LCD_RETURN_HOME = 0x02
LCD_ENTRY_MODE = 0x06
LCD_DISPLAY_ON = 0x0C
LCD_DISPLAY_OFF = 0x08
LCD_CURSOR_ON = 0x0E
LCD_BLINK_ON = 0x0F
LCD_SET_DDRAM = 0x80
# PCF8574に接続されたLCDのピン
RS = 0x01
RW = 0x02
EN = 0x04
# LCDの初期化
def lcd_init(bus):
# 初期化シーケンス
lcd_send(bus, 0x33, 0) # 4ビットモードに設定
time.sleep(0.005)
lcd_send(bus, 0x32, 0) # 4ビットモードに設定
time.sleep(0.005)
# コマンド設定
lcd_send(bus, 0x28, 0) # 2行表示、5x8ドット
time.sleep(0.00015)
lcd_send(bus, LCD_DISPLAY_OFF, 0) # ディスプレイオフ
time.sleep(0.00015)
lcd_send(bus, LCD_CLEAR_DISPLAY, 0) # ディスプレイクリア
time.sleep(0.002)
lcd_send(bus, LCD_ENTRY_MODE, 0) # エントリモード設定
time.sleep(0.00015)
lcd_send(bus, LCD_DISPLAY_ON, 0) # ディスプレイオン
time.sleep(0.00015)
# データ送信
def lcd_send(bus, data, mode):
high = mode | (data & 0xF0) | LCD_BACKLIGHT # 上位4ビット
low = mode | ((data << 4) & 0xF0) | LCD_BACKLIGHT # 下位4ビット
# データを送信
bus.write_byte(LCD_ADDR, high)
lcd_toggle_enable(bus, high)
bus.write_byte(LCD_ADDR, low)
lcd_toggle_enable(bus, low)
# トグル処理
def lcd_toggle_enable(bus, value):
bus.write_byte(LCD_ADDR, value | EN) # Enable ON
time.sleep(0.0005)
bus.write_byte(LCD_ADDR, value & ~EN) # Enable OFF
time.sleep(0.0005)
# カーソル位置設定
def lcd_set_cursor(bus, col, row):
addr = LCD_SET_DDRAM | (col + 0x40 * row)
lcd_send(bus, addr, 0)
# 文字列出力
def lcd_print(bus, text):
for char in text:
lcd_send(bus, ord(char), 1)
def main():
bus = smbus.SMBus(1)
lcd_init(bus)
while True:
now = datetime.now()
jst = timezone(timedelta(hours=9))
now_jst = now.astimezone(jst)
lcd_set_cursor(bus, 0, 0)
lcd_print(bus, now_jst.strftime("%Y/%m/%d (%a)"))
lcd_set_cursor(bus, 0, 1)
lcd_print(bus, now_jst.strftime("%H : %M"))
time.sleep(10)
if __name__ == "__main__":
main()
上記コードをsudoで実行します。
sudo python3 my_clock.py
すると、時計が起動します。
ずっとプログラムをそのまま動かしているわけにもいかないので、バックグラウンドで実行します。
nohup sudo python3 my_clock.py &
【その他】サンプルコードでハマった話
今回、使用したスターターキットには説明書がついてきます。
と言っても、自分で調べてネットからダウンロードしなければなりませんし、説明書は英語で書かれています。
以下が説明書がある場所です。
僕が買ったスターターキットは「FNK0020」の「Freenove Ultimate Starter Kit for Raspberry Pi」というやつで、その説明書をダウンロードしました。
説明書にはサンプルコードが載っており、当初それを使用する予定でした。
しかし、ここで結構ハマったわけです。
サンプルコードの一行目、以下の記述があります。
from PCF8574 import PCF8574_GPIO
ここで、以下のエラーが発生しました。
ModuleNotFoundError: No module named 'PCF8574'
このエラーでまず、以下を試します。
$ pip3 install PCF8574
しかし、これだと、
ModuleNotFoundError: No module named 'PCF8574'
は消えません。
ちなみに、
from pcf8574
はできるけど、
from PCF8574
はできませんでした。(いや、何が違うんだいっ!!!)
ググったりもしましたが、結局「pip3 install PCF8574」を勧められてしまう始末でした。
結果から言うと、インストールするのは「pcf8574-library」でした。
つまり、
$ pip3 install pcf8574-library
でした。(これはハマる)
しかし、これだけでは終わりません。
再度、実行すると、今度は以下のエラー。
ModuleNotFoundError: No module named 'machine'
これも「pip3 install machine」では消えません。
というのも、pyhon3.5までしか使えないようで、現在使っているのがpython3.7だったので、ここで断念しました。