Skocz do zawartości

Pomocna odpowiedź

(edytowany)

Zacznij od jednej prostej rzeczy: w ESP32 framework Arduino to po prostu interfejs do funkcji IDF/FreeRTOS (przy czym ten drugi jest dość mocno zmodyfikowany). Jaki jest sens używania konstrukcji rodem z AVR-ów? Szczególnie tych, co specjalnie dla owych AVR-ów zostały opracowane?

Rozumiem, że czytałeś sobie kody core i wiesz co piszesz...

To taka ironia była jakbyś się nie domyślił.

A co do String... jest wiele wskazówek w necie, jak prawidłowo stosować malloc/free w mikrokontrolerach. Warto się z nimi zapoznać przed wygłaszaniem prawd objawionych.

To była ironia jakbyś nie zauważył.

Edytowano przez ethanak

Tak, wiem że Arduino na ESP32 to warstwa nad ESP-IDF i FreeRTOS. Jak już idziesz tym tropem, to podąż dalej, i napisz - jakie konkretnie ma to znaczenie w kontekście tego projektu? To, że skoro jest dostępny zawsze pod spodem, to od razu należy z niego jawnie zawsze korzystać? Nie każdy projekt od razu wymaga schedulera, wielu tasków, itp. nomenklatury, zwłaszcza gdy używa klas/funkcji Arduino, które nie czują się dobrze w takim środowisku. W tym kontekście używanie prostych konstrukcji jak millis() i takie liniowe/stanowe podejście do logiki jakie zaproponowałem nie jest jakimś „reliktem AVR”, tylko propozycją do rozważenia, wynikającą z małej złożoności aplikacji. To zwykłe dobranie odpowiedniego rozwiązania do skali problemu, którego dotyczy. Dodatkowo, nie generuje niepotrzebnych, dodatkowych problemów wynikających z wielowątkowości, które mogą być bardzo niejasne dla początkowych programistów.

Nie wiem czy pracujesz zawodowo jako programista embedded, czy tylko jesteś aktywnym amatorem, ale jeśli trzeba wyjaśniać Ci takie - zdało by się oczywiste kwestie, to chyba osobiście nie chciałbym pracować z Twoim kodem. Już pomijam bezsensowne komentarze odnośnie malloc/free, zwłaszcza że w kontekście tego konkretnie kodu dyskusja na temat "prawidłowego stosowania malloc/free" jest bezprzedmiotowa, bo autor nie alokuje tutaj pamięci w sposób jawny za pomocą tych funkcji. A to że String() w swojej implementacji używa malloc/free jest i tak ogólnie poza kontrolą użytkownika.

I dodatkowo, jeśli dalej zamierzasz się "wspomagać" ironią, to generalnie nie widzę sensu w dalszym prowadzeniu dyskusji. Bo poza AsyncWebSerwer ogólnie nie napisałeś niczego konstruktywnego, a na zabawę z czyimś ego nie mam ani czasu, ani ochoty.

 

Panowie, nie chciałem wszczynać pomiędzy wami kłótni:) 

Wasze komentarze i sugestie dały mi wiele do myślenia. W swoim projekcie stawiam jednak na prostotę i łatwość w późniejszej modyfikacji. Generalnie jedynym problemem projektu było "gubienie" niektórych requestów, co udało się zminimalizować poprzez:

1. Wrzucenie w jeden wątek nasłuchiwania serwera i sprawdzania czy istnieje połączenie z siecią:

void ServerTask(void* pvParameters) {
  uint16_t licznik = 0;
  while (true) {
    licznik++;
    if(licznik > 10000){
      connectWiFi();
      licznik = 0;
    }
    server.handleClient();
    vTaskDelay(pdMS_TO_TICKS(1));
  }
}

2. Odpowiednie przydzielenie priorytetów wątkom:

Serial.println("Podpinam taski....");
  xTaskCreatePinnedToCore(TickTask, "tickTask", 8192, NULL, 0, &tickTask, 1);
  xTaskCreatePinnedToCore(ResetTask, "resetTask", 2048, NULL, 1, &resetTask, 1);
  xTaskCreatePinnedToCore(CheckButtons, "checkButtons", 4048, NULL, 2, &checkButtons, 1);
  xTaskCreatePinnedToCore(LcdTask, "lcdTask", 4048, NULL, 3, &lcdTask, 1);

  xTaskCreatePinnedToCore(ServerTask, "serverTask", 8192, NULL, 0, &serverTask, 0);
  Serial.println("Taski podpięte");

3. Usunięcie zmiennej globalnej char XML[] i dołożenie jej w obsłudze każdego żądania serwera z odpowiednią wielkością:

void jsonDataAction() {
  char XML[300];
  strcpy(XML, JSON_PAGE);

  String toSend = String(XML);

  toSend.replace("<RSSI>", String(rssi));
  toSend.replace("<DEVICE_NAME>", String(deviceName));
  toSend.replace("<IP>", myIp);
  toSend.replace("<DOOR>", String(door));
  toSend.replace("<BUTTON_BLUE>", String(button));
  toSend.replace("<BUTTON_STOP>", String(stop));

  toSend.replace("<MAC_NUMBER>", mac);

  server.send(200, "application/json", toSend);
}

Dzięki powyższym zmianą odpowiedzi są otrzymywane w akceptowalnych czasach 30-200ms, a to że czasami jakiś request jest trochę dłuższy, nie jest aż tak bardzo problematyczne. 

Fakt, wiele by tu można jeszcze poprawić, choćby zmianę na AsyncWebServer, ale póki co nie widzę takiej potrzeby. Aplikacja spełnia swoje założenia i działa stabilnie. 

Dziękuję wszystkim za pomoc:)

 

Jeśli działa to po co ruszać? Osobiście w małych maszynkach nie lubię String, ale response.printf działa świetnie.

  • Lubię! 1

O, czyli jednak moje sugestie okazały się trafne, i ostatecznie jednak wiem o czym mówię. 😉

Ja jeszcze bym się przyczepił do tego:

  char XML[300];
  strcpy(XML, JSON_PAGE);

Bądź konsekwentny, jak już używasz String, to nie ma sensu używanie tego bufora (zwłaszcza że ciągle używasz strcpy zamiast strncpy). Zamiast bawić sie w alokowanie buforów na stosie które kiedyś przez przypadek mógłbyś nadpisać, użyj po prostu:

  String toSend = String(JSON_PAGE);

 

21 godzin temu, jaszczurtd napisał:

Przykład: connectWiFi() działa synchronicznie i blokuje task przez kilka sekund

Abstrahując od filozofii 🙂

To jakiś staroć z czasów 8266. Czas jest wtedy tracony na czekanie na skanowanie sieci

Polecam WiFi.scanNetworksAsync(wifiScanCompleted);

Nic się nie blokuje

  • Lubię! 1

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...