Androidのメモとか

そふとうぇあえんじにゃーの備忘録

Google Apps ScriptのWebAPIで、ESP8266が光らせるLEDの色を指定する

GASとESP8266の禁断の関係。 (タイトルの日本語がおかしかったので修正したけど、まだなんかおかしい)

ESP8266ですべて処理させる時代は終わった

個人的にはそう思ってます(笑)

relativelayout.hatenablog.com

以前、思いつきで、「GASですべて判断して、ESP8266はGPIOだけ制御してればイイのでは?」みたいなことを考えていました。

ESP8266 Google Apps Script

要は、何かWeb上の情報をもとに判断して、フルカラーのLEDの光る色を変えるくらいなら、判断ロジックをGASに集約させて、GASとESP8266の界面では、何色に光らせるか会話しておけばいいのでは?ということでした。だんだん動作確認ができてきたので、実際にそういうコードを書いてみます。

GAS側の実装

WebAPIでアクセスされた時に、何色に光らせるかをRGBで返すようにします。特に難しいことはしたくないので、Plain Textで返すクソコードになっています。また、今回は色は決め打ちで赤としています。

function doGet() {
  return ContentService.createTextOutput("pokio,255,0,0");
}

pokioという文字をプレフィックスで付けています。念のため、ESP8266側では、プレフィックスの有無を確認します。(たぶん、その必要はないと思うけど、念のため)

ESP8266側

WebAPIを叩いて取得した文字列で、まずプレフィックスの有無を確認。その後、R/G/Bの値をintに変換して、その色で一定期間光らせます。WebAPIは定期的に叩いて、その都度色を計算します。

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

#define PIN 4
#define NUMLED 1
#define SSID "xxxxx"
#define PASSWORD "yyyyy"

#define HTTPS_PORT 443
#define HOST "script.google.com"
#define URL "/macros/s/zzzzz/exec"
#define FINGERPRINT "ここにフィンガープリント"

#define INTERVAL_SEC 60 // 60秒おきにWebAPIを叩くつもり

HTTPSRedirect* client = nullptr;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMLED, PIN, NEO_RGB + NEO_KHZ800);

void setup() {
  // Serialの初期化
  Serial.begin(115200);
  Serial.println("");

  // マイコン内蔵RGB LEDの初期化
  pixels.begin();
}

void loop() {
  // Wi-Fi接続開始
  connectWifi();

  // Google Apps Scriptを叩く
  String result = doRedirectGet();

  // Wi-Fi接続終了
  disconnectWifi();

  // サフィックスを念のため確認
  if (!result.startsWith("pokio")) {
    delay(INTERVAL_SEC * 1000);
    return;
  }

  letMeBlink(result);
}

// Wi-Fi接続
void connectWifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(SSID, PASSWORD);

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

  Serial.println("Wi-Fi connected");
}

// Wi-Fi切断
void disconnectWifi() {
  WiFi.disconnect();
  Serial.println("Wi-Fi disconnected");
}

// 取得した文字列をパースして、指定された色で光らせる
void letMeBlink(String result) {
  result = result.substring(result.indexOf(",") + 1);
  int r =  result.substring(0, result.indexOf(",")).toInt();

  result = result.substring(result.indexOf(",") + 1);
  int g =  result.substring(0, result.indexOf(",")).toInt();

  result = result.substring(result.indexOf(",") + 1);
  int b =  result.substring(0, result.indexOf(",")).toInt();

  Serial.println(String("blinking : ") + r + "," + g + "," + b);
  blinkRGB(INTERVAL_SEC, r, g, b);
}

// 点滅
void blinkRGB(int sec, int r, int g, int b) {
  int count = 0;

  while (count < sec) {
    for (int i = 0; i < 256; i += 5) {
      setColor((r * i / 255), (g * i / 255), (b * i / 255));
    }

    for (int i = 255; i >= 0; i -= 5) {
      setColor((r * i / 255), (g * i / 255), (b * i / 255));
    }

    count++;
  }
}

// LEDを指定した色で光らせる
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);
}

// Redirectを回避してHTTP-GETする
String doRedirectGet() {
  String body = "";
  client = new HTTPSRedirect(HTTPS_PORT);

  if (!client->connect(HOST, HTTPS_PORT)) {
    Serial.println("connection failed");
    return body;
  }

  if (!client->verify(FINGERPRINT, HOST)) {
    Serial.println("certificate doesn't match");
  }

  client->GET(URL, HOST);
  body = client->getResponseBody();
  delete client;
  client = nullptr;
  return body;
}

動作確認

まず、シリアルモニターから。

..Wi-Fi connected
Wi-Fi disconnected
blinking : 255,0,0

しっかり、赤で光らせることを理解できていそうです。

ESP8266 Google Apps Script

ポキオ基板v2上のLEDも赤く光っています。

これはイケそう

というわけで、ESP8266は判断ロジックは持たず、すべてGASにまとめても、LEDの色を変えることはできそう。今後は、GASに色んなロジックを搭載して、LEDを光らせまくります。Lチカ最高。

暗闇だと趣深いですね。

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

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