/*************************
ESP32 Wifi控制伺服馬
使用滑桿控制0~180°
************************/
#include <WiFi.h>
#include <ESP32Servo.h>
Servo myservo; //伺服馬達名稱
const int servoPin = 22;
// Replace with your network credentials
const char* ssid = "LankuoAP"; //你的WIFI id
const char* password = "abcd1234"; //密碼
WiFiServer server(80); //Wifi伺服器使用80埠
String header; //記錄HTTP請求字串
String angleString = String(5); //解析出來的角度值
//連線時間限制
unsigned long currentTime = millis(); //現在時間
unsigned long previousTime = 0; //上次時間
const long timeoutTime = 2000; //連線時間上限2秒
void setup() {
Serial.begin(115200);
myservo.attach(servoPin); //啟動伺服馬達
Serial.print("Connecting to "); //監看連線
Serial.println(ssid);
WiFi.begin(ssid, password); //連接wifi
while (WiFi.status() != WL_CONNECTED) { //若尚未能連接時
delay(500);
Serial.print("."); //印出...
}
Serial.println("");
Serial.println("WiFi已連線."); //顯示已連線
Serial.println("IP address: "); //顯示連線的ip
Serial.println(WiFi.localIP()); //網頁伺服器提供ip讓使用者連線
server.begin();
}
void loop(){
WiFiClient client = server.available(); //監聽…
if (client) { //有人連入
currentTime = millis(); //記錄現在時間
previousTime = currentTime; //記錄上次時間
Serial.println("New Client."); //顯示「有人連入」
String currentLine = ""; //空字串
while (client.connected() && currentTime - previousTime <= timeoutTime) { //當使用者時限內有連線
currentTime = millis(); //記錄連入時間
if (client.available()) { //有傳入文字
char c = client.read(); //讀取文字
Serial.write(c); //印出來
header += c; //串接連入的文字成字串
if (c == '\n') { //如果是換行指令
// 使用者最後按下enter會產生的\r\n (歸位+換行字元)
if (currentLine.length() == 0) { //使用者最後按下enter產生的新行
client.println("HTTP/1.1 200 OK"); //網頁的開始格式
client.println("Content-type:text/html"); //網頁格式
client.println("Connection: close"); //網頁格式
client.println(); //空白行
//顯示網頁的部分
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// CSS 格式
client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial; margin-left:auto; margin-right:auto;}");
client.println(".slider { width: 300px; }</style>");
client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>");
//網頁內容
client.println("</head><body><h1>ESP32 Slide Control Servo </h1>"); //標題
client.println("<p>Position: <span id=\"servoPos\"></span></p>"); //滑桿元件屬性
client.println("<input type=\"range\" min=\"0\" max=\"180\" class=\"slider\" id=\"servoSlider\" onchange=\"servo(this.value)\" angle=\""+angleString+"\"/>");
client.println("<script>var slider = document.getElementById(\"servoSlider\");"); //使用JAVAScript程式碼處理滑桿位置之網頁更新
client.println("var servoP = document.getElementById(\"servoPos\"); servoP.innerHTML = slider.value;");
client.println("slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value; }");
client.println("$.ajaxSetup({timeout:1000}); function servo(pos) { ");
client.println("$.get(\"/?angle=\" + pos + \"&\"); {Connection: close};}</script>"); //界定格式為: url/?angle=[SLIDER_POSITION]&。
client.println("</body></html>");
/*
http://192.168.1.216/?angle=0& //轉到0
http://192.168.1.216/?angle=180& //轉到180
*/
//GET /?angle=180& GET方式的指定參考字串
if(header.indexOf("GET /?angle=")>=0) { //如果有指定的字串格式
int pos1 = header.indexOf('='); //找到=的位置
int pos2 = header.indexOf('&'); //找到&的位置
angleString = header.substring(pos1+1, pos2); //角度值為=到&之間的數值文字。
myservo.write(angleString.toInt()); //驅動servo到該角度
Serial.print("伺服馬達現在角度位置=>");
Serial.println(angleString); //印出來
}
client.println(); //以空白行結束網頁的請求
break; //離開迴圈
} else {
currentLine = ""; //清除字串
}
} else if (c != '\r') { //如果不是return鍵
currentLine += c; //繼續接收文字
}
}
}
header = ""; //網頁控制字串清空
client.stop();
Serial.println("");
}
}