본문 바로가기

ESP32

ESP-32 LVGL 그래픽을 사용한 고급 기술 - 1부

반응형

ESP-32 및 LVGL 그래픽을 사용한 고급 기술 - 1부

 

이 튜토리얼의 1부에서는 시스템의 핵심인 CrowPanel 장치를 소개합니다. 그런 다음 Arduino IDE를 구성하여 장치를 프로그래밍하고, 코딩을 간소화하기 위해 Arduino 라이브러리를 다운로드합니다. 마지막으로, 다운로드한 Arduino 그래픽 라이브러리(TFT_eSPI)를 사용하여 속도계 애플리케이션의 배경 화면 이미지를 생성하는 코드를 작성합니다.

 

CrowPanel ESP32 장치

 

CrowPanel 디스플레이는 Elecrow라는 회사에서 제조합니다. AliExpress에서 검은색 플라스틱 케이스와 함께 제공되는 디스플레이 패널을 구매했습니다. 직접 케이스를 제작할 계획이라면 Amazon이나 DigiKey 등 다른 곳에서 플라스틱 케이스 없이도 구매할 수 있습니다. 아래 이미지는 보드의 부품 측면의 일반적인 레이아웃을 보여줍니다.

 

 

 

플라스틱 케이스를 설치하면, 아래와 같이 후면 패널에 다양한 연결부에 접근할 수 있는 개구부가 생깁니다.

 

 

 

 

이 장치는 2.4인치 컬러 디스플레이, 터치스크린 인터페이스, ESP-32 프로세서, SD 카드 슬롯, 스피커 연결이 가능한 내장 오디오 앰프, 그리고 내장 리튬 배터리 충전기를 포함합니다. 이 프로젝트에서는 이러한 모든 기능을 사용하지는 않지만, 향후 프로젝트를 위해 알아두면 유용할 것입니다 . ESP32 WROOM 프로세서를 사용하므로 Wi-Fi 및 블루투스 통신 기능도 지원합니다. 홈 오토메이션 프로젝트, 기상 관측소, 그리고 소형 컬러 그래픽 디스플레이 화면이 필요한 장비 제어기에 이상적인 장치입니다.

 

아두이노 IDE 설정

 

이 장치에 대해 온라인에서 검색해 보면 다양한 프로그래밍 라이브러리와 개발 환경에 대한 방대한 정보를 찾을 수 있습니다. 매우 혼란스러울 수 있습니다. 이 튜토리얼에서는 취미 프로그래머들에게 인기 있는 도구인 Windows, Linux 또는 MacOS에서 실행되는 Arduino IDE 환경에 중점을 둡니다. Arduino IDE가 아직 설치되어 있지 않다면 여기에서 설치 지침을 확인할 수 있습니다.

 

컴퓨터에 Arduino IDE를 설치하면 CrowPanel 장치 사용에 필요한 라이브러리를 설치하고 구성할 수 있습니다. Elecrow는 장치 구성 지침을 여기에서 제공하며 , 저희가 사용하는 특정 모델과 관련된 내용은 아래 섹션에 복사해 두었습니다.

 

Arduino IDE를 설치한 후에는 ESP32 보드 패키지를 설치해야 Arduino IDE에서 ESP32 개발이 가능합니다. 필요한 보드 패키지를 설치하려면 다음 단계를 따르세요.

 

Arduino IDE를 엽니다.

 

파일 > 환경 설정으로 이동합니다.

 

"추가 보드 관리자 URL" 필드에서 오른쪽 버튼을 클릭하고 다음 URL(Espressif Systems 제공)을 붙여넣습니다. https://espressif.github.io/arduino-esp32/package_esp32_index.json

 

 

 

 

 

"확인"을 클릭하여 설정을 저장합니다. Arduino IDE가 JSON 파일을 다운로드하고, 다운로드 진행률은 오른쪽 하단에 진행률 표시줄로 표시됩니다. 다운로드가 완료되면 진행률 표시줄이 자동으로 사라집니다.

 

이제 도구 > 보드 > 보드 관리자로 이동하세요.

 

 

 

 

"ESP32"를 검색하여 Espressif Systems에서 제공하는 패키지를 찾으세요.

 

2.0.15 버전을 선택하고 "설치"를 클릭하세요. (다른 버전을 선택하실 수도 있습니다. 하지만 이상한 버그를 줄이려면 2.0.15 버전을 사용하는 것이 좋습니다.)

 

 

 

 

이제 도구 > 보드로 가서 ESP32-WROOM-DA 모듈을 선택하세요.

 

파티션 구성표 로 가서 '거대 앱'을 선택하세요 . 이렇게 하면 코드를 저장할 더 큰 메모리 공간이 제공됩니다.

 

 

 

 

 

다음으로 Crowpanel 보드를 연결하고 Arduino IDE와 통신하는지 확인합니다.

 

USB Type-C 케이블을 사용하여 보드를 컴퓨터에 연결하세요.

 

도구 > 포트에서 올바른 COM 포트를 확인하세요. 보드를 연결하기 전에 COM1이 있었다면, 이 포트는 보드의 번호가 아닙니다. 올바른 COM 포트를 선택하세요. 제 포트는 COM 6입니다 . 하지만 시스템에 따라 COM 3, COM 8 등일 수 있습니다.

 

 

 

 

보드에 연결한 후 컴퓨터가 연결된 직렬 포트를 인식하지 못하는 경우, CH340 드라이버가 설치되지 않았기 때문일 수 있습니다 . 먼저 드라이버를 설치해야 합니다. 이 드라이버의 설치 ​​도구는 Tool/CH340 폴더에 있습니다 .

 

올바른 COM 포트가 선택되었는지 확인하려면 도구 > 보드 정보 가져오기로 이동하면 아래와 같이 연결 정보가 포함된 응답 창이 열립니다.

 

 

 

 

위와 비슷한 화면이 나타나면 그래픽 라이브러리를 로드하고 시스템을 테스트할 준비가 된 것입니다. 사용 가능한 그래픽 라이브러리는 많지만, 여기서는 "TFT_eSPI by Bodmer"를 사용합니다. 시스템에 설치하려면 도구 > 라이브러리 관리…로 이동한 다음 검색 창에 TFT_eSPI를 입력합니다 . Bodmer 라이브러리 항목을 찾은 다음 설치를 클릭합니다 .

 

 

 

 

코딩 환경 설정의 마지막 단계는 TFT_eSPI 라이브러리가 Crowpanel 장치와 올바르게 상호 작용하도록 구성하는 것입니다. 이 작업은 TFT_eSPI 라이브러리를 설치할 때 C:\Users\__user__\Documents\Arduino\libraries\TFT_eSPI\ 디렉터리에 설치되는 tft_setup.h라는 설치 파일을 통해 수행됩니다 . 이 디렉터리로 이동하여 파일 내용을 아래 줄로 바꾸세요.

 

#define ILI9341_DRIVER
#define TFT_WIDTH  320
#define TFT_HEIGHT 240 

#define TFT_BACKLIGHT_ON HIGH
#define TFT_BL   27 
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_CS   15
#define TFT_DC    2 
#define TFT_RST  -1
#define TOUCH_CS 33

#define SPI_FREQUENCY        27000000
#define SPI_TOUCH_FREQUENCY   2500000
#define SPI_READ_FREQUENCY   16000000

#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT

 

 

이제 구성을 테스트할 준비가 되었습니다. TFT_eSPI 라이브러리에 제공된 예제 프로그램 중 하나를 실행해 보겠습니다. Arduino IDE에서 파일 > 예제 > TFT_eSPI > 320X240 > TFT_Clock으로 이동합니다. 새 스케치가 열립니다. CrowPanel을 USB 포트에 연결한 상태에서 업로드 버튼(오른쪽 화살표)을 선택하여 코드를 컴파일하고, 연결하고, CrowPanel 장치에 업로드합니다.

 

 

 

완료되면 장치 화면에 현재 시간이 표시된 시계판이 나타납니다.

 

 

 

이제 우리는 우리만의 코드를 작성할 준비가 되었습니다.

 

속도계 면 코딩

 

속도계 표면의 그래픽 기능은 TFT_eSPI 라이브러리 루틴을 사용하여 쉽게 프로그래밍할 수 있습니다. 루틴 이름이 왜 이렇게 재밌을까요? TFT는 박막 트랜지스터(Thin Film Transistor)의 약자로, 능동 매트릭스 LCD 디스플레이 기술의 한 유형입니다. TFT 디스플레이에서 각 픽셀은 작은 박막 트랜지스터로 제어되어 픽셀 밝기와 색상을 정밀하게 제어할 수 있어 이전 LCD 기술에 비해 더 나은 이미지 품질, 빠른 응답 시간, 더 넓은 시야각을 제공합니다.

 

이름에서 SPI는 직렬 주변 장치 인터페이스(Serial Peripheral Interface)를 의미하며, 마이크로컨트롤러와 소형 주변 장치 간의 데이터 전송에 일반적으로 사용되는 인터페이스 버스입니다. ESP32에서 지원하는 표준 통신 프로토콜 중 하나입니다. 따라서 TFT_eSPI 라이브러리를 사용하면 ESP32에서 C++ 프로그래밍을 통해 SPI 인터페이스를 통해 그래픽 디스플레이에 명령을 쉽게 전송할 수 있습니다. 라이브러리 사용 방법을 보여주는 많은 코드 예제와 YouTube 동영상이 있지만, 전체 문서는 다소 단편적이며 시간이 지남에 따라 새로운 기능이 추가됨에 따라 발전하고 있습니다. 제가 찾은 가장 좋은 자료는 여기 입니다 .

 

다음 단계로 넘어가기 위해 속도계 면의 코드를 살펴보고, 필요에 따라 그래픽 라이브러리를 참고하여 관련 섹션을 살펴보겠습니다. 실제로는 70줄도 채 되지 않는 매우 간단한 코드입니다.

 

// Contents of Gauge_CrowPanel_Lesson1.ino

// 1 - setup for TFT screen
#include <TFT_eSPI.h> // include graphics library
#define DEG2RAD 0.0174532925
#define COLOR_BORDER TFT_BLUE
#define COLOR_NEEDLE TFT_RED

// 2 - constants for the display geometry
const int lcdWidth = 240;
const int lcdHeight = 320;
const int gaugeRad = 110;
const int gaugeWidth = 25;
const int gaugeWidth2 = 10;
const int xLoc = lcdWidth / 2;
const int yLoc = lcdHeight / 2;
const int numOffset = 40;

// 3 - define TFT objects for display
TFT_eSPI tft = TFT_eSPI(); // Background display

// 4 - setup constants for the speedometer app
const int minSpeed = 0;
const int maxSpeed = 24;
const int speedRange = maxSpeed - minSpeed;

// 5 - code to build speedometer background graphics
void drawBackground()
{
  // draw outline and label
  tft.fillScreen(TFT_BLACK);
  tft.fillCircle(lcdWidth/2, lcdHeight/2, gaugeRad + 10, COLOR_BORDER);
  tft.fillCircle(lcdWidth/2, lcdHeight/2, gaugeRad, TFT_BLACK);
  tft.fillCircle(lcdWidth/2, lcdHeight/2, 5, TFT_WHITE); // mark dial center
  tft.setTextDatum(MC_DATUM); // locate text graphics by center position
  tft.drawString("MPH",120,240,4); //label gauge MPH

  //draw major and minor tick marks - 3 minor ticks per major mark
    for (int i = 45; i < 316; i+=(3*270/speedRange)) // major marks
    {
      float sx = cos((i - 270) * DEG2RAD);
      float sy = sin((i - 270) * DEG2RAD);
      uint16_t x0 = sx * (gaugeRad - gaugeWidth -1) + xLoc;
      uint16_t y0 = sy * (gaugeRad - gaugeWidth -1) + yLoc;
      uint16_t x1 = sx * (gaugeRad-1) + xLoc;
      uint16_t y1 = sy * (gaugeRad-1) + yLoc;    
      tft.drawWideLine(x0, y0, x1, y1,3,TFT_WHITE); 
    }
    for (int j = 45; j < 315; j+=(270/speedRange)) //minor marks
    {
      float sx = cos((j - 270) * DEG2RAD);
      float sy = sin((j - 270) * DEG2RAD);
      uint16_t x0 = sx * (gaugeRad - gaugeWidth2-1) + xLoc;
      uint16_t y0 = sy * (gaugeRad - gaugeWidth2-1) + yLoc;
      uint16_t x1 = sx * (gaugeRad-1) + xLoc;
      uint16_t y1 = sy * (gaugeRad-1) + yLoc;    
      tft.drawLine(x0, y0, x1, y1, TFT_WHITE);
    }
  //draw number labels
    int dspNum = minSpeed;
    for (int i = 45; i < 316; i+=(3*270/speedRange)) // number labels by major marks
    {
      float sx = cos((i - 270) * DEG2RAD);
      float sy = sin((i - 270) * DEG2RAD);
      uint16_t x0 = sx * (gaugeRad - numOffset -1) + xLoc;
      uint16_t y0 = sy * (gaugeRad - numOffset -1) + yLoc;
      tft.drawNumber(dspNum, x0, y0,2);
      dspNum += 3; 
    }
}

// 6 - setup code.
void setup(void) 
{
  // initialize gauge screen
  tft.begin();
  tft.setRotation(0);
  drawBackground();
}

void loop() 
{
// do nothing here...
}

 

위에서 식별된 코드 섹션을 살펴보겠습니다.

 

1. TFT 화면 설정 — 이 섹션에서는 코드에서 사용할 그래픽 라이브러리를 포함하고 각도 측정을 위해 도 단위를 라디안 단위로 변환하는 방법을 정의합니다. 이 변환 계수는 화면의 그래픽 기능을 찾는 데 사용되는 일부 수학 연산에 유용합니다. 또한 디스플레이의 둥근 테두리 색상과 바늘 색상을 정의하여 나중에 모양과 느낌을 쉽게 변경할 수 있도록 합니다.

 

2. 디스플레이 지오메트리 상수 — 이 섹션에서는 그래픽 디스플레이 생성에 사용할 상수를 정의합니다. 사용하는 장치의 화면 너비는 240픽셀, 높이는 320픽셀이며, 화면 원점은 왼쪽 상단 모서리에 있습니다. xLoc 및 yLoc 상수는 다이얼 면 중앙까지의 오프셋 값을 정의하고, numOffset은 다이얼 면에 숫자를 배치하는 데 사용됩니다.

 

3. 디스플레이용 TFT 객체 정의 — 이 레슨에는 TFT 객체 하나만 있습니다. 바로 디스플레이 자체입니다. 이 코드는 tft라는 TFT_eSPI 객체를 생성하는데, 이를 통해 기기의 그래픽 디스플레이에 접근할 수 있습니다. 이후 레슨에서는 화면에 애니메이션이 적용될 바늘을 만들기 위해 스프라이트 객체를 추가하겠습니다.

 

4. 속도계 앱의 설정 상수 — 여기서는 속도계 측정값의 한계를 정의합니다. 제 골프 카트 속도는 컨트롤러에 의해 제한되며 시속 21마일(약 32km/h)을 초과하지 않습니다. 자전거 속도계나 다른 용도로 이 코드를 사용하려면 이 값을 변경해야 할 수 있습니다.

 

5. 속도계 배경 그래픽을 만드는 코드 — 속도계 면의 그래픽 요소가 디스플레이에 생성되는 곳입니다. tft.fillScreen(TFT_BLACK) 명령을 사용하여 검은색 배경을 만든 다음 tft.fillCircle을 세 번 사용합니다. 첫 번째 원은 디스플레이 중앙에 파란색 원을 만듭니다. 다음 원은 더 작은 원을 검은색으로 채우고 주변에 파란색 윤곽선을 남깁니다. 세 번째 원은 다이얼 중앙을 흰색으로 채웁니다. 파란색 윤곽선을 두꺼운 선 너비의 채워지지 않은 원으로 그릴 수도 있지만, 이 명령은 채워진 원 명령보다 훨씬 느립니다. tft.setTextDatum() 명령은 시스템에 너비와 높이 모두 중심(MC_DATUM)을 사용하여 텍스트를 찾도록 지시합니다. 그런 다음 tft.drawString()을 사용하여 MPH 레이블을 다이얼 중앙 아래에 배치합니다. 다음 코드 섹션은 디스플레이에 큰 눈금, 작은 눈금, 숫자를 그리는 데 사용됩니다. 제 작업을 확인하는 것은 여러분의 기하 도형 기술에 맡겨두겠습니다.

 

6. 설정 코드 - 여기서는 간단히 tft 객체를 초기화하고, 화면 방향을 설정하고, drawBackground() 루틴을 호출합니다.

 

이제 끝입니다! 위 코드를 새 Arduino Sketch에 복사하여 붙여넣으면 CrowPanel 기기에서 코드를 컴파일, 로드 및 실행할 수 있습니다. 결과 화면은 다음과 같습니다.

 

 

 

 

다음 튜토리얼에서는 다양한 속도 입력 값에 반응하는 바늘과 속도를 디지털로 표시하는 기능을 추가해 보겠습니다. 이 과정에서 스프라이트를 활용한 그래픽 프로그래밍에 대해서도 배우게 됩니다.

 

 

반응형

캐어랩 고객 지원

취업, 창업의 막막함, 외주 관리, 제품 부재!

당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약, 아이디어는 있지만 구현할 기술이 없는 막막함.

우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.

이제 고민을 멈추고, 캐어랩을 만나세요!

코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.

제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!

귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.

지난 30년 여정, 캐어랩이 얻은 모든 것을 함께 나누고 싶습니다.

카카오 채널 추가하기

카톡 채팅방에서 무엇이든 물어보세요

당신의 성공을 위해 캐어랩과 함께 하세요.

캐어랩 온라인 채널 바로가기

캐어랩