タクシーの表示器(スーパーサイン)を自作する

                                                       2019/09/23 7M4MON

adafruit の RGB Matrix 表示器 + SDカード読み出し


0.はじめに

タクシーの表示器(スーパーサイン)に「賃走」ではなく「珍走」って出たら面白いんじゃね?というのを思いついたので作ってみました。




1.機能

SDカードに保存されている Bitmapファイルを、16 X 32 ドットのフルカラーLEDマトリクスに表示します。
① 12個のボタンを搭載し、ボタンが押されたらそのボタンに紐付いたビットマップファイル( [1-6], [A-F] .BMP )を 表示します。
② SerialPort / USB で指定されたビットマップファイルを表示します。
  例: UARTから 'A' を送る→ 'A.BMP' を表示
  BLE-Nano を使えば Bluetooth LE経由で表示を変更することも可能です。

ON:モバイルバッテリーの電源供給ボタンを押して表示を開始します。
OFF:黒ボタン同時押しで消灯した後、40秒くらいするとモバイルバッテリーの電源供給が自動で断します。

2.ハードウェア

ボタンの読み取りにはアナログポートを使用しています。1ポートあたり6つぶら下がっていて、計12個です。
しきい値の計算は、しなぷすのハード製作記の回路設計サービスを使用しました。



ケースはタカチのPB-4を使用しました。ぴったりサイズです。
ハンガーユニットIQ型[IQ-1] @\410 x2 を側面に取り付け、
カメラ用のネックストラップを使用してウェアラブル化できるようにしました。



ケースのフタは、ゆるゆるですぐ外れるので、カン座を固定するネジの片方をトラスネジにして
そこにゴムバンドを通すことでフタが外れないようにしました。

(2019/11/17追記)
BLE-Nanoという、Arduino NanoにBluetooth LE (TI CC2540, USD 4.99) がくっついて
Arduino Nanoとピン互換のボードを発見したので、挿し換えてBLEに対応させてみました。



商品ページにも書かれていますが、Arduino IDE 1.8.6以降が必要です。
Android版の Light Blue というアプリで簡単に動作確認できました。



ただし、この状態だと消灯→自動で電源断が効かなくなります。

3.ソフトウェア

mixiの技術スレッドで公開されていたコードをアレンジしました。
ボタンとUART操作部だけ書いたので、この部分のみgistにあげておきます。
/*
* Display the Bitmap file saved on the SD card in a 16 x 32 dot full color LED matrix with Arduino nano.
* 7M4MON, 2019-Sep-20
* SDカードに保存されている Bitmapファイルを、16 X 32 ドットのフルカラーLEDマトリクスに表示します。
* ① 12個のボタンを搭載し、ボタンが押されたらそのボタンに紐付いたビットマップファイル( [1-6], [A-F] .BMP )を 表示します。
* ② SerialPort / USB で指定されたビットマップファイルを表示します。
*  例: UARTから 'A' を送る→ 'A.BMP' を表示
*
* mixiの技術スレッドで公開されていたコードに操作部を追加したもの。
* https://mixi.jp/view_bbs_comment.pl?comment_number=26&community_id=447391&bbs_id=76480266
*/
// 次の値は、しなぷすのハード製作記の回路設計サービスで計算して得られたもの
// R1 : 4.7kΩ
// R2 : 820Ω
// R3 : 1.5kΩ
// R4 : 2.7kΩ
// R5 : 5.6kΩ
// R6 : 18kΩ
#define KEY_THRES_0 69
#define KEY_THRES_1 240
#define KEY_THRES_2 432
#define KEY_THRES_3 621
#define KEY_THRES_4 798
#define KEY_THRES_5 957
uint8_t last_bmp_num;
uint8_t read_button(int analog_read, bool inv){
uint8_t key_num;
key_num = analog_read > KEY_THRES_5 ? 0 : //押されていないときが 0になるので。
analog_read > KEY_THRES_4 ? 1 :
analog_read > KEY_THRES_3 ? 2 :
analog_read > KEY_THRES_2 ? 3 :
analog_read > KEY_THRES_1 ? 4 :
analog_read > KEY_THRES_0 ? 5 : 6;
if (inv && key_num) key_num = 7 - key_num;
return key_num;
}
void loop(){
uint8_t button1, button2, bmp_num, rcv_byte;
if (Serial.available() > 0){
rcv_byte = Serial.read();
if((rcv_byte > 0x30 && rcv_byte < 0x37) || (rcv_byte > 0x40 && rcv_byte < 0x47)){ // 1-6,A-F
bmp_num = rcv_byte;
}else{
bmp_num = 0;
}
}else{
button1 = read_button(analogRead(A7), false);
button2 = read_button(analogRead(A6), true);
bmp_num = button1 + button2;
if (bmp_num) {
delay(100); // チャタリング防止
button1 = read_button(analogRead(A7), false);
button2 = read_button(analogRead(A6), true);
bmp_num = button1 ? button1 + 0x30 : // 1,2,3,4,5,6
button2 ? button2 + 0x40 : 0; // A,B,C,D,E,F
}
}
if ( button1 + button2 == 12) {
matrix.fillScreen(matrix.Color333(0, 0, 0));
cli(); // disable interrupts, stop matrix.
} else if ((bmp_num != 0) && (bmp_num != last_bmp_num)){
filename[0] = bmp_num;
sei(); // enable interrupts, (re)start matrix.
DrawBmp(PFFS.open_file(filename), filename);
last_bmp_num = bmp_num;
}
}

4.かかった費用

5000円くらい

5.感想

想定より費用はかかりましたが、良いものができました。
元のコードを公開してくださった「たく」様に感謝します。