개발/ESP32, ESP8266

ESP8266(ESP-01, ESP-01S) wifi client, 서버로 부터 데이터 받기

어중E 2022. 11. 11. 19:08

이번에는 wifi client - esp8266에 대해서 알아봅니다. 코드의 기능은 특정 서버에 데이터를 보내 응답을 받습니다. 따라서 esp8266은 client의 기능을 합니다.

 

/*
    This sketch establishes a TCP connection to a "quote of the day" service.
    It sends a "hello" message, and then prints received data.
*/

#include <ESP8266WiFi.h>

#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK  "your-password"
#endif

const char* ssid     = STASSID;
const char* password = STAPSK;

const char* host = "djxmmx.net";
const uint16_t port = 17;

void setup() {
  Serial.begin(115200);

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  /* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default,
     would try to act as both a client and an access-point and could cause
     network-issues with your other WiFi-devices on your WiFi-network. */
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  Serial.print("connecting to ");
  Serial.print(host);
  Serial.print(':');
  Serial.println(port);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    delay(5000);
    return;
  }

  // This will send a string to the server
  Serial.println("sending data to server");
  if (client.connected()) {
    client.println("hello from ESP8266");
  }

  // wait for data to be available
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      delay(60000);
      return;
    }
  }

  // Read all the lines of the reply from server and print them to Serial
  Serial.println("receiving from remote server");
  // not testing 'client.connected()' since we do not need to send data here
  while (client.available()) {
    char ch = static_cast<char>(client.read());
    Serial.print(ch);
  }

  // Close the connection
  Serial.println();
  Serial.println("closing connection");
  client.stop();

  delay(300000); // execute once every 5 minutes, don't flood remote service
}

전체적인 코드입니다. 기본적인 것들만 포함되어 있기 때문에 코드가 그리 길진 않습니다.

 

const char* host = "djxmmx.net";
const uint16_t port = 17;

host에는 url이 있고 포트가 적혀 있습니다. 해당 링크-포트로 데이터를 보내고, 특정 데이터를 얻습니다.

 

이후에 결과로 나오겠지만 얻어지는 특정 데이터는 ‘오늘의 시’라는 서비스로 시의 일부가 전달됩니다.

 

setup() 함수는 이전 글에서 충분히 설명된 부분이 많기 때문에 여기에서는 생략하고, 내용을 알기를 원하시면, 이전 글을 참고해주세요.

 

 

void loop(){
	...

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    delay(5000);
    return;
  }

	...

}

loop 함수를 살펴보면, WiFiClient 클래스 객체를 선언합니다. 이 클래스는 host, port를 매개변수로 연결을 시도합니다.

 

주석을 살펴보면 TCP Connections을 생성하기 위한 클래스입니다. TCP는 데이터를 교환하는 데 있어 사용되는 프로토콜 중 하나로 IP와 함께 TCP/IP라고도 불립니다.

 

// This will send a string to the server
  Serial.println("sending data to server");
  if (client.connected()) {
    client.println("hello from ESP8266");
  }

이어서 client가 host(서버)에 연결되어 있다면, “hello from ESP8266" 문자열을 보냅니다. 이 문자열을 서버에 보냅니다.

 

 

unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      delay(60000);
      return;
    }
  }

클라이언트(esp8266)가 서버에 메세지를 보내고 나서 서버는 다시 특정 데이터를 클라이언트에게 보냅니다. 그러면, 데이터가 왔는지 확인을 해야 합니다.

 

client.available() == 0의 뜻은 클라이언트가 받은 데이터가 있는지를 확인하는 코드입니다. 값이 = 0이면, 데이터가 없다는 것입니다.

 

따라서 데이터가 올 때까지 특정 시간만큼 기다린 다음에 시간이 넘어가면 timeout을 띄우고 넘어갑니다. 만일 데이터가 왔다면, 바로 다음 단계로 넘어갑니다.

 

 

// Read all the lines of the reply from server and print them to Serial
  Serial.println("receiving from remote server");
  // not testing 'client.connected()' since we do not need to send data here
  while (client.available()) {
    char ch = static_cast<char>(client.read());
    Serial.print(ch);
  }

이후 전송된 데이터를 하나하나 출력한 후, 모두 출력할 때까지 while로 반복합니다

.

여기까지가 client가 server로 데이터를 보내고 받는 과정입니다. 물론 서버에서 어떤 데이터를 보내는지는 서버에 따라 다릅니다. 이 예제에서는 client가 어떤 데이터를 보내도 서버는 데이터를 전송해줍니다. 업로드해보시면 다음과 같은 결과를 확인할 수 있습니다.