#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#define SCL 16
#define SDA 17

static TaskHandle_t xGatewayTask = NULL;    // 网关线程  

// 时钟获取线程
void clock_task(void *param_t){
  RTC_DS1307 rtc;         // 定义时钟
  if (rtc.begin()) {
    while(1){
      DateTime now = rtc.now();
      /* 获得 年 月 日 时 分 秒 五个参数,封装到4字节数据中,并通过任务通知发送出去
       * 秒(0~59) 占用 1 ~ 6  位,6
       * 分(0~59) 占用 7 ~ 12 位,6
       * 时(0~23) 占用13 ~ 17 位,5
       * 日(1~31) 占用18 ~ 22 位,5
       * 月(1~12) 占用23 ~ 26 位,4
       * 年(0~63) 占用27 ~ 32 位,6
       * 年的计算减去2000
       */
      uint32_t time=0;
      time =  ((now.year()-2000) & 0b111111);
      time <<= 4;   time |= (now.month()  & 0b1111);      
      time <<= 5;   time |= (now.day()    & 0b11111);     
      time <<= 5;   time |= (now.hour()   & 0b11111);     
      time <<= 6;   time |= (now.minute() & 0b111111);    
      time <<= 6;   time |= (now.second() & 0b111111);
      // 发送数据
      xTaskNotify(xGatewayTask, time, eSetValueWithOverwrite);  // 以覆盖形式发送
      vTaskDelay(1000);   // 每间隔一段时间上报一次时间
    }
  }
  vTaskDelete(NULL);  // 自我终结
}

// 物联网网关
void gateway_task(void *param_t){
  uint32_t time;
  LiquidCrystal_I2C lcd(0x27, 20, 4);
  lcd.init();
  lcd.backlight();

  char line1[17]; // 第一行
  char line2[17]; // 第二行

  while(1){
    if(xTaskNotifyWait(0x00, 0x00, &time, 0) == pdTRUE){
      // 收到数据,转换后打印输出
      int second  = time & 0b111111;  time >>= 6;
      int minute  = time & 0b111111;  time >>= 6;
      int hour    = time & 0b11111;   time >>= 5;
      int day     = time & 0b11111;   time >>= 5;
      int month   = time & 0b1111;    time >>= 4;
      int year    =(time & 0b111111) +2000;
      // printf("当前时间:%d-%02d-%02d %02d:%02d:%02d\n",
      //       year, month, day, hour, minute, second);
      sprintf(line1, " %04d - %02d - %02d", year, month, day);
      sprintf(line2, "  %02d : %02d : %02d", hour, minute, second);
      lcd.setCursor(0, 0);
      lcd.print(line1);
      lcd.setCursor(0, 1);
      lcd.print(line2);
    }
    vTaskDelay(200);
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello, ESP32-S3!");
  Wire.begin(SDA, SCL);   // 初始化I2C总线

  xTaskCreate(gateway_task, "GATEWAY", 10240, NULL, 1, &xGatewayTask);
  xTaskCreate(clock_task, "CLOCK", 10240, NULL, 1, NULL);
  
  vTaskDelete(NULL);  // 自宫
}

void loop() {
  delay(3000);
}
esp:0
esp:1
esp:2
esp:3
esp:4
esp:5
esp:6
esp:7
esp:8
esp:9
esp:10
esp:11
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:20
esp:21
esp:35
esp:36
esp:37
esp:38
esp:39
esp:40
esp:41
esp:42
esp:45
esp:46
esp:47
esp:48
esp:3V3.1
esp:3V3.2
esp:RST
esp:5V
esp:GND.1
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:GND.4
GND5VSDASCLSQWRTCDS1307+
rtc1:GND
rtc1:5V
rtc1:SDA
rtc1:SCL
rtc1:SQW
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL