아두이노 강좌 #50 SD-Card를 사용한 웹 서버로 LED 제어
Lucy Archive
Lucy 2023
2020. 11. 27. 16:19

Arduino Web Server LED Control Using SD-Card

지난 포스트에서는 SD-Card를 사용하여 웹서버를 구축하는 방법에 대해 설명하였습니다. 이번 포스트는

SD-Card를 사용한 웹서버에서 LED를 제어하는 방법

에 대해 소개합니다. SD-Card 사용 방법과 Arduino Ehternet Shield를 사용하여 LAN에 연결하고 웹 서버 구축하는 방법은 하단의 관련 페이지를 참고해주세요.

SD-Card를 사용하여 웹 서버 동작

준비물

본 예제의 구성품은 아래와 같습니다.

  • Arduino Uno x 1EA
  • Arduino Ethernet Shield 2 x 1EA
  • LED x 1EA
  • Resistor x 1EA
  • BreadBoard x 1EA
  • 유무선 공유기 x 1EA
  • Jumper Wires

하드웨어 연결

아두이노 웹 서버로 LED 제어를 하기 위해 아래와 같이 하드웨어 부품을 연결 하였습니다. 

아두이노 웹서버로 LED 제어 테스트 셋업

네트워크 구성

네트워크 구성은 아래 그림과 같이 Arduino는 192.168.0.50 고정 IP로 사용하고, 192.168.0.2 ~ 192.168.0.255 네트워크 범위를 가지는 유무선 공유기에 연결하였습니다.  

아두이노 웹 서버 네트워크 구성

웹 페이지

이번 예제에서는 3개의 HTML 문서를 SD-Card에 저장할 예정입니다. 파일의 확장자가 HTM인 이유는 아두이노 SD-CARD 라이브러리가 파일 확장자 3글자만 인식 가능하기 때문입니다.

  • INDEX.HTM : 웹 서버에 처음 접속할 때 보여지는 페이지
  • LED_ON.HTM : index.htm 또는 Led_off.htm 에서 LED ON 버튼을 누르는 이동하는 웹 페이지
  • LED_OFF.HTM : index.htm 또는 Led_on.htm 에서 LED OFF 버튼을 누르면 이동하는 웹 페이지

SD-Card 저장할 HTML 문서 3가지

INDEX.HTM 소스 코드

<!DOCTYPE html>
<head>
	<meta charset="UTF-8">
	<title>LED Control</title>
</head>
<body>
	<h1>LED Control</h1>
	<FORM method="GET" action="led.cgi">
		<input type="radio" name="LED" value="1" onclick="submit();"> LED ON
		<input type="radio" name="LED" value="0" onclick="submit();"> LED OFF
	</FORM>
	<p>LED Status : <strong>OFF<strong></p>
</body>
</html>

LED_ON.HTM 소스 코드

<!DOCTYPE html>
<head>
	<meta charset="UTF-8">
	<title>LED Control</title>
</head>
<body>
	<h1>LED Control</h1>
	<FORM method="GET" action="led.cgi">
		<input type="radio" name="LED" value="1" onclick="submit();" checked> LED ON
		<input type="radio" name="LED" value="0" onclick="submit();"> LED OFF
	</FORM>
	<p>LED Status : <strong>ON<strong></p>
</body>
</html>

LED-OFF.HTM 소스 코드

<!DOCTYPE html>
<head>
	<meta charset="UTF-8">
	<title>LED Control</title>
</head>
<body>
	<h1>LED Control</h1>
	<FORM method="GET" action="led.cgi">
		<input type="radio" name="LED" value="1" onclick="submit();"> LED ON
		<input type="radio" name="LED" value="0" onclick="submit();" checked> LED OFF
	</FORM>
	<p>LED Status : <strong>OFF<strong></p>
</body>
</html>

아두이노 프로그래밍

아래 코드는 아두이노 웹 서버로 LED 를 제어하는 예제입니다. 같은 네트워크에 연결된 PC 또는 스마트폰에서 아두이노 서버로 접속하게 되면 index.htm 파일을 웹 브라우저에 보여주고, LED ON 또는 LED OFF 버튼 클릭 이벤트가 발생하면 아두이노 2번핀에 연결된 LED를 제어하고 LED_ON.HTM 파일 또는 LED_OFF.HTM 파일을 웹 브라우저로 보여주는 예제입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
 
#define LED_PIN 2 // LED 연결핀
#define CS_PIN 4 // SD-Card CS PIN
#define INDEXFILE F("index.htm"// SD-CARD의 HTML 파일 이름
#define WEB1 F("led_on.htm"// SD-CARD의 HTML 파일 이름
#define WEB2 F("led_off.htm"// SD-CARD의 HTML 파일 이름
 
byte mac[] = {0x900xA20xDA0x100x530x07}; // MAC Address 
IPAddress ip(192168050); // IP Address
EthernetServer server(80); // Server Port 80
 
String buffer = ""//HTTP 통신 수신 버퍼
boolean currentLineIsBlank = false;
 
void setup()
{
    pinMode(LED_PIN, OUTPUT); // LED OFF 초기화
 
    Serial.begin(115200);
    Serial.println(F("Initializing SD card..."));
 
    if (!SD.begin(CS_PIN)) {
        Serial.println(F("Card failed, or not present"));
        while (1);
    }
    Serial.println(F("card initialized."));
 
    if ((!SD.exists(INDEXFILE)) && (!SD.exists(WEB1)) && (!SD.exists(WEB2))) {
        Serial.println(F("ERROR - Can't find Proper Webpage File!"));
        while (1); // 파일이 없는 경우 무한 루프
    }
    Serial.println(F("SUCCESS - Found Proper Webpage file."));
 
    Ethernet.begin(mac, ip); 
    server.begin(); 
}
 
void loop(){
    EthernetClient client = server.available();  // try to get client
    String fileName;
    if (client) {  // got client?
        while (client.connected()) {
            buffer = "";
            while(client.available()){
                char c = client.read();
                if(c == '\r'){
                    client.read();
                    break;
                }
                buffer = buffer + c;
            }
            if(buffer.length() == 0)
                currentLineIsBlank = true;
            else
                currentLineIsBlank = false;
            Serial.println(buffer);
            if(buffer.indexOf(F("GET / ")) >=0) { // led.htm
                fileName = INDEXFILE;
            }
            else if(buffer.indexOf(F("GET /led.cgi?LED=1")) >= 0){ // led_on.htm
                fileName = WEB1; 
            } 
            else if(buffer.indexOf(F("GET /led.cgi?LED=0")) >= 0){ // led_off.htm
                fileName = WEB2;
            } 
            if(currentLineIsBlank) break;
        }
 
        client.println(F("HTTP/1.1 200 OK"));
        client.println(F("Content-Type: text/html"));
        client.println(F("Connection: close"));
        client.println();
        // send web page
        File webFile = SD.open(fileName);        // open web page file
        if (webFile) {
            while(webFile.available()) {
                client.write(webFile.read()); // send web page to client
            }
            webFile.close();
    
            if(fileName == WEB1){
                digitalWrite(LED_PIN, HIGH);
                Serial.println("LED ON");
            }
            else if(fileName == WEB2){
                digitalWrite(LED_PIN, LOW);
                Serial.println("LED OFF");
            }
        }        
        delay(1);  
        client.stop(); // close the connection
    }
}
cs

 

실행결과

SD-Card에 위 3개의 HTM 파일을 저장 후, 이더넷 실드에 연결합니다. 아두이노에 위 코드를 업로드 한 후, 같은 네트워크에 있는 PC에서 웹 브라우저 192.168.0.50 에 접속하면 아래 화면과 같이 아두이노의 D2핀에 연결된 LED를 제어 할 수 있습니다.

Arduino_Web-Server_Led-Control

동작 설명

브라우저에서 HTML <form> 태그의 method="GET" 을 사용하여 만들어진 버튼을 클릭하면 HTTP로 서버에게 첫번째 데이터로 GET /{action}?{name}={value} HTTP/1.1 메세지가 송신됩니다. 여기서 서버는 아두이노이고, 브라우저는 같은 네트워크에 있는 PC 또는 모바일폰과 같은 클라이언트 측의 브라우저 입니다. 

브라우저의 LED ON, LED OFF 클릭시 송신되는 HTTP 메세지

브라우저에서 버튼 클릭 이벤트가 발생하면 아두이노에서 아래와 같은 HTTP 메세지를 받을 수 있습니다. 여기서 첫번째 줄의 GET /led.cgi?LED=1 텍스트가 HTTP 수신데이터를 저장한 String 변수 존재하는지 if문에서 확인 후 LED ON을 클릭했는지, LED OFF를 클릭 했는지 판단하고 LED를 제어하고, 적절한 웹페이지를 다시 송출합니다.

수신된 HTTP 메세지 확인


마무리

이번 포스트에서는 SD-Card를 사용한 웹 서버에서 LED를 제어하는 방법에 대해 소개 하였습니다. SD-Card와 Ethernet 사용 관련 포스트는 이전의 포스트를 참고해주세요.

관련포스트

👉 아두이노 이더넷 관련글 목록 보기

👉 아두이노 SD-Card 관련글 목록 보기

👉 아두이노 관련글 전체 목록 보기