前回までの話。
relativelayout.hatenablog.com
京急 が遅延や運転見合わせをすると、光るガジェットを作りました。わりとポジティブなフィードバックが多かったし、刺さる人にはかなり刺さってた気がします。IoTLTでも発表させていただいたし、人生初のデブサミ 出展も果たせました。ただ、課題も見つかりました。
ガジェットに足りなかったもの
ガジェットはできたものの、いまいちパンチが弱かった気がした。やっぱりガジェットは光ってなんぼ。光ってこそモテるわけです。
ギャル電さん並に光ってみたいものの、流石に急に光るとちょっとアレかなと思い、まずはRGBフルカラーLEDを買って様子見ようと思った。
輝くと決めたら、あとは作るだけ
輝くガジェット。でも京急 への愛は捨てられない。取り敢えず、京急 を輝かせようと思ったわけです。前回はガチャガチャで引き当てた京急 を使いましたが、先頭車両が出てくるまで、それなりのコストがかかったので、今回はBトレインショーティー というプラモデルを潔く購入しました。
プラモデルの中に、先程のLEDを詰めるわけですが。世の中には便利なものがあって、ハサミで切れるユニバーサル基板のようなものがあるのを見つけてしまい、今回はこれを使ってみました。
プラモデルとはいえ、かなり小さいわけです。それにピッタリ入るような基盤をハサミで簡単に作れるのは本当に素晴らしいです・・・。そんなこんなでプラモデルの中にLEDを埋め込むことができました。
LEDの制御や情報の取得は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 Mar 24, 2017 at 8:14am PDT