M5StickCでNode-Redにアクセス

目次
RPi で回線遅延シュミレーターを作る続き。
UIの拡張
回線遅延シュミレーターを操作するのに、以下の順にUIを拡張した。
- ssh login でコマンド実行
- LED(8個)で状況表示
- Node-Red で操作
- M5StickC で操作
最後は、M5StickC で操作できるようにする。 ボタンを押すと、遅延msecを増やす、リセットするなど。
似たようなものは、以下で作成済み。
endpoint
最初は、遅延時間を100msecづつ伸ばすendpointを想定していたけれど、うざい。 ということで、こんなendpointを用意した。
http://rsslss.local:1880/tc?delay_msec=100
100 は、 100msec ということ。
ボタンを押す毎に、以下の設定を順繰りに繰り返すようにした。
- 0
- 100msec
- 200msec
- 500msec
- 1000msec
- 1500msec
Arduino プログラム
仕様
- 起動時に以下のAPにアクセスする。
- SSID: rpisll
- PASS: ソースコードの12行目に埋込
-
WIFI接続に成功したら、ntpd(
ntp.nict.jporntp.jst.mfeed.ad.jp) に時刻合わせする。 -
ボタンAを押すと、遅延時間を順次変更する
-
ボタンBを押すと、遅延時間を
0に変更する。
追加で利用したライブラリ
NodeRed のREST APIが返すJsonを解析するために、 ArduinoJson を利用した。

rpissl_ctl.ino · Gistcpp
#include <M5StickC.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include "time.h"
//
// Setting
//
const char* SSID = "rpilss";
const char* PASSWORD = "パスワード";
const char* lss_end_point = "http://192.168.100.1:1880/tc";
const int Delays[] = { 0, 100, 200, 500, 1000, 1500 };
#define PIN_LED 10
//
// Global Variable
//
int Delay_msec = 0;
int Delay_next_msec = 0;
char Lan_ip[128];
//
// setup RTC by NTP
//
void setup_rtc() {
struct tm timeinfo;
uint8_t hh, mm, ss;
RTC_TimeTypeDef TimeStruct;
// connect NTP server
configTime(9 * 3600, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp");
if (!getLocalTime(&timeinfo)) {
M5.Lcd.println("Failed to obtain time");
return;
}
//
// set localtime to RTC
//
hh = timeinfo.tm_hour;
mm = timeinfo.tm_min;
ss = timeinfo.tm_sec;
// Serial.printf("%02d:%02d:%02d\r\n", hh, mm, ss);
TimeStruct.Hours = hh;
TimeStruct.Minutes = mm;
TimeStruct.Seconds = ss;
M5.Rtc.SetTime(&TimeStruct);
}
//
// connect wifi
//
int setup_wifi() {
M5.Lcd.setTextSize(1);
M5.Lcd.setCursor(0, 0);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextColor(DARKGREY);
WiFi.disconnect(true);
M5.Lcd.print("Connecting to ");
// Serial.println("Connecting to ");
M5.Lcd.printf(SSID);
WiFi.begin(SSID, PASSWORD); //connect to wifi
int count = 100;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
M5.Lcd.print(".");
count -= 1;
if (count == 0) {
// Serial.println("max try failed");
M5.Lcd.setTextSize(3);
M5.Lcd.setTextColor(RED);
M5.Lcd.setCursor(0, 0);
M5.Lcd.println("fail wifi connect");
return -1;
}
}
M5.Lcd.println("");
M5.Lcd.println("WiFi connected.");
M5.Lcd.print("IP address: ");
M5.Lcd.println(WiFi.localIP());
M5.Lcd.println();
return 0;
}
void setup() {
Serial.begin(9600);
M5.begin();
M5.Axp.ScreenBreath(10);
M5.Lcd.setRotation(3); // 左を上にする
M5.Lcd.setTextSize(1);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextColor(DARKGREY);
delay(500);
// PIN MODE setup
pinMode(PIN_LED, OUTPUT); // LED
//
// Wifi
//
setup_wifi();
//
// setup RTC time
//
setup_rtc();
// LED OFF
digitalWrite(PIN_LED, HIGH);
}
//
// change delay msec to RPi
//
void change_delay(int delay_msec) {
HTTPClient http;
int httpCode;
char url[256];
sprintf(url, "%s?delay_msec=%d", lss_end_point, delay_msec);
Serial.println(url);
http.begin(url);
httpCode = http.PATCH((uint8_t*)"", 0);
if (httpCode == 200) {
Stream* resp = http.getStreamPtr();
DynamicJsonDocument json_response(255);
deserializeJson(json_response, *resp);
Delay_msec = json_response["delay_msec"];
strncpy(Lan_ip, json_response["lan_ip"], sizeof(Lan_ip));
}
http.end();
return;
}
void loop() {
const int WAIT_TIME = 300;
RTC_TimeTypeDef RTC_TimeStruct;
int next_delay_msec;
if (WiFi.status() != WL_CONNECTED) {
Serial.println("not connect");
if (setup_wifi() < 0) {
return;
}
// Serial.println("connect ok");
}
// pinの状態など更新
M5.update();
int pressBtn = 0;
int is_reset = false;
if (M5.BtnA.wasPressed()) {
pressBtn = 1;
}
if (M5.BtnB.wasPressed()) {
is_reset = true;
pressBtn = 2;
}
Delay_next_msec = 0;
if (pressBtn) {
// get time
M5.Rtc.GetTime(&RTC_TimeStruct);
M5.Lcd.setTextSize(1);
M5.Lcd.setCursor(32, 9*8);
M5.Lcd.setTextColor(DARKGREEN);
M5.Lcd.fillRect(0, 9*8, 256, 12, BLACK);
M5.Lcd.printf("Time: %02d : %02d : %02d\n",
RTC_TimeStruct.Hours, RTC_TimeStruct.Minutes, RTC_TimeStruct.Seconds);
// LED ON
digitalWrite(PIN_LED, LOW);
Serial.println("Delay_msec");
Serial.println(Delay_msec);
if (!is_reset) {
for (int i; i < sizeof(Delays); i++) {
if (Delay_msec == Delays[i]) {
if (i < (sizeof(Delays)-1)) {
Delay_next_msec = Delays[i+1];
}
break;
}
}
}
change_delay(Delay_next_msec);
// display
M5.Lcd.fillRect(0, 4*8, 256, 32, BLACK);
// LAN IP
M5.Lcd.setTextSize(1);
M5.Lcd.setCursor(0, 4*8);
M5.Lcd.setTextColor(DARKGREEN);
M5.Lcd.printf("eth0 IP: %s\r\n", Lan_ip);
// delay msec
M5.Lcd.setTextSize(1);
M5.Lcd.setCursor(0, 6*8);
M5.Lcd.setTextColor(DARKGREEN);
M5.Lcd.printf("delay:\r\n");
M5.Lcd.setTextSize(2);
M5.Lcd.setCursor(32, 6*8);
M5.Lcd.setTextColor(DARKGREEN);
M5.Lcd.printf(" %d msec\r\n", Delay_msec);
// LED OFF
digitalWrite(PIN_LED, HIGH);
}
delay(WAIT_TIME);
}