wifi搭載マイコンでSlackに日本語投稿

概要

ESP8266(Arduino IDEで書けるwifi搭載マイコン)で、ボタンを押したらSlackに投稿できるようにしました。日本語も使えました。NodeMcu v3(Lolin)というESP8266搭載ボードを使いました(以降Lolin)。(名前が可愛いですね)。
弊社はSlackで出退勤やお休みや遅刻連絡のログを残しています。具体的には「おはようございます」や「ぞい」と投稿すると出勤時間が記録される、といったような感じです。以下に、ボタンを押すとSlackの任意のチャンネルに「ぞい」と投稿するスクリプトを載せます。
はじめての電子工作。先生(すぺしゃるさんくす):@izm

作業前の確認事項(初歩)

まず、LEDを光らせました。Arduino Unoと違ってLolinは内蔵LEDがないのでLEDを刺さなければいけませんでした。ピン配置図はボードの名前で検索すると出てきました。

f:id:nyanko_omori:20160814141607j:plain

これを見ながら、VCC GNDにLEDをつないで、ボードが生きてるか(初期不良がないか)確認をしました。 じわじわと熱くなるし、そのまま放置すると破裂すると聞いてこわごわ確認をしていました。(本当は抵抗が必要なんだそうです)。

スイッチ関連の確認

タクトスイッチ(INPUT_PULLUP)がLolinでも動くことを確認しました。 また、スクリプトチャタリングを防止する記述を書きました。 Lolinは書き込み速度が比較的遅い(らしい)ので、ProMicroで先にwifiを使わなくていい部分などの簡単な動作確認をしておきました。

f:id:nyanko_omori:20160801224237j:plain

slackへの投稿

以下の記事を参考にさせていただきました。

www.iotforest.com

Arduino IDEは内部ではutf-8ArduinoのシリアルモニタはSJISなのでシリアルモニタ上では文字化けしてしまいますが、Slackはutf-8なので文字化けせずにそのまま投稿することができました。

参考文献

以下の記事を参考にさせていただきました。

qiita.com

qiita.com

スクリプト

以下にスクリプトを載せます。 もしご使用の際は、適宜ご自身の環境に合わせて書き換えてください。 動作確認のために、Slackに投稿する際にLEDを光らせるようにしました。

#include <ESP8266WiFi.h>


int input=D5;
int led=D7;
//チャタリング防止
int prev=1;


// your wifi details
const char* ssid = "ssid";
const char* password = "pass";


// slack webhook host and endpoint information
const char* host = "hooks.slack.com";
const char* SlackWebhookURL = "url";


// SSL Certificate finngerprint for the host
const char* fingerprint = "fingerprint";

void setup() {
pinMode(input, INPUT_PULLUP);
pinMode(led, OUTPUT);

Serial.begin(115200);
delay(100); 
// We start by connecting to a WiFi network

Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

Serial.println("WiFi connected"); 
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}

void loop() {


int sensorVal = digitalRead(input);
//押してる間はsensorval=0;
//print out the value of the pushbutton
//スイッチオンになった瞬間に動作
if(prev==1 && sensorVal==0){
Serial.println(sensorVal);
Serial.println("find switch on");
}
//スイッチオフになった瞬間に動作
//ここでslackに書き込む
if(prev==0 && sensorVal==1){
Serial.println(sensorVal);
Serial.println("find switch off");


String channel = "#channel";
String username = "nyanko_omori";
String message = "ぞい";


Serial.print("connecting to ");
Serial.println(host);


// create a secure connection using WiFiClientSecure
WiFiClientSecure client;
const int httpPort = 443;
if (client.connect(host, httpPort)) {


// verify the signature of the ssl certificate
if (client.verify(fingerprint, host)) {
Serial.println("ssl cert matches");
} else {
Serial.println("ssl cert mismatch");
}

String PostData="payload={\"channel\": \"" + channel + "\", \"username\": \"" + username + "\", \"text\": \"" + message + "\", \"icon_emoji\": \":ghost:\"}";
Serial.println(PostData);

client.print("POST ");
client.print(SlackWebhookURL);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(host);
client.println("User-Agent: ArduinoIoT/1.0");
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded;");
client.print("Content-Length: ");
client.println(PostData.length());
client.println();
client.println(PostData);

delay(500);

// Read all the lines of the reply from server and print them to Serial for debugging
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
}

Serial.println();
Serial.println("closing connection"); 
}

delay(6000);




}
prev = sensorVal;

delay(10);
// Keep in mind the pullup means the pushbutton's
// logic is inverted. It goes HIGH when it's open,
// and LOW when it's pressed. Turn on pin 13 when the
// button's pressed, and off when it's not:

if (sensorVal == HIGH) {
digitalWrite(led, LOW);
} else {
digitalWrite(led, HIGH);
}


}