つくったもの
なんでも鑑定団の鑑定額を発表するところだけやりたかったので、7セグLEDを使って装置を作った。
結果的にすごくうまくいったので大満足。
ところでこれまでの工作は、主にサーボやタミヤのDCモータを使って動きを見せるものだった。
なのでLEDを使った光るモノは本当に知識がなく、7セグLEDは結構憧れだった。
色々と初歩的なところから学んで理解出来たので、メモを残す。3ヶ月後には絶対忘れているし。
まず1桁の7セグLEDを光らせるための準備
今回買った7セグLEDはこれだ。
akizukidenshi.com
すごくでかい16セグLEDが4つセットになったキット。
作りたいものとしては8桁の7セグを光らせたかったので、aitendoで8桁のキット(下のやつ)を買ったのだけど、大きさが小さい(というか普通の7セグのサイズ)ためにはんだ付けが大変そうで、チャレンジングすぎるということで秋月のキットにした。チップ抵抗とか10年くらいはんだ付けしてないし……。
www.aitendo.com
7セグLEDは言ってしまえば単に7つのLEDが1つになったものなので、対応するLEDのピンに電圧を印加すれば光る。
記事にも貼ったけど、一番単純に光らせる状態をまずは目指した。
今回使った7セグLEDはアノードコモンなので、7セグから出ているピンをGNDに落とすと光る。
つまり、7セグのピンをArduinoのピンに刺して、光らせるためにArduino側でdigitalWrite(ピンID, LOW)としてやる感じである。ちょっとこれまでと直感がずれるので気をつけないといけない。
そしてLEDに流す電流量を調整するために抵抗を入れる必要がある。LEDのスペック表ではIFと書かれていたりする。
で、これは本当に初歩の初歩なのだけど、LEDは順方向電圧降下という性質があってアノードからカソードに電流が流れるときに電圧降下が起きてしまう。LEDのスペック表にはVFとして書かれているもので、LEDごとに異なる。(こんなこともちゃんと分かっていなかったくらい、初心者なのである)
LED自体はこれ↓で、VFは3.4Vとある。IFは光る箇所によって40mAと20mAに分かれていたのだけど、小さい方に合わせて20mAで良さそう。
akizukidenshi.com
Vccが5VであればVFの分の3.4Vが降下するので抵抗には1.6Vがかかることになる。この抵抗に20mA流れればいいので、必要な抵抗値は1.6V/20mA=80Ωになる。
小学生でやる計算をしたけど、さらに楽をすることが出来て秋月のサイトに計算ツールがある。何も考えずにこれでもいいかもしれない。
akizukidenshi.com
80Ωはないので数値が近い100Ωの抵抗を使うことにした。
これで、LEDのピン - 100Ω抵抗 - ArduinoのGNDピンという接続にしてやればいい。
なんだけど、加えて今回のキットではどの桁を光らせるかのピンもつなぐ必要がある。
対応するピンをHIGHにすることで光らせることが出来る。
どのピンがどの桁なんだっけについては秋月のデータシートを読めばいいが、線が多くて大変なので下記のサイトの画像をすごく参考にさせてもらった。
temari.co.jp
複数の桁を光らせる
1桁を光らせることは出来たが、複数の桁を光らせる場合はダイナミック点灯という方法を使う。
これはそれぞれの桁のLEDを高速で点滅させることで、目の残像を利用して点滅ではなく点灯しているように感じさせ、なおかつ配線を少なく出来るという利点がある。
7セグは複数桁を使おうとするとすぐに配線が爆発するので、必須ともいえる基本テクニックのようだった。初めて知りました。
実験すると10ms間隔だとなんかちらついてるなー、という風に見えて、3ms間隔だとちらつきは感じなくなった。
個人差はあるだろうけど面白い。人間欺いてるー、という感じがする。
このあたりの諸々については下記のブログがとても参考になった。4桁の光らせ方もやっていたので、たくさん読んだ。
tsukutta.hatenablog.com
最終的に回路はこんな感じになった。
7セグLEDを図に入れるとややこしくなるので省いている。
7セグLEDは20ピンあるが、19と20は使わなかったので9ピン2列のソケットを使った。
実際の回路はこういう感じ。
これでLED側の回路は出来上がり。8桁光らせたいのでもう1セット作る必要がある。
鑑定額発表用の機能を作る
鑑定額発表のためには下記の光らせ方が必要になる。
- 0~9までの数字が表示出来る(7セグの基本機能ですが)
- ランダムに数字を表示出来る(鑑定額発表前の表示)
- 数字を表示しない(鑑定額がその桁未満の場合)
4桁の表示を制御したいので、シリアル通信で4桁分のデータを送って、それに従ってLEDを光らせるプログラムにすることとした。(コードへのリンクは最後に)
「1234;」と送ると1234と表示される、という感じだ。「;」はデータの末尾として機能する。
同じように「-」が含まれればランダムの数字を表示して、「*」が含まれれば数字を表示しないというようにした。
いま思ったけど「*」はワイルドカードの意味合いがあるから、逆の割り当てでも良かったな。
なので、「----;」を送ると全桁がランダムで表示されるし、「--00;」だと1000と100の桁がランダムで10と1の桁が0を表示するようになる。
また「*800;」は800として表示されて、1000の桁は表示されない。800円だ。
これなら送る側はやりやすいし、LED側も作りやすいと考えた。
ランダムの表示については、毎ループで数字を変えると間隔が短すぎて鑑定団っぽくならなかったので、5ループごとに数字をランダムに変えるようにした。
鑑定団っぽくなるチューニングが見つかったので満足している。
LEDをシリアル通信で制御する
ここまでで4桁の7セグLEDを光らせることが出来るようになった。
ただ実際には8桁光らせないといけない。LEDキット2台を1台のArduinoで制御する方法が思いつかず、2台のArduinoを1台のRaspberry Piにつなぐという富豪的な解決方法をとった。
たぶんもっと頭のいい方法があると思う。
それぞれのArduinoをUSBケーブルでRasPiとつないだら、普通に2つのポートでシリアル通信が出来た。
あとはいいタイミングで表示したい内容をそれぞれに送ってやればいい。
値段の声も自分で録音したので、それも同時に再生してやれば鑑定額発表装置の出来上がりだ。
RasPiをホストにしたことで、音声周りもPythonで柔軟に流せるようになったので結果的には良かったかもしれない。
スピーカーはダイソーのアンプ付きスピーカーを使った。これ前にも書いたけど300円なの本当に信じられない。ちょっと音を出したいときはものすごく使えるのでみんな買った方がいいと思う。
出来たソースコード
Arduinoを光らせるコードはこのようになった。
https://github.com/stamefusa/kanteidan/blob/master/serial_7segled.ino
また、RasPiで動かしたPythonコードはこちら。
https://github.com/stamefusa/kanteidan/blob/master/kanteidan.py
すごくきれいに書けたわけではないのでご容赦……。
ただ締め切りぎりぎりにはなったけど初めてやることも多かったしとても良かった。
メイカーフェアにも出したいし、そのときには絶対にすべてを忘れているのでこのメモを残す。