卓上時計としてGoogle Home Hubを使っていたんだけれど、時間なんてPCに表示されてるし、腕時計もあるから要らないんじゃないかと思って別の場所に移設したんだ。ところが、人間の癖とは面白いもので、時間が気になると、卓上時計が置いてあった元の場所をちらっと見てしまう。卓上時計はきちんとその役割を果たしていたんだなと気づいた。
そんなわけで、今回の話はPicoに月齢を表示させた回の続きになる。卓上時計を作るなら、月齢と時刻に加えて、星座、気温、湿度を表示させたら面白いかなと思った。実際のところ、実用性は時計だけに求めていて、ほかは参考程度の情報なの。というより、今回の制作は、IoTとかPythonの勉強をするための一過程なんだよ。
やったこと
気温・湿度センサー
Pico/Pico Wには温度センサーが実装されているので、気温を取得することはできるんだが、湿度センサーがないので、湿度センサーをつけることにした。温湿度センサーとしては定番らしいDHT11を調達。湿度は小数点以下は取得できないらしい。足は4本ついているけれど、使うのは3本。うち2本はプラスとマイナス。残り一本がデータ用なので、これをGPIO 0につないだ。githubにdht11.pyというライブラリが上がっているので、これを使うとらくちん。
NTPサーバーから時刻を取得
Raspberry Pi Pico にはRTCが搭載されていないので、本体に時間を保持する機能がない。RTCを接続する手もあったけれど、今回は、月齢表示プログラム自体をWi-Fi接続機能のあるPico Wに乗せ換えて、NTPサーバ経由で時間を取得することにした。サンプルスクリプトはいろんなところに落ちているんだが、ものは試しにとChat GPTさんにプログラムを書いてもらった。
raspberry pi pico w でNTPサーバー経由で時刻を取得するプログラムを書いて
うっかり、Pythonを指定するのを忘れてしまったんだが、Pythonスクリプトを返してくれた。きっと、Picoといえば、Pythonなのね。
import network
import ntptime
import utime
# Wi-Fi接続情報を設定
ssid = 'Your_SSID'
password = 'Your_Password'
# Wi-Fi接続
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect(ssid, password)
# Wi-Fi接続待機
while not sta_if.isconnected():
utime.sleep(1)
# NTPサーバーから時刻を取得
ntptime.settime()
# 取得した時刻を表示
print(utime.localtime())
# システムスリープ
utime.sleep(3600) # 1時間ごとに時刻を更新
# システムスリープ解除
machine.deepsleep()
SSIDとパスワードの部分を書き換えて実行したら動いた。びっくり! まんまいただく。時刻を取得できたので、時計表示の部分はこれでOK。あとで日本標準時に変換することは忘れずに。
星座判定
「あなたは何座?」「ぎょうざ」みたいなやりとりを小学生のころにしたような記憶がある。生年月日が分かれば、生まれた星座を判定できるので、それ自体は簡単。しかし何月生まれなら何座とか知らんし、覚えるつもりないし、関心ないし。いちいち調べて書くのが面倒くさいし…|д゚) デキル?
誕生日を入力したら、何座生まれかが分かるpythonプログラムを書いてください
立ちどころに関数を書いてくれたよ。本当に日付があっているかは検証していないけれど、私の星座は合っている模様。
def get_zodiac_sign(day, month):
if (month == 3 and day >= 21) or (month == 4 and day <= 19):
return "牡羊座"
elif (month == 4 and day >= 20) or (month == 5 and day <= 20):
return "牡牛座"
elif (month == 5 and day >= 21) or (month == 6 and day <= 20):
return "双子座"
elif (month == 6 and day >= 21) or (month == 7 and day <= 22):
return "蟹座"
elif (month == 7 and day >= 23) or (month == 8 and day <= 22):
return "獅子座"
elif (month == 8 and day >= 23) or (month == 9 and day <= 22):
return "乙女座"
elif (month == 9 and day >= 23) or (month == 10 and day <= 22):
return "天秤座"
elif (month == 10 and day >= 23) or (month == 11 and day <= 21):
return "蠍座"
elif (month == 11 and day >= 22) or (month == 12 and day <= 21):
return "射手座"
elif (month == 12 and day >= 22) or (month == 1 and day <= 19):
return "山羊座"
elif (month == 1 and day >= 20) or (month == 2 and day <= 18):
return "水瓶座"
else:
return "魚座"
# ユーザーからの入力
day = int(input("日を入力してください: "))
month = int(input("月を入力してください: "))
# 星座を取得
zodiac_sign = get_zodiac_sign(day, month)
print(f"あなたの星座は{zodiac_sign}です。")
別の書き方も提案してくれる。こっちのほうがスマート
# 誕生日を入力して、星座を特定するプログラム
# 月と日を入力
month = int(input("誕生月を入力してください (1-12): "))
day = int(input("誕生日を入力してください (1-31): "))
# 星座の辞書を作成
zodiac_signs = {
"牡羊座": (3, 21, 4, 19),
"牡牛座": (4, 20, 5, 20),
"双子座": (5, 21, 6, 20),
"蟹座": (6, 21, 7, 22),
"獅子座": (7, 23, 8, 22),
"乙女座": (8, 23, 9, 22),
"天秤座": (9, 23, 10, 22),
"蠍座": (10, 23, 11, 21),
"射手座": (11, 22, 12, 21),
"山羊座": (12, 22, 1, 19),
"水瓶座": (1, 20, 2, 18),
"魚座": (2, 19, 3, 20)
}
# 入力された誕生日を星座と比較
for sign, (start_month, start_day, end_month, end_day) in zodiac_signs.items():
if (month == start_month and day >= start_day) or (month == end_month and day <= end_day):
print(f"あなたは{sign}生まれです。")
break
することないやん。月齢を求めるスクリプトはすでにあるので、試していないけれど、たぶんきっちり書いてくれるんだろう。勉強になるなあ。
pimoroni graphics
前回使ったDisplay Packは小さかったので、上位互換の表示面積が大きいDisplay Pack 2を使う。専用のライブラリはPimoroniが用意してくれているので、それを使うと線や円の描画はもちろん、かんたんにJPGが扱える。
かんたんと言いながら、はまったのはJPGの表示。月面のJPGは表示できたので、星座絵を表示しようと考えた。
フリー素材を取ってきて、12星座のJPG画像をPico Wに放りこんだのだが、j.decode(75, 100, jpegdec.JPEG_SCALE_FULL) とした行でエラーがでる。文法が間違っているわけではない。メモリの問題かと思ったけれど、そこまでデカいファイルではない。頑張って2kくらいまでサイズを落としたけれどダメ。
ググり続けること1週間。同じエラーで悩むユーザーさんがいた。「MSペイントで出力した画像なら表示できた」という話だった。
試しにMSペイントで保存したところ、読み込めた。ICCプロファイルとか余計な情報が入っているとダメなんかな(追記:そうじゃないっぽい)。フォトショップから12星座の画像をICCプロファイルのオプションをはずしてJPGに書き出したら読み込めたので解決。
その他
Display Pack 2についているボタンA,B,X,Yのうち、XとYに輝度調整機能を割り当て。表面実装されているRGB LEDは、満月に近づくほど明るく輝くように。
そんなこんなをやってみたら、きちんと動くものが完成。モバイルバッテリから給電しても正確な時刻を表示している。室温・湿度もそれっぽい。月齢も合っている。
表示されている星座は「さそり座」。えっ、秋なのに「さそり座」なの? 夏の星座なのにね。でも、これで合っているみたい。どうも納得がいかんけれど、昔の人はそう考えたんだね。
まとめ
というわけで、デジタル天文時計ができました。というか、作ったのはAIだけどな。Python初心者でも、AIの力を借りれば、難なくプログラムが書けるという話になってしまった。あんまりAIに頼りすぎると勉強にならないね。それでも、AIが出してきたコードを修正するくらいには、言語を分かっていないといけないということは分かった。
それから12星座の画像をお絵描きAIに出力させようと試みたんだが、やはりトーン&マナーが統一されていないし、絵もでたらめなことが多くて、今回のようなケースでは画像生成をAIに頼むのには、まだ時間がかかりそうな雰囲気。
3Dプリンタでケーシングを作るかどうかは、そのうち気分で考える。
この記事へのコメント
プログラミングってパズルな面白さがあったのに、それを奪ってしまうとは!
AIって無慈悲。
途中まで回答して、「あとは自分で頑張ってね」と言ってきたら面白いけど、それはそれで嫌。
チートですよねぇ。楽に作れるのはいいんですが、できた!って楽しみは半減です。
100本ノックとか相手してくれそうですが、たぶんそれはやらないです(笑)
占いで使う12星座は、太陽がその星座の位置に来る時期なんだよ。
だからその星座を見る時期とは真逆だね。
蠍の尻尾とったら蟹に見えなくもないなぁ。v^^v←かに座生まれな奴
なるほどそういうことでしたか。太陽と星座が同時に見られるわけではないのに、面白いですね。さらに運命の星の下に生まれてくる発想も面白いです^^
赤とんぼ赤とんぼの羽をとったらあぶら虫♪
占星術は春分の日を起点として、黄道を十二等分した「黄道十二宮」を元にしており、各宮にある星座から宮名に付けています。
(現在は歳差のため、一宮ずつ星座名とずれているそう。)
よって正確には星座ではなく星宮で呼ぶべきですが、大衆にわかりやすくするため星座名で呼んでいると思われます。
そんな経緯を無視して近年、「十三星座」と称して黄道上にある蛇遣い座を加えている一派が出てきましが、もうね、アホか、馬鹿かと・・・
以上、天文知識ひけらかしウザオジさんでした。
ちなみに私は占いは全く信じません。
ある朝の各テレビ局の占いコーナーで自分の星座が1位と12位だったのは笑いました。
占いを世間話程度で語るのは良いですが、信じている人はもうね(略
特に血液型占いは、馬鹿げています。
ネタとしておみくじはよく引きますが、無神論者です。
ははぁ、春分の日が基準になっているのですね。12宮のご説明納得です。
星占いってやってもらったことないです。占い自体、あんまり興味がないというか。
ダン・ブラウンのオカルト小説は面白いですね。
宇宙人が地球を攻めてくる話はもっと好きです(笑)