#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.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 = "ZHIYI";           // 设置WiFi账号 Set up WiFi account
const char *password = "zy12345678";  // 设置WiFi密码 Set WiFi password
const int Trig = 17;                  // 超声波传感器的触发引脚  Trigger pin of ultrasonic sensor
const int Echo = 18;                  // 超声波传感器的回声引脚  The echo pin of the ultrasonic sensor
// 创建 AsyncWebServer 对象
AsyncWebServer server(80);

// 生成网页的 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 Ultrasonic</h2>
  <p>
    <i id="ultrasonicIcon" class="fas fa-ruler-vertical" style="color:#70a3ff;"></i> 
    <span class="dht-labels" id="ultrasonicText">Distance: -- cm</span>
  </p>
</body>
<script>
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var distance = parseInt(this.responseText);
      if (distance != -1) {
        document.getElementById("ultrasonicText").innerHTML = "Distance: " + distance + " cm";
      } else {
        document.getElementById("ultrasonicText").innerHTML = "Distance: Error";
      }
    }
  };
  xhttp.open("GET", "/ultrasonic", true);
  xhttp.send();
}, 1000);
</script>
</html>
)rawliteral";

float GetDistance()  //获取超声波传感器数值  Get ultrasonic sensor values
{
  float distance;
  //发送一个低短脉冲到Trig触发测距
  digitalWrite(Trig, LOW);  //发送一个低电平到Trig
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig, LOW);
  distance = pulseIn(Echo, HIGH) / 58.00;
  //Serial.print("Distance = ");
  //Serial.println(distance); //串行输出距离转换成厘米
  delay(10);
  return distance;
}

void setup() {
  Serial.begin(9600);
  pinMode(Trig, OUTPUT);  //定义引脚工作模式为输入 Define the pin operation mode as the input
  pinMode(Echo, INPUT);   //定义引脚工作模式为输出 Define the pin operation mode as output
  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

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

  // 清空屏幕缓冲区 Clear the screen buffer
  display.clearDisplay();

  // 显示超声波距离  Display ultrasonic distance
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(16, 8);
  display.println("Distance");
  display.setCursor(16, 40);
  display.print("0");
  display.print(" cm");
  display.display();

  // 设置 WiFi 连接  Setting up WiFi connection
  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("/ultrasonic", HTTP_GET, [](AsyncWebServerRequest *request) {
    float distance = GetDistance();
    if (distance >= 400 || distance <= 2) {
      distance = -1;  // 超出范围或错误值
    }
    request->send(200, "text/plain", String(distance));

    // 清空屏幕缓冲区
    display.clearDisplay();

    // 显示超声波距离
    display.setTextSize(2);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(16, 8);
    display.println("Distance");
    display.setCursor(16, 40);
    display.print(distance);
    display.print(" cm");
    display.display();
  });

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

void loop() {
}
