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

이 시리즈의 마지막 강의는 다른 강의들과는 상당히 다릅니다. 더 이상 Arduino IDE를 사용하여 CrowPanel 디스플레이 장치에서 코딩하지 않을 것입니다. 장치 코딩은 이미 완료되었으므로 더 이상 추가할 내용은 없습니다. 대신, 안드로이드 모바일 플랫폼에서 장치와 상호 작용하는 맞춤형 앱을 만드는 데 집중하겠습니다. 혹시 안드로이드 앱을 만들어 본 적이 없으신가요? 저도 최근까지 안드로이드 앱을 만들어 본 적이 없었습니다.
MIT App Inventor App이라는 웹 기반 시각적 프로그래밍 개발 도구를 사용해 보겠습니다. 이 도구에 대한 소개는 다음과 같습니다.
MIT App Inventor는 누구나, 심지어 어린이도 Android 휴대폰, iPhone, Android/iOS 태블릿에서 완벽하게 작동하는 앱을 개발할 수 있는 직관적이고 시각적인 프로그래밍 환경입니다. MIT App Inventor를 처음 사용하는 사람도 30분 이내에 간단한 첫 번째 앱을 개발하고 실행할 수 있습니다. 더욱이, 블록 기반 도구를 사용하면 기존 프로그래밍 환경보다 훨씬 짧은 시간에 복잡하고 효과적인 앱을 만들 수 있습니다. MIT App Inventor 프로젝트는 모든 사람, 특히 젊은 세대가 기술 소비에서 기술 창조로 전환할 수 있도록 지원함으로써 소프트웨어 개발의 민주화를 목표로 합니다.
흥미로울 것 같나요? 한번 시도해 볼까요…
이 시리즈의 4과에서는 Arduino IDE를 사용하여 CrowPanel 디스플레이 장치의 코드를 완성하고, 장치에 내장된 ESP32 프로세서를 프로그래밍했습니다. 블루투스 시리얼 인터페이스를 추가하여 장치가 외부 앱과 통신하여 주행 거리계 정보에 접근하고 거리 단위를 마일과 킬로미터로 전환할 수 있도록 했습니다. 그 후, Serial Bluetooth라는 범용 안드로이드 앱을 사용하여 연결하는 방법을 배웠습니다. 이제 MIT App Inventor를 사용하여 동일한 결과를 얻을 수 있는 특수 앱을 만들어 보겠습니다.
MIT App Inventor 시작하기
MIT App Inventor는 여기 웹에서 호스팅됩니다 . 메인 페이지에서 "앱 만들기!" 버튼을 선택하면 Gmail 계정에 연결된 계정을 설정하라는 메시지가 표시됩니다. 이는 저장 및 인증에 Google 인프라를 사용하기 때문입니다. Gmail 계정이 없는 경우, 애플리케이션을 사용하려면 계정을 만들어야 합니다. Gmail 계정을 입력하면 다양한 옵션이 있는 프로젝트 개발 화면으로 이동합니다. " 프로젝트" 메뉴 항목을 선택한 다음 "새 프로젝트 시작"을 선택합니다 . 프로젝트 이름을 입력하고 "툴킷"과 "테마"는 기본값을 사용한 후 "확인"을 선택합니다 . 아래 화면과 유사할 것입니다.

MIT App Inventor는 객체 지향적인 시각적 프로그래밍 환경이며, 애플리케이션 개발은 두 가지 주요 단계로 진행됩니다.
1. 먼저, 사용자 인터페이스는 프로토타입 화면에 버튼, 텍스트 상자, 슬라이더, 체크 박스, 레이블, 목록 선택기 등의 그래픽 객체를 배치하여 정의됩니다. 왼쪽 패널에서 다양한 항목 유형 목록을 볼 수 있습니다. 항목을 선택하여 프로토타입 화면으로 끌어오면 오른쪽의 속성 패널에 선택한 항목의 속성이 채워집니다. 선택한 객체 유형에 따라 색상, 크기, 레이블, 글꼴 및 기타 특성을 설정할 수 있습니다. 나중에 볼 수 있듯이 기본 객체 이름을 객체의 의도를 더 잘 설명하는 새 이름으로 재정의하려는 경우가 많습니다. 새 항목이 화면에 추가되면 속성 패널 바로 왼쪽에 표시되는 구성 요소 객체 트리 구조에도 추가됩니다.
2. 모든 화면 인터페이스 객체를 정의하면 이벤트 발생 시 또는 화면 객체 활성화 시(예: 버튼 눌림 시) 동작을 제어하는 코드 블록을 작성할 수 있습니다. 오른쪽 상단 모서리에 있는 디자이너 버튼이 선택된 상태에서 디스플레이 화면에 항목을 추가합니다. 블록 버튼을 선택하면 코딩 블록을 추가할 수 있습니다. 이 부분은 나중에 다시 살펴보겠습니다.
애플리케이션을 구현하는 데 여러 화면이 필요한 경우 디자이너 모드에서 각 화면을 정의한 다음 프로그램이 실행될 때 화면 간에 전환하는 코드 블록을 작성할 수 있습니다.
앱 디자인을 시작하기 전에, 실제 기기에서 화면을 미리 볼 수 있도록 Android 기기를 연결해 보겠습니다. Google Play 스토어에서 MIT AI2 Companion 앱을 검색하세요. Android 기기에 앱을 다운로드하여 설치하세요. 이제 브라우저의 MIT App Inventor 화면에서 ' 연결' 메뉴 항목을 선택한 다음 'AI Companion'을 선택하세요. 아래와 같이 QR 코드가 있는 새 창이 열립니다.

이제 Android 기기가 브라우저 기기와 동일한 LAN(Local Area Network)에 연결되어 있다고 가정하고, 방금 설치한 MIT AI2 Companion 앱을 엽니다. 'QR 코드 스캔' 버튼이 표시됩니다 . 이 버튼을 선택하고 브라우저 창에 있는 QR 코드를 스캔합니다. 그러면 브라우저의 뷰어 창에 보이는 이미지가 Android 기기에 표시됩니다. 브라우저 창에서 변경 사항을 적용하면 Android 기기에도 변경 사항이 표시됩니다. 예를 들어, 객체 트리에서 Screen1 객체(현재까지 유일한 객체)를 선택하고 배경색을 노란색으로, 제목을 주행거리계로 설정합니다. 브라우저와 Android 기기에서 화면이 다음과 같이 표시되어야 합니다.


브라우저에서 화면에 새로운 요소를 추가하면 Android 기기에 표시되므로, 화면을 만들 때 최종 화면이 어떻게 보일지 미리 볼 수 있습니다.
Arduino 인터페이스 화면 만들기
설정이 완료되었으니 새 주행 거리계 인터페이스를 만들어 보겠습니다. '프로젝트' 및 '새 프로젝트 시작 ' 메뉴 명령을 선택하고 '주행 거리계'라는 새 프로젝트를 생성하고, 다른 필드의 기본값을 그대로 사용합니다.
새 프로젝트에는 Screen1이라는 요소가 하나 있습니다. 표시되는 속성 값을 조정하여 모양을 변경할 수 있습니다. Title 속성을 Odometer로 변경하세요. Screen1 객체의 오른쪽 상단 점 세 개 뒤에 메뉴가 있는 것을 확인할 수 있습니다. 기본적으로 "이 애플리케이션 중지" 와 "이 애플리케이션 정보" 메뉴 항목이 포함되어 있습니다. 지금은 기본 설정을 그대로 유지하겠습니다.
상단에 정렬된 네 개의 버튼을 추가하여 주행 거리계가 Bluetooth 인터페이스를 통해 응답할 네 가지 명령에 연결하려고 합니다. 먼저 정렬을 위해 버튼을 놓을 가로 컨테이너를 추가합니다. 팔레트 패널에서 "레이아웃" 이라고 표시된 항목까지 아래로 스크롤하여 옵션을 확장합니다. 그런 다음 목록에서 "수평 배열"을 선택하여 화면 상단 이미지로 드래그합니다. 이제 속성을 다음과 같이 설정합니다. 배경색 = 회색, 높이 = 70픽셀, 너비 = 부모 채우기. 이제 팔레트에서 사용자 인터페이스로 다시 스크롤하여 버튼을 선택하고 가로 상자로 드래그합니다. 버튼의 속성을 아래와 같이 수정합니다.
글꼴 굵게 - 체크됨
글꼴 크기 — 16
높이 - 부모 채우기
너비 — 23퍼센트
텍스트 - 데이터 가져오기
활성화됨 - 선택 안 함(Bluetooth 연결이 설정되면 코드에서 버튼을 활성화합니다)
이제 버튼을 선택하고 Ctrl-C를 눌러 복사합니다. Ctrl-V를 세 번 눌러 정렬 상자에 새 버튼 세 개를 만듭니다. 새 버튼 세 개의 텍스트를 "Reset Trip", "MI/KM", "Exit BT"로 편집합니다.
프로그래밍에서 이 버튼들을 사용할 것이므로, 버튼의 이름을 더 의미 있는 값으로 바꾸는 것이 좋습니다. [구성 요소] 패널에서 각 버튼을 선택하고 다음과 같이 이름을 바꿀 수 있습니다.
버튼1 = 데이터 가져오기
버튼2 = 여행 재설정
버튼3 = 거리 스위치
버튼4 = BT 종료
이제 화면은 다음과 같습니다. 색상, 글꼴, 크기를 원하는 대로 수정하여 인터페이스를 맞춤 설정하세요.

다음으로 Bluetooth 클라이언트를 선택하고 연결하는 구성 요소를 추가합니다. 사용자 인터페이스 팔레트에서 ListPicker 객체를 선택하여 버튼 막대 아래 화면으로 드래그합니다. 속성을 다음과 같이 설정합니다.
배경색 — 녹색
FontBold — 체크됨
글꼴 크기 — 24
높이 - 자동
너비 — FillParent
항목 배경색 — 회색
텍스트 — 블루투스 연결
활성화됨 - 참
이제 시스템이 블루투스 연결을 통해 주행 거리계에 연결되지 않았을 때 메시지를 표시하는 Label 요소를 추가합니다. 방금 만든 ListPicker 아래에 Label 객체를 드래그 앤 드롭하고 아래와 같이 속성을 설정합니다.
FontBold — 체크됨
글꼴 크기 — 24
높이 - 자동
너비 — FillParent
텍스트 - 연결되지 않음
TextColor — 빨간색
마지막으로 주행 거리계의 응답 메시지를 표시할 메시지 상자를 추가합니다. 방금 추가한 연결 메시지 아래 화면에 TextBox 객체를 드래그 앤 드롭하고 아래와 같이 속성을 설정합니다.
FontBold — 체크됨
글꼴 크기 — 24
높이 — FillParent
너비 — FillParent
활성화됨 - 체크됨
MultiLine — 체크됨
읽기 전용 — 선택됨
이름을 msgText로 바꾸세요
이제 화면이 아래와 같아야 합니다.

코드 블록을 살펴보기 전에 프로젝트에 몇 가지 객체를 더 추가해야 합니다. 이는 코딩을 시작할 때 필요한 눈에 보이지 않는 컴포넌트입니다.
팔레트 패널에서 아래로 스크롤하여 Connectivity 라는 범주 를 확장합니다. BluetoothClient 객체를 프로젝트 화면으로 드래그 앤 드롭합니다. 센서 팔레트를 열고 같은 방식으로 Clock 객체 두 개를 추가합니다. 각 Clock 객체의 TimerAlwaysFires 및 TimerEnabled 체크박스의 선택을 해제하고 TimerInterval을 1000밀리초로 설정합니다. 한 Clock 객체의 이름을 timerBT로, 다른 Clock 객체의 이름을 timerData로 변경합니다. 마지막으로 사용자 인터페이스 팔레트로 돌아가 Notifier 객체 두 개를 추가합니다. 하나는 resetOK, 다른 하나는 exitOK로 이름을 지정합니다. 이제 인터페이스를 빌드하는 데 필요한 모든 것이 준비되었습니다. 동작 흐름을 제어하는 코드 블록만 추가하면 됩니다.
코드 블록 추가
MIT App Inventor는 그래픽 프로그래밍 스타일을 사용하는데, 저처럼 오래된 프로그래머라면 처음에는 약간 혼란스러울 수 있지만, 실제로는 배우기가 매우 쉽습니다.
화면 오른쪽 상단에서 " 블록" 버튼을 선택하세요. 그러면 코드 블록을 입력할 수 있는 사용자 인터페이스로 이동합니다. 코드는 논리적 블록 단위로 어떤 순서로든 입력할 수 있습니다. 왼쪽의 "블록" 패널에는 선택할 수 있는 코드 범주 목록이 표시되며, 여기에는 이전에 입력한 각 화면 객체에 대한 동작 범주도 포함됩니다. 이는 코드를 추가하는 일반적인 순서입니다.
1. 사용 가능한 Bluetooth 연결 목록으로 ListPicker를 채웁니다.
2. 사용자가 ListPicker에서 Bluetooth 클라이언트를 선택하면 BluetoothClient에 연결 요청을 보냅니다.
3. timerBT를 사용하여 연결이 완료될 때까지 기다리세요. 성공적으로 연결되면 네 개의 기능 버튼을 활성화하고 Label1 텍스트 속성을 업데이트하여 연결을 표시하세요. 연결되지 않은 경우, 버튼을 비활성화하고 메시지를 변경하세요. timerBT는 계속 작동하며 재설정될 때마다(1초) Bluetooth 연결을 다시 확인합니다. 어떤 이유로든 연결이 끊어지면 화면을 업데이트합니다.
4. 다음으로, 네 개의 버튼 중 하나를 누를 때마다 연결된 Bluetooth 서버로 명령 데이터를 전송하도록 시스템을 프로그래밍합니다. BluetoothClient는 한 번에 한 문자씩 ASCII 형식의 바이트 데이터를 전송합니다. 예를 들어, getData 버튼을 누르면 시스템은 숫자 0을 나타내는 ASCII 값 48을 전송합니다. ASCII 코드는 여기에서 확인할 수 있습니다 .
5. 두 개의 명령 버튼인 ' 여행 재설정' 과 'BT 종료' 의 경우 알림 창을 팝업하여 사용자에게 작업을 수행할지 확인하도록 요청합니다.
6. timerData라는 두 번째 시계를 사용하여 연결된 블루투스 서버가 기기로 데이터를 전송했는지 확인합니다. 이 타이머는 버튼 중 하나를 누르면 활성화되고, 데이터가 수신되면 비활성화됩니다. 수신된 데이터는 msgText라는 텍스트 상자에 표시됩니다.
코딩을 시작하려면 블록 창으로 이동하여 왼쪽 목록에서 ListPicker1 을 선택하세요. 그러면 시작할 여러 코드 조각이 표시되고, When ListPicker1.BeforePicking 이라는 코드를 선택하여 목록을 채워야 합니다.
이제 Set ListPicker1.Elements to 라는 코드 조각을 찾아 do 마커 옆의 이전 요소에 연결합니다 .
이제 BluetoothClient1 객체를 선택하고 BluetoothClient1.AddressesAndNames 라는 코드 조각을 찾습니다 . 이 코드 조각을 선택하고 이전 조각의 끝에 연결되도록 드래그합니다. 코드 시퀀스는 다음과 같습니다.

축하합니다! 방금 기기와 페어링되어 있고 연결 가능한 모든 기기의 Bluetooth 주소와 이름으로 목록을 채우는 코드를 추가했습니다. 이는 MIT App Inventor 프로그램에서 코드 블록 정의가 어떻게 진행되는지 보여주는 예입니다. 색상으로 구분된 코드 세그먼트는 구문적으로 올바르지 않은 방식으로는 연결할 수 없는 퍼즐 조각처럼 연결되어 있습니다. 제대로 맞물리면 유효한 코드입니다. 하지만 코드가 논리적으로 올바르다는 것을 의미하는 것은 아닙니다. 논리적으로 올바른지 확인하는 것은 여러분의 몫입니다.
아래에 표시된 추가 코드 블록을 추가하려면 동일한 작업 순서를 따르면 됩니다.

위 섹션은 사용자가 목록에서 블루투스 클라이언트를 선택하면 호출됩니다. 블루투스 클라이언트에게 해당 클라이언트에 연결하도록 요청하고 ListPicker 선택 항목을 업데이트합니다. 그런 다음 timerBT를 시작하여 1000밀리초 후에 알람을 울립니다.

위 섹션은 timerBT 알람이 울릴 때 호출됩니다. BluetoothClient1 연결이 성공했을 때 특정 동작을 수행하고, 실패했을 때 다른 동작을 수행하는 로직 분기를 포함합니다. Label1의 색상과 텍스트를 변경한 후 네 개의 버튼을 각각 활성화 또는 비활성화합니다. 또한 timerBT를 다시 시작하여 연결 상태를 계속 모니터링합니다.

이 두 코드 섹션은 getData 버튼이나 distanceSwitch 버튼을 누를 때 응답합니다. BluetoothClient1을 사용하여 1바이트의 데이터를 전송하는데, getData 버튼의 경우 ASCII 값 48, distanceSwitch 버튼의 경우 ASCII 값 50을 사용합니다. 이는 텍스트 문자 "0" 또는 "2"와 동일합니다. 그런 다음 timerData를 설정하여 연결된 장치의 응답을 기다립니다.

timerData 시계 알람이 울리면(1000밀리초) BluetoothClient1은 연결된 기기가 프로그램으로 문자를 전송했는지 확인합니다. 전송된 문자가 있으면 해당 문자를 수신하여 msgText 내용에 추가합니다. 그런 다음 timerData 시계를 비활성화합니다.

마지막 두 버튼인 resetTrip과 exitBT의 경우, 진행하기 전에 사용자에게 해당 작업을 수행할지 여부를 묻는 메시지를 표시하려고 합니다. 이는 앞서 정의한 Notifier 객체를 사용하여 수행됩니다. 위 코드에서는 resetOK 알림이 메시지, 제목, 그리고 해당 버튼과 함께 표시됩니다. 사용자가 재설정을 확인하는 옵션을 선택하면 ASCII 문자 49(텍스트 값 "1")가 연결된 장치로 전송됩니다.

마지막으로, exitBT 버튼을 처리하는 코드는 위에 나열되어 있습니다. 이 코드는 위의 resetTrip 로직과 매우 유사하지만, 사용자가 알림에서 요청을 검증하면 주행 거리계 장치에 메시지를 전송하지 않고 블루투스 연결을 직접 끊습니다. timerBT는 계속 실행 중이며 다음 1초 간격으로 연결 상태를 업데이트합니다.
코드 관점에서 보면 그렇습니다. 완벽하게 작동하는 Android 앱에 필요한 사용자 인터페이스와 모든 코드 블록을 정의했습니다.
앱을 생성하여 Android 기기에 다운로드하기 전에, Android 기기에 표시되는 사용자 지정 아이콘을 추가하는 맞춤 기능이 하나 더 있습니다. Flaticon이라는 웹 사이트가 있는데, 방대한 아이콘 컬렉션을 제공하는데, 저는 이 사이트를 제 프로그램에 선택했습니다. PNG 버튼을 선택하면 이전 문장에서처럼 출처를 명시하면 PC에 무료로 다운로드할 수 있습니다.
이제 MIT App Inventor의 Designer 패널로 돌아가면 구성 요소 트리 뷰 아래에 Media라는 패널이 표시됩니다. " Upload File" 버튼을 클릭하고 golf-cart.png 파일을 MIT App 서버로 복사합니다. 화면 상단에 " Project Properties" 라는 버튼이 표시됩니다. 이 버튼을 선택하고 아래로 스크롤하여 "Icon" 항목을 찾습니다 . 이 항목을 선택한 후 아이콘으로 사용할 golf-cart.png 파일을 선택합니다. 이제 "Close"를 선택하면 APK 파일을 생성하고 다운로드할 준비가 됩니다.
APK 파일을 만들려면 최상위 메뉴인 '빌드' 로 가서 'Android 앱' 옵션을 선택하세요 . 컴파일 및 패키징 과정이 진행되는 동안 진행률 표시줄이 나타나고, 잠시 후 다음과 같은 화면이 표시됩니다.

그런 다음 Android 기기에서 QR 코드를 읽고 APK 파일을 다운로드할 수 있습니다. 파일을 다운로드하라는 메시지가 표시되면 해당 파일을 선택하여 기기에 앱을 설치하거나 업데이트할 수 있습니다.

내 안드로이드 폰에 주행거리계 아이콘이 있는 모습은 다음과 같습니다.

오도미터 앱이 실제로 작동하는 모습은 다음과 같습니다.
이제 CrowPanel 주행 거리계 기기를 활성화하고 Android 기기에서 주행 거리계 앱을 열어 5부로 구성된 이 튜토리얼의 최종 결과물을 확인하실 수 있습니다. 끝까지 완주하신 것을 축하드립니다! 하지만 이것이 끝이 아니기를 바랍니다. 이 튜토리얼이 여러분만의 창의적인 애플리케이션을 위한 진정한 시작점이 되기를 바랍니다.
'ESP32' 카테고리의 다른 글
| GPS 데이터 지도에 그려주는 사이트 (0) | 2025.11.29 |
|---|---|
| ESP32 NEO-6M GPS 모듈 문제 해결 가이드 (0) | 2025.11.28 |
| ESP32 NEO-6M GPS 모듈 인터페이스 (0) | 2025.11.28 |
| FreeRTOS ESP32 듀얼 코어를 사용하는 방법 Arduino IDE (0) | 2025.11.27 |
| ESP-32 LVGL 그래픽을 사용한 고급 기술 - 4부 (0) | 2025.11.27 |
| ESP-32 LVGL 그래픽을 사용한 고급 기술 - 3부 (0) | 2025.11.26 |
| ESP-32 LVGL 그래픽을 사용한 고급 기술 - 2부 (0) | 2025.11.26 |
| ESP-32 LVGL 그래픽을 사용한 고급 기술 - 1부 (1) | 2025.11.24 |
취업, 창업의 막막함, 외주 관리, 제품 부재!
당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약,
아이디어는 있지만 구현할 기술이 없는 막막함.
우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.
이제 고민을 멈추고, 캐어랩을 만나세요!
코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.
제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!
귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.
캐어랩