ESP8266で(電車やバスの)カウントダウンタイマーを作った話

この記事は，[岩手県立大学 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/ipu)の24日目の記事です。
ついでにQiita初投稿です。

# **はじめに**
ESP8266とは一昨年の夏くらいに流行ったWi-Fiモジュールです。なんとこれ単体でArduinoスケッチを書き込み・実行することが出来ます。
これを用いてちょっとホームオートメーションした話を書こうかと思いましたが正直n番煎じなので，今回は(電車やバスの)カウントダウンタイマーを作った話を書きたいと思います。

# **概要**
電車の時刻表確認や次の電車までの残り時間を確認するために[トレインタイマー](https://play.google.com/store/apps/details?id=com.wawproject.TrainTimer)と言うアプリを使っています。
非常に便利ではあるのものの時刻表や残り時間の確認のためだけにスマホをいちいち開くのが地味に面倒なので，置き時計的なものとして欲しいと考え自分で作ることにしました。(あと，余ってる部品で何か作りたかった…。)

## 目標
 - 「現在時刻」と「(最寄りバス停の)次のバス時刻」を表示する
 - 「次のバス時刻」と「次のバス時刻までの残り時間」の表示を切り替えれるようにする
 - ブラウザ上から各種設定出来るようにする

# **材料**
## 自作マイコンボード「Saketoba」
![IMG_20171223_163908.jpg](https://qiita-image-store.s3.amazonaws.com/0/135303/9f9f51af-2f1f-0399-efed-73046276c2c0.jpeg)

USBスティック型のESP8266搭載マイコンボードです。
"この形状"かつ"低価格"で"沢山手に入れれそうなもの"を探したのですが見つからなかったので作りました。
試作段階ですのでこれについての詳細は割愛させていただきます。

## タイマー本体
|部品名|型番|数量|
|:---:|:-:|:-:|
|7セグメントLED|HDSP-U513|8個|
|トランジスタ|[2SC1815](http://akizukidenshi.com/catalog/g/gI-04268/)|8個|
|I/Oエキスパンダ|[MCP23017](http://akizukidenshi.com/catalog/g/gI-09486/)|1個|
|100Ω抵抗|[RD16S 100E](http://akizukidenshi.com/catalog/g/gR-16101/)|8個|
|4.7kΩ抵抗|[RD16S 4K7](http://akizukidenshi.com/catalog/g/gR-16472/)|2個|
|10kΩ抵抗|[RD16S 10K](http://akizukidenshi.com/catalog/g/gR-16103/)|1個|
|47kΩ抵抗|[RD16S 47K](/)|1個|
|タクトスイッチ|[DTS-6-V](http://akizukidenshi.com/catalog/g/gP-03647/)|1個|
|ICソケット|[6604S-40](http://akizukidenshi.com/catalog/g/gP-01591/)|1本|
|1x5ピンソケット|[FH150-1x5SG](http://akizukidenshi.com/catalog/g/gC-10397/)|1個|
|1x10ピンソケット|[FH150-1x10SG](http://akizukidenshi.com/catalog/g/gC-07914/)|1個|
|電子ワイヤ|[0.2sq (7/0.18) AWG24x10](http://akizukidenshi.com/catalog/g/gP-10672/)|1パック(10本)|

# **回路設計**
![Bus_timer_回路図.png](https://qiita-image-store.s3.amazonaws.com/0/135303/5a1ba617-1d06-bb39-e250-36a2c8891f55.png)


今回使う7セグメントLEDはコモンカソードなので，GND側をトランジスタでスイッチングしてダイナミック点灯させます。
また，7セグメントLEDの制御にGPIOが16個必要なのですが，Saketobaだと6個が限界なのでI/Oエキスパンダで拡張します。


# **プログラムのフロー**
![BusTimerFlowChart.png](https://qiita-image-store.s3.amazonaws.com/0/135303/20841b9f-4624-c461-d147-79d071cc7399.png)
すごくざっくりですが上記の図のような感じです。

本機器は起動時にNTPで時刻同期をする関係上，Wi-Fiに接続して使用するのが前提条件のため，接続先が登録されていない・接続が失敗した場合はWi-Fi接続モードに移行します。
この場合，ESP8266はAP/サーバモードとして振る舞うので，"ESP_{MAC_ADDR}"と言うSSIDのAPに接続後，ブラウザから192.168.100.1を叩くと設定画面に潜れます。

Wi-Fiへの接続が完了したら時刻表示モードに移行します。ここでは現在時刻と次の電車・バスの時刻を表示します。
更にボタンを押すとカウントダウンモードに移行し，現在時刻と次の電車・バスまでの残り時間を表示します。
この２つのモード中にブラウザからESP8266に潜ると時刻表の設定が出来ます。
なお，時刻表は以下の構造のJSONで設定します。

```json
{
	"from": "盛岡駅前",
	"to": "岩手県立大学入口",
	"time-table": {
		"weekday": [
			{
				"hour": 6,
				"minutes": [
					58
				]
			},
			{
				"hour": 7,
				"minutes": [
					18,
					33,
					48
				]
			},
			{
				"hour": 8,
				"minutes": [
					5,
					15,
					25,
					32,
					35,
					45,
					55
				]
			},
			{
				"hour": 9,
				"minutes": [
					5,
					15,
					20,
					38,
					52,
					53
				]
			},
			{
				"hour": 10,
				"minutes": [
					8,
					12,
					38
				]
			},
			{
				"hour": 11,
				"minutes": [
					8,
					27,
					38
				]
			},
			{
				"hour": 12,
				"minutes": [
					8,
					38
				]
			},
			{
				"hour": 13,
				"minutes": [
					8,
					12,
					38
				]
			},
			{
				"hour": 14,
				"minutes": [
					8,
					38,
					57
				]
			},
			{
				"hour": 15,
				"minutes": [
					8,
					51,
					57
				]
			},
			{
				"hour": 16,
				"minutes": [
					8,
					38,
					47
				]
			},
			{
				"hour": 17,
				"minutes": [
					11,
					24,
					41
				]
			},
			{
				"hour": 18,
				"minutes": [
					11,
					29,
					39
				]
			},
			{
				"hour": 19,
				"minutes": [
					8,
					12,
					38
				]
			},
			{
				"hour": 20,
				"minutes": [
					15,
					40
				]
			},
			{
				"hour": 21,
				"minutes": [
					20
				]
			}
		],
		"saturday": [
			{
				"hour": 7,
				"minutes": [
					30
				]
			},
			...
			{
				"hour": 19,
				"minutes": [
					10
				]
			}
		],
		"holiday": [
			{
				"hour": 7,
				"minutes": [
					30
				]
			},
			...
			{
				"hour": 19,
				"minutes": [
					10
				]
			}
		]
	}
}
```

# **完成**
![完成画像_上](http://or2.mobi/data/img/188668.jpg)

![完成画像_横](http://or2.mobi/data/img/188669.jpg)
汚い配線ですみません…。
あとはこれをSaketobaにスタックさせれば完成です。

Youtubeに動作確認の動画をアップロードしています↓
[![動作確認動画](http://img.youtube.com/vi/ljn5RJv_m24/0.jpg)](https://youtu.be/ljn5RJv_m24)

# **まとめ**
現状では1種類の時刻表しか保持出来ないので，いずれは複数の時刻表を保持できるようにしたいです。
あとは急ごしらえとは言え，Wi-Fiのパスワードを平文で保存してしまっているのでその辺もどうにかしたい…。

なお，今回利用したソースコードや回路図は以下のリポジトリに上げています。
[バス時刻表ジェネレーター](https://github.com/c-ardinal/bus-timetable-generator) ... 岩手県交通のバス時刻表をJSON形式で生成するツール
[カウントダウンタイマー](https://github.com/c-ardinal/saketoba.countdown-timer) ... 今回制作したカウントダウンタイマー

さて明日はいよいよアドベントカレンダー最終日。担当は[hellooo](https://qiita.com/hellooo)くんです。