본문 바로가기
  • 재미있는 펌웨어와 코딩
ESP32/펌웨어

ESP32 웹서버 만들기 - 입력 받기

by 윤재윤호 2023. 10. 3.

이전 강좌까지는 웹페이지에서 버튼을 눌러 ESP32 모듈에 부착된 LED를 ON/OFF 했습니다.

 

https://jooduino.tistory.com/7

 

ESP32 웹서버 만들기 - CSS를 이용하여 버튼 예쁘게

지난 강좌에 이어서 이번에는 버튼을 좀더 예쁘게 만들겠습니다. https://jooduino.tistory.com/5 ESP32 웹서버 만들기 - 버튼 추가 지난 강좌에 이어서 이번에는 웹페이지에 버튼을 만들고 모듈의 내부에

jooduino.tistory.com

 

이제는 반대로 ESP32 모듈에 부착된 버튼의 상태를 웹페이지에서 확인해 보겠습니다.

 

먼저, 회로도 입니다.

GPIO13번에 버튼 연결

버튼 라이브러리 참조

https://jooduino.tistory.com/10

 

아두이노 버튼 라이브러리

아두이노에 버튼을 연결하여 사용시 하드웨어와 소프트웨어 두 종류에 신경을 써야 합니다. 버튼을 누를 때 발생하는 채터링( chattering )이 발생 하여 한 번 눌렀지만 입력이 여러번 반복되어 생

jooduino.tistory.com

 

전체 소스코드

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "SPIFFS.h"
#include "SButton.h"

AsyncWebServer server(80);

// 웹페이지로 데이터를 전송하는 이벤트
AsyncEventSource events("/events");

const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";

const char index_html[] PROGMEM = R"==(
  <!DOCTYPE html>
  <html>
    <head>
      <meta charset="utf-8">
      <title>ESP32 테스트 페이지</title>
      <link href="my.css" type="text/css" rel="stylesheet" crossorigin="anonymous">
      <style>
        html {font-family: Arial; display: inline-block; text-align: center;}
      </style>
    </head>
    <body>
      <h2>버튼</h2>
      <label class="switch">
        <input type="checkbox" id="sw1">
        <span class="slider round"></span>
      </label>
      <script>
        if(!!window.EventSource) {
          var source = new EventSource('/events');
          
          source.addEventListener('open', function(e) {
            console.log("Events Connected");
          }, false);
          
          source.addEventListener('switch', function(e) {
            var sw_value = e.data;
            console.log(sw_value);
            const checkbox = document.getElementById('sw1');
            if(sw_value == "on") checkbox.checked = true;
            else checkbox.checked = false;
          }, false);
        }
      </script>
    </body>
  </html>
)==";

int SW1 = 13; // 입력받을 스위치 GPIO13
SButton sw( SW1, true ); // GPIO13번, 내부 풀업 설정

// 페이지를 찾을 수 없을 때
void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}

void setup() {
    Serial.begin(115200);
    if( !SPIFFS.begin( true ) )
    {
      Serial.println( F("An Error has occurred while mounting SPIFFS") );
      return;
    }

    pinMode(SW1, INPUT_PULLUP);
    
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    
    // 와이파이가 연결될 때까지 기다린다.
    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.printf("WiFi Failed!\n");
        return;
    }

    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());

    // SPIFFS의 CSS파일 연결
    server.on( "/my.css", HTTP_GET, [] (AsyncWebServerRequest *request )
    {
      request->send( SPIFFS, "/my.css", "text/css" );
    });
    
    // 루트
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      request->send(200, "text/html", index_html);
    });

    server.onNotFound(notFound);
    server.addHandler(&events); // 이벤트 추가
    server.begin(); // 서버 시작
}

void loop() {
  sw.update(); // 스위치 상태 확인
  
  if( sw.isDown() ) { // 스위치를 눌렀을 때.
    Serial.println( "Switch ON" );
    events.send("on", "switch", millis());
  }
    
  if( sw.isUp() ) { // 스위치를 뗐을 때.
    Serial.println( "Switch OFF" );
    events.send("off", "switch", millis());
  }
}

 

실행 화면

버튼을 누르지 않을 때

 

버튼을 눌렀을 때

 

웹페이지로 데이터를 보내려면 몇가지 작업을 해야 합니다.

 

1. 이벤트 설정

/events 라는 이름으로 이벤트 생성

AsyncEventSource events("/events");

 

2. 서버에 이벤트 추가

server.addHandler(&events); // 이벤트 추가

 

3. 이벤트 보내기

switch 라는 이름으로 on 데이터 보내기

events.send("on", "switch", millis());

 

4. HTML 내용에서 스위치 id 설정

<label class="switch">
	<input type="checkbox" id="sw1">
	<span class="slider round"></span>
</label>

 

5. 스크립트 작성

<script>
if(!!window.EventSource) {
  var source = new EventSource('/events');
  
  source.addEventListener('open', function(e) {
	console.log("Events Connected");
  }, false);
  
  source.addEventListener('switch', function(e) {
	var sw_value = e.data;
	console.log(sw_value);
	const checkbox = document.getElementById('sw1');
	if(sw_value == "on") checkbox.checked = true;
	else checkbox.checked = false;
  }, false);
}
</script>

 

이벤트 등록

HTML 안에서 /events 이름으로 등록

<script>
if(!!window.EventSource) {
  var source = new EventSource('/events');

 

클라이언트 접속시 이벤트 등록 알림

source.addEventListener('open', function(e) {
  console.log("Events Connected");
}, false);

 

이벤트 발생시 동작 스크립트

switch 이름의 이벤트 발생시 체크박스 id를 찾아서 버튼 상태 변경.

source.addEventListener('switch', function(e) {
  var sw_value = e.data;
  console.log(sw_value);
  const checkbox = document.getElementById('sw1');
  if(sw_value == "on") checkbox.checked = true;
  else checkbox.checked = false;
}, false);

 

버튼을 누를 때 마다 웹페이지의 버튼이 상태에 따라서 변하는 것을 볼 수 있습니다.

타이머를 이용하여 주기 적으로 어떠한 값을 보낼 수도 있습니다.

이벤트명을 추가하여 여러개의 이벤트를 받을 수 있습니다.