Sterowanie suplą przez esp32 z dotykowym LCD 4”

vajera
Posts: 1177
Joined: Wed Oct 31, 2018 7:58 am

Post

zmienne umieszczone w ciele funkcji, tzn. pomiędzy

void moja_funkcja () {

a

};

są lokalne, tzn. ich widoczność jest ograniczona do tejże funkcji.

Wyrzuć definicję zmiennej timer, np. przed funkcję setup() a w samej funkcji dokonaj tylko inicjalizacja tej zmiennej.
SOYER
Posts: 1342
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry

Post

vajera wrote: Wed Jan 15, 2025 6:25 am zmienne umieszczone w ciele funkcji, tzn. pomiędzy

void moja_funkcja () {

a

};

są lokalne, tzn. ich widoczność jest ograniczona do tejże funkcji.

Wyrzuć definicję zmiennej timer, np. przed funkcję setup() a w samej funkcji dokonaj tylko inicjalizacja tej zmiennej.
W ciele mojej funkcji screenSaver nie mam nic co ma coś wspólnego z timer1.
Wiem co to zmienne globalne i lokalne, ale moje dotychczasowe doświadczenia z nimi to tylko np
int zmienna = 1;
a potem gdzieś
zmienna = innaZmienna;
a typy zmiennych tylko podstawowe używałem.
:))
Dla mnie takie zmienne ze wskaźnikami, inicjalizacji itp to nawet nie wiem co jest co.
Czy
lv_timer_t
to typ zmiennej jest?
Kto mi to wbije do głowy?
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
User avatar
klew
Posts: 10708
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

SOYER
Posts: 1342
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry

Post

Dziękuję, w miarę to wiedziałem, jednak nadal proszę o wytłumaczenie dlaczego w argumencie funkcji screenSaver(lv_timer_t * timer1)
mamy tak deklarację(?) zmiennej timer1?
Myślałem, że deklaracja jest tu:
lv_timer_t * timer1 = lv_timer_create(screenSaver, 600000, NULL);[
wtedy faktycznie była by to zmienna lokalna bo w SETUP, ale dlaczego działa funkcja screenSaver() skoro jest nad SETUP, a już
lv_timer_reset(timer1) osadzony gdzieś tam w jakiejś funkcji pod loop, jest undeclared…?

Wytłumaczcie mi to ktoś tak krok po kroku o co tu biega, please…
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
User avatar
klew
Posts: 10708
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

SOYER wrote: Wed Jan 15, 2025 11:04 am Dziękuję, w miarę to wiedziałem, jednak nadal proszę o wytłumaczenie dlaczego w argumencie funkcji screenSaver(lv_timer_t * timer1)
mamy tak deklarację(?) zmiennej timer1?
Myślałem, że deklaracja jest tu:
lv_timer_t * timer1 = lv_timer_create(screenSaver, 600000, NULL);[
wtedy faktycznie była by to zmienna lokalna bo w SETUP, ale dlaczego działa funkcja screenSaver() skoro jest nad SETUP, a już
lv_timer_reset(timer1) osadzony gdzieś tam w jakiejś funkcji pod loop, jest undeclared…?

Wytłumaczcie mi to ktoś tak krok po kroku o co tu biega, please…
Nie przeglądałem kodu, ale:
1. W C++ możesz używać tych samych nazw zmiennych wiele razy. I to nie są te same zmienne, tylko inne, ale jest ta sama nazwa. Czasem kompilator będzie o tym mówił, że nie wie, o którą zmienną chodzi, a czasem jest to jasno określone jak ma się zachować i będzie to działąć zgodnie ze standardem C++.
2. W nagłówku metody są definiowane parametry jakie ona przyjmuje. One mają zasięg podobny jak zmienne lokalne definiowane w ciele funkcji. Nazwy parametrów i zmienne lokalne mają pierwszeństwo w ciele tej funkcji. Tzn. jeśli masz zmienną globalną, albo membera klasy o nazwie "foo" i masz metodę z parametrem o nazwie "foo", to w ciele tej metody "foo" odwołuje się do parametru przekazanego do metody, a nie do innych zmiennych o tej samej nazwie. Jeśli chcesz się odwołać do membera klasy, to można użyć this->foo, a jeśli chcesz do zmiennej globalnej, to możesz użyć ::foo
SOYER
Posts: 1342
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry

Post

To wszystko wiem, ale nadal nie mogę połączyć kropek, chyba.
Po mojemu muszę zrobić tak:
nad SETUP:
lv_timer_t * timer1;
potem(może być w SETUP?):
timer1= lv_timer_create(screenSaver, 600000, NULL);
rozumiem że funkcja screenSaver() może być bez argumentów(?)
i teraz w dowolnej funkcji mogę wywołać
lv_timer_reset(timer1);
Si?
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
User avatar
klew
Posts: 10708
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

SOYER wrote: Wed Jan 15, 2025 11:39 am timer1= lv_timer_create(screenSaver, 600000, NULL);
rozumiem że funkcja screenSaver() może być bez argumentów(?)
Nie patrzyłem w kod, więc nie wiem. Jeśli lv_timer_create przyjmuje wskaźnik na funkcję bez parametrów, to tak, jeśli z parametrami, to nie :P.
Tego typu "callbacki w stylu C" robi się dla funkcji o określonych parametrach. Ty przekazując callback, musisz się do tego dostosować.
SOYER wrote: Wed Jan 15, 2025 11:39 am i teraz w dowolnej funkcji mogę wywołać
lv_timer_reset(timer1);
Si?
W ogólności nie. Symbol o nazwie "timer1" jest znany od miejsca jego deklaracji do końca tego pliku (jeśli mowa o cpp/ino).
Także jeśli masz:

Code: Select all

void fun() {
  do_something(timer1); // błąd
}

void ehh(cośtam *timer1) {
  boom(timer1);  // odwołanie do parametru funkcji - zadziała
}

cośtam *timer1;

void bar() {
  do_something_else(timer1);  // ok
}

void ehh(cośtam *timer1) {
  boom(timer1);  // odwołanie do parametru funkcji - ok
  badam(::timer1); // odwołanie do zmiennej globlanej zdefiniowanej ~10 linjiek wyżej - ok
}
To na metodzie fun będziesz miał error, a na bar nie.
SOYER
Posts: 1342
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry

Post

https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
User avatar
klew
Posts: 10708
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

masz tam przykład i widać, że callback musi przyjmować parametr:

Code: Select all

void my_timer(lv_timer_t * timer)
SOYER
Posts: 1342
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry

Post

Jeśli umieszczę nad SETUP:

Code: Select all

void screenSaver(lv_timer_t * timer1){
  LV_UNUSED(timer1);
  if (lv_scr_act()==objects.main){
   lv_scr_load_anim(objects.scr6, LV_SCR_LOAD_ANIM_OVER_TOP, 1000, 100, false);
  }
  else if (lv_scr_act()==objects.scr6){
   lv_scr_load_anim(objects.scr7, LV_SCR_LOAD_ANIM_OVER_TOP, 1000, 100, false);
  }
  else if (lv_scr_act()==objects.scr7){
   lv_scr_load_anim(objects.scr6, LV_SCR_LOAD_ANIM_OVER_TOP, 1000, 100, false);
  }
}

 lv_timer_t * timer1 = lv_timer_create(screenSaver, 600000,  NULL);
Wtedy mogę mieć w kodzie lv_timer_reset(timer1); i się skompiluje...
...ale po wgraniu mam takie coś:

Code: Select all

17:48:10.411 -> Rebooting...
17:48:10.411 -> ESP-ROM:esp32s3-20210327
17:48:10.411 -> Build:Mar 27 2021
17:48:10.411 -> rst:0xc (RTC_SW_CPU_RST),boot:0xb (SPI_FAST_FLASH_BOOT)
17:48:10.411 -> Saved PC:0x403781a9
17:48:10.411 -> SPIWP:0xee
17:48:10.411 -> mode:DIO, clock div:1
17:48:10.411 -> load:0x3fce3818,len:0x109c
17:48:10.411 -> load:0x403c9700,len:0x4
17:48:10.459 -> load:0x403c9704,len:0xb50
17:48:10.459 -> load:0x403cc700,len:0x2fe4
17:48:10.459 -> entry 0x403c98ac
17:48:10.975 -> Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.
17:48:10.975 -> 
17:48:10.975 -> Core  0 register dump:
17:48:10.975 -> PC      : 0x4202d253  PS      : 0x00060130  A0      : 0x8202d3f0  A1      : 0x3fceb200  
17:48:10.975 -> A2      : 0x00000000  A3      : 0x0000000c  A4      : 0x00000000  A5      : 0x3fcf2398  
17:48:10.975 -> A6      : 0x00001800  A7      : 0x00000004  A8      : 0x00000000  A9      : 0x00000003  
17:48:10.975 -> A10     : 0x00000003  A11     : 0x3fceb208  A12     : 0x3fceb20c  A13     : 0x00000000  
17:48:10.975 -> A14     : 0x00000003  A15     : 0x00000000  SAR     : 0x00000019  EXCCAUSE: 0x0000001c  
17:48:10.975 -> EXCVADDR: 0x00000014  LBEG    : 0x400556d5  LEND    : 0x400556e5  LCOUNT  : 0xfffffffd  
17:48:10.975 -> 
17:48:10.975 -> 
17:48:10.975 -> Backtrace: 0x4202d250:0x3fceb200 0x4202d3ed:0x3fceb230 0x4202af7a:0x3fceb250 0x4202ac9b:0x3fceb270 0x4202cc74:0x3fceb290 0x4200584a:0x3fceb2c0 0x4204c3d2:0x3fceb2e0 0x40377e7f:0x3fceb310 0x403cdb0e:0x3fceb340 0x403cdea5:0x3fceb380 0x403c9919:0x3fceb4b0 0x40045c01:0x3fceb570 0x40043ab6:0x3fceb6f0 0x40034c45:0x3fceb710
17:48:10.975 -> 
17:48:10.975 -> 
17:48:10.975 -> 
17:48:10.975 -> 
17:48:10.975 -> ELF file SHA256: f53fa2d250fc1e14
17:48:10.975 -> 
17:48:10.975 -> E (556) esp_core_dump_flash: Core dump flash config is corrupted! CRC=0x7bd5c66f instead of 0x0
17:48:10.975 -> E (564) esp_core_dump_elf: Elf write init failed!
17:48:11.022 -> E (569) esp_core_dump_common: Core dump write failed with error=-1
17:48:11.022 -> Rebooting...
Jeśli jednak linijkę

Code: Select all

 lv_timer_t * timer1 = lv_timer_create(screenSaver, 600000,  NULL);
umieszczę w SETUP to wtedy esp włącza się normalnie, funkcja void screenSaver() działa normalnie, ale nie mogę w kodzie użyć:
lv_timer_reset(timer1);
bo przy kompilacji wywala to o czym pisaliśmy:

Code: Select all

In function 'void action_akcja(lv_event_t*)':
02_LVGL_Porting_YES:439:18: error: 'timer1' was not declared in this scope; did you mean 'timer_t'?
  439 |   lv_timer_reset(timer1);
      |                  ^~~~~~
      |                  timer_t
exit status 1
'timer1' was not declared in this scope; did you mean 'timer_t'?
Dlaczego mam ciągłe resety w tym pierwszym przypadku.
Wzorowałem się też przy tych timerach na tym:
https://randomnerdtutorials.com/esp32-t ... tal-clock/,
i generalnie to wszystko działa(oprócz resetu timera) jeśli linijka
lv_timer_t * timer1 = lv_timer_create(screenSaver, 600000, NULL);
jest w SETUP, jeśli jest nad to mam ciągle się resetujące esp.
:o
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79

Return to “Zagadnienia ogólne”