概要
電車の運行状況を鉄道会社のホームページから取得し、通勤ルートの電車が通常運行なのか、遅延している可能性があるのかをLEDの色で判断できるようにする。
作ったきっかけ
毎朝、スマホで電車の運行状況を見る手間をなくしたい。
朝起きて、家を出るまでに電車の遅延情報がLEDで分かり(チラッとLEDを見るだけ!)、電車が遅れていることがあらかじめ分かっていれば、少し早く1本前の電車に乗るなど予定変更ができる。
と考えました。
機能
・JR九州のホームページにある運行状況を読み取り、通勤ルートの情報が掲載されたら、LEDの色を変える。
※通勤ルートは鹿児島本線 門司港~久留米間としています。
・乗車する駅と降車する駅が遅延情報記載の区間であった場合、赤色LEDを発光させる。(遅延の可能性:大)
・乗車する駅と降車する駅が遅延情報記載の区間に1つでも含まれる場合、黄色LEDを発光させる。(遅延の可能性:中)
・乗車する駅と降車する駅が遅延情報がない場合は緑色LEDを発光させる。(通常運行)
・5分間隔で、情報更新する。
工夫したところ
・ホームページにある遅延情報は九州全域の路線が含まれるため、通勤ルートに影響ある情報のみに絞れるようにしました。
部品
・ESP32-WROOM-32D開発ボード(ESP32-DevKitC-V4 )
・ブレッドボード(EIC-803)
・LED(赤、黄、緑)
・抵抗220Ω x3
・ジャンパ線
・USBケーブル(TypeB micro)
開発環境
PC:Windows10
開発ソフト:Arduino Software (IDE)
(ESP32 ボードを追加しています)
実装方法・回路図
ブレッドボードに開発ボード(ESP32-DevKitC-V4)をさして、実装します。3色のLEDと抵抗を回路図通りにジャンパ線で結線します。ESP32-DevKitC-V4はUSBで電源供給(スマホの充電器を使用)しています。実装した写真と回路図を示します。
プログラムの説明
①設定
LEDを光らせるため、デジタルピンを割り当てます。
5 : 赤色LED
17:黄色LED
16:緑色LED
②WiFi接続
Wifi.begin()でアクセスポイントに接続します。
WiFi.status()で、接続するまで、待ちます。
待つ間、黄色LEDを点滅させて、接続がうまく行くかの状態がわかるようにしています。
③HTTPClient(HTML取得)
http.begin(url)でURLを登録します。
その後、http.GET()でGETリクエスト送信します。
※エラーの場合は負の値が返ってくるのでエラー処理
http.getString()でHTMLの内容をStringの変数に格納します。
④WiFi切断
Wifi.disconnect()でWiFi接続を切断します。
⑤遅延情報の検索
Stringの関数を使い、遅延情報の箇所のみを切り出します。
.indexOfで遅延情報が記載される【】をの文字の位置を得ます。
.substringで文字の位置を指定し、切り出し、配列listに格納します。
[例] HTMLにある遅延情報
・・・いろんな情報が含まれている・・・
●鹿児島本線(上下線)運休及び遅延
【遅延:小倉 から 博多】
・・・いろんな情報が含まれている・・・
であれば、「【遅延:小倉 から 博多」を探します。
⑥通勤ルートへの影響を検索
遅延情報を格納した配列listに、通勤ルートに影響する駅名がないかを検索します。
例:【遅延:小倉 から 博多 であれば、
遅延情報を切り出した文字列に対象の駅名(遅延発生区間の起点駅)がないかを探します。(例:小倉)
その後、遅延情報を切り出した文字列に対象の駅名(遅延発生区間の終点駅)がないかを探します。(例:博多)
遅延の可能性(中):遅延発生区間の始点、終点内に、通勤ルートの対象駅が1つ含まれる
遅延の可能性(大):遅延発生区間の始点、終点内に、通勤ルートの対象駅が2つ含まれる
としています。変数k,nがその影響度を示しています。
⑦通勤ルートへの影響をLEDで表示
遅延の可能性(大):赤色LED
遅延の可能性(中):黄色LED
通常運行 :緑色LED
⑧5分待ち
delay()で待ちます。
コード
unkou_check.ino
#include <WiFi.h>
#include <HTTPClient.h>
/*LED出力ピン番号*/
#define LED_RED 5
#define LED_YELLOW 17
#define LED_GREEN 16
/*Wi-Fi接続先*/
char ssid[] = "WiFi接続先名";
char password[] = "WiFi接続先パスワード";
String list[40] = {"\0"}; /*分割された文字列を格納する配列*/
/*駅名(遅延、運休が発生した時、通勤ルートの電車に影響がでる駅名)*/
/*[例]
●鹿児島本線(上下線)運休及び遅延
【遅延:小倉 から 博多】
のように運行情報がホームページに掲載されるので、遅延発生区間に駅名(station)があるかを検索する
*/
String station[49] = {"門司港","小森江","門司","小倉","西小倉","九州工大前","戸畑","枝光","スペースワールド",
"八幡","黒崎","陣原","折尾","水巻","遠賀川","海老津","教育大前","赤間","東郷","東福間",
"福間","千鳥","古賀","ししぶ","新宮中央","福工大前","九産大前","香椎","千早","箱崎","吉塚",
"博多","竹下","笹原","南福岡","春日","大野城","水城","都府楼南","二日市","天拝山","原田",
"けやき台","基山","弥生が丘","田代","鳥栖","肥前旭","久留米"};
void setup() {
pinMode(LED_RED, OUTPUT); /*赤色LED 出力ピン設定*/
pinMode(LED_YELLOW, OUTPUT); /*黄色LED 出力ピン設定*/
pinMode(LED_GREEN, OUTPUT); /*緑色LED 出力ピン設定*/
/*起動時のLED点滅*/
digitalWrite(LED_RED, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_GREEN, LOW);
delay(1000);
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_YELLOW, HIGH);
digitalWrite(LED_GREEN, HIGH);
delay(1000);
digitalWrite(LED_RED, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_GREEN, LOW);
}
void loop() {
int split_start;
int split_end;
int serach;
int i;
HTTPClient http;
char url[] = "https://www.jrkyushu.co.jp/trains/unkou.php"; /*ホームページのURL*/
/*WiFi接続*/
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { /*接続完了するまで、黄色LEDを点滅させる*/
digitalWrite(LED_YELLOW, HIGH);
delay(500);
digitalWrite(LED_YELLOW, LOW);
}
digitalWrite(LED_YELLOW, LOW); /*接続完了後、黄色LEDを消灯*/
http.begin(url); /* URLの登録 */
int httpCode = http.GET(); /* GETリクエスト送信 */
String payload = "";
if (httpCode < 0) { /* HTTPのリターンコードがエラーの場合は負の値 */
payload = http.errorToString(httpCode);
}
else{
payload = http.getString(); /*htmlの内容を変数に格納する*/
}
http.end();
/* WiFi切断 */
WiFi.disconnect();
split_end = 1;
split_start = 1;
memset(list, '\0', sizeof(list)); /*格納する初期化*/
/*運行状況で遅延が発生している駅の区間を切り出し、list[i]に格納する*/
for( i=1; ((split_start > 0) and (split_end > 0)); i++){ /*切り出す文字【、】がない場合はfor文を抜ける*/
list[i] = (payload.substring((split_start), (split_end)));
split_start = payload.indexOf("【", split_end);
split_end = payload.indexOf("】", split_start);
}
/*切り出した文字列の中に、通勤ルートに影響がある駅名がないかを探す*/
int k = 0;
int n = 0;
for(serach = 1; serach < i; serach++){
for(k=0; k<49; k++){
if(list[serach].indexOf(station[k]) > 0){ /*遅延情報を切り出した文字列に対象の駅名(遅延発生区間の起点駅)がないかを探す*/
list[serach] = list[serach] + "HIT1";
for(k=k+1;k<49;k++){
if(list[serach].indexOf(station[k]) > 0){ /*遅延情報を切り出した文字列に対象の駅名(遅延発生区間の終点駅)がないかを探す*/
list[serach] = list[serach] + "HIT2";
}
}
}
}
}
/*通勤ルートへの影響を検索*/
k = 0;
n = 0;
for(serach=1; serach < i; serach++){
if(list[serach].indexOf("HIT1") > 0){ /*遅延発生区間の始点、終点内に、通勤ルートの対象駅が1つ含まれる:遅延の可能性:中*/
k = 1;
}
else{
if(list[serach].indexOf("HIT2") > 0){ /*遅延発生区間の始点、終点内に、通勤ルートの対象駅が2つ含まれる:遅延の可能性大*/
n = 2;
}
}
}
/*結果をLEDで表示*/
/*いったんすべて消灯*/
digitalWrite(LED_RED, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_GREEN, LOW);
i = k + n;
if(i == 3){
digitalWrite(LED_RED, HIGH); /*遅延の可能性:大 → 赤色LED点灯*/
}
if(i == 2){
digitalWrite(LED_RED, HIGH); /*遅延の可能性:大 → 赤色LED点灯*/
}
if(i == 1){
digitalWrite(LED_YELLOW, HIGH); /*遅延の可能性:中 → 黄色LED点灯*/
}
if(i == 0){
digitalWrite(LED_GREEN, HIGH); /*正常運行 → 緑色LED点灯*/
}
delay(60000*5); /*5分待ち*/
}
おわりに
スマホで、ネットに接続してもあたりまえと思ってしまいますが、自分が作ったArduino(ESP32)がネットにつながり、処理してくれ、LEDでお知らせしてくれるだけで、嬉しく思いました。
スマホをインターフェースにするよりも、LEDの方が、瞬時に判断できるので、その他の情報もお知らせできると面白いかなと思います。
参考
ESP32の使い方について、参考にさせて頂きました。ありがとうございます。
Arduino(ESP32)ライブラリリファレンス
投稿者の人気記事
-
46yomu
さんが
2021/02/26
に
編集
をしました。
(メッセージ: 初版)
-
46yomu
さんが
2021/02/26
に
編集
をしました。
(メッセージ: 章番号を修正しました。)
-
46yomu
さんが
2021/02/26
に
編集
をしました。
(メッセージ: 章番号表示を修正しました。)
-
46yomu
さんが
2021/02/27
に
編集
をしました。
(メッセージ: 部品名、回路図を修正しました。)
-
46yomu
さんが
2021/02/28
に
編集
をしました。
(メッセージ: 実装方法の説明を詳細にしました。)
ログインしてコメントを投稿する