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