Androidのメモとか

ポキオの日記です。今日も遅延してない。

ESP8266を使った京急の運行状況を監視するガジェットを進化させた

前回までの話。

relativelayout.hatenablog.com

京急が遅延や運転見合わせをすると、光るガジェットを作りました。わりとポジティブなフィードバックが多かったし、刺さる人にはかなり刺さってた気がします。IoTLTでも発表させていただいたし、人生初のデブサミ出展も果たせました。ただ、課題も見つかりました。

ガジェットに足りなかったもの

ガジェットはできたものの、いまいちパンチが弱かった気がした。やっぱりガジェットは光ってなんぼ。光ってこそモテるわけです。

ギャル電さん並に光ってみたいものの、流石に急に光るとちょっとアレかなと思い、まずはRGBフルカラーLEDを買って様子見ようと思った。

RGBフルカラーLED

輝くと決めたら、あとは作るだけ

輝くガジェット。でも京急への愛は捨てられない。取り敢えず、京急を輝かせようと思ったわけです。前回はガチャガチャで引き当てた京急を使いましたが、先頭車両が出てくるまで、それなりのコストがかかったので、今回はBトレインショーティーというプラモデルを潔く購入しました。

Bトレインショーティー 京急

Bトレインショーティー 京急

プラモデルの中に、先程のLEDを詰めるわけですが。世の中には便利なものがあって、ハサミで切れるユニバーサル基板のようなものがあるのを見つけてしまい、今回はこれを使ってみました。

サンハヤト 薄型ユニバーサル基板 UB-THN01

サンハヤト 薄型ユニバーサル基板 UB-THN01

プラモデルとはいえ、かなり小さいわけです。それにピッタリ入るような基盤をハサミで簡単に作れるのは本当に素晴らしいです・・・。そんなこんなでプラモデルの中にLEDを埋め込むことができました。

LEDの制御や情報の取得はESP8266

やっぱり安心と信頼のESP8266です。

ESPr Developer(ESP-WROOM-02開発ボード)

ESPr Developer(ESP-WROOM-02開発ボード)

ESP8266

ESP8266

基本的なシーケンスは既存のガジェットと変わりませんが、運行状況によって光り方を変えるようにしています。

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <Adafruit_NeoPixel.h>

char ssid[] = "xxx";
char password[] = "yyy";

char unkopage[] = "unkou.keikyu.co.jp";
int intervalSec = 10 * 60;

#define PIN 4
#define NUMLED 4

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMLED, PIN, NEO_RGB + NEO_KHZ800);


void setup() {
  Serial.begin(115200);
  Serial.println("");

  pixels.begin();
  pixels.setBrightness(60);
}

void loop() {
  connectWifi();
  String result = getPageSource();
  Serial.println(result);
  disconnectWifi();

  if (result.indexOf("平常") > 0) {
    Serial.println("平常通り運転!");
    delay(intervalSec * 1000);
    return;
  }

  if (result.indexOf("受託") > 0) {
    Serial.println("振替輸送受託!");
    ledExtreme(intervalSec);
    return;
  }

  if (result.indexOf("見合わせ") > 0) {
    Serial.println("運転見合わせ!");
    ledStopped(intervalSec);
    return;
  }

  if (result.indexOf("遅れ") > 0 || result.indexOf("乱れ") > 0 {
    Serial.println("遅延!");
    ledDelayed(intervalSec);
    return;
  }

  Serial.println("もう一度取得します!");
  ledConnecting(3);
}

void connectWifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    ledConnecting(3);
  }

  Serial.println("connected!");
}

void disconnectWifi() {
  WiFi.disconnect();
  Serial.println("disconnected!");
}

String getPageSource() {
  WiFiClient client;

  if ( !client.connect(unkopage, 80) ) {
    return String("");
  }

  client.print(String("GET ") + "/" + " HTTP/1.1\r\n" +
               "Host: " + unkopage + "\r\n" +
               "Range: bytes=8000-9000\r\n" +
               "Connection: close\r\n\r\n");
  client.println();

  delay(1000);

  String body = "";
  String unko = "<!-- ======================== 運行情報 =================================== -->";

  while (client.available()) {
    body += client.readStringUntil('\r');
  }

  body = body.substring(body.indexOf(unko) + unko.length());
  body = body.substring(0, body.indexOf(unko));

  return body;
}

// 白い点滅
void ledConnecting(int sec) {
  int count = 0;

  while (count < sec) {
    for (int i = 0; i < 256; i += 5) {
      setColor( i, i, i);
    }

    for (int i = 255; i >= 0; i -= 5) {
      setColor( i, i, i);
    }

    count++;
  }
}

// 黄色い点滅
void ledDelayed(int sec) {
  int count = 0;

  while (count < sec) {
    for (int i = 0; i < 256; i += 5) {
      setColor( i, i, 0);
    }

    for (int i = 255; i >= 0; i -= 5) {
      setColor( i, i, 0);
    }

    count++;
  }
}

// 赤い点滅
void ledStopped(int sec) {
  int count = 0;

  while (count < sec) {
    for (int i = 0; i < 256; i += 5) {
      setColor( i, 0, 0);
    }

    for (int i = 255; i >= 0; i -= 5) {
      setColor( i, 0, 0);
    }

    count++;
  }
}

// パリピ
void ledExtreme(int sec) {
  int count = 0;

  while (count < sec) {

    for (int i = 0; i < 20; i++) {
      setRandomColor();
      delay(50);
    }

    count++;
  }
}

void setColor(int r, int g, int b) {
  for (int i = 0 ; i < NUMLED; i++) {
    pixels.setPixelColor(i, pixels.Color(r, g, b));
    pixels.show();
  }
  delay(10);
}

void setRandomColor() {
  for (int i = 0 ; i < NUMLED; i++) {
    pixels.setPixelColor(i, pixels.Color(64 * random(1, 5) - 1 , 64 * random(1, 5) - 1 , 64 * random(1, 5) - 1 ));
    pixels.show();
  }
  delay(10);
}

相変わらずのクソコードですが、京急の運行状況ページをパースして、現在の状況を判断しています。とはいえ、なかなか遅延しないため、動作確認ができていないパターンがあり、正しく動作しないかもしれません・・・。

改めて見るとif文がキモいですね・・・。setup()loop()は極力汚さないコーディングを目指します。(きっといつかは)

デモ

こんな感じで光ります。(デモ用のコードで動作させています)

#keikyu #esp8266

A post shared by pokio (@pokipokio) on

「Androidのメモとか」は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。

このブログは個人的なメモ書きであったり、考えを書く場所であります。執筆者の所属する団体や企業のコメントや意向とは無関係であります。また、このブログは必ずしも正しいことが書かれているとは限らず、誤字脱字や意図せず誤った情報を載せる場合がありえます。それが原因で読者が不利益を被ったとしても、執筆者はいかなる責任も負いません。ありがとうございます。