(macOS) Visual Studio Code에 PlatformIO IDE extension을 추가하여 ESP8266 개발 준비

ESP 개발보드를 프로그래밍하는 데 있어 ESP-IDF가 필요하다고 하여 기타 블로그를 참고하면서 나름 또 정리하고 있었는데, 막상 내가 지금 가지고 있는 보드가 ESP32 (신형) 가 아니고 ESP8266 (구형) 이라 Visual Studio Studio의 ESP-IDF extension으로는 힘들 것으로 판단했다.

그래서 일단 ESP32 보드들이 배송될 때까지 다른 방법으로 PlatformIO IDE extension을 사용해 보기로 했다.


설치와 예제 프로그램을 돌리는 데에는 VS Code와 PlatformIO에서 ESP32, ESP8266 개발 환경 블로그와 아두이노IDE대신 PlatformIO 사용하기를 참고하였다.

영상으로는 아래 3개의 YouTube을 참고했다.

How to use VS Code and PlatformIO to program WEMOS ESP8266



ESP32 & ESP8266 - How to setup Visual Studio Code for ESP32 and ESP8266 projects with PlatformIO



Arduino PlatformIO: Five Minute Zero to Hero - From Install to Compile to Flashing



1. PlatformIO IDE extension 설치

설치는 ESP-IDF 설치 때보다 오히려 매우 간단하고 짧았다.

ESP-IDF는 단순 extension 뿐만 아니라 다양한 부가 프로그램을 같이 설치하기 때문에 오래걸린 듯.

여튼 아래와 같이 "PlatformIO IDE"를 Extensions에서 검색해서 설치하면 됨.




설치가 완료되면 위와 같이 terminal에서 command line으로도 사용할 수 있게 해 주는 PlatformIO Core를 설치할 건지에 대해 질문하는데, Visual Studio Code만 사용할 예정이라면 일단 skip하면 된단다.


2. WeMos D1 R1 (ESP8266) Blink LED 예제 (Arduino framework)

이제 PlatformIO IDE가 잘 돌아가는지 확인해 보기 위해 WeMos D1 R1 (ESP8266) 에 Blink LED 예제를 탑재해 보겠다.

왼쪽 사이드에 추가된 PlatformIO IDE 외계인 아이콘을 클릭하여 하단 "Quick Access" -> "PIO Home" -> "Open"을 클릭하면 우측에 시작 창이 뜨는데, 여기에서 "New Project"를 클릭한다.


그러면 "Project Wizard" 창이 뜨면서프로젝트 이름, 개발 보드, 프레임워크, 저장 위치를 설정할 수 있게 된다.



"Use default location" 체크를 해제하면 저장하기를 원하는 다른 위치를 선택할 수 있다.


프로젝트 셋업이 끝나고 "Finish" 버튼을 누르면 프로젝트 생성을 시작하며, 시간이 생각보다 좀 걸렸다.

한 30초-1분 정도??


프로젝트 생성이 완료되면 platformio.ini 환경설정 파일을 먼저 보여 준다.

기본적으로 platform, board, framework 부분이 셋업 환경에 맞게 고정되어 있고, 만약 추가로 개발보드 통신 속도를 변경하고 싶다면 (아마 WeMos D1 R1의 기본값이 9600일 듯?)

> monitor_speed = 원하는 속도

을 추가해 주자.


저장 후 "src" 폴더에 들어가면 "main.cpp" 파일이 있다.

Arduino IDE에서의 메인 파일과 같다고 보면 된다.


내용을 싹 지우고 아래와 같이 Blink LED를 구현하기 위한 코드로 재작성해 본다.


이제 WeMos D1 R1을 연결시킨 후 올바른 port를 인식시켜야 한다.

Command Pallette ([command] + [shift] + [p]) 에 "PlatformIO: Set Project Port (upload/monitor/test)" 를 검색하여 클릭한다. 


그럼 현재 컴퓨터에서 사용할 수 있는 port가 목록으로 표시되는데, 여기에서 USB serial port를 찾아 주면 된다. (한번에 여러 보드가 연결되어 있으면 헷갈리겠는디..?)


선택한 port가 하단 상태표시 줄 전기 플러그 모양 옆에 표시될 것이다.

그럼 먼저 작성한 .cpp 파일을 build하자.

왼쪽 PlatformIO IDE 외계인 아이콘을 눌러 "Build" 를 선택하면 됨.


성공했다면 이번에는 "Upload"를 클릭하여 WeMos D1 R1에 올리자.


결과:


그리고 코드를 자세히 보면 "LED is on", "LED is off" 가 번갈아가며 무한 루프로 출력됨을 알 수 있는데, 이런 출력 결과를 확인하기 위해서는 좌측에 "Monitor" 을 누르면 하단에 터미널 창이 뜨며 출력물을 확인할 수 있다.


혹시 WeMos D1 R1을 초기화시키고 싶으면 아래와 같이 빈 void functions를 입히면 됨.




3. WeMos D1 R1 (ESP8266) Blink LED 예제 (ESP8266 RTOS SDK framework)

위와 같이 Arduino framework에서는 큰 문제 없이 잘 돌아간다.

구글링해 보니 요즘은 거의 Arduino framework + .cpp 파일 구조로 개발하는 것으로 보여지는데, 내가 요즘 테스트해 보고 싶은 소스파일은 .c파일이더라 ㅜㅜ

그래서 또 몇 시간 동안 이곳 저곳 살펴보다가 PlatformIO documentationsESP8266 RTOS SDK 웹페이지examples가 있음을 확인했다.

특히 여기에도 ESP8266 RTOS SDK용 Blink 예제 폴더 "esp8266-rtos-sdk-blink" 가 있었음.


희망을 갖고 이제 Framework를 ESP8266 RTOS SDK로 설정하여 새로운 프로젝트 "Blink_LED_ESP8266_RTOS"를 생성해 보았다.



아까 Arduino framework때와는 다르게 "src" 폴더 안에 기본 main 파일이 없었다.

esp8266-rtos-sdk-blink GitHub에도 다른 폴더는 별 게 없고 "src" 폴더에만 main.c 파일이 존재하길래 다운받아 보았다.


곧바로 build -> upload -> monitor 를 해보았다.




문제 없이 build, upload 다 잘 되는데, LED가 안 깜빡거림 ㅋ

뭘까?

그래서 GitHub에서 받은 main.c 를 뜯어보니 LED port가 GPIO16으로 되어 있더라.


Arduino framework에서 보면 LED port는 GPIO2인데 말이다.

그래서 저 숫자를 바꿔보려고 했는데 GPIO2는 아예 알아듣지를 못 한다.

왜그럴까?


ChatGPT와 Gemini의 경우 Blink 예제 코드를 짜달라고 하면 GPIO2를 서슴없이 쓴다.

그럼 혹시 PlatformIO IDE 설치 시 딸려온 ESP8266 RTOS SDK의 버전이 최신 버전이 아닌 걸까?

우연히 gpio.h 헤더 파일을 살펴 보다가 이 파일이 위치한 ~/.platformio/packages/framework-esp8266-rtos-sdk/documents 에서 ESP8266 RTOS SDK 설명서 pdf를 발견했다.


v1.4.0 (2016년)...

구글링해 보니 지금 벌써 v3.0 대

후 그랬다.

버전이 심각하게 구려서 GPIO2 같은 최신 예약어가 안 먹히는 것이었다.

그럼 ESP8266 RTOS SDK를 update 할 수 는 없을까 했는데 이것도 일단 만만치 않은 일인 듯 ㅜ


일단 gpio16_output_conf()과 gpio16_output_set(0)을 각각 gpio.h와 pdf 파일에서 발견한 gpio_output_conf()와 gpio_output_set() 함수로 대체해 보기로 한다.

설명서와 ChatGPT의 도움을 받아 위 언급한 함수들은 아래와 같은 성질이 있는 것으로 파악했다.

(정확하지 않음 ㅜ)


gpio_output_conf(a, b, c, d)

a: set_mask (예: 0000 0000 0000 0100 일 경우 GPIO2high bit 할당, 그 외 GPIO는 stay ??)

b: clear_mask (예: 0000 0000 0001 0000 일 경우 GPIO4low bit 할당, 그 외 GPIO는 stay ??)

c: enable_mask (예: 0000 0000 0100 0000 일 경우 GPIO6 활성화 ??)

d: disable_mask (예: 1000 0000 0000 0000 일 경우 GPIO15 활성화 ??)


gpio_output_set(a, b)

a: gpio_no (예: 2일 경우 GPIO2 ??)

b: bit_value (예: 1일 경우 high bit, 0일 경우 low bit ??)


맞는 것 같지만 불확실해서 다 일단 ?? 붙여놨다.

이를 바탕으로 코드를 다음과 같이 바꿔봤다.

>> gpio16_output_conf(); →  gpio_output_conf(0, 0, BIT(2), 0);

>> gpio16_output_set(0) → GPIO_OUTPUT_SET(2, 0); 또는 gpio_output_conf(0, BIT(2), BIT(2), 0);

>> gpio16_output_set(1)GPIO_OUTPUT_SET(2, 1); 또는 gpio_output_conf(BIT(2), 0, BIT(2), 0);


Build, Upload 모두 잘 됐다.

LED도 잘 깜빡거린다!!ㅎㅎ


printf 문도 넣은 김에 monitor도 한번 켜봤다.


밑에 뭐가 계속 출력되긴 하는데.. 폰트가 깨진다.

보통 이게 통신 속도가 안 맞을 때 생기는 현상이라던데.

monitor_speed 속도를 아예 115,200으로 고정시켜야겠다.

이를 위해서는 platformio.ini와 main.c의 "user_init()" 함수에 각각 아래를 추가해야 한다.

>> monitor_speed = 115200

>> uart_div_modify(0, UART_CLK_FREQ/115200);



오, 이제 출력 문자열도 잘 나온다!


3. WeMos D1 R1 (ESP8266) Blink LED 예제 (ESP8266 Non-OS SDK framework)

바로 이어서 PlatformIO documentations의 ESP8266 Non-OS SDK 웹페이지에 examples 중 ESKP8266 Non-OS SDK용 Blink 예제도 테스트해 보겠다.


이 경우에도 platformio.ini 에 monitor 속도를 115,200 Baud/sec으로 하겠다는 부분을 삽입


ESP8266 RTOS SDK때와 마찬가지로 "src" 폴더가 비어있다.

Example GitHub에서 "src" 폴더에 있는 user_main.c와 "include" 폴더에 있는 user_config.h도 다운받고 로컬에서도 동일한 위치에 저장해 준다.


포트 설정은 기존과 같은 방법으로 Command Palette ([command] + [shift] + [p])에서 "port"를 검색한 후 USB 직렬 연결부를 찾아 선택해 준다.


자, build를 해 볼까


~/.platformio/packages/framework-esp8266-nonos-sdk/include/user_interface.h로부터 "user_config.h: No such file or directory" 오류가 발생했다.

include 폴더에 있는 user_config.h이 제대로 인식이 안 되는 모양?

잠시 고민하다가 우연히 example GitHub의 platformio.ini를 살펴 봤는데 이전에는 보지 못 했던 build_flags = - I include 줄이 하나 삽입되어 있었다.

PaltformIO Community에 올라온 Why can’t PlatformIO find header file main.h? 게시물을 살표 보니 기본 제공 libraries 외에 외부 libraries를 (예를 들어 지금과 같은 include 폴더에 있는 user_config.h) 컴파일 시 포함시키려면 위 명령어를 platformio.ini에 추가해 줘야 한다고 한다.


다시 build!


성공적.

곧바로 upload와 monitor도 해 본다.


아, 그런데 기본 예제 파일에는 딱히 monitor할 만한 출력문 부분이 없는 것 같다.

그래서 아래와 같이 printf() 문을 추가시켜 보았다.


다시 build!


흠.

분명 printf()만 추가했기 때문에 여기에서부터 생긴 오류일 것이다.

ChatGPT에게 한번 고견을 물어보니 뭐라뭐라 하면서 Non-OS SDK에는 os_printf()를 써야한다고 하더라.


그럼 os_printf()로 바꾸고 다시 build를 해 보자.



크으 갓 ChatGPT

Comments