webserver控制伺服馬達-ESP32
webserver控制伺服馬達-ESP32
伺服馬達對於微控板玩家一定是再熟悉不過,也是入門必學的元件之一,只是特別要注意如果要控制2個以上的伺服馬達,一定要使用外接電源或者PCA9685。
伺服馬達有很多款,小型常用的就屬SG-90,它是塑膠齒輪,還有一種是金屬齒輪
SG-90規格
- 工作電壓:4.8V.
- 轉矩:1.8kg-cm
- 運轉速度:0.1秒∕ 60度
- 轉動角度:最大90°
- 脈衝寬度範圍:500~2400µs.
MG90S規格
- 此次實驗以MG-90為主
- 要控制伺服馬達有兩種方式,一種是利用PWM,另一種是使用現有的庫包來控制,本次實驗以庫包為主
首先安裝
接線方式
進行實驗
#include <ESP32Servo.h> Servo myservo; int pos = 20; const int pin = 12; void setup(){ Serial.begin(115200); myservo.attach(pin, 500, 2400); } void loop(){ for (pos=20; pos<=160; pos+=3){ myservo.write(pos); delay(100); } for (pos=160; pos>=20; pos-=3){ myservo.write(pos); delay(100); } }
ESP32網頁伺服器
上面伺服馬達簡單的測試完成後,就可以納入網頁伺服器來控制伺服馬達,這裡我覺得有點難度的是網頁的編寫,因為寫HTML+CSS我沒學過,所以參考網路上教學文的網頁範例。
這是我參考教學網站上的網頁範例
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="data:,"> <style> body { text-align: center; font-family: "Trebuchet MS", Arial; margin-left:auto; margin-right:auto; } .slider { width: 300px; } </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> </head> <body> <h1>ESP32 with Servo</h1> <p>Position: <span id="servoPos"></span></p> <input type="range" min="0" max="180" class="slider" id="servoSlider" onchange="servo(this.value)"/> <script> var slider = document.getElementById("servoSlider"); var servoP = document.getElementById("servoPos"); servoP.innerHTML = slider.value; slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value; } $.ajaxSetup({timeout:1000}); function servo(pos) { $.get("/?value=" + pos + "&"); {Connection: close}; } </script> </body> </html>
使用 script 和 /script 標籤將一些 JavaScript 代碼添加到您的 HTML 文件中。此代碼片段使用當前滑塊位置更新網頁
var slider = document.getElementById("servoSlider"); var servoP = document.getElementById("servoPos"); servoP.innerHTML = slider.value; slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value; }
接下來的幾行在此特定 URL 路徑 /?value\u003d[SLIDER_POSITION]& 中的 ESP IP 地址上發出 HTTP GET 請求。
$.ajaxSetup({timeout:1000}); function servo(pos) { $.get("/?value=" + pos + "&"); {Connection: close}; }
例如,當滑塊位於 0 時,您在以下 URL 上發出 HTTP GET 請求:
http://192.168.1.135/?value=0&
完整程式碼
#include <ESP32Servo.h> #include <WiFi.h> //定義伺服馬達 Servo myservo; //伺服馬達的起始值和腳位 int pos = 0; const int servoPin = 12; //WIFI const char *ssid = "---"; const char *password = "------"; //將 Web 服務器端口號設置為 80 WiFiServer server(80); //用於存儲 HTTP 請求的變量 String header; //解碼 HTTP GET 值 String valueString = String(0); int pos1 = 0; int pos2 = 0; // 當下的時間 unsigned long currentTime = millis(); // 之前的時間 unsigned long previousTime = 0; // 超時 const long timeoutTime = 2000; void setup(){ Serial.begin(115200); //指定伺服器上的pin myservo.attach(servoPin, 500, 2400); //連接wifi WiFi.begin(ssid, password); while (WiFi.isConnected() == false){ Serial.print("."); delay(1000); } Serial.println("Connected successful!"); Serial.print("IP: "); Serial.print(WiFi.localIP()); //連接伺服器 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 <= 2000)){ currentTime = millis(); if (client.available()){ //如果有字節要從客戶端讀取, char c = client.read(); //讀取字節 Serial.write(c); //印到序列監測窗口 header += c; if (c == '\n'){ //如果字節是換行符 //如果當前行為空,則表示一行中有兩個換行符。 //這是客戶端 HTTP 請求的結束,因此發送響應: if (currentLine.length() == 0){ client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html; charset=utf-8"); 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:,\">"); 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>"); // Web Page client.println("</head><body><h1>ESP32 控制伺服馬達練習</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)\" value=\""+valueString+"\"/>"); client.println("<script>var slider = document.getElementById(\"servoSlider\");"); 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(\"/?value=\" + pos + \"&\"); {Connection: close};}</script>"); client.println("</body></html>"); //GET /?value=180& HTTP/1.1 if(header.indexOf("GET /?value=")>=0) { pos1 = header.indexOf('='); pos2 = header.indexOf('&'); //取得=和&之中的字節 valueString = header.substring(pos1+1, pos2); //轉換成整數後傳入伺服馬達令其動作 myservo.write(valueString.toInt()); delay(15); Serial.println(valueString); } // The HTTP response ends with another blank line client.println(); break; }else { //如果有一個換行符,就清除 currentLine currentLine = ""; } }else if (c != '\r'){ //否則如果除了enter以外還有別的字串,把它加入currentLine末端 currentLine += c; } } } // 將header清空 header = ""; // 關閉連結 client.stop(); Serial.println("Client disconnected."); Serial.println(""); } }
留言
張貼留言