Timer ESP32

99 views
Skip to first unread message

Bartolito

unread,
May 9, 2022, 12:48:44 PM5/9/22
to Embebidos32
Hola a todos, estoy en un proyecto con un ESP32 en el cual tengo que medir tiempo. 
Basicamente se presiona un boton, se inicia el contador y al presionar otro boton deberia cortar y retornarme cuanto tiempo transcurrio. 
Miro la plantilla de idf y no entiendo por usa cola de mensajes. Ni encuentro un ejemplo sensillo para usar como base. Programa en C, no quiero nada de arduino para el proyecto.
¿Alguna idea para que pueda encarar el problema? 
Saludos,

jecar...@sinc.unl.edu.ar

unread,
May 11, 2022, 7:27:06 AM5/11/22
to Embebidos32
Justo estoy arrancando con los ESP32-S2 lo que entendí es que tenes un RTOS en el ESP-IDF... por otro lado que error de medición tolera la aplicación? Quedo atento para aprender, Salud!

Bartolito

unread,
May 11, 2022, 9:04:08 AM5/11/22
to embeb...@googlegroups.com
Buen dia, el ejemplo peripherals/timer_group del idf trabaja a 1s de interrupcion no logro resolver aun como hacer que trabaje a ms o us.
Luego intente usar un conteo de los ticks del sistema, pero no encuentro ningun ejemplo en C, ese me daria una resolucion del orden de los nS. De algun lado estas sacando informacion?
Saludos,
--
-- Recibiste este mensaje porque estás suscripto al Grupo Google Embebidos32. Para postear en este grupo, escribe un email a embeb...@googlegroups.com. Para des-suscribirte, envía un email a embebidos32...@googlegroups.com. Para más opciones, visita el sitio del grupo en https://groups.google.com/d/forum/embebidos32?hl=es
---
Has recibido este mensaje porque estás suscrito al grupo "Embebidos32" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a embebidos32...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/embebidos32/3b16edf0-2957-4e91-887d-920fa2f4365bn%40googlegroups.com.

Carlos Pantelides

unread,
May 11, 2022, 9:18:33 AM5/11/22
to Embebidos32
Hola,

aporto mi granito, en lugar de buscar información específica para esp-idf, buscá para freertos, por ejemplo "measuring time with freertos"

Saludos

GERARDO LUIS STOLA

unread,
May 11, 2022, 12:19:35 PM5/11/22
to embeb...@googlegroups.com
Esta recomendación de usar gettimeofday()  me resultó para medir intervalos de tiempo con precisión de decenas de microsegundos.

https://esp32.com/viewtopic.php?f=13&t=2214#p10411

Avisá si te trabaste y busco snippet.


Pablo A. Llanos

unread,
May 11, 2022, 3:12:14 PM5/11/22
to embeb...@googlegroups.com
Buenas, sería interesante saber qué precisión necesitas para poder acotar la respuesta porque hay muchas variantes. No teniendo esa información, aquí va una respuesta general:

- Para lograr una precisión de segundos puedes usar las funciones standard POSIX, como por ejemplo, gettimeofday() o time(). Más información aquí
Si bien hay una forma de obtener el tiempo en microsegundos, no es muy preciso, depende del clock que estés utilizando en ese momento, si estás en modo sleep usando el clock de 32kHz y con el PLL deshabilitado, los ticks del sistema pueden ser del orden de ms y, por lo tanto, el cálculo que harás (es una suma y multiplicación con enteros de 64 bits) será mentiroso.

- Para precisión de ms o us puedes usar la función esp_timer_get_time(). Ejemplo:
  int64_t time_since_boot = esp_timer_get_time();

También podrías utilizar un timer de alta resolución (ver ejemplo en "/esp-idf/examples/system/esp_timer")


Consideraciones adicionales:
1. Supongo que ya tuviste en cuenta el rebote del botón.
2. Sobre tu comentario:
"Miro la plantilla de idf y no entiendo porqué usa cola de mensajes."
Las colas de mensajes se utilizan para enviar mensajes entre tareas, EDP-IDF utiliza como base un FreeRTOS, es un sistema operativo real time, multi tarea, ejecutándose en un MCU multicore! Es un tema largo pero en términos simples, no puedes acceder a un recurso simultáneamente desde dos o más tareas porque tendrás un problema de race condition (un vistazo superficial aquí). Para evitar esto se utiliza un patrón "producer-consumer" de un sólo consumer, se envían mensajes usando la cola de mensajes y de esa forma evitas locks, mutex, semáforos o cualquier otro mecanismo con bloqueos.

Aunque fue muy general la respuesta, espero que te sirva la info.

Saludos cordiales,

Pablo Llanos Clariá
Embedded Linux Expert
UNITED CODERS
+54 9 343 6229383

Bartolito

unread,
May 15, 2022, 7:14:21 PM5/15/22
to embeb...@googlegroups.com
Buen dia, gracias por la informacion.
Respecto a lo que decis Pablo, la precision que necesito es de 1us. 

La funcion esp_timer_get_time() devuelve el numero de us desde que fue inicializada. Ahora bien, no puedo discriminar fracciones de tiempo 1.5, 1.6,... etc us  ¿Es posible hacerlo?

Saludos,

Pablo A. Llanos

unread,
May 15, 2022, 8:18:29 PM5/15/22
to embeb...@googlegroups.com
Fracciones de microsegundos son nanosegundos. Puedes usar un timer de alta resolución en modo contador pero ten en cuenta las prioridades que le asignas a las tareas e interrupciones o el sistema operativo puede switchear a otra tarea y tendrás mediciones inconsistentes.

Para lograr precisión de nanosegundos de forma consistente, tienes que eliminar RTOS, trabajar en bare metal poniendo el foco en las partes críticas. El problema de eso es que pierdes toda la funcionalidad que te brinda el SDK de Espressif (ESP-IDF).

Saludos,

Pablo Llanos Clariá
Embedded Linux Expert
UNITED CODERS

Bartolito

unread,
May 16, 2022, 5:40:34 PM5/16/22
to embeb...@googlegroups.com
Pablo, sin llegar a ese nivel por medio de la cuenta de los ticks del procesador no se puede?
Saludos

Pablo A. Llanos

unread,
May 16, 2022, 8:54:57 PM5/16/22
to embeb...@googlegroups.com
Lo que sugerí en el correo anterior era utilizar un timer de alta resolución, esos timers toman el clock del MCU (con un prescaler opcional), es el caso donde puedes obtener la mejor precisión en cuanto a tiempos. Aún así, como tienes el scheduler del sistema operativo, otras tareas, prioridades, etc, tienes que tener todo eso en cuenta para que tu tarea sea la de mayor prioridad o puedes colocar algún código mínimo dentro de la misma interrupción (por ejemplo, calcular el periodo de tiempo entre los eventos) y luego generar una notificación (ver queue o eventos) para que después la tarea procese esa información y haga lo que tenga que hacer.

Los ticks son del sistema operativo (en el caso de ESP-IDF es FreeRTOS), el tick es la unidad de tiempo en la que se ejecuta el task scheduler. El máximo que puedes setear en FreeRTOS es 1000 ticks por segundo (por defecto se configura en 100 o 120) y la razón para esto es que el scheduler se ejecuta en cada tick, si por ejemplo el código del scheduler consume 25 us y cada tick ocurre cada 10 ms (CONFIG_FREERTOS_HZ=100, 100 ticks por segundo), la carga de trabajo del scheduler representa un 2.5%. Si, en cambio, se pudiera configurar el sistema para 10.000 ticks por segundo, el scheduler se ejecutará cada 100 us y la carga de trabajo del scheduler será del 25%. Si sigues aumentando los ticks llegaras a un punto donde la ejecución se mantendrá siempre en el task scheduler y no podrá ejecutar ninguna tarea. Se entiende?

Lo normal es hacer lo que expliqué en el primer párrafo:
1) configuras un timer de alta resolución (usa el prescaler para lograr el mejor balance entre precisión del timer y máximo overflow)
2) en la interrupción del primer botón disparas el timer
3) en la interrupción del segundo botón detienes el timer, calculas el Delta de tiempo y generas un evento o posteas el evento en una queue (por ejemplo, usando el delta de tiempo como parámetro)
4) en una tarea capturas ese evento y haces lo que debas. Recuerda configurar la tarea con la prioridad adecuada (ver RTOS task priority)

Saludos cordiales,

Pablo Llanos Clariá
Embedded Linux Expert
UNITED CODERS

jecar...@sinc.unl.edu.ar

unread,
May 17, 2022, 6:33:21 AM5/17/22
to Embebidos32
Che cuando el soft se complica empiezo a iterar en el hard, suponiendo que tus pulsadores no son mecánicos y no tienen rebote(y son parte de la alineación de un bisturi x tiempo!) para esto de los pulsadores podrías pensar en utilizar el MCU mas económico que consigas dedicado y hacerlo a bare metal.. tal vez el ULP del ESP32s2?
Reply all
Reply to author
Forward
0 new messages