#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ESP32Servo.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128  // 定义屏幕宽度为128像素 Define the screen width to be 128 pixels
#define SCREEN_HEIGHT 64  // 定义屏幕高度为64像素 Define the screen height to be 64 pixels
#define OLED_RESET -1     // 定义 OLED 复位引脚为-1（如果不使用复位功能，则设置为-1） Define the OLED reset pin to -1 (or -1 if the reset function is not used)
// 创建 Adafruit_SSD1306 对象，用于控制 OLED 屏幕，指定屏幕宽度、高度、I2C 总线对象和复位引脚
// Create an Adafruit_SSD1306 object that controls the OLED screen, specifying the screen width, height, I2C bus object, and reset pin
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const char *ssid = "XXXXXX";          // 设置WiFi账号 Set up WiFi account
const char *password = "XXXXXXXX";    // 设置WiFi密码 Set WiFi password
const int servoPin = 9;               // 舵机控制引脚 Servo control pin
Servo servo;                          // 实例化舵机对象  Instantiate the steering gear object
AsyncWebServer server(80);            // 创建 AsyncWebServer 对象

// 生成网页的 HTML 代码  Generates the HTML code for the web page
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .dht-labels{
      font-size: 1.5rem;
      vertical-align:middle;
      padding-bottom: 15px;
    }
    .slider {
      width: 80%;
    }
  </style>
</head>
<body>
  <h2>ESP32 Servo Control</h2>
  <p>
    <i id="servoIcon" class="fas fa-compass" style="color:#70a3ff;"></i> 
    <span class="dht-labels" id="servoText">Servo Angle: 90</span>
  </p>
  <p>
    <input type="range" min="0" max="180" value="90" class="slider" id="servoSlider">
  </p>
</body>
<script>
document.getElementById("servoSlider").addEventListener("input", function() {
  var angle = this.value;
  document.getElementById("servoText").innerHTML = "Servo Angle: " + angle;
  var xhttp = new XMLHttpRequest();
  xhttp.open("GET", "/servo?angle=" + angle, true);
  xhttp.send();
});
</script>
</html>
)rawliteral";

void setup() {
  Serial.begin(9600);
  Wire.begin(5, 4);  //初始化 I2C 总线 SDA引脚设置为5，SCL引脚设置为4 The initial I2C bus SDA pin is set to 5 and the SCL pin is set to 4

  // 初始化屏幕
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 initialization failed"));
    for (;;)
      ;
  }

  display.clearDisplay();
  // 初始化显示舵机角度  Initialize display steering Angle
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 8);
  display.println("SG90 Angle");
  display.setCursor(32, 40);
  display.print("0");
  display.display();

  servo.attach(servoPin);  //关联舵机引脚  Associate servo pin
  // 设置 WiFi 连接
  WiFi.begin(ssid, password);
  Serial.println("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println(".");
  }
  Serial.println(WiFi.localIP());  //打印IP地址

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send_P(200, "text/html", index_html);
  });

  server.on("/servo", HTTP_GET, [](AsyncWebServerRequest *request) {
    if (request->hasParam("angle")) {
      int angle = request->getParam("angle")->value().toInt();
      servo.write(angle);
      display.clearDisplay();

      // 显示舵机角度  Display steering Angle
      display.setTextSize(2);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(0, 8);
      display.println("SG90 Angle");
      display.setCursor(32, 40);
      display.print(angle);
      display.display();
      request->send(200, "text/plain", "OK");
    } else {
      request->send(400, "text/plain", "Missing angle parameter");
    }
  });

  //启用服务器
  server.begin();
}

void loop() {
}
