#include <M5Unified.h>

int interval_msec[] = { 333, 1000, 2000 }; // Led, Lcd, Beep
TaskHandle_t tH[3];

void ledTask(void *pvParam) {
  /** setup をここに書く **/
  portTickType lastTime;
  int PIN = 10;
  pinMode(PIN, OUTPUT); // PINのモード設定
  int highOrLow = 0;
  for (;;) {
    /** loop をここに書く **/
    lastTime = xTaskGetTickCount();
    vTaskDelayUntil(&lastTime, interval_msec[0] ); // 第2引数に、実行間隔ミリ秒を指定
    digitalWrite(PIN, highOrLow); // HIGH = 1, LOW = 0
    highOrLow = 1 - highOrLow; // HIGH <=> LOW を切り替える
  }
}

void lcdTask(void *pvParam) {
  /** setup をここに書く **/
  portTickType lastTime;
  M5.Display.setRotation(0);
  M5.Display.fillScreen(GREEN);
  M5.Display.setTextColor(WHITE, OLIVE);
  M5.Display.setTextSize(2);
  M5.Display.setCursor(0, 0);
  int count = 0;
  for (;;) {
    /** loop をここに書く **/
    M5.Display.printf("count=%d\n", count);
    count++;
    lastTime = xTaskGetTickCount();
    vTaskDelayUntil(&lastTime, interval_msec[1] ); // 第2引数に、実行間隔ミリ秒を指定
    if (count % 10 == 0) {
      M5.Display.fillScreen(GREEN);
      M5.Display.setCursor(0, 0);
    }
  }
}

void beepTask(void *pvParam) {
  /** setup をここに書く **/
  portTickType lastTime;
  int f[8] = { 262, 294, 330, 349, 392, 440, 494, 524 };
  int note = 0;
  for (;;) {
    /** loop をここに書く **/
    lastTime = xTaskGetTickCount(); // ここでの時刻を変数に保存
    tone(GPIO_NUM_2, f[note], 500);  M5.Display.setBrightness(255);
    M5.delay(500); //0.5秒鳴らす
    note = (note+1)%8;
    vTaskDelayUntil(&lastTime, interval_msec[2] ); 
    // 途中の処理やdelayは含まず、「保存」時刻の2秒後まで待つ。
  }
}

void setup() {
  auto cfg = M5.config();
  cfg.serial_baudrate = 115200;
  M5.begin(cfg);

  xTaskCreatePinnedToCore(ledTask , "LedT", 4096, NULL, 1, &tH[0],  1/*<= CoreNo.*/ );
  xTaskCreatePinnedToCore(lcdTask , "LcdT", 4096, NULL, 1, &tH[1],  1/*<= CoreNo.*/ );
  xTaskCreatePinnedToCore(beepTask,"BeepT", 4096, NULL, 1, &tH[2],  0/*<= CoreNo.*/ );
}

void loop() {
  delay(10);
}