Re: ESP32 domácí automatizace

as5s as5sgm na gmail.com
Úterý Srpen 3 09:53:41 CEST 2021


tiez nevidim vytvaranie tasku ako vhodne riesenie.

neviete vyuzit General Purpose Timer?

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/timer.html#

Myre

On 3. 8. 2021 7:35, Jan Půhoný wrote:
> Tak jsem to přepsal na vTaskDelayUntil , ale chová se to stejně. 
> Problém je totiž v tom, že když se stiskne tlačítko we webovém 
> rozhraní pro ovládání toho ventilu rychleji než se provede ten task, 
> pustí se task pro otevírání a zavírání přes sebe a pak dochází k tomu, 
> že to zůstane viset někde uprostřed. Pro tuto aplikaci asi nebude 
> zásadní rozdíl mezi vTaskDelayUntil a vTaskDelay.
>
> Ošetřil jsem to přidáním proměnné unBlock, která blokuje čtení 
> tlačítka po dobu spuštění tasku. Takto to funguje spolehlivě. Nicméně 
> předpokládám, že to jde vyřešit nějak elegantněji. *Jak se to správně 
> dělá?*
>
> Díky,
>
> HP
>
> Callback tlačítka:
> button1.attachCallback([&](bool value)
>                          {
>                            /* Print our new button value received from dashboard */
> Serial.println("Button Triggered: " + String((value) ? "true" : "false"));
>                            /* Make sure we update our button's value and send update to dashboard */
> digitalWrite(ledPinRed, value);
> if (unBlock)
>                            {
> if (value)
>                              {
> xTaskCreatePinnedToCore(
> vent1On,   // Function that should be called
> "vent1On", // Name of the task (for debugging)
> 2000,      // Stack size (bytes)
> NULL,      // Parameter to pass
> 1,         // Task priority
> NULL,      // Task handle
> 0          // Core 1/0
>                                );
>                              }
> else
>                              {
> xTaskCreatePinnedToCore(
> vent1Off,   // Function that should be called
> "vent1Off", // Name of the task (for debugging)
> 2000,       // Stack size (bytes)
> NULL,       // Parameter to pass
> 1,          // Task priority
> NULL,       // Task handle
> 0           // Core 1/0
>                                );
>                              }
>                            }
> dashboard.sendUpdates();
>                          });
>
> Ovládání ventilů:
> void vent1On(void *parameter)
> {
> TickType_t xLastWakeTime;
> const TickType_t xFrequency = (20000 / portTICK_PERIOD_MS);
>   // Initialise the xLastWakeTime variable with the current time.
> xLastWakeTime = xTaskGetTickCount();
> for (;;)
>   {
> unBlock = 0;
> digitalWrite(ventMain1, HIGH);
> digitalWrite(ventOn1, HIGH);
> digitalWrite(ledPinRed, HIGH);
> button1.update(1);
> systemCard.update((float)xFrequency);
>     // Pause the task fo 20s
> vTaskDelayUntil(&xLastWakeTime, xFrequency);
>     //vTaskDelay(20000 / portTICK_PERIOD_MS);
> digitalWrite(ventMain1, LOW);
> digitalWrite(ventOn1, LOW);
> digitalWrite(ledPinRed, LOW);
> unBlock = 1;
> vTaskDelete(NULL); //spustí se jen jednou
>   }
> }
> void vent1Off(void *parameter)
> {
> TickType_t xLastWakeTime;
> const TickType_t xFrequency = (20000 / portTICK_PERIOD_MS);
>   // Initialise the xLastWakeTime variable with the current time.
> xLastWakeTime = xTaskGetTickCount();
> for (;;)
>   { // infinite loop
> unBlock = 0;
> digitalWrite(ventMain1, HIGH);
> digitalWrite(ventOn1, LOW);
> digitalWrite(ledPinRed, HIGH);
> button1.update(0);
> systemCard.update((float)xFrequency);
>     // Pause the task fo 20s
> vTaskDelayUntil(&xLastWakeTime, xFrequency);
>     //vTaskDelay(20000 / portTICK_PERIOD_MS);
> digitalWrite(ventMain1, LOW);
> digitalWrite(ventOn1, LOW);
> digitalWrite(ledPinRed, LOW);
> unBlock = 1;
> vTaskDelete(NULL); //spustí se jen jednou
>   }
> }
>
>
>
> po 2. 8. 2021 v 16:11 odesílatel Jaroslav Buchta 
> <jaroslav.buchta na hascomp.cz <mailto:jaroslav.buchta na hascomp.cz>> napsal:
>
>     A zrovna nad tim badam a jedna vec mi nejde do hlavy:
>     v modulu port.c je obsluha
>
>     BaseType_t xPortSysTickHandler( void )
>     {
>         BaseType_t ret;
>
>         portbenchmarkIntLatency();
>         traceISR_ENTER(SYSTICK_INTR_ID);
>         ret = xTaskIncrementTick();
>         if( ret != pdFALSE )
>         {
>             portYIELD_FROM_ISR();
>         } else {
>             traceISR_EXIT();
>         }
>         return ret;
>     }
>
>     Je logicky umistena v IRAM sekci ale proc??? Funkce nema
>     specifikovany IRAM_ATTR, ani v hlavicce.
>     zrovna tak BaseType_t xTaskIncrementTick( void ) v tasks.c
>
>     Tady uz treba attribut je
>     void IRAM_ATTR esp_vApplicationTickHook(void)
>     {
>         int n;
>         int core = xPortGetCoreID();
>         for (n=0; n<MAX_HOOKS; n++) {
>             if (tick_cb[core][n]!=NULL) {
>                 tick_cb[core][n]();
>             }
>         }
>     }
>
>     Funkce se vnoruji v tomto poradi.
>
>     Zkousel jsem se povesit na hook od toho casovace a funguje to, jak
>     z Flash, tak z IRAM (to je asi rozumnejsi, kdyz je to v ISR)
>
>
>     Dne 02.08.2021 v 12:32 Jaroslav Buchta napsal(a):
>>     At to ctu stale dokola, nevidim prostor pro zkraceni FreeRTOS -
>>     ESP32 - — ESP-IDF Programming Guide latest documentation
>>     (espressif.com)
>>     <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html#task-api>
>>     Jen je tam upozorneni, ze je nejista prodleva, kdy bude zavolana
>>     funkce a az od te doby se to pocita. vTaskDelayUntil bude mit asi
>>     jediny rozdil v tom, ze je tam dany cas ukonceni cekani jako
>>     parametr, u vTaskDelay se tato hodnot asi ulozi v okamziku volani.
>>     A i tak by se jednalo spis o milisekundy nez sekundy...
>>
>>     Koukam na to, ze ty funkce pracuji v principu uplne stejne,
>>     pouziji pro uspani
>>         prvAddCurrentTaskToDelayedList(...);
>>      jenom jinak pocitaji dobu pro uspani...
>>
>>     Pokud opravdu muze dojit ke zkraceni intervalu, bylo by v systemu
>>     neco velmi spatne. Neprobehne nahodou spis restart?
>>
>>     //////////////////////////////
>>
>>         void vTaskDelay( const TickType_t xTicksToDelay )
>>         {
>>         BaseType_t xAlreadyYielded = pdFALSE;
>>
>>             /* A delay time of zero just forces a reschedule. */
>>             if( xTicksToDelay > ( TickType_t ) 0U )
>>             {
>>                 configASSERT( uxSchedulerSuspended[xPortGetCoreID()]
>>     == 0 );
>>                 taskENTER_CRITICAL( &xTaskQueueMutex );
>>                 {
>>                     traceTASK_DELAY();
>>
>>                     /* A task that is removed from the event list
>>     while the
>>                     scheduler is suspended will not get placed in the
>>     ready
>>                     list or removed from the blocked list until the
>>     scheduler
>>                     is resumed.
>>
>>                     This task cannot be in an event list as it is the
>>     currently
>>                     executing task. */
>>                     prvAddCurrentTaskToDelayedList( xPortGetCoreID(),
>>     xTicksToDelay );
>>                 }
>>                 taskEXIT_CRITICAL( &xTaskQueueMutex );
>>             }
>>             else
>>             {
>>                 mtCOVERAGE_TEST_MARKER();
>>             }
>>
>>             /* Force a reschedule if xTaskResumeAll has not already
>>     done so, we may
>>             have put ourselves to sleep. */
>>             if( xAlreadyYielded == pdFALSE )
>>             {
>>                 portYIELD_WITHIN_API();
>>             }
>>             else
>>             {
>>                 mtCOVERAGE_TEST_MARKER();
>>             }
>>         }
>>
>>
>>
>>         void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
>>     const TickType_t xTimeIncrement )
>>         {
>>         TickType_t xTimeToWake;
>>         BaseType_t xAlreadyYielded = pdFALSE, xShouldDelay = pdFALSE;
>>
>>             configASSERT( pxPreviousWakeTime );
>>             configASSERT( ( xTimeIncrement > 0U ) );
>>             configASSERT( uxSchedulerSuspended[xPortGetCoreID()] == 0 );
>>
>>             taskENTER_CRITICAL( &xTaskQueueMutex );
>>             {
>>                 /* Minor optimisation.  The tick count cannot change
>>     in this
>>                 block. */
>>                 const TickType_t xConstTickCount = xTickCount;
>>
>>                 /* Generate the tick time at which the task wants to
>>     wake. */
>>                 xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
>>
>>                 if( xConstTickCount < *pxPreviousWakeTime )
>>                 {
>>                     /* The tick count has overflowed since this
>>     function was
>>                     lasted called.  In this case the only time we
>>     should ever
>>                     actually delay is if the wake time has also   
>>     overflowed,
>>                     and the wake time is greater than the tick time. 
>>     When this
>>                     is the case it is as if neither time had
>>     overflowed. */
>>                     if( ( xTimeToWake < *pxPreviousWakeTime ) && (
>>     xTimeToWake > xConstTickCount ) )
>>                     {
>>                         xShouldDelay = pdTRUE;
>>                     }
>>                     else
>>                     {
>>                         mtCOVERAGE_TEST_MARKER();
>>                     }
>>                 }
>>                 else
>>                 {
>>                     /* The tick time has not overflowed.  In this
>>     case we will
>>                     delay if either the wake time has overflowed,
>>     and/or the
>>                     tick time is less than the wake time. */
>>                     if( ( xTimeToWake < *pxPreviousWakeTime ) || (
>>     xTimeToWake > xConstTickCount ) )
>>                     {
>>                         xShouldDelay = pdTRUE;
>>                     }
>>                     else
>>                     {
>>                         mtCOVERAGE_TEST_MARKER();
>>                     }
>>                 }
>>
>>                 /* Update the wake time ready for the next call. */
>>                 *pxPreviousWakeTime = xTimeToWake;
>>
>>                 if( xShouldDelay != pdFALSE )
>>                 {
>>                     traceTASK_DELAY_UNTIL();
>>
>>                     /* prvAddCurrentTaskToDelayedList() needs the
>>     block time, not
>>                     the time to wake, so subtract the current tick
>>     count. */
>>                     prvAddCurrentTaskToDelayedList( xPortGetCoreID(),
>>     xTimeToWake - xConstTickCount );
>>                 }
>>                 else
>>                 {
>>                     mtCOVERAGE_TEST_MARKER();
>>                 }
>>             }
>>             taskEXIT_CRITICAL( &xTaskQueueMutex );
>>
>>             /* Force a reschedule if xTaskResumeAll has not already
>>     done so, we may
>>             have put ourselves to sleep. */
>>             if( xAlreadyYielded == pdFALSE )
>>             {
>>                 portYIELD_WITHIN_API();
>>             }
>>             else
>>             {
>>                 mtCOVERAGE_TEST_MARKER();
>>             }
>>         }
>>
>>
>>     Dne 02.08.2021 v 12:09 as5s napsal(a):
>>>
>>>     Netusim ako to presne funguje, ale v dokumentacii na to upozornuju.
>>>
>>>     ale je mi cudne ze sa to skrati. O kolko sa to skrati?
>>>
>>>     Myre
>>>
>>>
>>>     On 2. 8. 2021 10:35, Jaroslav Buchta wrote:
>>>>     To jako opravdu vTaskDelay muze fungovat nespolehlive, teda
>>>>     jeste k tomu se zkratit?
>>>>     To snad primo pocita systemova preruseni od casovace (default
>>>>     tusim 100Hz), ze by se nejaky nestihly bych jeste pochopil...
>>>>
>>>>     Dne 02.08.2021 v 9:49 as5s napsal(a):
>>>>>
>>>>>     Dobry den,
>>>>>
>>>>>     skuste pozriet na vTaskDelayUntil()
>>>>>
>>>>>     https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html#_CPPv415vTaskDelayUntilPC10TickType_tK10TickType_t
>>>>>     <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html#_CPPv415vTaskDelayUntilPC10TickType_tK10TickType_t>
>>>>>
>>>>>     mozno vam to bude stacit.
>>>>>
>>>>>     Myre
>>>>>
>>>>>     On 2. 8. 2021 9:45, Jan Půhoný wrote:
>>>>>>     Dobrý den,
>>>>>>
>>>>>>     mám tady další zádrhel - mějme funkci, která ovládá výstupní
>>>>>>     piny, potřebuji po nastavení udžet cca 20 sekund v HIGH a pak
>>>>>>     vrátit vše do low. Jedná se o otevítání a zavírání ventilu.
>>>>>>     Přidal jsem tedy mezi to vTaskDelay(20000 /
>>>>>>     portTICK_PERIOD_MS); , problém je v tom, že někdy se to
>>>>>>     zpoždění značně zkrátí a ventil zůstane napolo otevřený. Jak
>>>>>>     se toto dá ošetřit aby se vTaskDelay(20000 /
>>>>>>     portTICK_PERIOD_MS); nikdy nemohlo zkrátit a bylo dodrženo.
>>>>>>
>>>>>>     Volám to pak standardně přes xTaskCreatePinnedToCore() ....
>>>>>>
>>>>>>     void vent1On(void * parameter){
>>>>>>     for(;;){ // infinite loop
>>>>>>     button1.update(1);
>>>>>>     digitalWrite(ventMain1, HIGH);
>>>>>>     digitalWrite(ventOn1, HIGH);
>>>>>>     digitalWrite(ledPinRed, HIGH);
>>>>>>         // Pause the task fo 20s
>>>>>>     vTaskDelay(20000 / portTICK_PERIOD_MS);
>>>>>>     digitalWrite(ventMain1, LOW);
>>>>>>     digitalWrite(ventOn1, LOW);
>>>>>>     digitalWrite(ledPinRed, LOW);
>>>>>>     vTaskDelete(NULL); //spustí se jen jednou
>>>>>>       }
>>>>>>     }
>>>>>>
>>>>>>
>>>>>>     xTaskCreatePinnedToCore(
>>>>>>         vent1On,    // Function that should be called
>>>>>>         "vent1On",   // Name of the task (for debugging)
>>>>>>         1000,            // Stack size (bytes)
>>>>>>         NULL,            // Parameter to pass
>>>>>>         1,               // Task priority
>>>>>>         NULL,            // Task handle
>>>>>>         0            // Core 1/0
>>>>>>       );
>>>>>>
>>>>>>     HP
>>>>>>
>>>>>>
>>>>>>     so 31. 7. 2021 v 8:27 odesílatel Jan Půhoný
>>>>>>     <konference na puhy.cz <mailto:konference na puhy.cz>> napsal:
>>>>>>
>>>>>>         Díky, zkusil jsem jak 2000 tak 4000 ale stále stejné.
>>>>>>         Resetuje se to pořád dokola s tímto:
>>>>>>
>>>>>>         rst:0x1 (POWERON_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
>>>>>>         configsip: 0, SPIWP:0xee
>>>>>>         clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
>>>>>>         mode:DIO, clock div:2
>>>>>>         load:0x3fff0018,len:4
>>>>>>         load:0x3fff001c,len:1044
>>>>>>         load:0x40078000,len:10124
>>>>>>         load:0x40080400,len:5828
>>>>>>         entry 0x400806a8
>>>>>>
>>>>>>         *Ale zjistil jsem, že to dělá jen pokud to napájím z USB.
>>>>>>         Když to dám přímo do svého zapojení, kde je pořádná
>>>>>>         kapacita na Vin, tak to drží. Takže skutečně jen problém
>>>>>>         s napájením.*
>>>>>>
>>>>>>         Teď už to budu programovat jen přes OTA, takže vyřešeno.
>>>>>>
>>>>>>         HP
>>>>>>
>>>>>>
>>>>>>         so 31. 7. 2021 v 6:44 odesílatel Jaroslav Buchta
>>>>>>         <jaroslav.buchta na hascomp.cz
>>>>>>         <mailto:jaroslav.buchta na hascomp.cz>> napsal:
>>>>>>
>>>>>>             kod jsem nezkoumal ale na prvni pohled mi prijde maly
>>>>>>             zasobnik pro
>>>>>>             vlakno, tady je to tusim v btech. dal bych 2 nebo 4K
>>>>>>             na zkousku
>>>>>>             _______________________________________________
>>>>>>             HW-list mailing list  -  sponsored by www.HW.cz
>>>>>>             <http://www.HW.cz>
>>>>>>             Hw-list na list.hw.cz <mailto:Hw-list na list.hw.cz>
>>>>>>             http://list.hw.cz/mailman/listinfo/hw-list
>>>>>>             <http://list.hw.cz/mailman/listinfo/hw-list>
>>>>>>
>>>>>>
>>>>>>     _______________________________________________
>>>>>>     HW-list mailing list  -  sponsored bywww.HW.cz  <http://www.HW.cz>
>>>>>>     Hw-list na list.hw.cz  <mailto:Hw-list na list.hw.cz>
>>>>>>     http://list.hw.cz/mailman/listinfo/hw-list  <http://list.hw.cz/mailman/listinfo/hw-list>
>>>>>
>>>>>     _______________________________________________
>>>>>     HW-list mailing list  -  sponsored bywww.HW.cz  <http://www.HW.cz>
>>>>>     Hw-list na list.hw.cz  <mailto:Hw-list na list.hw.cz>
>>>>>     http://list.hw.cz/mailman/listinfo/hw-list  <http://list.hw.cz/mailman/listinfo/hw-list>
>>>>
>>>>
>>>>
>>>>     _______________________________________________
>>>>     HW-list mailing list  -  sponsored bywww.HW.cz  <http://www.HW.cz>
>>>>     Hw-list na list.hw.cz  <mailto:Hw-list na list.hw.cz>
>>>>     http://list.hw.cz/mailman/listinfo/hw-list  <http://list.hw.cz/mailman/listinfo/hw-list>
>>>
>>>     _______________________________________________
>>>     HW-list mailing list  -  sponsored bywww.HW.cz  <http://www.HW.cz>
>>>     Hw-list na list.hw.cz  <mailto:Hw-list na list.hw.cz>
>>>     http://list.hw.cz/mailman/listinfo/hw-list  <http://list.hw.cz/mailman/listinfo/hw-list>
>>
>>
>>
>>     _______________________________________________
>>     HW-list mailing list  -  sponsored bywww.HW.cz  <http://www.HW.cz>
>>     Hw-list na list.hw.cz  <mailto:Hw-list na list.hw.cz>
>>     http://list.hw.cz/mailman/listinfo/hw-list  <http://list.hw.cz/mailman/listinfo/hw-list>
>
>
>     _______________________________________________
>     HW-list mailing list  -  sponsored by www.HW.cz <http://www.HW.cz>
>     Hw-list na list.hw.cz <mailto:Hw-list na list.hw.cz>
>     http://list.hw.cz/mailman/listinfo/hw-list
>     <http://list.hw.cz/mailman/listinfo/hw-list>
>
>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20210803/b9e44b72/attachment-0001.html>


Další informace o konferenci Hw-list