#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define SCL 41
#define SDA 42
LiquidCrystal_I2C lcd(0x27, 20, 4);

QueueHandle_t queueMsg = xQueueCreate(8, sizeof(char[20]));   // 创建消息队列,长度为8,每条消息大小为20字节

char user_id = 'A'; // 用户ID

// 随机返回一段文字
String randomMsg() {
  static const String myStrings[] = {
    "Nice to meet you",
    "Where are U from?",
    "What do you do?",
    "What do U like?",
    "What is UR num?",
    "Do U have FB?",
    "Thanks so much.",
    "I am Chinese.",
    "I do not KNOW.",
    "Thank you.",
    "That helps.",
    "I Love U",
    "Do U miss me?",
    "Be careful.",
    "Don't worry.",
    "Good idea.",
    "He's right.",
    "I ate already.",
    "More than that.",
    "Nothing else.",
    "See you later.",
    "Take it outside.",
  };
  return myStrings[random(0, 22)];
}

// 用户线程
void user_task(void *param_t){
  char msg[20];
  String prefix= String(user_id++);
  prefix += ":";
  while(1){
    (prefix + randomMsg()).toCharArray(msg, 20);    // 拼接消息体
    // 向消息队列中发送一条消息, 如果满了,则无限期等待
    if (xQueueSend(queueMsg, &msg, portMAX_DELAY) == pdPASS)  {
      Serial.println(msg);
    }else{
      Serial.println("消息队列已满!");
    }
    vTaskDelay(pdMS_TO_TICKS(random(2000,5000)));
  }
}

// 显示屏线程
void lcd_task(void *param_t){
  Wire.begin(SDA, SCL);
  lcd.init();
  lcd.backlight();

  // LCD每行显示的内容
  char line0[20] = {' '};
  char line1[20] = {' '};
  char line2[20] = {' '};
  char line3[20] = {' '};
  char * lines[] = { line0, line1, line2, line3 };

  while(1){
    //文字向上滚动
    strcpy(line0, line1);
    strcpy(line1, line2);
    strcpy(line2, line3);

    // 从消息队列中取出一条消息,如果成功则显示到屏幕上
    if (xQueueReceive(queueMsg, lines[3], 1000) == pdPASS) {
      for (int i = 3; i >= 0; i--) {
        lcd.setCursor(0, i);                // 定位文字打印位置
        lcd.print("                    ");  // 清空这一行内容,向这一行发送20个空格即可清空
        lcd.setCursor(0, i);                // 重新定位文字打印位置,因为print操作后光标会变
        lcd.print(lines[i]);                // 在这行位置上输出内容
      }
    }else {
      Serial.println("消息队列没有内容...");
    };
    vTaskDelay(100);
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println("Hello, ESP32-S3!");

  // 创建LCD显示任务
  xTaskCreate(lcd_task, "LCD", 1024 * 8, NULL, 1, NULL);

  // 创造一些用户
  for(int i=0; i<3; i++){
    xTaskCreate(user_task, "USER", 1024 * 8, NULL, 1, NULL);
  }
}

void loop() {
  delay(10); 
}
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
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL