前回の続き。

M5StickCでWifi と SerialのI/Fを作る。

配線

G26とG0をRX/TXに利用する。

program

wifi http 2 serial · Gistcpp
#include <M5StickC.h>
#include <WiFi.h>
#include "time.h"
#include <HTTPClient.h>
#include <HTTPServer.hpp>
#include <HTTPRequest.hpp>
#include <HTTPResponse.hpp>

using namespace httpsserver;
HTTPServer insecureServer = HTTPServer();

void handleRoot(HTTPRequest *req, HTTPResponse *res);

const char *ssid = "ssid";
const char *password = "pass";

#define PIN_LED 10
#define PIN_ANALOG_READ 33

WiFiClient client;
int last_min = -1;

//
// 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);

  M5.Lcd.print("Connecting to ");
  // Serial.println("Connecting to ");
  M5.Lcd.printf(ssid);

  WiFi.begin(ssid, password); // connect to wifi

  int count = 49;
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(800);
    M5.Lcd.print(".");
    count -= 1;
    if ((count % 10) == 0)
    {
      // Serial.println("max try failed");
      WiFi.disconnect();
      delay(500);
      WiFi.begin(ssid, password);
    }

    if (count == 0)
    {
      M5.Lcd.println("WiFi connected failed.");
      return -1;
    }
  }
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.print("IP address: ");
  M5.Lcd.println(WiFi.localIP());
  M5.Lcd.println("");

  return 0;
}

void setup_server()
{
  ResourceNode *nodeRoot = new ResourceNode("/", "GET", &handleRoot);
  insecureServer.registerNode(nodeRoot);

  Serial.println("Starting HTTP server...");
  insecureServer.start();

  while (!insecureServer.isRunning())
  {
    delay(800);
    M5.Lcd.setTextColor(RED);
    M5.Lcd.print(".");
  }
}

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_ANALOG_READ, INPUT); // GROVE input
  pinMode(PIN_LED, OUTPUT);        // LED

  //
  // Wifi
  //
  digitalWrite(PIN_LED, LOW);
  setup_wifi();
  digitalWrite(PIN_LED, HIGH);

  //
  // setup RTC time
  //
  setup_rtc();

  // Grove Serial
  Serial1.begin(115200, SERIAL_8N1, 0, 26); // Grove

  //
  // setup HTTP server
  //
  setup_server();
}

void loop()
{

  const int WAIT_TIME = 500;
  RTC_TimeTypeDef RTC_TimeStruct;
  if (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("not connect");
    if (setup_wifi() < 0)
    {
      delay(WAIT_TIME * 10);
      return;
    }
    // Serial.println("connect ok");
  }

  // pinの状態など更新
  M5.update();

  insecureServer.loop();

  // get time
  M5.Rtc.GetTime(&RTC_TimeStruct);

  // button status
  int pressed = M5.BtnA.wasPressed();
  if (pressed == 1 || last_min != RTC_TimeStruct.Minutes)
  {

    last_min = RTC_TimeStruct.Minutes;

    // display values on LCD
    M5.Lcd.setTextSize(2);
    M5.Lcd.setCursor(0, 4 * 8);
    M5.Lcd.setTextColor(DARKGREEN);
    M5.Lcd.fillRect(0, 4 * 8, 256, 32, BLACK);

    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);
  }

  delay(WAIT_TIME / 10);
}

void handleRoot(HTTPRequest *req, HTTPResponse *res)
{

  std::string param = req->getRequestString();

  res->setHeader("Content-Type", "text/html");

  res->println("<!DOCTYPE html>");
  res->println("<html>");
  res->println("<body>");
  res->print("<p>Your server is running for ");
  res->print((int)(millis() / 1000), DEC);
  res->println(" seconds.</p>");
  res->println(param.c_str());
  res->println("</body>");
  res->println("</html>");

  Serial1.println(param.c_str());
}

テスト

配線し、M5StickCの準備ができたら、Mac/PCからHTTPで、試してみる。 f は、 forward

bash
curl http://M5StickCのIP/?f

これで、めでたく動いたら、次回へ続く。