?>

Hard Copy World

HCW

ESP8266, ESP32

Home > Learning >

ESP8266, ESP32

ESP8266 활용 가이드 - 아두이노와 연동하기 2

페이지 정보

작성자 하드카피 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 작성일15-01-07 00:22 조회13,948회 댓글14건

본문

 

ESP8266 활용 가이드 목차

 

 

홈 오토메이션이나 다양한 IoT 프로젝트에서 WiFi 모듈의 필요성은 두말할 나위가 없습니다만 가장 큰 문제는 가격과 크기일 것입니다. WiFi 실드나 Serial WiFi 고급형 모듈은 가격과 크기 때문에 여러 프로젝트에 사용하기에는 좀 부담스럽죠. 그런 점에서 ESP8266 Serial WiFi 모듈의 장점이 빛납니다. WiFi 실드의 1/10, 고급형 Serial Wifi 모듈의 1/5 정도의 가격이면 되니까요. 비록 국내에서 구매가 안되고, 사용하기가 까다롭긴 하지만요.

지난 글에서 ESP8266 모듈의 기본 사용법에 대해 다루었는데, 모듈의 Serial Baudrate(통신속도)가 115200 으로 맞춰져 있어 사용하기가 여간 까다로운게 아니었습니다. 일반적으로 Bluetooth 모듈 사용할 때 쓰는 SoftwareSerial 라이브러리는 19200 속도까지만 지원하므로 HardwareSerial을 사용해야 하고 (PC에서 업로드 할 때는 모듈의 전원을 차단해야 함) 아두이노 Pro Mini 3.3v와 같이 8MHz 로 동작하는 보드에서는 115200 속도를 아예 사용할 수가 없습니다.

그래서 이번 글에서는 펌웨어 업데이트를 통해 ESP8266 모듈의 Serial 통신속도를 9600으로 맞추고 Bluetooth 모듈처럼 간단하게 연결해서 사용하는 방법을 다루고자 합니다.

(매뉴얼 작성에 redflag(지운아빠)님께서 많은 도움을 주셨습니다. 이 자리를 빌어 감사의 인사를 전합니다.)

 

 

1. 펌웨어 업데이트

 

먼저 아래 링크에서 펌웨어 업데이트 툴을 받습니다. (Windows 용)

https://docs.google.com/file/d/0B3dUKfqzZnlwVGc1YnFyUjgxelE/edit

실행파일 외에 링크에 포함된 .bin 파일은 최신으로 받아서 적용하셔야 합니다. 아래 링크에서 ESP8266_AT_V00180902_02_baudrate watchdog added 버전의 바이너리 파일을 받으세요. 이 버전으로 업데이트 하면 기본 baudrate 가 9600 으로 설정됩니다.

https://docs.google.com/file/d/0B3dUKfqzZnlwdUJUc2hkZDUyVjA/edit

 

이제 FTDI 모듈을 준비합니다. FTDI 모듈을 3.3v로 셋업하시고 아래 그림과 같이 6개의 핀을 연결해줍니다.

IMG_6499 ESP8266_V091

  • FTDI --> ESP8266
  • VCC (3.3v) --> VCC
  • VCC (3.3v) --> CH_PD
  • GND --> GND
  • GND --> GPIO0
  • TX --> URXD
  • RX --> UTXD

ESP8266 모듈의 8개의 핀 중 6개의 핀을 연결해줘야 합니다. 주의하실 점은 CH_PD 는 VCC, GPIO0 는 GND로 연결한다는 점입니다. CH_PD는 chip enable 핀으로 항상 VCC 로 연결되어야 합니다.(Flash boot 및 update mode 모드 상태로 설정) GPIO0 핀은 LOW status일 때 update 모드로 들어가도록 해줍니다. 따라서 펌웨어 업데이트 할 때는 GPIO0 핀을 GND로 묶어주고 일반적인 동작모드에서는 연결을 해제해 줍니다.

이제 앞서 다운로드 받은 펌웨어 업데이트 프로그램을 실행합니다. (esp8266_flasher.exe)

esp8266-update-02

먼저 1번 항목에 다운로드 받은 바이너리 파일(v0.9.2.2 AT Firmware.bin) 경로와 파일명을 입력해 줘야 합니다. BIN 버튼을 누르면 선택할 수 있는데 경로에 공백이나 2바이트 문자가 포함된 경우 인식이 안될 수 있습니다. 적당히 파일 경로를 바꿔주고 선택해줍니다.

2번 항목에 FTDI 모듈의 COM 포트를 입력해줍니다. FTDI 모듈을 연결하고 [내 컴퓨터 - 마우스 우클릭 - 속성 - 장치관리자] 에 들어가셔서 COM 포트 확인하시면 됩니다.

3번을 누르면 다운로드가 시작될 겁니다. 정상적으로 연결된 경우 99% 까지 진행되고 Leaving... 메시지까지 보일겁니다. 그럼 펌웨어 업데이트는 완료됩니다.

 

 

2. 아두이노와 연결

 

이제 ESP8266 모듈을 9600 통신속도로 사용할 수 있으므로 블루투스 모듈처럼 디지털 핀 2개에 TX, RX를 연결하고 SoftwareSerial 라이브러리로 사용할 수 있습니다.

ESP8266 - 아두이노를 다음과 같이 연결합니다. VCC - 3.3v, GND - GND 연결을 하고 TX, RX를 임의의 디지털핀에 연결합니다. 전 TX - D2, RX - D3 로 연결했습니다. 아래 그림에서는 초록색, 파란색 라인이 D0, D1 에 연결되어 있는데 이걸 바꿔주면 됩니다. 그리고 CH_PD - 3.3v로 연결해줍니다. GPIO0 핀은 연결할 필요가 없습니다.

(WiFi 모듈의 소모 전류가 꽤 큽니다. UNO로는 감당이 안될 수도 있다고 합니다. AT 커맨드가 먹히긴 하지만 동작이 이상한 경우 외부 전원을 WiFi 모듈에 넣는 것을 권장합니다. 일부 모듈은 300mA 이상이 필요하다고 함.)

weather-display1-569x390

그리고 ESP8266 모듈은 동작전압이 3.3v 이므로 5V 동작전압의 보드에서는 level shifting을 해주어야 합니다. 전 5v-3.3v level shift 모듈을 사용했지만 저항 2개를 이용해서 간단히 회로 만드셔도 됩니다. WiFi RX - 아두이노 TX 연결하는 선만 해주면 됩니다. 아래 링크 아래부분 댓글 참고. 
http://www.esp8266.com/viewtopic.php?f=8&t=6&sid=49f5396903eb3e078ccd6a2132be50cb 

 

 

3. 라이브러리 설치

 

인터넷 상에 대부분 소스들이 HardwareSerial 을 통해 115200 속도로 연결한 상태에서 작성한 소스입니다. 사용상 편의를 위해 9600 속도로 맞추었으므로 여기에 맞는 라이브러리를 사용해야 합니다. 아래 ESP8266 라이브러리는 SoftwareSerial을 통해 모듈을 제어할 수 있도록 작성된 라이브러리입니다.

https://github.com/Diaoul/arduino-ESP8266

라이브러리를 다운로드 받아 설치하시면 됩니다. 라이브러리에 포함된 예제 소스 Complete.ino 파일에는 거의 모든 라이브러리 사용법이 포함되어 있습니다. 소스를 분석해서 다양하게 활용하시면 됩니다.

 

 

4. 기본 HTTP Request - HTTP Response 예제

 

라이브러리를 설치하고 아래 예제를 실행해 볼겁니다. 상단의 SSID, PASS, DST_IP (목적지 URL 또는 IP) 를 자신의 환경에 맞게 수정하고 SoftwareSerial(2, 3); 코드에서 모듈의 TX, RX 핀이 연결된 핀 번호 바꿔주세요.

 

#include 

#include "ESP8266.h"

#define SSID "xxxxxxxx"
#define PASS "xxxxxxxx"
#define DST_IP "220.181.111.85" //baidu.com

SoftwareSerial esp8266Serial = SoftwareSerial(2, 3);
ESP8266 wifi = ESP8266(esp8266Serial);

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

    // ESP8266
    esp8266Serial.begin(9600);
    wifi.begin();
    wifi.setTimeout(1000);

    /****************************************/
    /******       Basic commands       ******/
    /****************************************/
    // test
    Serial.print("test: ");
    Serial.println(getStatus(wifi.test()));

    // restart
    Serial.print("restart: ");
    Serial.println(getStatus(wifi.restart()));

    // getVersion
    char version[16] = {};
    Serial.print("getVersion: ");
    Serial.print(getStatus(wifi.getVersion(version, 16)));
    Serial.print(" : ");
    Serial.println(version);


    /****************************************/
    /******        WiFi commands       ******/
    /****************************************/
    // joinAP
    Serial.print("joinAP: ");
    Serial.println(getStatus(wifi.joinAP(SSID, PASS)));


    /****************************************/
    /******       TCP/IP commands      ******/
    /****************************************/
    // connect
    Serial.print("connect: ");
    Serial.println(getStatus(wifi.connect(ESP8266_PROTOCOL_TCP, DST_IP, 80)));

    // send
    Serial.print("send: ");
    Serial.println(getStatus(wifi.send("GET / HTTP/1.0\r\n\r\n")));

}

void loop()
{
    /****************************************/
    /******        WiFi commands       ******/
    /****************************************/

    // read data
    unsigned int id;
    int length;
    int totalRead;
    char buffer[300] = {};

    if ((length = wifi.available()) > 0) {
      id = wifi.getId();
      totalRead = wifi.read(buffer, 300);

      if (length > 0) {
        Serial.print("Received ");
        Serial.print(totalRead);
        Serial.print("/");
        Serial.print(length);
        Serial.print(" bytes from client ");
        //Serial.print("from client ");
        Serial.print(id);
        Serial.print(": ");
        Serial.println((char*)buffer);
      }
    }
}

String getStatus(bool status)
{
    if (status)
        return "OK";

    return "KO";
}

String getStatus(ESP8266CommandStatus status)
{
    switch (status) {
    case ESP8266_COMMAND_INVALID:
        return "INVALID";
        break;

    case ESP8266_COMMAND_TIMEOUT:
        return "TIMEOUT";
        break;

    case ESP8266_COMMAND_OK:
        return "OK";
        break;

    case ESP8266_COMMAND_NO_CHANGE:
        return "NO CHANGE";
        break;

    case ESP8266_COMMAND_ERROR:
        return "ERROR";
        break;

    case ESP8266_COMMAND_NO_LINK:
        return "NO LINK";
        break;

    case ESP8266_COMMAND_TOO_LONG:
        return "TOO LONG";
        break;

    case ESP8266_COMMAND_FAIL:
        return "FAIL";
        break;

    default:
        return "UNKNOWN COMMAND STATUS";
        break;
    }
}

String getRole(ESP8266Role role)
{
    switch (role) {
    case ESP8266_ROLE_CLIENT:
        return "CLIENT";
        break;

    case ESP8266_ROLE_SERVER:
        return "SERVER";
        break;

    default:
        return "UNKNOWN ROLE";
        break;
    }
}

String getProtocol(ESP8266Protocol protocol)
{
    switch (protocol) {
    case ESP8266_PROTOCOL_TCP:
        return "TCP";
        break;

    case ESP8266_PROTOCOL_UDP:
        return "UDP";
        break;

    default:
        return "UNKNOWN PROTOCOL";
        break;
    }
}

 

  • wifi.joinAP : AP(공유기)에 연결
  • wifi.connect(ESP8266_PROTOCOL_TCP, DST_IP, 80) : 특정 서버와의 연결 설정, 연결에 성공하면 linked 상태가 됨
  • wifi.send("GET / HTTP/1.0\r\n\r\n") : 특정 주소로 Request를 전송
  • loop() 함수 안에서 request 날린 페이지의 응답을 버퍼로 읽어옵니다.
  • wifi.close() : 연결 설정을 해제합니다. unlink 상태가 됩니다.

Serial Monitor를 통해 모듈 Setup, Request 과정과 Response 데이터가 출력되는 과정을 확인하실 수 있습니다.

코드를 보시면...  loop() 함수 안에서 response 데이터를 계속 읽어와서 출력하도록 되어 있는데 일정 크기 이상은 읽어들이질 못합니다. Response 데이터가 크기가 크기 때문에 조금씩 읽어 들여야 하는데 현재 소스는 뭔가 문제가 있는 것 같습니다. 데이터를 아두이노로 다 읽어들이기 보다는 라이브러리에서 제공하는  find 함수들을 이용해서 원하는 문자열을 찾아나가는 방식으로 수정해서 사용하시길 권합니다.

 

더 상세한 내용과 다른 활용법은 더 테스트 해보고 추가하겠습니다.  라이브러리에 포함된 Complete.ino 파일을 참고하면 다양하게 활용할 수 있습니다.

 

참고자료 :

 

[이 게시물은 최고관리자님에 의해 2016-01-24 15:11:27 Communication module에서 복사 됨]


하드카피 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물

모든 전통이 한 때는 오해를 면치 못했다. 마찬가지로 모든 아이디어는 한 때는 비웃음을 면치 못했다. -홀브룩 잭슨 ::::: 느닷없이 떠오르는 생각이 가장 귀중한 것이며, 보관해야할 가치가 있는 것이다. -베이컨 ::::: 미리 숙고하면 힘든 일도 그저 실행에 옮기는 순간 쉬워진다. - 로버트 M. 피어식

추천 1
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글목록

유성가면님의 댓글

유성가면 이름으로 검색 작성일

좋은 정보 감사드립니다.
아직 ESP8266에 대한 정보가 많지 않아 테스트 하는데 많은 어려움이 있습니다.
펌웨어를 올렸고 스마트폰에서 와이파이로 잡힙니다.
위 코드를 아두이노에 적용하니 아래와 같이 나오는데 test OK 로 나오는것은 아두이노와 연결은 됐다고 봐야할까요? 버전정보부터 타임아웃이 발생하는데..
어디부터 체크해야 하는지 진단 부탁드립니다
test: OK
restart: KO
getVersion: TIMEOUT :
joinAP: TIMEOUT
connect: TIMEOUT
send: NO LINK

최고관리자님의 댓글

최고관리자 쪽지보내기 메일보내기 홈페이지 자기소개 아이디로 검색 전체게시물 댓글의 댓글 작성일

restart 까지 정상적으로 실행되었다면 아두이노와 serial wifi 연결 및 기본 동작은 이상 없는 것 같습니다. 그런데 getVersion이 안되는 것은 의외네요;; 그냥 내부의 버전값만 가져오는건데... joinAP가 안되는 것은 그럴수도 있겠다 싶지만요.
안되는 지점이 좀 이상하니까.. 일단 라이브러리에 포함된 예제파일을 가지고 한번 해보시길 추천드려요.

유성가면님의 댓글

유성가면 이름으로 검색 댓글의 댓글 작성일

답변 감사드립니다.
라이브러리에 포함되어 있는 complete 소스를 참고로 하여 실행했습니다.
wifi.restart()를 빼고하니 버전정보가 나옵니다.
말씀하신거 처럼 역시나 joinAP에서 에러가 발생합니다.
공유기 SSID랑 패스워드를 정확히 입력했는데 접속되지 않습니다.
물론 MAC차단은 되어 있지 않은 공유기 입니다.
이부분은 어떻게 확인해야 좋을런지요^^?
=======================
test: OK
getVersion: OK : 0018000902
joinAP: ERROR
getAP: TIMEOUT :
quitAP: OK
getAPConfiguration: OK : ESP8266 -  - 10 - 4
getMAC STA: TIMEOUT : 0:0:0:0:0:0
getMAC AP: TIMEOUT : 0:0:0:0:0:0
getIP STA: TIMEOUT : 0.0.0.0
getIP AP: TIMEOUT : 0.0.0.0
connect: TIMEOUT

하드카피님의 댓글

하드카피 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 댓글의 댓글 작성일

저도 이 문제때문에 골치가 아프네요.
AP 연결까지 되고 request 까지 되던 모듈이 소스코드 변경하고 AP 접속 안되기 시작하더니 계속 안됩니다. 뭐가 문제인지 아직 못찾는 중인데... 전원 문제일 수도 있을 것 같고...(ESP8266에서 소비하는 전원이 200~350mA 정도라고 합니다.) GPIO0 핀을 pull up으로 맞추기도 해봤는데 안되네요. 공유기에서 차단시킨건지...

Reset 명령어 안먹힐 때는 펌웨어 업데이트 다시 받아보세요. 그러니까 정상적으로 되네요.

유성가면님의 댓글

유성가면 이름으로 검색 댓글의 댓글 작성일

답변 감사드립니다
안정적인 펌에어가 나올때까지 당분간 다른모듈쪽으로 접근해야겠습니다.
해결방법이나 기타 좋으정보 찾으셨으면 여기 게시판을 통해 알려주셨으면 좋겠습니다^^

유민아빠님의 댓글

유민아빠 이름으로 검색 작성일

저도 윗분들 처럼 wifi.restart()를 빼고하니 버전정보까진 나오는데,
그 다음 안됨... ㅠㅠ
=====================================
test: OK
restart: getVersion: OK : 0018000902
joinAP: ERROR
connect: TIMEOUT
send: NO LINK

llpmpll님의 댓글

llpmpll 이름으로 검색 작성일

좋은 정보 고맙습니다. ^^
질문이 있습니다.
esp8266에서 와이파이를  검색해서 접속할수는 없는건가요??
뭐였드라... scannetworks??? 이런거요..
꼭 setup 이전에 ssid와 pass를 작성해야 가능한건가요??

하드카피님의 댓글

하드카피 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 댓글의 댓글 작성일

AT+CWLAP 커맨드가 주변 AP 검색하는 커맨드네요. 이 커맨드 날리면 주변 AP 검색 결과가 응답으로 올 것 같은데... 문제는 그 긴 문자열을 처리해서 원하는 AP의 SSID 찾아내고, Pass 처리하는 부분을 아두이노에서 감당하기가 좀 버거울것 같네요;;;

sonzweil님의 댓글

sonzweil 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 작성일

ESP8266 무턱대고 덤비려다가 힘들엇는데 여기 보물같은 글을 발견해서 희망의 빛줄기를 얻는 거 같습니다ㅠ.
제가 ESP8266과 Arduino mini를 연결하려는데 초짜라 혹시 답변 얻을 수 있을까 질문해봅니다.
- Arduino mini 3.3v/8Mhz 보드와 3.3v FTDI를 구매하였는데. 이 보드를 이용했을 때 전원을 어떻게 사용해야 맞는 건지 잘 모르겠습니다. 아두이노 mini에서 3.3v 출력을 내는 곳이 있는지 모르겠습니다
- ESP8266같은 경우 3.3v 전압을 이용하는데, 3.7v Lipo배터리를 연결해서 사용해도 되는지 모르겠습니다. 3.3v와 3.7v 호환이 되는 건가요? 서로 호환되게 만들어야 하는지 궁금하네요

최고관리자님의 댓글

최고관리자 쪽지보내기 메일보내기 홈페이지 자기소개 아이디로 검색 전체게시물 댓글의 댓글 작성일

1. 프로 미니 보드에 있는 VCC 핀을 사용하시면 됩니다. 동작전압에 해당하는 출력이 나올겁니다.
2. 네 말씀대로 사용하시면 됩니다. lipo 배터리가 충전되면 3.7V 정도의 출력이 나오고 사용할수록 점점 떨어진다고 하네요.

sonzweil님의 댓글

sonzweil 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 댓글의 댓글 작성일

답변 감사드립니다^^. 이 사이트에서 정말 많은 걸 배울수 있네요. 저도 열심히 해서 언젠가 관리자님을 도울 수 있을 정도가 되겠습니다 ㅎㅎ

sonzweil님의 댓글

sonzweil 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 작성일

AT 명령어를 이리저리 만지다가 우연히 joinAP를 성공하였습니다. 좀 더 살펴보다 나름의 해결책을 찾아낸 것 같아 댓글을 남겨 봅니다.
 
 우리는 3번 항목에서 라이브러리를 다운받았었고, 이 라이브러리의 example, Complete.ino를 보면 아래와 같은 선언이 있습니다.
 wifi.setMode(ESP8266_WIFI_ACCESSPOINT)
 그런데 이렇게 ACCESSPOINT 상태로 모드가 지정되었을 경우에는 joinAP가 곧바로 ERROR가 뜨는 것 같습니다. 그리고 이 setMode 선언은 쭉 남아있게 되는 듯 합니다.

 그러므로 현재 joinAP가 ERROR가 뜨는 상황이라면, joinAP 선언부분 이전에
wifi.setMode(ESP8266_WIFI_STATION)
wifi.setMode(ESP8266_WIFI_BOTH)
둘 중의 하나를 먼저 호출해서 Mode를 변경해주면 joinAP가 가능해지는 것 같습니다. 다만 ACCESSPOINT, STATION의 정확한 차이는 잘 모르겠습니다.

하드카피님의 댓글

하드카피 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 댓글의 댓글 작성일

귀한 정보 정말 감사드립니다~!! 저도 늘 이 지점에서 문제가 생기곤 했었거든요. ACCESSPOINT, STATION은... AP모드는 공유기 처럼 동작하는 모드, STATION(혹은 STANDALONE)은 PC나 휴대폰처럼 공유기에 접속해서 HTTP Request를 날리는 모드를 말하는 것 같습니다. BOTH는 두 가지 모두가 동시에 활성화 됨을 의미하구요. 다른 wifi 모듈을 설정할 때 보니 모드를 이렇게 3가지를 지원하는 것 같았습니다.