ThingSpeakは15秒の制限があるので、30秒周期でデータを送ることに。
自然な発想でTimerを仕込むが、何故かうまく通信できない。
UDPならうまく行ったのに何故??
参考にしたのは以下のサイト。
http://www.esp8266.com/viewtopic.php?p=62981
// ソースはこんな感じ
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Ticker.h>
extern "C" {
#include "user_interface.h"
}
const char* SSID = "<SSID>", PASS= "<PASS>";
Ticker tic1;
void setup() {
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
IPAddress myIP = WiFi.localIP();
tic1.attach_ms(30 * 1000, tic1_loop); // 30秒に1回、tic1_loopを実行
}
void sendMessage(String buf) {
HTTPClient http;
String url = "http://api.thingspeak.com/update?key=";
String key = <ThingSpeak API KEY>;
http.begin(url + key + buf);
int httpCode = http.GET();
if(httpCode) {
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
if(httpCode == 200) {
String payload = http.getString();
Serial.println(payload);
}
} else {
Serial.printf("[HTTP] GET... failed, error: %d\n", httpCode);
}
http.end();
}
void tic1_loop(){
sendMessage(<センサデータ>);
}
void loop{}
いろいろ試行錯誤して気づいたのだが、HTTPClientも割り込みを使うので割り込みの中では使えない。
検証は以下の通り。
1)sendMessage()を単体で呼ぶ ⇒OK
2)loop内でdelayでsendMessage()を何度も動かす ⇒OK
3)Timer割り込みでsendMessage()を何度も動かす ⇒NG
noInterrupts()なのが問題なのでinterrupts()を明示的に呼び出せばHTTPClientも動くはずだが、今回はシンプルにフラグ処理で逃げることにした。
char flag = 0;void interruptFunc(){
flag = 1;
}
void loop{
if(flag){
sendMessage(<センサデータ>);
flag = 0;
}
}
これでOKだった。
ESP8266は1か月以上動かしているけど、元気に温度とドアの開閉を記録してくれている。
0 件のコメント:
コメントを投稿