2021년 1월 23일 토요일

저가 IoT 장치 개발을 위한 통합 임베디드 모듈 TTGO WiFi Bluetooth ESP32 개발 방법 및 사용기

이 글은 그 동안 리뷰 미루어 두었던, 통합 무선 모듈 TTGO WiFi Bluetooth ESP32 개발 방법 및 사용기를 간단히 나눔한다. 

이 모듈은 GPIO16, WiFi, Bluetooth, OLED, 충전식 배터리 장치를 모두 포함하고도 겨우 10달러 아래에 구입할 수 있는 ESP32 칩 기반 소형 임베디드 컴퓨터이다. 18650 소형 배터리를 지원하며, 프로그래밍은 아두이노 IDE에서 코딩할 수 있다. 이런 기능을 통해, 손쉽게 저가의 IoT 장치를 개발할 수 있다.

다음 영상은 이 모듈을 이용해 개발한 사례를 보여준다.

개발 사례(TTGO WiFi & Bluetooth Battery ESP32 0.96 inch OLED development tool)
날씨 측정을 위한 웨더스테이션 개발 사례

ESP32 보드
TTGO ESP32에 사용된 메인칩인 ESP32는 Wi-Fi, Bluetooth가 통합된 칩 마이크로 컨트롤러이며, 저가형 저전력 시스템이다. 참고로, TTGO는 www.lilygo.cn 브랜드이며, 중국 심천의 보드 회로 메이커이다. ESP32 시리즈는 Tensilica Xtensa LX6 마이크로 프로세서를 사용해 내장 안테나 스위치, RF, 필터 및 전력 관리 모듈을 포함하고 있다. ESP32는 상하이에 본사를 둔 중국 회사인 Espressif Systems가 개발했으며 TSMC에서 40nm 공정을 사용하여 제조된다. 이 칩은 ESP8266 마이크로 컨트롤러의 후속 제품이다.

ESP32 칩 기반 보드는 주변에 어떤 모듈을 추가했느냐에 따라 다음 그림과 같이 다양한 변종이 존재한다. TTGO WiFi Bluetooth ESP32 모듈은 ESP32 칩 기반 모듈 중 무선 통신 및 OLED 기능을 가지고 있다.

ESP32 모듈의 GPIO 레이아웃 구조는 다음과 같다. 

모듈 스펙
이 모듈은 다음과 같은 형태로 디자인되어 있다. 앞면은 OLED, WiFi, GPIO등이 보이고, 뒤면은 18650배터리를 장착할 수 있도록 되어 있다.
ESP32 보드와 18650 배터리

이 모듈의 자세한 스펙은 다음과 같다. 
  • Micro USB 입력
  • Integrated 18650 충전 지원
  • SDA OLED, SCL은 D1 pin, D2 pin과 연결됨
  • 인터럽트 / pwm / I2C 지원
  • Integrated OLED 지원
  • Input voltage range: 5-12V. Charge current: 500 mA
다음은 18650 배터리 사용 시 주의사항이다. 
If the battery is in the wrong direction, the charging chip will be destroyed.
When you burn a program. Please disconnect the battery and check that the switch is in position.

아두이노 IDE 설정 및 사용 방법
다음 순서로 아두이노 IDE를 설정한다. 우선, 개발보드를 추가해야 하고, 그 다음 라이브러리를 추가해 예제를 실행해 본다.

1. 모듈과 컴퓨터를 USB 케이블로 연결한다. 그리고, FILE > 환경 설정 메뉴에서 다음 링크를 추가한다.

2. 아두이노 IDE에서 Tools > Board > Boards Manager 메뉴를 선택하고 ESP32 를 검색한 후보드를 설치한다. 

BOARD IN ESP32 BY Espressif

3. 다음과 같이 WEMOS LOLIN32 보드를 선택한다. 그리고, 연결된 COM 포트를 선택한다.

4. 아두이노 IDE에서 FILE > EXAMPLE > ESP32 메뉴의 BLUETOOTH 예제를 선택한다.

5. 아두이노 IDE에서 UPLOAD 버튼을 클릭한다. 이때, 보드의 BOOT BUTTON을 누르고 있어야 한다. 모듈의 PORT 0 과 GND를 서로 연결해도 동일하게 동작한다. 만약, 버튼을 누르지 않으면, 다음과 같은 에러가 발생하고, 코드가 모듈로 업로드되지 않는다.

ESP32 Timed out 문제
코드 업로드 장면(Boot 버튼 푸시 후 코드 업로드되면 EN버튼 푸시할 것)

이 문제에 대한 좀 더 상세한 내용은 다음 링크를 참조한다.

6. 코드가 다 업로드되면, BOOT 버튼를 놓고, 모듈의 EN 버튼을 클릭한다. 그럼, 코드가 동작할 것이다. 

7. 아두이노 IDE의 시리얼 모니터 메뉴를 선택하면, 예제 코드에서 출력되는 내용을 확인할 수 있다. 다음과 같이 모듈에서 획득한 BLUETOOTH 스캔 결과를 데이터로 볼 수 있을 것이다. 


동작 결과

다른 ESP32 모듈 예제는 FILE > EXAMPLE > ESP32 메뉴에서 실행해 본다. 

OLED 디스플레이 예제
내장된 디스플레이에 그림을 출력해 본다. 디스플레이 칩은 SSD1306이다. 사용을 위해 다음과 같이 라이브러리를 추가한다.

그리고, 새파일을 만든 후, 다음 소스코드를 복사해 붙여 넣는다.
/*********
  Complete project details at https://randomnerdtutorials.com  
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

static const uint8_t image_data_Saraarray[1024] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x14, 0x9e, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x36, 0x3f, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x6d, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xfb, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xd7, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xef, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xdf, 0xff, 0x90, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xbf, 0xff, 0xd0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1d, 0x7f, 0xff, 0xd0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x01, 0x1b, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x02, 0xa7, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0x80, 0x00, 0x0b, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x07, 0xff, 0xf8, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0e, 0x01, 0xff, 0xc0, 0x38, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0x46, 0xff, 0xb1, 0x18, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0x97, 0xff, 0xc0, 0x7a, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xbf, 0xff, 0xff, 0xff, 0xfe, 0x81, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xfc, 0x81, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xfe, 0xff, 0xfd, 0x83, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xbf, 0xff, 0xfe, 0xff, 0xfd, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfb, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xdc, 0xff, 0xfa, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xd8, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xd0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x90, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x02, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xb0, 0x00, 0x0f, 0xf5, 0xff, 0xd7, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xb0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x5f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xa0, 0x00, 0x0f, 0xfb, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x0f, 0xfd, 0xff, 0xdf, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0xbf, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x87, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x43, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x73, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfe, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7b, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfd, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00, 0x33, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfd, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x27, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x67, 0xff, 0xe0, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfd, 0x40, 0x00, 0x00, 0xf3, 0xff, 0xc4, 0x00, 0x00, 0x0b, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfe, 0x80, 0x00, 0x00, 0xfc, 0xff, 0x8c, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0x3c, 0x3c, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x7c, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff
};
 
void setup() {
  Serial.begin(115200);
  
  // Start I2C Communication SDA = 5 and SCL = 4 on Wemos Lolin32 ESP32 with built-in SSD1306 OLED
  Wire.begin(5, 4);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000); // Pause for 2 seconds
 
  // Clear the buffer.
  display.clearDisplay();
  
  // Draw bitmap on the screen
  display.drawBitmap(0, 0, image_data_Saraarray, 128, 64, 1);
  display.display();
}
 
void loop() {
  
}

앞서 했던 것처럼, TTGO ESP32보드에 코드를 업로드한다. 그럼, 다음과 같이 OLED에 출력된 그래픽을 확인할 수 있다.

기타 예제는 다음 github를 참고한다.
충전 및 사용
TTGO 모듈은 충전기가 내장되어 있다. 18650 배터리 (2600mAh)를 테스트해본 결과, OLED LCD를 계속 동작시킨 상태에서 2일정도를 사용할 수 있었다. 

마무리
이 글은 TTGO WiFi Bluetooth ESP32 개발 방법 및 사용기를 간단히 정리해 보았다. 이 모듈은 센서, OLED 디스플레이, WiFi, Bluetooth 등이 모두 통합되어 있어, 관련 기능이 필요할 때 매우 편리하게 개발할 수 있다. 가격도 몇 달러밖에 되지 않아, 사용에 부담이 없다. 다만, 개발 시 자료가 부족하고, 응용 사례가 많지 않은 것이 단점이다. 잘 활용한다면, 저렴한 가격에 괜찬은 IoT 장치를 개발할 수 있을 것이다.

레퍼런스

TTGO WiFi Bluetooth Battery Module 18650 ESP32 0.96 inch OLED Development Tools
TTGO ESP32 OLED DEVELOPMENT TOOL
TTGO Weather station
PlatformIO.org and getting started
ThingPlus OLED SSD1306
ESP32 OLED SSD1306
A fatal error occurred: Timed out waiting for packet content - problem after writing to SPIFFS memory of ESP32

댓글 없음:

댓글 쓰기