서보 모터 제어 웹 서버 구축 Servo Web Server
Arduino IDE를 사용한 ESP32 서보 모터 웹 서버
이 튜토리얼에서는 슬라이더를 사용하여 서보 모터의 샤프트 위치를 제어하는 ESP32로 웹 서버를 만드는 방법을 알아봅니다. 먼저 ESP32로 서보를 제어하는 방법을 간략히 살펴본 다음 웹 서버를 빌드합니다.
필요한 부품
이 튜토리얼을 따르려면 다음 부품이 필요합니다.
ESP32 DOIT DEVKIT V1 보드 - ESP32 개발 보드 리뷰 및 비교 읽기
마이크로 서보 모터 - S0009/S90 또는 서보 모터 - S0003
점퍼 와이어
서보 모터를 ESP32에 연결하기
서보 모터에는 전원, 접지, 신호의 세 개의 전선이 있습니다. 전원은 일반적으로 빨간색이고, GND는 검정색 또는 갈색이며, 신호선은 일반적으로 노란색, 주황색 또는 흰색입니다.
신호 노란색, 주황색 또는 흰색입니다.
Wire | Color |
Power | Red |
GND | Black, or brown |
Signal | Yellow, orange, or white |
아래 그림과 같이 S0009와 같은 소형 서보를 사용하는 경우 ESP32에서 직접 전원을 공급할 수 있습니다.
하지만 두 개 이상의 서보 또는 다른 모델을 사용하는 경우 외부 전원 공급 장치를 사용하여 서보에 전원을 공급해야 할 것입니다.
S0009와 같은 소형 서보를 사용하는 경우 다음을 연결해야 합니다.
GND -> ESP32 GND 핀;
전원 -> ESP32 VIN 핀;
신호 -> GPIO 13(또는 모든 PWM 핀).
참고: 이 경우 모든 ESP32 GPIO를 사용할 수 있습니다. 모든 GPIO가 PWM 신호를 생성할 수 있기 때문입니다. 그러나 통합 SPI 플래시에 연결된 GPIO 9, 10, 11은 사용하지 않는 것이 좋으며 다른 용도로는 권장되지 않습니다.
추천 자료: ESP32 핀아웃 참조: 어떤 GPIO 핀을 사용해야 합니까?
회로도
예제에서 신호선을 GPIO 13에 연결합니다. 따라서 다음 회로도를 따라 서보 모터를 배선할 수 있습니다.
ESP32를 서보 모터 SG90에 배선
(이 회로도는 36개의 GPIO가 있는 ESP32 DEVKIT V1 모듈 버전을 사용합니다. 다른 모델을 사용하는 경우 사용하는 보드의 핀아웃을 확인하세요.)
서보 모터를 제어하는 방법?
서보의 샤프트를 0~180º의 다양한 각도로 배치할 수 있습니다. 서보는 펄스 폭 변조(PWM) 신호를 사용하여 제어됩니다. 모터로 전송된 PWM 신호의 듀티 사이클이 샤프트의 위치를 결정합니다.
모터를 제어하려면 적절한 펄스 폭으로 50Hz 신호를 보내 ESP32의 PWM 기능을 사용하면 됩니다. 또는 라이브러리를 사용하여 이 작업을 훨씬 더 간단하게 만들 수 있습니다.
서보 모터가 있는 ESP32
Arduino IDE 준비
계속하기 전에 Arduino IDE와 ServoESP32 라이브러리에 ESP32 보드를 설치했는지 확인하세요.
Arduino IDE가 있는 ESP32
Arduino IDE를 사용하여 ESP32를 프로그래밍합니다. 따라서 ESP32 애드온이 설치되어 있는지 확인하세요. 아직 설치하지 않았다면 다음 튜토리얼을 따르세요.
Arduino IDE 2에 ESP32 보드 설치
또는 VS Code와 platformIO 확장을 사용하여 ESP32를 프로그래밍할 수도 있습니다.
ESP32 및 ESP8266용 VS Code 및 PlatformIO IDE 시작하기
ESP32Servo 라이브러리 설치
ESP32Servo 라이브러리를 사용하면 Arduino IDE를 사용하여 ESP32로 서보 모터를 더 쉽게 제어할 수 있습니다. Arduino IDE에 라이브러리를 설치하려면 다음 단계를 따르세요.
1. 스케치 > 라이브러리 포함 > 라이브러리 관리로 이동하세요.
2. ESP32Servo를 검색하세요.
3. 라이브러리를 설치하세요.
ESP32 Servo 라이브러리 arduino ide 설치
예제 테스트
라이브러리를 설치한 후 Arduino IDE로 이동하여 다음 코드를 복사하세요.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-servo-motor-web-server-arduino-ide/
Based on the ESP32Servo Sweep Example
*********/
#include <ESP32Servo.h>
static const int servoPin = 13;
Servo servo1;
void setup() {
Serial.begin(115200);
servo1.attach(servoPin);
}
void loop() {
for(int posDegrees = 0; posDegrees <= 180; posDegrees++) {
servo1.write(posDegrees);
Serial.println(posDegrees);
delay(20);
}
for(int posDegrees = 180; posDegrees >= 0; posDegrees--) {
servo1.write(posDegrees);
Serial.println(posDegrees);
delay(20);
}
}
코드 이해
이 스케치는 서보를 한쪽으로 180도, 다른 쪽으로 180도 회전합니다. 작동 방식을 살펴보겠습니다.
먼저 Servo 라이브러리를 포함해야 합니다.
#include <ESP32Servo.h>
서보 데이터 핀에 연결된 핀을 정의합니다. 이 경우 GPIO 13에 연결하지만 다른 적합한 핀을 사용할 수 있습니다.
static const int servoPin = 13;
ESP32 GPIO에 대해 자세히 알아보세요. ESP32 핀아웃 참조: 어떤 GPIO 핀을 사용해야 합니까?
그런 다음 Servo 객체를 만들어야 합니다. 이 경우 servo1이라고 합니다.
Servo servo1;
setup()
setup()에서 디버깅 목적으로 직렬 통신을 초기화하고 GPIO 13을 servo 객체에 연결합니다.
void setup() {
Serial.begin(115200);
servo1.attach(servoPin);
}
loop()
loop()에서 모터의 샤프트 위치를 0도에서 180도로 변경한 다음 180도에서 0도로 변경합니다. 샤프트를 특정 위치로 설정하려면 Servo 객체에서 write() 메서드를 사용하기만 하면 됩니다. 인수로 위치를 도 단위로 나타낸 정수를 전달합니다.
myservo.write(pos);
스케치 테스트
ESP32에 코드를 업로드합니다. 코드를 업로드한 후 모터의 샤프트가 한쪽으로 회전한 다음 다른 쪽으로 회전하는 것을 볼 수 있습니다.
ESP32 웹 서버 만들기
이제 ESP32로 서보를 제어하는 방법을 알았으니 이를 제어하는 웹 서버를 만들어 보겠습니다. 빌드할 웹 서버는 다음과 같습니다.
- 여기에는 0~180의 슬라이더가 포함되어 있으며, 이를 조정하여 서보의 샤프트 위치를 제어할 수 있습니다.
- 현재 슬라이더 값은 새로 고침할 필요 없이 웹 페이지에서 자동으로 업데이트됩니다. 이를 위해 AJAX를 사용하여 백그라운드에서 ESP32에 HTTP 요청을 보냅니다.
- 웹 페이지를 새로 고쳐도 슬라이더 값이나 샤프트 위치는 변경되지 않습니다.
웹 서버로 ESP32 제어 서보 모터
다음도 마음에 드실 수 있습니다. ESP32 및 ESP8266으로 웹 서버 구축 전자책
HTML 페이지 만들기
먼저 ESP32가 브라우저로 보내야 하는 HTML 텍스트를 살펴보겠습니다.
<!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>
슬라이더 만들기
이 프로젝트의 HTML 페이지에는 슬라이더를 만드는 것이 포함됩니다. HTML에서 슬라이더를 만들려면 input 태그를 사용합니다. input 태그는 사용자가 데이터를 입력할 수 있는 필드를 지정합니다.
<input type="range" min="0" max="180" class="slider" id="servoSlider" onchange="servo(this.value)"/>
다양한 입력 유형이 있습니다. 슬라이더를 정의하려면 "range" 값과 함께 "type" 속성을 사용합니다. 슬라이더에서는 "min" 및 "max" 속성을 사용하여 최소 및 최대 범위를 정의해야 합니다.
다음과 같은 다른 속성도 정의해야 합니다.
- 슬라이더 스타일을 지정하는 클래스
- 웹 페이지에 표시된 현재 위치를 업데이트하는 id
- 마지막으로 슬라이더가 움직일 때 ESP32에 HTTP 요청을 보내는 servo 함수를 호출하는 onchange 속성.
HTML 파일에 JavaScript 추가
다음으로 script 태그를 사용하여 HTML 파일에 JavaScript 코드를 추가해야 합니다. 이 코드 조각은 현재 슬라이더 위치로 웹 페이지를 업데이트합니다.
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=[SLIDER_POSITION]&에서 ESP IP 주소에 대한 HTTP GET 요청을 만듭니다.
$.ajaxSetup({timeout:1000});
function servo(pos) {
$.get("/?value=" + pos + "&");
}
예를 들어, 슬라이더가 0일 때 다음 URL에서 HTTP GET 요청을 합니다.
http://192.168.1.135/?value=0&
슬라이더가 180도일 때 다음과 같은 결과가 나옵니다.
http://192.168.1.135/?value=180&
이렇게 하면 ESP32가 GET 요청을 받을 때 URL에서 값 매개변수를 가져와서 그에 따라 서보 모터를 움직일 수 있습니다.
코드
이제 이전 HTML 텍스트를 스케치에 포함하고 그에 따라 서보를 회전해야 합니다. 다음 스케치는 정확히 그렇게 합니다.
다음 코드를 Arduino IDE에 복사하지만 아직 업로드하지 마세요. 먼저 작동 방식을 간단히 살펴보겠습니다.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-servo-motor-web-server-arduino-ide/
*********/
#include <WiFi.h>
#include <ESP32Servo.h>
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
// GPIO the servo is attached to
static const int servoPin = 13;
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Set web server port number to 80
WiFiServer server(80);
// Variable to store the HTTP request
String header;
// Decode HTTP GET value
String valueString = String(5);
int pos1 = 0;
int pos2 = 0;
// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0;
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;
void setup() {
Serial.begin(115200);
myservo.attach(servoPin); // attaches the servo on the servoPin to the servo object
// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
}
void loop(){
WiFiClient client = server.available(); // Listen for incoming clients
if (client) { // If a new client connects,
currentTime = millis();
previousTime = currentTime;
Serial.println("New Client."); // print a message out in the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected
currentTime = millis();
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
// Display the HTML web page
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 to style the on/off buttons
// Feel free to change the background-color and font-size attributes to fit your preferences
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 with 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)\" 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);
//Rotate the servo
myservo.write(valueString.toInt());
Serial.println(valueString);
}
// The HTTP response ends with another blank line
client.println();
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
코드 작동 방식
먼저 Servo 라이브러리를 포함하고 myservo라는 Servo 객체를 만듭니다.
#include <ESP32Servo.h>
Servo myservo; // create servo object to control a servo
// 서보를 제어하기 위한 서보 객체 생성
또한 서보가 연결된 GPIO 번호를 보관할 변수도 생성합니다. 이 경우 GPIO13입니다.
const int servoPin = 13;
네트워크 자격 증명을 포함하도록 다음 두 줄을 수정해야 한다는 것을 잊지 마세요.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
그런 다음 HTTP 요청에서 슬라이더 위치를 추출하는 데 사용할 변수를 생성합니다.
// Decode HTTP GET value
String valueString = String(5);
int pos1 = 0;
int pos2 = 0;
setup()
setup()에서 myservo.attach()를 사용하여 서보를 연결된 GPIO에 연결해야 합니다.
myservo.attach(servoPin); // servoPin의 서보를 서보 객체에 연결합니다.
loop()
loop()의 첫 번째 부분은 웹 서버를 생성하고 HTML 텍스트를 보내 웹 페이지를 표시합니다. 이 웹 서버 프로젝트에서 사용한 것과 동일한 방법을 사용합니다.
다음 코드 부분은 HTTP 요청에서 슬라이더 값을 검색합니다.
//GET /?value=180& HTTP/1.1
if(header.indexOf("GET /?value=")>=0) {
pos1 = header.indexOf('=');
pos2 = header.indexOf('&');
valueString = header.substring(pos1+1, pos2);
슬라이더를 움직일 때 =와 & 기호 사이에 슬라이더 위치가 포함된 다음 URL에서 HTTP 요청을 합니다.
http://your-esp-ip-address/?value=[SLIDER_POSITION]&
슬라이더 위치 값은 valueString 변수에 저장됩니다.
그런 다음 myservo.write()를 사용하여 valueString 변수를 인수로 사용하여 서보를 해당 특정 위치로 설정합니다. valueString 변수는 문자열이므로 toInt() 메서드를 사용하여 정수로 변환해야 합니다. 이는 write() 메서드에서 허용하는 데이터 유형입니다.
myservo.write(valueString.toInt());
웹 서버 테스트
이제 코드를 ESP32에 업로드할 수 있습니다. 올바른 보드와 COM 포트를 선택했는지 확인하세요. 또한 네트워크 자격 증명을 포함하도록 코드를 수정하는 것을 잊지 마세요.
코드를 업로드한 후, 시리얼 모니터를 115200의 전송 속도로 엽니다. ESP32 EN/RST 버튼을 눌러 보드를 재시작하고, 시리얼 모니터에 표시된 ESP32 IP 주소를 복사합니다.
ESP32 서보 웹 서버 IP 주소 시리얼 모니터
브라우저를 열고 ESP IP 주소를 붙여넣으면 이전에 만든 웹 페이지가 표시됩니다. 슬라이더를 움직여 서보 모터를 제어합니다.
ESP32 서보 웹 서버 데모
직렬 모니터에서 슬라이더를 움직일 때 ESP32에 보내는 HTTP 요청도 볼 수 있습니다.
ESP32 서보 웹 서버 - 슬라이더 값 가져오기 직렬 모니터
웹 서버를 잠시 실험하여 제대로 작동하는지 확인하세요.
비디오 튜토리얼 및 프로젝트 데모 보기
이 가이드는 비디오 형식(아래에서 시청)과 서면 형식(계속 읽기)으로 제공됩니다.
마무리
요약하면, 이 튜토리얼에서는 ESP32로 서보 모터를 제어하는 방법과 슬라이더를 사용하여 위치를 제어하는 웹 서버를 만드는 방법을 배웠습니다.
이것은 서보 모터를 제어하는 방법의 예일 뿐입니다. 슬라이더 대신 텍스트 입력 필드, 사전 정의된 각도가 있는 여러 버튼 또는 기타 적합한 입력 필드를 사용할 수 있습니다.
이것은 Arduino IDE로 ESP32 배우기 과정에서 발췌한 것입니다. ESP32를 좋아하고 이에 대해 자세히 알고 싶다면 Arduino IDE로 ESP32 배우기 과정에 등록하는 것이 좋습니다.
ESP32와 다른 모터를 인터페이스하는 방법에 대한 튜토리얼이 있습니다.
DC 모터 및 L298N 모터 드라이버가 있는 ESP32 - 속도 및 방향 제어
스테퍼 모터가 있는 ESP32(28BYJ-48 및 ULN2003 모터 드라이버)
ESP32 웹 서버: 스테퍼 모터 제어(HTML 양식)
ESP32 웹 서버: 스테퍼 모터 제어(WebSocket)
ESP32에 대해 자세히 알아보고 리소스를 사용하여 웹 서버를 구축하는 방법에 대해 알아보세요.
Arduino IDE로 ESP32 배우기(eBook)
ESP32 및 ESP8266으로 웹 서버 구축(eBook)
무료 ESP32 프로젝트 및 튜토리얼...
이 튜토리얼이 도움이 되었기를 바랍니다.
읽어주셔서 감사합니다. 문서 출처 링크