esp-idf 환경에서 m5 Stack 소프트웨어 개발 및 시작
목적
환경 버전
(esp-idf)
$ git log -n1
commit 8bf14a9238329954c7c5062eeeda569529aedf75 (HEAD, tag: v4.3.2)
Author: Ivan Grokhotkov <[email protected]>
Date:   Mon Dec 20 19:02:41 2021 +0100
    versions: Update version to 4.3.2
    
(M5GFX)
$ git log -n1
commit a8e406af056f3b1cb331c0b66126ab828197755e (HEAD -> master, tag: 0.0.15, origin/master, origin/HEAD)
Merge: 41af34c c2370c0
Author: lovyan03 <[email protected]>
Date:   Sat Nov 27 12:21:25 2021 +0900
    Merge pull request #24 from m5stack/develop
    
    0.0.15
  절차.
Install
github에서clone esp-idf를 시작합니다.일반적으로 clone은 pull master를 하기 때문에 적당한 버전에서 체크아웃(본편에서는 이미 체크아웃
v4.3.2합니다.esp-idf에submodule가 있기 때문에 체크아웃 시 잊지 마세요git submodule update[1].pyenv와 asdf를 가져오면psyhon의 처리를 주의하십시오.python 시스템 오류가 발생했을 때 pip install를 검사할 때 어디에 설치되었는지, ep-idf에서 어떤python을 사용했는지 등을 검사합니다.
git clone https://github.com/espressif/esp-idf.git -b v4.3.2
cd esp-idf.git
./install.sh
  Build hello_world
idf.py를 사용하기 위해 export.sh에서 환경 변수를 읽습니다.이렇게 하면 idf.py 등을 사용할 수 있다.앞으로 빌딩과 기록 사용
idf.py.source export.sh
 구축, 쓰기examples/get-started/hello_world를 시도합니다.cd examples/get-started/hello_world
idf.py build
 다음과 같은 경우 성공Project build complete. To flash, run this command:
/home/fai/.espressif/python_env/idf5.0_py3.8_env/bin/python ../../../components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32  write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 build/bootloader/bootloader.bin 0x8000 build/partition_table/partition-table.bin 0x10000 build/hello_world.bin
or run 'idf.py -p (PORT) flash'
 m5 Stack을 PC에 연결하여 디바이스 파일을 확인합니다.ls /dev/*USB*에서 대충 확인할 수 있습니다.$ ls /dev/*USB*
/dev/ttyUSB0
 구축이 성공했을 때의 메시지에 따라 flash하면 기록합니다.편하네요.idf.py -p /dev/ttyUSB0 flash
 hello_월드가 직렬로 출력되기 때문에 monitor에서 직렬을 확인합니다."Serial을 종료하려면 누르기ctrl + ]"메시지가 표시되므로 Serial을 종료하려고 합니다[2].idf.py -p /dev/ttyUSB0 monitor
 다음 텍스트는 직렬로 수신해야 합니다.Hello world!
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, silicon revision 1, 2MB external flash
Minimum free heap size: 294012 bytes
 참고로 샘플은 printf을 사용하지만 로그를 직렬로 출력하려면 printf 대신 "esp_log.h"#includeESP_LOGI("TAG", "message v=%d", 5); 등을 사용하는 것이 좋다.또 지령을 나란히 쓸 수 있기 때문에 개발할 때 다음 명령을 자주 두드린다.
idf.py -p /dev/ttyUSB0 build flash monitor
 기타 명령이 풍부하다.특히 사용이 가능한 것은 fullcleanmenuconfig 등이다.Import M5GFX
https://github.com/m5stack/M5GFX.
이동만 한다면 아래처럼components에 깊이 들어가면 됩니다.
cd components
git clone https://github.com/m5stack/M5GFX
  Run M5GFX samples
esp-idf의 맨 윗부분 디렉터리로 돌아가서work 디렉터리를 만듭니다.이번에는 아래에서 프로젝트를 만들어 작업하기로 했다.hello_월드 복제, 혹시 모르니까 구축 가능.
cp -ar examples/get-started/hello_world work/
cd work/hello_world
idf.py fullclean
idf.py -p /dev/ttyUSB0 build flash monitor
 M5GFX는 C++입니다.hello_world_main.c를 hello_world_main.cpp로 바꾸다.다시 쓰다
work/hello_world/main/CMakeLists.txt.파일 이름 바꾸기 외에 M5GFX 를 추가하여 PRIV_REQUIRES "M5GFX" 에 의존하도록 했다.idf_component_register(SRCS "hello_world_main.cpp"
                       PRIV_REQUIRES "M5GFX"
                       INCLUDE_DIRS "")
 M5GFX의 샘플을 복사해 이동하고 싶었지만, 아두노 IDE를 겨냥한 샘플에만 들어갔기 때문에 자기 앞에서 호출setup과loop로 실행했다.esp-idf는 임무 개념을 가지고 여러 코드를 병렬로 이동할 수 있다.
app_main함수로도 잡도 무한순환을 할 수 있지만 얻기 어려워xTaskCreatePinnedToCore를 사용한다.ref: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html
// hello_world_main.cpp
// ============================================================================
// BEGIN BarGraph.ino
// https://github.com/m5stack/M5GFX
// //examples/Basic/BarGraph/BarGraph.ino
// FIXME: 下記URLのコードをここに貼り付ける
// https://github.com/m5stack/M5GFX/blob/a8e406af056f3b1cb331c0b66126ab828197755e/examples/Basic/BarGraph/BarGraph.ino 
// END BarGraph.ino
// ============================================================================
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
TaskHandle_t g_handle = nullptr;
void runMainLoop(void *args) {
  setup();
  for (;;) {
    loop();
    // avoid `The following tasks did not reset the watchdog in time`
    vTaskDelay(1);
  }
  vTaskDelete(g_handle);
}
void initializeTask() {
  xTaskCreatePinnedToCore(&runMainLoop, "task1-main", 8192, nullptr, 1,
                          &g_handle, 1);
  configASSERT(g_handle);
}
extern "C" {
void app_main(void) {
  //
  initializeTask();
}
}
idf.py -p /dev/ttyUSB0 build flash monitor에 기록을 구축하고 BarGraph의 시위 행진이 시작되면 ok.Implement M5GFX App
또 시료에서 알아채기 어려운 M5GFX와 관련된 문제 등을 들었다.
GPIO25 및 GND는 점프 라인을 통해 연결한 후 해제됩니다.아래의 보도는 매우 상세한 것 같다.
M5GFX의 드로잉 명령이 버퍼링되지 않습니다.M5Canvas를 사용하여 사이다를 써넣고 사이다를 붙여서 완충하는 것은 일반적인 상황인 것 같습니다.M5GFX g_display;
M5Canvas g_canvas(&g_display);
int g_time = 0;
void setupDisplay() {
  g_display.init();
  g_display.startWrite();
  g_canvas.createSprite(g_display.width(), g_display.height());
}
void renderDisplay() {
  int kW = g_display.width();
  int kH = g_display.height();
  int kL = std::min(kW, kH) * 4 / 10;
  g_display.waitDisplay();
  g_canvas.fillRect(0, 0, kW, kH, TFT_BLACK);
  float a1 = 0.01 * g_time;
  float a2 = a1 + PI * 2 / 3;
  float a3 = a1 - PI * 2 / 3;
  g_canvas.fillTriangle(std::cos(a1) * kL + kW / 2, std::sin(a1) * kL + kH / 2,
                        std::cos(a2) * kL + kW / 2, std::sin(a2) * kL + kH / 2,
                        std::cos(a3) * kL + kW / 2, std::sin(a3) * kL + kH / 2,
                        TFT_WHITE);
  g_canvas.pushSprite(0, 0);
  g_display.display();
  g_time += 3;
}
 위에 설명된 구현 방법 중에서도 유선이 들어오는 깜박임이 발생할 수 있습니다.그리는 과정에서 인터럽트가 삽입되어 있어서 그런지 적당히 라인을 양보하면 해제[3]됩니다.수중의 환경에서vTaskDelay(15 / portTICK_PERIOD_MS); 현상이 발생하여vTaskDelay(40 / portTICK_PERIOD_MS);에 억제되었다.Control GPIO (buttons, speaker)
버튼과 스피커가 GPIO에 연결되어 있어 아두노와 랩베리피의 작업감각과 같다.새치기도 가능합니다.
buttons
gpio_config에서 설정하고 gpio_get_level에서 값을 읽습니다.중단된 구현 사례는
examples/peripherals/gpio/에 포함됩니다.void initialize() {
  gpio_config_t io_conf = {};
  io_conf.intr_type = GPIO_INTR_DISABLE;
  io_conf.pin_bit_mask =
      (1ull << GPIO_NUM_39) | (1ull << GPIO_NUM_38) | (1ull << GPIO_NUM_37);
  io_conf.mode = GPIO_MODE_INPUT;
  io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
  gpio_config(&io_conf);
}
std::array<bool, 3> update() {
  bool a = gpio_get_level(GPIO_NUM_39);
  bool b = gpio_get_level(GPIO_NUM_38);
  bool c = gpio_get_level(GPIO_NUM_37);
  return std::array<bool, 3>{a, b, c};
}
  speaker
driver/ledc.h를 사용하여 PWM 제어를 수행합니다.duty와 hpoint에 대한 상세한 설명http://blueeyes.sakura.ne.jp/2021/01/31/3672/.공식 문서에는 ESP32 Technical Reference Manual LED PWM Controller 14개에 적혀 있습니다.void initialize() {
  gpio_config_t config;
  config.intr_type = GPIO_INTR_DISABLE;
  config.pin_bit_mask = (1ull << GPIO_NUM_25);
  config.mode = GPIO_MODE_OUTPUT;
  config.pull_up_en = GPIO_PULLUP_DISABLE;
  config.pull_down_en = GPIO_PULLDOWN_DISABLE;
  gpio_config(&config);
}
void setSound(uint32_t freq, bool enable) {
  ledc_timer_config_t timer_config = {};
  timer_config.speed_mode = LEDC_HIGH_SPEED_MODE;
  timer_config.duty_resolution = LEDC_TIMER_8_BIT;
  timer_config.timer_num = LEDC_TIMER_3;
  timer_config.freq_hz = freq;
  timer_config.clk_cfg = LEDC_AUTO_CLK;
  ledc_timer_config(&timer_config);
  ledc_channel_config_t channel_config = {};
  channel_config.gpio_num = GPIO_NUM_25;
  channel_config.speed_mode = LEDC_HIGH_SPEED_MODE;
  channel_config.channel = LEDC_CHANNEL_1;
  channel_config.intr_type = LEDC_INTR_DISABLE;
  channel_config.timer_sel = timer_config.timer_num;
  channel_config.duty = enable ? 0x7F : 0x00;
  channel_config.hpoint = 0x0;
  ledc_channel_config(&channel_config);
}
void runSpeakerLoop(void *args) {
  vTaskDelay(3000 / portTICK_PERIOD_MS);
  g_my_io.setSound(262, true);
  vTaskDelay(500 / portTICK_PERIOD_MS);
  g_my_io.setSound(294, true);
  vTaskDelay(500 / portTICK_PERIOD_MS);
  g_my_io.setSound(330, true);
  vTaskDelay(500 / portTICK_PERIOD_MS);
  g_my_io.setSound(330, false);
  vTaskDelete(nullptr);
}
 그나저나 channel_config.channel = LEDC_CHANNEL_7라면 duty=0 모니터가 길이 되어 사라지거나 timer_config.clk_cfg = LEDC_AUTO_CLK 이외에 다른 동작이 없어 디테일을 파악하지 못하거나...만약 무슨 착오가 있으면 나중에 수정할 것이다.sample code
동작을 확인할 때 사용하는 전체 이미지 코드
각주
까먹고 반했어.↩︎
환경에 따라 다를 수 있음↩︎
한마디로 집행
M5Canvas#pushSprite 과정에서 새치기당하지 말아야 한다.M5Canvas#fillRect 등 사이에 새치기가 발생해도 문제가 없었다.나는 더 좋은 방법이 있다고 생각한다. 어쨌든 지금은 이렇다.↩︎ Reference
이 문제에 관하여(esp-idf 환경에서 m5 Stack 소프트웨어 개발 및 시작), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/mai/articles/72519e289973c6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)