Tiempo de respuesta ISR en el esp32

Alguien ha calculado el tiempo que tarda ( o el orden nseg, useg ) un ESP32 en iniciar la primera instrucción de la Interrupción desde una petición GPIO?
Y de paso.
Y en responder a la función analogRead () ?

Calculado? Dirás medido en todo caso.
Además eso es variable y debería estar indicado en la hoja de datos de tu modelo ESP32.
analogRead en el ESP32 es una función que forma parte del core de Arduino para ESP32, diseñada para simplificar la lectura de valores analógicos de los pines ADC
Esta es la forma directa de interactuar con ESP32

#include "driver/adc.h"
Configurar el ADC:

cpp
Copiar código
void setup() {
  Serial.begin(115200);

  // Configurar el ADC1 para el canal 6 (GPIO34)
  adc1_config_width(ADC_WIDTH_BIT_12); // Configurar la resolución a 12 bits
  adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_0); // Configurar la atenuación a 0 dB
}
void loop() {
  // Leer el valor del ADC1, canal 6 (GPIO34)
  int analogValue = adc1_get_raw(ADC1_CHANNEL_6);
  Serial.println(analogValue);
  delay(1000);
}

ya ves que esto

 int analogValue = adc1_get_raw(ADC1_CHANNEL_6);

no es muy diferente de esto

 int analogValue = analogRead(GPIO34);

pero si mucho mas legible si no estas habituado.

Vuelvo al tema interrupción.
Revisando, el tiempo que mencionas se llama "no lo recordaba" latencia de interrupción.
Este tiempo puede variar dependiendo de varios factores, incluyendo la carga del sistema (qué esta haciendo el ESP) y la configuración específica del hardware y el software, tienes ADC activos, tienes Serial, I2C, SPI, BT, WIFI, todo consume tiempo y la reacción tiene prioridades.

Encontré una forma de medirlo

Medición Práctica de la Latencia de Interrupción

Para obtener una medición precisa de la latencia de interrupción en tu configuración específica, puedes realizar un experimento práctico. Aquí hay un ejemplo de cómo podrías hacerlo:

  1. Configuración del Pin GPIO y la Interrupción:
#define INTERRUPT_PIN 4  // Pin GPIO usado para la interrupción
volatile uint32_t startTime = 0;
volatile uint32_t interruptTime = 0;

void IRAM_ATTR handleInterrupt() {
  interruptTime = micros();
}

void setup() {
  Serial.begin(115200);
  pinMode(INTERRUPT_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), handleInterrupt, FALLING);
}

void loop() {
  // Generar una señal para medir la latencia de interrupción
  startTime = micros();
  digitalWrite(INTERRUPT_PIN, LOW);
  delayMicroseconds(10);  // Pequeño retardo para asegurar la captura de la interrupción
  digitalWrite(INTERRUPT_PIN, HIGH);
  
  // Esperar a que la interrupción ocurra
  delay(1);
  
  // Calcular la latencia de la interrupción
  uint32_t latency = interruptTime - startTime;
  Serial.print("Interruption latency: ");
  Serial.print(latency);
  Serial.println(" microseconds");
  
  // Pequeño retardo antes de la siguiente medición
  delay(1000);
}

Entonces:

  • Configuras un pin GPIO para generar una interrupción.
  • handleInterrupt es llamada cuando ocurre la interrupción y registra el tiempo de interrupción.
  • En el loop generamos un flanco en el pin GPIO y medimos la latencia de interrupción.

Muchas gracias por la completa información .

En realidad la palabra correcta era "medido",

Tengo una aplicación con wifi y cámara, aparte necesito un proceso de medición cada 10 uS mediante un A/D, pensaba hacerlo mediante interrupciones.
Por ahí leí que el tiempo de latencia del ESP32 era de 10uS...... me extrañó tanto que hice la pregunta porque no me lo creía, ya que ese procesador trabaja a 240Mhz y no creía posible que respondiera a esa velocidad.
Eso de las librerías es muy cómodo, pero no puedes controlar los recursos, ya que no puedes optimizarlos, no sabes en realidad lo que hacen dichas librerías.

Yo vengo de procesadores donde las respuestas a interrupciones eran de nS, y podías hasta contar los ciclos de reloj para la latencia y tiempo de proceso.....ahora esto es imposible.
En conclusión voy a utilizar el ULP del ESP32, programando en asembler solo para coger datos cada 10uS, ahí puedo contar ciclos, ese no lo utiliza nadie y no voy a perder ningún dato.

Gracias por tu interés e información, no obstante cuando pueda haré la prueba con un osciloscopio digital que me dará el máximo retardo.

El hilo permanecerá abierto por 6 meses.
Si haces la medición comparte los resultados.
Gracias.

El IDE compila tu programa usando una copia de la librería que reside en tu computadora.

Puedes revisar el código fuente directamente ahí o en internet y averiguar qué hace la librería, incluso puedes modificar tu copia.

Gracias Mancera por el consejo, soy un programador de bajo nivel, mi fuerte ha sido siempre la programación en assembler para procesos rápidos muy optimizados, el C me lo programaban.
Ahora a mis años todo depende de mi y he tenido que aprender el C++ a base de ......
entiendo lo que me dices, pero al menos en Arduino con les ESP32 las librerías están accesibles para los .h muchos de los ficheros .cpp están previamente compilados y salen como .a de los cuales no creo que no se puede recomponer el fuente, al memos es lo que creo.
No se si hay alguna forma de leer y tocar los .a, al menos yo no la sé.

Gracias por tu interés, no obstante si puedes aportar algo mas, estaré encantado.

Javier Valero

No exactamente...

Gracias Maximo, algunas si, pero no tienes la certeza que sean iguales o hayan sido re_compiladas para caracterizar las proto boards.

Eso lo vi cuando buscaba los sdk_config. que no coincidían.

Si estuvieran en Arduino los .cpp sin pre_compilar, con la versión 2.x.x y la ventaja de acceder a las funciones directamente a través de "ir a la definición " seria un puntazo.

Gracias por el comentario

Javier Valero

Ese es el core oficial, difícilmente haya algo cambiado.

De cualquier modo, yo empezaría mirando por ahí. :wink:

Saludos

Ya tenemos la latencia de las ISR del ESP32, para mi muy decepcionantes. he aplicado el acceso a registros para minimizar las perdidas por funciones de Arduino. El código resumido aplicado ha sido el siguiente.

// Inicializacion+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
volatile int analogValue ;
uint * p_GPIO_SET = ( uint *) 0x3ff44008 ;
uint * p_GPIO_CLR = ( uint *) 0x3ff4400C ;

// interrupcion routine
void  IRAM_ATTR Interrupt() {  // void IRAM_ATTR Interrupt() {//
  * p_GPIO_SET = 0x00008004 ;  // confirma inicio de int (2), inicio de conversion(13)
  analogValue = analogRead(33);// GPIO33  
  * p_GPIO_CLR = 0x00008000 ;  // final de conversion
  return ;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

y

void loop() {
  * p_GPIO_CLR = 0x00000004 ; // Ini. int. flanco de bajada gpio4
  Serial.println( analogValue, HEX);
  delay(5);
}

Aplicando esto y procesando a la vez la función WIFI, eso si en el core0, y la captación de 30 frames/seg con una definición SVGA resulta lo siguiente.
1- Desde que pido ISR hasta que puedo ejecutar la primera instrucción de la funcion de interrupción pasan 2 uS.
2- Con los parámetros sin tocar, el tiempo de respuesta de una lectura de un pin Analógico, ya sea de 9 o . 12 bits de resolución es de 37,5 uS. Eso para mi es mucho, supongo que programando la frecuencia de muestreo se podrá mejorar, pero me temo que perdiendo precisión.

Con respecto al canal2 del conversor no me lo deja programar, ya que el WIFI lo usa en exclusiva, por lo cual las mediciones se han hecho en el canal1 que esta libre.
Con esto yo daria por cerrado esto

Javier Valero