[아두이노 공부] 12. ESP8266으로 현재시간을 알아보자
공부/아두이노, 전자·전기

[아두이노 공부] 12. ESP8266으로 현재시간을 알아보자

안녕하세요.

기계과 감성쟁이입니다.

 

저번에 온습도센서 써볼 때

시간을 넣고싶다고 했었어요.

 

우선 esp8266으로 시간부터 가져와봅시다.

 

 

0. 현재 시간을 아는 방법?


 

일반적으로 시계는 3가지 종류가 있습니다.

 

태엽으로 기어를 돌려 움직이거나 (오토매틱),

수정에 전류를 흘려 일정한 진동수를 만들거나 (쿼츠),

인터넷에서 시간을 받아오거나 (디지털)

 

오토매틱은 아두이노와 전혀 어울리지 않고,

쿼츠를 하자니, RTC 모듈을 사용해야합니다.

 

가장 깔끔한건 디지털이죠. 그리고 우린 ESP8266 이라는 와이파이 모듈이 있습니다.

 

1. 가져온 코드


 

 

How to read current time from internet using ESP8266? - Everything ESP8266

Hi all, The problem, that there is no tool that s[…]

www.esp8266.com

 

위 링크에서 코드를 가져와서 

 

#include <ESP8266WiFi.h>

const char* ssid = "WiFi_name";
const char* password = "WiFi_PW";

void setup() {
  Serial.begin(9600);
  Serial.println();
  initWiFi(); // 뒤에 나올 initWiFi() 함수
}

void loop() {
  Serial.println(getTime()); // 뒤에 나올 getTime() 함수 
  delay(5000);
}
 
String getTime() {
  WiFiClient client;
  while (!!!client.connect("google.com", 80)) { //  google.com 연결 안되면, !!! 또는 ! 는 부울
  Serial.println("connection failed, retrying..."); 
  }
  
  client.print("HEAD / HTTP/1.1\r\n\r\n"); // google.com 에 접속해서 헤더파일 받아오는 명령어?

  while(!!!client.available()) {} // !!! 또는 ! 는 부울

  while(client.available()){
    if (client.read() == '\n') {   
      if (client.read() == 'D') {   
        if (client.read() == 'a') {   
          if (client.read() == 't') {   
            if (client.read() == 'e') {   
              if (client.read() == ':') {   
                client.read();
                String theDate = client.readStringUntil('\r'); 
                client.stop();
                return theDate;  // Date: 까지 읽고, 맞으면 \r 까지 읽어오기.
              }
            }
          }
        }
      }
    }
  }
}

void initWiFi() {
  
   Serial.print("Connecting to ");
   Serial.print(ssid);
   
   if (strcmp (WiFi.SSID().c_str(),ssid) != 0) { // strcmp, c.str() 에 대해서는 밑에서 설명
      WiFi.begin(ssid, password); // 와이파이 이름이랑, 비밀번호 입력해서 와이파이 연결
   }
   
   while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
   }
   
  Serial.print("\nWiFi connected, IP address: ");
  Serial.println(WiFi.localIP()); // local IP 출력
}

 

이렇게 수정했습니다.

 

2. 코드 몇 가지 설명


1. client.print ("HEAD / HTTP/1.1\r\n\r\n");

 

이건 client 사이트에서 헤더파일을 받아오는 명렁어입니다.

근데 우리는 구글의 시간을 가져오잖아요?

 

자 그러면 구글의 헤더파일을 봅시다.

 

 

구글 메인화면에서 F12 를 눌러서 개발자 도구를 불러오고,

Network 에서 헤더파일을 확인해보면

 

date 라는 글자 뒤에 시간이 나옵니다.

그래서 코드 중간에 date 라는 글자를 확인하고,

뒤에 적힌 텍스트를 가져오는 코드가 있습니다.

 

우리가 나타내는 시간은,

이렇게 헤더파일에서 가져오는 겁니다.

 

2. strcmp () 함수

 

if (strcmp (WiFi.SSID().c_str(),ssid) != 0) 이라는 코드가 의미하는 것은

현재 연결된 SSID(와이파이의 이름)과, 사용자가 입력한 SSID 가 다를 경우,

와이파이를 연결한다는 뜻입니다.

 

즉, strcmp (const char* a, const char* b) 는

문자열 a 와 문자열 b 를 비교하는 것이죠.

 

비교하는 원리는

문자열을 앞에서부터 하나씩 ASCII 코드로 비교하는 겁니다.

 

다른 문자가 나왔을 때, 두 문자의 아스키코드를 비교하고

무엇의 숫자가 높은지에 따라 반환값이 달라집니다.

 

 

[C언어/C++] strcmp, strncmp 함수(문자열 비교)에 대해서

안녕하세요 BlockDMask입니다. 오늘은 c/c++에서 두개의 문자열이 같은지, 다른지 다르면 어떤식으로 다른지 검사할 수 있는 strcmp 함수. 문자열 비교 함수인 strcmp 함수를 알아 보려고 합니다. 오늘은

blockdmask.tistory.com

 

좋은 게시글이 있으니 참고해주세요.

(BlockDMask 님의 블로그)

 

3. c_str() 함수

 

if (strcmp (WiFi.SSID().c_str(),ssid) != 0)

 

.c_str() 이 의미하는 것은 무엇일까요?

해당 코드 없이 업로드를 하면 아래와 같은 오류가 나타납니다.

 

'error: cannot convert ‘std::string’ to ‘const char*’ for argument ‘1’ to ‘int strcmp(const char*, const char*)'

 

우리의 친구 구글과 스택오버플로를 참고해봅시다.

 

 

Cannot convert ‘std::string’ to ‘const char*

Hi can any one tell what wrong with this code ?. string s=getString(); //return string if(!strcmp(s,"STRING")){ //Do something } while compiling I am getting the error like er...

stackoverflow.com

 

strcmp 는 const char* 를 argument 로 받아들이므로, .c_str() 를 붙여주라는군요.

왜냐하면, c_str() 은 문자열const char* 형태로 바꿔주기 때문입니다.

 

3. 결과


 

 

집에 있는 와이파이를 연결했습니다.

잘 되는군요.

 


위 코드를 조금 더 간단하게 만들 수도 있지만,

여러가지 함수와 코드를 알아보자는 차원에서 거의 그대로 사용하였습니다.

 

다음은 온습도와 함께 나타내는 일이네요.

고생하셨습니다.