Problema con attachInterrupt esp32

muy buenas , haber si alguien me puede arrojar una idea , estoy utilizando esta función para contar pulsos rápidos . unos 4 pulsos en medio segundo algo así , el tema esque le tengo que poner una función millis , para que el conteo no le agá tan rapido por que si no me bloquea el programa o se reinicia el esp32, para ser mas precisos le tengo que retrasar 300 milisegundos el conteo para que
no se bugue el programa . pero claro al ponerle eso pierdo velocidad le lectura y ya no me sirve. Alguna idea por donde empezar o que hacer? muchas gracias aaa se me olvidada eso conteo lo mando atreves de un bot por telegram

Moderador:
HIlo movido a Microcontroladores

Si estas con millis() y no usas delay() en ningún sitio no veo porque el programa te reinicie el ESP32.
Porque no subes el programa (usa etiquetas) y explicas donde ocurre el inconveniente.
Asi como lo has planteado, es dificil responder algo particular como lo que preguntas.

¿No habras puesto las millis en la rutina de servicio de la interrupción?. Ten en cuenta que dentro de una ISR no funcionan ni los delays ni las millis.
saludos.

estoy usando la funcion millis , viendo el monitor serie me sale el error backtrace 0*400d07a6...... despues me sale rebooting... creo que es por que al contar super rapido con la funcion attachinterrup cuenta tan rapido que se crashea . y si le meto el millis para que cuente con 300 milisegundos entre conteo y conteo es cuando parece que funciona

el caso que el mismo programa en arduino mega si que funciona

Ok, que corre en el Mega sin problemas es un dato poco útil porque seguimos sin ver el código y un Mega no es lo mismo que un ESP32.
Ayudanos a ayudarte y sube el código, ¿te parece?

Saludos

Agrego:
Un par de detalles, no usas attachInterrupt() para contar nada porque attachInterrupt() le dice al micro en cual pin recibe las interrupciones, cual es la rutina ISR que sirve esas interrupciones y cual es la señal a la que debe atender.
En todo caso la que lleva la cuenta es la ISR que defines con attachInterrupt().
Por otro lado, si el mismo código corre en Mega sin cambios entonces está incompleta la definición de la ISR para trabajar satisfactoriamente en ESP32, debería tener la siguiente forma

void IRAM_ATTR isr() {

isr es el nombre que tu le hayas dado a la rutina.
El modificador IRAM_ATTR hace que la rutina se cargue en la ram (rápida) en lugar de la memoria flash (lenta).

#include <ArduinoJson.h>


#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>


// Wifi network station credentials
#define WIFI_SSID "xxxx"
#define WIFI_PASSWORD "xxxx"
// Telegram BOT Token (Get from Botfather)
#define BOT_TOKEN "xxxx"
#define ID_Chat "xxxxxx"

const unsigned long tiempo = 1000; // mean time between scan messages

WiFiClientSecure secured_client;
UniversalTelegramBot bot(BOT_TOKEN, secured_client);

int RELE1 = 0;
unsigned long tiempoAnterior;
float conteo = 0;
String conteoString = "0";
String mensaje ="";
int inicio = 1; 
String chat_id;
int ANTERIOR=0 ;
unsigned long intervalCont = 150;
 
unsigned long previousMillis = 0;

{
  for (int i = 0; i < numerosMensajes; i++)
  
  { 
    String chat_id = bot.messages[i] .chat_id;
     String text = bot.messages[i].text;
  //señal 1 en el 21 //
    if (text=="xxxx")
    { 
    bot.sendMessage ( chat_id, "xxxx" );
       }
        }
         }
     

void setup()
{
  Serial.begin(9600);  
  attachInterrupt(digitalPinToInterrupt(2), sensor, RISING); // interrupcion sobre pin digital 2

  
  Serial.println("lectura leida");


  // attempt to connect to Wifi network:
  Serial.print("Connecting to Wifi SSID ");
  Serial.print(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  secured_client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.print("\nWiFi connected. IP address: ");
  Serial.println(WiFi.localIP());
  if (inicio==1){
    Serial.println("sistemapreparado");
bot.sendMessage (ID_Chat, "xxxxxx!!!");
 inicio = 0;
}

 }



void loop() {
unsigned long currentMillis = millis();
  if ((currentMillis - previousMillis) >=(intervalCont1))
  { previousMillis = currentMillis ;   
  
{ 
  if (ANTERIOR != conteo){    // si hubo un cambio respecto del valor anterior
    
    ANTERIOR = conteo ;
     conteoString = String(conteo);
mensaje= conteo;
 bot.sendMessage(ID_Chat, mensaje, "") ;
 RELE1=1 ;
  } 
   // 
}
   

}
}
  
  
void sensor()    
  if ((currentMillis - previousMillis) >=(intervalCont))
  { previousMillis = currentMillis ;   
  conteo = conteo + 0.5;
       
 

}
}

aqui lo tienes

Como te dije la ISR deberias definirla así

void IRAM_ATTR sensor() {
  if (currentMillis - previousMillis >= intervalCont) {
    previousMillis = currentMillis ;
    conteo = conteo + 0.5;
  }
}

Los problemas que veo:

  • conteo, previousMillis y currentMillis deberían estar declararlas como volatile sino pueden generar problemas, especialmente previousMillis y currentMillis que las modificas también en el loop().
    Por cierto, ¿no ves un posible conflicto con previousMillis?
  • currentMillis no está declarada como global (es local dentro de loop() ), me extraña no te haya saltado el error.

No entiendo por qué incrementas de a 0.5

Al margen, la ISR debería ser algo como

void IRAM_ATTR sensor() {
    conteo++;
}

para que sea realmente rápida y el resto del tratamiento lo tendrías que hacer en el loop().
De hecho, así como está planteada no tiene sentido.

Otra opción es olvidarte de la interrupción y leer el gpio directamente cada X tiempo desde el loop().

Saludos

Moderador:
Por favor, lee las Normas del foro y edita tu código/error (post#7) usando etiquetas de código.
Ve a edición, luego selecciona todo el código que has publicado, lo cortas y click en </>


vale voy a probar asi , lo tengo puesto el incremento de 0.5 por que es la lectura de un monedero ( un pulso 50 cent, dos 1 euro. y 4 dos euros ) , el monedero lo da todo como en medio segundo . luego me llega el mensaje de telegram por ejemplo 7.50 Euros . Esta tarde lo pruebo y te digo si me a funcionando denominando asi el el IRAM_ATTR , el tema de MIllis lo puse para que me retrasa el tiempo de lectura , quitando la funcion attach, como puedo poner para que el tiempo de lectura sea de 70 milisegundos por ejemplo . siento mi novatez pero llevo una semana de aprendizaje , a @Surbyte surbyte lo siento , ya no volverá a ocurrir

Ok, pero si cuentas los pulsos y luego, ya en el loop(), los divides por 2 obtienes el mismo resultado.
Es más rápido incrementar un int que sumarle 0.5 a un float y tu quieres que la interrupción pase casi desapercibida.

Estaba revisando tu código a ver cómo lo podiamos modificar y encuentro ésto

{
  for (int i = 0; i < numerosMensajes; i++)
  
  { 
    String chat_id = bot.messages[i] .chat_id;
     String text = bot.messages[i].text;
  //señal 1 en el 21 //
    if (text=="xxxx")
    { 
    bot.sendMessage ( chat_id, "xxxx" );
       }
        }
         }
     

Ese bloque de código está huérfano, no es una función, no está en setup() ni en loop()
¿Y dices que compila y corre en un Mega?

Con este bloque huérfano y currentMillis excluida el ámbito de la ISR, me cuesta creer que compile.


Moderador:
Recuerda al llegar a un foro en leer sus normas. Siempre!.
Lo del código lo hiciste a medias pero viendo tu intención de editarlo, terminé modificando lo que quedó fuera, mas de la mitad del código.

Observa que yo me he tomado el trabajo de ordenarlo.
Por favor!! Cuando postees un código hazlo de modo que sea fácil de leer por nosotros.
Tu código tiene las llaves por cualquier lado.
Usa identación y ve dándole la profundidad adecuada para que sea fácil leer. De otro modo quien te responda se debe tomar el trabajo de hacerlo y la verdad no corresponde.

Respondiendo tu código me enfocaré primero a cuestiones simples como esta

// que es esto???

{
  for (int i = 0; i < numerosMensajes; i++){
      String chat_id = bot.messages[i] .chat_id;
      String text = bot.messages[i].text;
      //señal 1 en el 21 //
      if (text=="xxxx")
      {
        bot.sendMessage ( chat_id, "xxxx" );
      }
  }
}
  1. Esto esta antes del setup y la verdad no se si compilará, aunaque dudo que lo haga.

  2. Haces consultas a intervalcount1 y no esta definido. Si tienes definido intervalcount pero no lo usas.
    Osea es un código que no creo funcione por donde se lo mire.

Ahora yendo de lleno al código y mas allá que no es la versión que nos mencionas porque esta versión no puede compilar por las razones ya expuestas.

  1. Para qué usar una interrupción si le pones una especie de delay de 150mseg?
    Puede haber 1000 interrupciones pero no las verá a menos que se active la lectura cada 150 mseg
    Para eso no uses interrupcones y cuenta directamente en el loop.
    Si usas interrupciones haz como te indica @anon90500195. Directamente conteo++ y que sea entera sin signo. Un contador como se espera.

no no eso corria en un esp32 . he eliminado la parte del las librerias y eso y con el mega si que me funciona

de verdad que si que me funciona , no engaño a nadie si quieres cambiale los datos puestos con XX y haz la prueba en un esp 32

claro pero si lo hago así , el conteo lo hace cada segundo mas o menos y lo que necesito el 4 o 5 conteos en medio segundo , y el bot ya me manda el conteo entero, lo de las interrupciones a 150 milisegundos es por eso que comente es lo minimo que puedo poner para que no se crashe el programa y se reinicie , de echo el mismo programa en el mega , si no pongo un minimo alomejor en un segundo me cuenta 66 conteos , le tengo que poner un tiempo como minimo de 70 milisegundos ( en el mega ) para que los conteos sean los que busco

Porque lo va a hacer cada segundo?
Entonces en lugar de usar millis() usa micros() y tendras 1000 veces mas resolución.
cuenta con entero o un long para no quedarte corto.
en lugar de 150mseg ahora usa 150x1000 = 150000 useg

if ((currentMicros - previousMicros) >= intervalCont) {  // recuerda modificar intervalCont a 150000
   previousMicros = currentMicros ;   
   conteo++;

Tendrás que hacer ajustes pero tienes mas control

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.