質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
M5Stack

M5Stackは、小型のマイコンモジュールです。拡張モジュールが豊富に用意されており、センサと組み合わせることで測定機能を自由に追加することができます。

Q&A

解決済

1回答

3119閲覧

M5Stack Core2にlvglのサンプルコードをマルチタスクの1つとして追加すると操作ができなくなる。

MaeharaKenji

総合スコア86

M5Stack

M5Stackは、小型のマイコンモジュールです。拡張モジュールが豊富に用意されており、センサと組み合わせることで測定機能を自由に追加することができます。

0グッド

0クリップ

投稿2021/12/31 09:22

編集2022/01/02 02:56

現在こちらのサイトでM5Stack Core2を複数台使用して、AWSを介したドアベルのようなシステムプログラムを作成しています。

M5Stack Core2にはタッチパネル機能が搭載されたTFTがあるため、ドアベル操作をTFT画面で行いたいと思い、こちらのサイトにあったlvglのサンプルコードが追加したのですが、画面表示は出てくるのですが、操作が最初はできるのに、その後フリーズしたようになってしまいます(フリーズするコードのgithubブランチ)。

この症状を解消する方法は何かありませんでしょうか?

なお、サンプルコードのみでM5Stack Core2にダウンロードすると、正常に動作することは確認しました。

C++

1#include <M5Core2.h> 2#include <Arduino.h> 3#include <lvgl.h> 4#include <Wire.h> 5#include <SPI.h> 6 7 8 9TFT_eSPI tft = TFT_eSPI(); 10static lv_disp_buf_t disp_buf; 11static lv_color_t buf[LV_HOR_RES_MAX * 10]; 12uint32_t startTime, frame = 0; // For frames-per-second estimate 13 14//===================================================================== 15/*Read the touchpad*/ 16bool my_touchpad_read(lv_indev_drv_t * indev_driver, 17 lv_indev_data_t * data){ 18 TouchPoint_t pos = M5.Touch.getPressPoint(); 19 bool touched = ( pos.x == -1 ) ? false : true; 20 if(!touched) { 21 data->state = LV_INDEV_STATE_REL; 22 } else { 23 data->state = LV_INDEV_STATE_PR; 24 /*Set the coordinates*/ 25 data->point.x = pos.x; 26 data->point.y = pos.y; 27 } 28 return false; 29//Return `false` because we are not buffering and no more data to read 30} 31//===================================================================== 32/* Display flushing */ 33void my_disp_flush(lv_disp_drv_t *disp, 34 const lv_area_t *area, lv_color_t *color_p){ 35 uint32_t w = (area->x2 - area->x1 + 1); 36 uint32_t h = (area->y2 - area->y1 + 1); 37 tft.startWrite(); 38 tft.setAddrWindow(area->x1, area->y1, w, h); 39 tft.pushColors(&color_p->full, w * h, true); 40 tft.endWrite(); 41 lv_disp_flush_ready(disp); 42} 43//===================================================================== 44void setup(void){ 45 M5.begin(true, true, true, true); 46 tft.begin(); 47 tft.setRotation(1); 48 M5.Axp.SetLcdVoltage(2800); 49 M5.Axp.SetLcdVoltage(3300); 50 M5.Axp.SetBusPowerMode(0); 51 M5.Axp.SetCHGCurrent(AXP192::kCHG_190mA); 52 M5.Axp.SetLDOEnable(3, true); 53 delay(150); 54 M5.Axp.SetLDOEnable(3, false); 55 M5.Axp.SetLed(1); 56 delay(100); 57 M5.Axp.SetLed(0); 58 M5.Axp.SetLDOVoltage(3, 3300); 59 M5.Axp.SetLed(1); 60 //------------------------------------------------------------------- 61 lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); 62 lv_init(); 63 startTime = millis(); 64 65 //------------------------------------------------------------------- 66 /*Initialize the display*/ 67 lv_disp_drv_t disp_drv; 68 lv_disp_drv_init(&disp_drv); 69 disp_drv.hor_res = 320; 70 disp_drv.ver_res = 240; 71 disp_drv.flush_cb = my_disp_flush; 72 disp_drv.buffer = &disp_buf; 73 lv_disp_drv_register(&disp_drv); 74 75 //------------------------------------------------------------------- 76 /*Initialize the (dummy) input device driver*/ 77 lv_indev_drv_t indev_drv; 78 lv_indev_drv_init(&indev_drv); 79 indev_drv.type = LV_INDEV_TYPE_POINTER; 80 indev_drv.read_cb = my_touchpad_read; 81 lv_indev_drv_register(&indev_drv); 82 83 //------------------------------------------------------------------- 84 /*Create a Tab view object*/ 85 lv_obj_t *tabview; 86 tabview = lv_tabview_create(lv_scr_act(), NULL); 87 88 //------------------------------------------------------------------- 89 /*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/ 90 lv_obj_t *tab1 = lv_tabview_add_tab(tabview, "Tab 1"); 91 lv_obj_t *tab2 = lv_tabview_add_tab(tabview, "Tab 2"); 92 lv_obj_t *tab3 = lv_tabview_add_tab(tabview, "Tab 3"); 93 94 //------------------------------------------------------------------- 95 /*Add content to the tabs*/ 96 lv_obj_t * label = lv_label_create(NULL, NULL); 97 static lv_anim_path_t path_overshoot; 98 lv_anim_path_init( &path_overshoot); 99 lv_anim_path_set_cb(&path_overshoot, lv_anim_path_overshoot); 100 101 static lv_anim_path_t path_ease_out; 102 lv_anim_path_init( &path_ease_out); 103 lv_anim_path_set_cb(&path_ease_out, lv_anim_path_ease_out); 104 105 static lv_anim_path_t path_ease_in_out; 106 lv_anim_path_init( &path_ease_in_out); 107 lv_anim_path_set_cb(&path_ease_in_out, lv_anim_path_ease_in_out); 108 109 //------------------------------------------------------------------- 110 /*Gum-like button*/ 111 static lv_style_t style_gum; 112 lv_style_init(&style_gum); 113 lv_style_set_transform_width( &style_gum, LV_STATE_PRESSED, 10); 114 lv_style_set_transform_height( &style_gum, LV_STATE_PRESSED, -10); 115 lv_style_set_value_letter_space(&style_gum, LV_STATE_PRESSED, 5); 116 lv_style_set_transition_path( &style_gum, LV_STATE_DEFAULT, &path_overshoot); 117 lv_style_set_transition_path( &style_gum, LV_STATE_PRESSED, &path_ease_in_out); 118 lv_style_set_transition_time( &style_gum, LV_STATE_DEFAULT, 250); 119 lv_style_set_transition_delay( &style_gum, LV_STATE_DEFAULT, 100); 120 lv_style_set_transition_prop_1( &style_gum, LV_STATE_DEFAULT, LV_STYLE_TRANSFORM_WIDTH); 121 lv_style_set_transition_prop_2( &style_gum, LV_STATE_DEFAULT, LV_STYLE_TRANSFORM_HEIGHT); 122 lv_style_set_transition_prop_3( &style_gum, LV_STATE_DEFAULT, LV_STYLE_VALUE_LETTER_SPACE); 123 124 lv_obj_t * btn1 = lv_btn_create(tab1, NULL); 125 lv_obj_align( btn1, NULL, LV_ALIGN_CENTER, 0, -20); 126 lv_obj_add_style(btn1, LV_BTN_PART_MAIN, &style_gum); 127 128 //------------------------------------------------------------------- 129 /*Instead of creating a label add a values string*/ 130 lv_obj_set_style_local_value_str(btn1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Gum"); 131 132 //------------------------------------------------------------------- 133 /*Halo on press*/ 134 static lv_style_t style_halo; 135 lv_style_init(&style_halo); 136 lv_style_set_transition_time( &style_halo, LV_STATE_PRESSED, 400); 137 lv_style_set_transition_time( &style_halo, LV_STATE_DEFAULT, 0); 138 lv_style_set_transition_delay( &style_halo, LV_STATE_DEFAULT, 200); 139 lv_style_set_outline_width( &style_halo, LV_STATE_DEFAULT, 0); 140 lv_style_set_outline_width( &style_halo, LV_STATE_PRESSED, 20); 141 lv_style_set_outline_opa( &style_halo, LV_STATE_DEFAULT, LV_OPA_COVER); 142 /*Just to be sure, the theme might use it*/ 143 lv_style_set_outline_opa( &style_halo, LV_STATE_FOCUSED, LV_OPA_COVER); 144 lv_style_set_outline_opa( &style_halo, LV_STATE_PRESSED, LV_OPA_TRANSP); 145 lv_style_set_transition_prop_1(&style_halo, LV_STATE_DEFAULT, LV_STYLE_OUTLINE_OPA); 146 lv_style_set_transition_prop_2(&style_halo, LV_STATE_DEFAULT, LV_STYLE_OUTLINE_WIDTH); 147 148 lv_obj_t * btn2 = lv_btn_create(tab1, NULL); 149 lv_obj_align( btn2, NULL, LV_ALIGN_CENTER, 0, 60); 150 lv_obj_add_style( btn2, LV_BTN_PART_MAIN, &style_halo); 151 lv_obj_set_style_local_value_str( btn2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Halo"); 152 153 //------------------------------------------------------------------- 154 /*Ripple on press*/ 155 static lv_style_t style_ripple; 156 lv_style_init(&style_ripple); 157 lv_style_set_transition_time( &style_ripple, LV_STATE_PRESSED, 300); 158 lv_style_set_transition_time( &style_ripple, LV_STATE_DEFAULT, 0); 159 lv_style_set_transition_delay( &style_ripple, LV_STATE_DEFAULT, 300); 160 lv_style_set_bg_opa( &style_ripple, LV_STATE_DEFAULT, 0); 161 lv_style_set_bg_opa( &style_ripple, LV_STATE_PRESSED, LV_OPA_80); 162 lv_style_set_border_width( &style_ripple, LV_STATE_DEFAULT, 0); 163 lv_style_set_outline_width( &style_ripple, LV_STATE_DEFAULT, 0); 164 lv_style_set_transform_width( &style_ripple, LV_STATE_DEFAULT, -20); 165 lv_style_set_transform_height( &style_ripple, LV_STATE_DEFAULT, -20); 166 lv_style_set_transform_width( &style_ripple, LV_STATE_PRESSED, 0); 167 lv_style_set_transform_height( &style_ripple, LV_STATE_PRESSED, 0); 168 169 lv_style_set_transition_path( &style_ripple, LV_STATE_DEFAULT, &path_ease_out); 170 lv_style_set_transition_prop_1(&style_ripple, LV_STATE_DEFAULT, LV_STYLE_BG_OPA); 171 lv_style_set_transition_prop_2(&style_ripple, LV_STATE_DEFAULT, LV_STYLE_TRANSFORM_WIDTH); 172 lv_style_set_transition_prop_3(&style_ripple, LV_STATE_DEFAULT, LV_STYLE_TRANSFORM_HEIGHT); 173 174 lv_obj_t * btn3 = lv_btn_create(tab1, NULL); 175 lv_obj_align( btn3, NULL, LV_ALIGN_CENTER, 0, 140); 176 lv_obj_add_style( btn3, LV_BTN_PART_MAIN, &style_ripple); 177 lv_obj_set_style_local_value_str(btn3, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Ripple"); 178 179 label = lv_label_create(tab2, NULL); 180 lv_label_set_text(label, "Second tab"); 181 182 label = lv_label_create(tab3, NULL); 183 lv_label_set_text(label, "Third tab"); 184} 185//===================================================================== 186void loop(){ 187 lv_task_handler(); /* let the GUI do its work */ 188 /* 189 // Show approximate frame rate 190 if(!(++frame & 255)) { // Every 256 frames... 191 uint32_t elapsed = (millis() - startTime) / 1000; // Seconds 192 if(elapsed) { 193 M5.Lcd.setCursor(278, 232); 194 M5.Lcd.print(frame / elapsed); M5.Lcd.println(" fps"); 195 } 196 } 197 */ 198 delay(5); 199} 200//===================================================================== 201

なんとなく、現在4つのタスクを動作させたマルチタスク動作のため、この現象が出ているような気がするのですが、この現象を解消する方法をご教示の程宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

実機を持ってないのでコード実行ができないのですが、タスク関連で気になった点がありました。

タスクをたぶん3つ、プライオリティ4、コア0で起動しているのですが、TFTの操作はメインのループ内で行っています。これで4つのタスクという認識なのかな。

ESPIDFのデフォルト環境ではメインループ内のプライオリティは1で低かったと思います。(Arduino環境だとちょっと不明なのですが)
vSoundTaskのループ内ではvTaskDelayがコメントアウトされているので空いているCPU時間はメイン側に行かずvSoundTaskが優先実行されてしまうのではと思います。

TFTの操作もxTaskCreatePinnedToCoreで同じ優先順位でタスク起動するか、別のタスクは別コアで動かすとかすればどうでしょうか。

投稿2022/01/02 03:02

ta.fu

総合スコア1667

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MaeharaKenji

2022/01/02 05:37

回答頂きありがとうございます。 とりあえずですが、別途宣言した3つのタスクの動作コアを0から1にすべて変更することでlvglのGUIのフリーズ動作が解消されました。今回の現象の原因が何なのかはまだ正確にはわからないのですが、別のESP32を使ったプロジェクトでlvglを動作させているプログラムを確認してみたところ、lvglのタスクとほかのタスクは完全にコアを別にしていて、こちらでも行ってみたところlvglが動作できました。
MaeharaKenji

2022/01/02 05:41

改善コードはこちらのブランチに配置しました。
ta.fu

2022/01/02 08:11

vSoundTaskのループ内ではvTaskDelayがコメントアウトはMP3の音切れ防止のためだったのですね。 そうするとMP3再生に関してはCPUリソースが必要だったのか、単純にvTaskDelayの引数が大きく再生データの処理が間に合わなかったのか。 どのタスクがどれだけのリソースを必要とするのか、もしくは遅延が許容できないのかを意識して設計していかないと、機能改良などで別タスクを追加した時、また同じ状況になると思います。 そのあたり整理しておいたほうが良いですよ。 今回のも、もしかしたらvSoundTaskのvTaskDelayの引数を小さくすれば改善したのか、MP3再生優先のためvSoundTaskだけ別コアにすればよかったのか、とかの最善の手段が選べると思います。
MaeharaKenji

2022/01/02 22:46

回答頂きありがとうございます。 このコードとは別のESP32に関するプログラムがあり、そのコードでlvglを使用していて、それをM5Stackでも使えないかと思い、今回のリポジトリを作ったという経緯があります(ほとんど模倣です。) そのコードによれば今回のようなタスクのコア配置になっていることに気づきました。作った方にも今度聞いてみたい気はしています(lvglが重いのかなぁ・・・)
MaeharaKenji

2022/01/02 22:49

ESP32はデフォルトでもプログラム領域やメモリ量もかなり豊富にあるようなので、マルチタスク処理のような複雑で大量のリソースを食いつぶしそうな機能を気軽に搭載できるところが良いですね。
MaeharaKenji

2022/01/02 22:51

マルチタスクにすれば搭載したい機能をタスクごとに追加できるのでプログラムもシンプルに作れますし、タスクも無限に追加できるのか?なんていう興味もあるのですが、これはいずれ挑戦してみたいと考えております。
thkana

2022/01/02 23:29

う~ん、そんなに簡単で気軽なものだろうか...>マルチタスク 「恐ろしいもの」でも無いけれど。
MaeharaKenji

2022/01/03 07:59

もうお正月休みもそろそろなので・・・ その前にいろいろとやりたいですねぇ・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問