본문 바로가기

개인 연구실/바람의 연구실

아두이노 웹서버 예제 분석

아두이노 웹서버 분석 예제입니다.


1. 개요


아두이노와 이더넷실드를 연결해서 A0 부터 A5 까지의 값을 읽어서 클라이언트의 웹브라우저에서 보여줍니다.

바꿀 부분은 mac 과 ip 주소입니다.



/*

  Web Server


 A simple web server that shows the value of the analog input pins.

 using an Arduino Wiznet Ethernet shield.


 Circuit:

 * Ethernet shield attached to pins 10, 11, 12, 13

 * Analog inputs attached to pins A0 through A5 (optional)


 created 18 Dec 2009

 by David A. Mellis

 modified 9 Apr 2012

 by Tom Igoe

 modified 02 Sept 2015

 by Arturo Guadalupi


 */


#include <SPI.h>

#include <Ethernet.h>


// Enter a MAC address and IP address for your controller below.

// The IP address will be dependent on your local network:

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x48 };

IPAddress ip(192, 168, 0, 148);


// Initialize the Ethernet server library

// with the IP address and port you want to use

// (port 80 is default for HTTP):

EthernetServer server(80);


void setup() {

  // Open serial communications and wait for port to open:

  Serial.begin(9600);

  while (!Serial) {

    ; // wait for serial port to connect. Needed for native USB port only

  }



  // start the Ethernet connection and the server:

  Ethernet.begin(mac, ip);

  server.begin();

  Serial.print("server is at ");

  Serial.println(Ethernet.localIP());

}



void loop() {

  // listen for incoming clients

  EthernetClient client = server.available();

  if (client) {

    Serial.println("new client");

    // an http request ends with a blank line

    boolean currentLineIsBlank = true;

    while (client.connected()) {

      if (client.available()) {

        char c = client.read();

        Serial.write(c);

        // if you've gotten to the end of the line (received a newline

        // character) and the line is blank, the http request has ended,

        // so you can send a reply

        if (c == '\n' && currentLineIsBlank) {

          // send a standard http response header

          client.println("HTTP/1.1 200 OK");

          client.println("Content-Type: text/html");

          client.println("Connection: close");  // the connection will be closed after completion of the response

          client.println("Refresh: 5");  // refresh the page automatically every 5 sec

          client.println();

          client.println("<!DOCTYPE HTML>");

          client.println("<html>");

          // output the value of each analog input pin

          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {

            int sensorReading = analogRead(analogChannel);

            client.print("analog input ");

            client.print(analogChannel);

            client.print(" is ");

            client.print(sensorReading);

            client.println("<br />");

          }

          client.println("</html>");

          break;

        }

        if (c == '\n') {

          // you're starting a new line

          currentLineIsBlank = true;

        } else if (c != '\r') {

          // you've gotten a character on the current line

          currentLineIsBlank = false;

        }

      }

    }

    // give the web browser time to receive the data

    delay(1);

    // close the connection:

    client.stop();

    Serial.println("client disconnected");

    Ethernet.maintain();

  }

}



mac 과 ip 를 다음과 같이 수정했습니다.


byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x48 };

IPAddress ip(192, 168, 0, 148);


IPTIME 공유기를 사용하므로 ip 는 192.168.0. 까지는 그냥 쓰고 나머지 네번째 자리는 비어있는 곳중 충돌을 일으킬 가능성이 적은 148 을 사용했습니다.

mac 은 장비의 유일성을 알려주는 정보인데, ip 의 마지막 번호를 mac 의 끝자리로 사용했습니다. 그러면 내부 네트웍을 사용할 때 mac 이 충돌할 일은 없습니다.


그렇게 해서 실행시키고 웹브라우저인 크롬에서 192.168.0.148 로 접속해서 찍은 화면입니다.




2. 프로그램 분석


우선 mac 과 ip 를 부여하고 서버 포트 80번을 엽니다. 


byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x48 };

IPAddress ip(192, 168, 0, 148);

EthernetServer server(80);


setup() 함수에서 이더넷과 서버를 시작합니다. 


Ethernet.begin(mac, ip);

server.begin();


loop() 함수의 내용입니다. 중요 부분만 짚습니다.


클라이언트 연결을 위한 준비를 합니다.

EthernetClient client = server.available();


클라이언트가 연결되면, 준비된 html 코드를 보냅니다. 

  if (client) {

    boolean currentLineIsBlank = true;

    while (client.connected()) {

      if (client.available()) {

        char c = client.read();

        if (c == '\n' && currentLineIsBlank) {

          // send a standard http response header

          client.println("HTTP/1.1 200 OK");

          client.println("Content-Type: text/html");

          client.println("Connection: close");  


5초마다 반복해서 화면을 새로 뜨게 합니다.

          client.println("Refresh: 5"); 

          client.println();

          client.println("<!DOCTYPE HTML>");

          client.println("<html>");


아날로그0 에서 아날로그5까지 총 6개의 아두이노의 아날로그 포트에 입력된 값을 보여줍니다.

          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {

            int sensorReading = analogRead(analogChannel);

            client.print("analog input ");

            client.print(analogChannel);

            client.print(" is ");

            client.print(sensorReading);

            client.println("<br />");

          }

          client.println("</html>");

          break;

        }

        if (c == '\n') {

          currentLineIsBlank = true;

        } else if (c != '\r') {

          currentLineIsBlank = false;

......