Falsos disparos en pluviometro

Hola! tengoun ESP32 trabajando para levantar datos de una estacion meteorologica para mi web, el tema es que tengo falsas activaciones en el pluviometro, me tira datos falsos

Ya descarte que sea el reedswitch que se activa.

Es ruido xq de la nada me suba un monton de activaciones

tengo conectado al reedswitch asi

3.3v A entrada del reedswitch y a la vuelta hay una resistencia de 10k directo a GND en paralelo con un capacitor ceramico 104

Ya probe mandando GND al sensor y es peor.

estoy alimentando con un cargador de celular Xiaomi original, empalme con un USB, cable de telefono apantallado hasta arriba del techo y conectado al 5v del esp32



#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <time.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <WiFiServer.h>
#include "SinricPro.h"
#include "SinricProTemperaturesensor.h"

// ==========================================
// CREDENCIALES
// ==========================================
#define WIFI_SSID         "ParraX_IoT"
#define WIFI_PASSWORD     ""
#define SERVER_URL        ""
#define SINRIC_APP_KEY    ""
#define SINRIC_APP_SECRET ""
#define SINRIC_DEVICE_ID  ""
#define BOT_TOKEN         ""

#define CHAT_ID_GENERAL   ""
#define CHAT_ID_ALERTAS   ""
#define OTA_PASSWORD      "admin123"

// --- CREDENCIALES WUNDERGROUND ---
const char* WU_ID = "";
const char* WU_KEY = "";

// ==========================================
// CONSTANTES DE HARDWARE
// ==========================================
const int    PIN_VELETA       = 34;
const int    PIN_PLUVIOMETRO  = 25; 
const int    PIN_ANEMOMETRO   = 26; 

const float  FACTOR_VIENTO_KMH = 2.4f;
const float  TEMP_MIN = -10.0f;
const float  TEMP_MAX =  55.0f;
const float  LLUVIA_POR_CLICK = 0.2794f; 

// ==========================================
// CONSTANTES DE TIEMPO
// ==========================================
const long   GMT_OFFSET_SEC       = -10800;
const int    DST_OFFSET_SEC       = 0;
const unsigned long INTERVALO_ENVIO_MS    = 60000UL;
const unsigned long INTERVALO_TELEGRAM_MS =  5000UL;

const unsigned long DEBOUNCE_LLUVIA_MS    =   100UL; 
const unsigned long DEBOUNCE_VIENTO_MS    =    15UL;
const unsigned long TIMEOUT_WIFI_MS       = 15000UL; 
const unsigned long COOLDOWN_ALERTA_LLUVIA = 300000UL; // 5 minutos entre alertas de lluvia

// ==========================================
// VARIABLES VOLÁTILES (ISR)
// ==========================================
volatile unsigned long totalClicksLluvia    = 0;
volatile unsigned long clicksLluviaPeriodo  = 0;
volatile unsigned int  clicksViento         = 0;
volatile unsigned long ultimoClickLluvia    = 0;
volatile unsigned long ultimoClickViento    = 0;
volatile bool banderaLluvia = false; 

unsigned long tiempoAnteriorEnvio   = 0;
unsigned long ultimaVezTelegram     = 0;
unsigned long tiempoReconexionWiFi  = 0;
unsigned long ultimoAvisoTelegramLluvia = 0;
long ultimoUpdateId = 0;

Adafruit_BME280 bme;
WiFiServer      serverTelnet(23);
WiFiClient      clienteTelnet;

// ==========================================
// PROTOTIPOS
// ==========================================
void IRAM_ATTR registroLluvia();
void IRAM_ATTR registroViento();
void conectarWiFi();
void chequearWiFi();
void configurarOTA();
void logConsola(const String& mensaje);
void manejarConsola();
void enviarTelegram(String mensaje, String targetChatId);
void revisarComandosTelegram();
void reiniciarSistema(const String& motivo);
float leerTemperaturaSegura();
float leerHumedadSegura();
float leerPresionSegura();
String obtenerDireccionViento(int pin);
int obtenerGradosViento(int pin);
String obtenerFechaHora();
void enviarWeatherUnderground(float tempC, float hum, float presHpa, float vientoKmh, int vientoDirDeg, float lluviaMm);

// ==========================================
// SETUP
// ==========================================
void setup() {
  Serial.begin(115200);
  Wire.begin();
  analogReadResolution(10);

  pinMode(PIN_VELETA,      INPUT);
  pinMode(PIN_PLUVIOMETRO, INPUT); 
  pinMode(PIN_ANEMOMETRO,  INPUT_PULLUP);

  bool bmeOk = bme.begin(0x77);

  conectarWiFi();
  serverTelnet.begin();
  configurarOTA();
  
  configTime(GMT_OFFSET_SEC, DST_OFFSET_SEC, "pool.ntp.org", "time.nist.gov");

  String miIP = WiFi.localIP().toString();
  
  if (!bmeOk) {
    enviarTelegram("⚠️ BME280 no detectado. IP: " + miIP, CHAT_ID_ALERTAS);
  } else {
    enviarTelegram("🚀 Estación online. IP: " + miIP, CHAT_ID_ALERTAS);
  }

  SinricPro.begin(SINRIC_APP_KEY, SINRIC_APP_SECRET);

  attachInterrupt(digitalPinToInterrupt(PIN_PLUVIOMETRO), registroLluvia, RISING);
  attachInterrupt(digitalPinToInterrupt(PIN_ANEMOMETRO),  registroViento,  FALLING);

  tiempoAnteriorEnvio = millis();
}

// ==========================================
// LOOP
// ==========================================
void loop() {
  ArduinoOTA.handle();
  manejarConsola();
  SinricPro.handle();
  chequearWiFi();

  unsigned long ahora = millis();

  if (ahora - ultimaVezTelegram >= INTERVALO_TELEGRAM_MS) {
    revisarComandosTelegram();
    ultimaVezTelegram = ahora;
  }

  // AVISO INMEDIATO DE LLUVIA POR TELEGRAM
  if (banderaLluvia) {
    banderaLluvia = false; 
    if (ahora - ultimoAvisoTelegramLluvia > COOLDOWN_ALERTA_LLUVIA || ultimoAvisoTelegramLluvia == 0) {
      enviarTelegram("🌧️ ¡Atención! Se detectó lluvia en la estación.", CHAT_ID_ALERTAS);
      ultimoAvisoTelegramLluvia = ahora;
    }
  }

  // ENVÍO PERIÓDICO (Web ASPX, Sinric, WU)
  if (ahora - tiempoAnteriorEnvio >= INTERVALO_ENVIO_MS) {
    tiempoAnteriorEnvio = ahora;

    if (WiFi.status() != WL_CONNECTED) return; 
    
    float t = leerTemperaturaSegura();
    float h = leerHumedadSegura();
    float p = leerPresionSegura();
    String dirStr = obtenerDireccionViento(PIN_VELETA);
    int dirDeg = obtenerGradosViento(PIN_VELETA);

    if (isnan(t)) return;

    noInterrupts();
    unsigned int  vClicksPeriodo  = clicksViento;
    unsigned long lluviaPeriodo   = clicksLluviaPeriodo;
    unsigned long lluviaTotal     = totalClicksLluvia;
    clicksViento        = 0;
    clicksLluviaPeriodo = 0;
    interrupts();

    float duracionSegundos = INTERVALO_ENVIO_MS / 1000.0f;
    float vKmh = ((float)vClicksPeriodo / duracionSegundos) * FACTOR_VIENTO_KMH;
    float lluviaMm = (float)lluviaPeriodo * LLUVIA_POR_CLICK;

    SinricProTemperaturesensor &sensorGoogle = SinricPro[SINRIC_DEVICE_ID];
    sensorGoogle.sendTemperatureEvent(t, h);

    JsonDocument doc;
    doc["temp"]      = serialized(String(t, 1));
    doc["hum"]       = serialized(String(h, 1));
    doc["pres"]      = serialized(String(p, 1));
    doc["dir"]       = dirStr;
    doc["vel"]       = serialized(String(vKmh, 1));
    doc["lluvia_c"]  = lluviaTotal;
    doc["lluvia_p"]  = lluviaPeriodo;
    doc["fecha_rpi"] = obtenerFechaHora();

    String jsonString;
    serializeJson(doc, jsonString);
    logConsola("[TX ASPX] " + jsonString);

    WiFiClientSecure clientSecure;
    clientSecure.setInsecure();
    HTTPClient http;
    http.begin(clientSecure, SERVER_URL);
    http.addHeader("Content-Type", "application/json");
    http.POST(jsonString);
    http.end();

    enviarWeatherUnderground(t, h, p, vKmh, dirDeg, lluviaMm);
  }
}

// ==========================================
// WEATHER UNDERGROUND
// ==========================================
void enviarWeatherUnderground(float tempC, float hum, float presHpa, float vientoKmh, int vientoDirDeg, float lluviaMm) {
  WiFiClient client; 
  HTTPClient http;

  float tempF = (tempC * 9.0 / 5.0) + 32.0;
  float presIn = presHpa * 0.02953;
  float vientoMph = vientoKmh * 0.621371;
  float lluviaIn = lluviaMm * 0.0393701;

  String url = "http://rtupdate.wunderground.com/weatherstation/updateweatherstation.php?";
  url += "ID=" + String(WU_ID);
  url += "&PASSWORD=" + String(WU_KEY);
  url += "&dateutc=now";
  url += "&tempf=" + String(tempF, 2);
  url += "&humidity=" + String(hum, 0);
  url += "&baromin=" + String(presIn, 2);
  url += "&windspeedmph=" + String(vientoMph, 2);
  url += "&winddir=" + String(vientoDirDeg);
  url += "&rainin=" + String(lluviaIn, 3);
  url += "&action=updateraw";

  logConsola("[TX WU] Enviando datos...");
  
  http.begin(client, url);
  int httpCode = http.GET();
  
  if (httpCode > 0) {
    logConsola("[TX WU] Respuesta: " + String(httpCode));
  } else {
    logConsola("[TX WU] Error: " + http.errorToString(httpCode));
  }
  http.end();
}

// ==========================================
// INTERRUPCIONES
// ==========================================
void IRAM_ATTR registroLluvia() {
  // FILTRO POR SOFTWARE: Espera 1ms para matar el ruido electromagnético
  delayMicroseconds(1000); 
  
  if (digitalRead(PIN_PLUVIOMETRO) == HIGH) { 
    unsigned long ahora = millis();
    if (ahora - ultimoClickLluvia > DEBOUNCE_LLUVIA_MS) {
      totalClicksLluvia++;
      clicksLluviaPeriodo++;
      ultimoClickLluvia = ahora;
      banderaLluvia = true; 
    }
  }
}

void IRAM_ATTR registroViento() {
  unsigned long ahora = millis();
  if (ahora - ultimoClickViento > DEBOUNCE_VIENTO_MS) {
    clicksViento++;
    ultimoClickViento = ahora;
  }
}

// ==========================================
// FUNCIONES AUXILIARES
// ==========================================
void reiniciarSistema(const String& motivo) {
  enviarTelegram("🔄 Reiniciando: " + motivo, CHAT_ID_ALERTAS);
  delay(500);
  ESP.restart();
}

void conectarWiFi() {
  if (WiFi.status() == WL_CONNECTED) return;
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  unsigned long inicio = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - inicio < TIMEOUT_WIFI_MS) { delay(500); }
}

void chequearWiFi() {
  if (WiFi.status() != WL_CONNECTED && (millis() - tiempoReconexionWiFi >= TIMEOUT_WIFI_MS)) {
    WiFi.disconnect();
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    tiempoReconexionWiFi = millis();
  }
}

void configurarOTA() {
  ArduinoOTA.setHostname("Estacion_Peyrano");
  ArduinoOTA.setPassword(OTA_PASSWORD);
  ArduinoOTA.begin();
}

void logConsola(const String& mensaje) {
  String linea = "[" + obtenerFechaHora() + "] " + mensaje;
  Serial.println(linea);
  if (clienteTelnet && clienteTelnet.connected()) clienteTelnet.println(linea);
}

void manejarConsola() {
  if (serverTelnet.hasClient()) {
    if (!clienteTelnet || !clienteTelnet.connected()) clienteTelnet = serverTelnet.available();
    else serverTelnet.available().stop();
  }
}

void enviarTelegram(String mensaje, String targetChatId) {
  if (WiFi.status() != WL_CONNECTED) return;
  mensaje.replace(" ", "%20");
  WiFiClientSecure client; client.setInsecure();
  HTTPClient http;
  String url = "https://api.telegram.org/bot" + String(BOT_TOKEN) + "/sendMessage?chat_id=" + targetChatId + "&text=" + mensaje;
  http.begin(client, url);
  http.GET();
  http.end();
}

void revisarComandosTelegram() {
  if (WiFi.status() != WL_CONNECTED) return;
  WiFiClientSecure client; client.setInsecure();
  HTTPClient http;
  String url = "https://api.telegram.org/bot" + String(BOT_TOKEN) + "/getUpdates?offset=" + String(ultimoUpdateId + 1) + "&limit=1";
  http.begin(client, url);
  if (http.GET() == HTTP_CODE_OK) {
    JsonDocument doc;
    deserializeJson(doc, http.getStream());
    for (JsonObject update : doc["result"].as<JsonArray>()) {
      ultimoUpdateId = update["update_id"];
      String texto = update["message"]["text"] | "";
      if (texto == "/reset") { http.end(); reiniciarSistema("Telegram"); return; }
    }
  }
  http.end();
}

float leerTemperaturaSegura() { float t = bme.readTemperature(); return (isnan(t) || t < TEMP_MIN || t > TEMP_MAX) ? NAN : t; }
float leerHumedadSegura() { float h = bme.readHumidity(); return (isnan(h) || h < 0 || h > 100) ? NAN : h; }
float leerPresionSegura() { return bme.readPressure() / 100.0F; }

String obtenerDireccionViento(int pin) {
  int v = analogRead(pin);
  if (v < 90) return "E"; if (v < 180) return "SE"; if (v < 350) return "S";
  if (v < 550) return "NE"; if (v < 700) return "SW"; if (v < 830) return "N";
  if (v < 940) return "NW"; return "W";
}

int obtenerGradosViento(int pin) {
  int v = analogRead(pin);
  if (v < 90) return 90;  if (v < 180) return 135; if (v < 350) return 180;
  if (v < 550) return 45;  if (v < 700) return 225; if (v < 830) return 0;
  if (v < 940) return 315; return 270;
}

String obtenerFechaHora() {
  struct tm ti;
  if (!getLocalTime(&ti)) return "1970-01-01 00:00:00";
  char b[25]; 
  strftime(b, sizeof(b), "%Y-%m-%d %H:%M:%S", &ti);
  return String(b);
}

que puedo hacer?

No he mirado el código, primero revisa el circuito: el condensador debe estar en paralelo solo con el 'reed switch'. Tal y como describes no me queda claro como lo has puesto si en paralelo a la resistencia o a todo.

           PINo------o------+
                     |      |
                     |      |
                     |   \  o
                    ---   \
                    ---    \.
                     |      o
                     |      |
                     |      |
                     |      |
                    ===    ===
                    GND    GND

Si usas la resistencia 'pull-up' interna del micro puedes ahorrarte la resistencia externa.

En vez de estar entre gpio y gnd, está entre gpio y 3.3v el pluviómetro

Si has echo esto:

                                VCC
                                 +
                                 |
                                 o----+
                                 |    |
                              \  o    |
                               \     ---
                                \.   ---
                                 o    |
                                 |    |
                                 o----+----oPIN
                                 |
                                .-.
                                | |
                                | |
                                '-'
                                 |
                                 |
                                ===
                                GND

En el código no tienes que habilitar al resistencia interna 'pullup' y tu tienes:

  pinMode(PIN_ANEMOMETRO,  INPUT_PULLUP);

Por otro lado, con esa configuración tenemos que el pin siempre será cero y un cierre del reed será un 1, por lo tanto hay que detectar un RISING y tu tienes

attachInterrupt(digitalPinToInterrupt(PIN_ANEMOMETRO),  registroViento,  FALLING);

Nos puedes especificar mejor como lo has hecho, el tipo de anemometro y si puede ser alguna foto de las conexiones. Mientras habrá que echarle un vistazo al resto del código.

Si el capacitor va como pusiste en el diagrama, lo tengo mal puesto, el pluviómetro es un balancín con un imán en el medio y un reedswitch , es de una estación meteorológica comercial

Vale. No se por qué pero estaba leyendo mal... es el pluviometro no el anomemetro. Mea culpa.

Si el condensador no lo pusiste así no está haciendo su función. Debe estar en paralelo al reed.

En cuanto al código, al hacer:

  pinMode(PIN_PLUVIOMETRO, INPUT); 

Si no está bien puesta la resistencia externa tendrás el pin 'fluctuando' lo que hará que haya cosas raras por medio. Y si el condensador está mal colocado tampoco irá bien.

Generalmente, recomiendo usar la resistencia pullup interna, te ahorras una resistencia, y a no ser que se necesite una 'precisión' absoluta es más que suficiente. Para ello, se usa el esquema que te puse primero.

estuve viendo los diagramas que hice cuando lo arme y lo tengo asi (Tengo el esp32 y los sensores en una torre sobre el techo de casa)

* 3.3V
* |
* O  \ 
* \   Interruptor Reed (Pluviómetro)
* O  /
* |
* +----------+--------------> PIN 25 (ESP32)
* |          |
* [ ]        ---
* Resistencia    --- Capacitor
* [ ]        |
* |          |
* --+----------+--------------> GND (Tierra)

Deberia poner el capacitor en paralelo con el reedswitch?

Tambien tuve la siguente configuracion y el ruido que tenia era realmente excesivo, no habia momento que no tuviera falsos disparos

* GND (Tierra)
* |
* O  \ 
* \   Interruptor Reed (Pluviómetro)
* O  /
* |
* +----------+--------------> PIN 25 (ESP32)
* |          |
* [ ]        ---
* Resistencia    --- Capacitor
* [ ]        |
* |          |
* --+----------+--------------> 3.3V

al principio probe sin capacitor y sin resistencia , usando la resistencia de pullup interna y tambien habia ruido.

el sensor esta usando el cable telefonico con el que viene incluido aprox 5metros hsta una caja estanca que esta el ESP32, no pasa cerca de cables electricos, solamente pasa cerca de los cables de TV el cable de alimentacion que es de aprox 3m

Hi,
Adjunto esquematico del circuito para prevenir suidos al cerrar/abrir un swtch. Para que el condensador trabaje debe estar en paralelp al switch, Cuando el contacto cierra descarga el condensador. Al estar el condesador descargado al abrir el contacto el condesador al estar descargado absober los ruidos que se produce al abrir el contacto. Yo uso dos condesadores uno de 5 uf electrolico y uno 1ns. El condesador electrolitico de 5 uf elimina los ruidos de baja frecuencia y el de 1ns elimina los ruidos de alta frecuencia.

Más que descargar el capacitor, lo estás cortocircuitando, lo cual puede llegar a ser peligroso para el pin del circuito integrado o microcontrolador al cuál esté conectado. Lo ideal es colocar una resistencia en serie con el interruptor, para que el capacitor se descargue a través de esta.

El colocar solamente un capacitor en paralelo con el switch es una práctica común que se ve en muchos diagramas, lo cual no quiere decir que esté correcto. Es decir, cuando el pulsador o interruptor se presiona sin esta resistencia, el capacitor, que está cargado a la tensión de alimentación, se descarga instantáneamente a tierra a través de los contactos mecánicos del interruptor.

Una de las consecuencias principales es la degradación de los contactos del interruptor. Es decir, al cortocircuitar el capacitor (al cerrar el switch), la única resistencia presente sería la resistencia equivalente en serie del mismo capacitor, la resistencia de las pistas de la PCB (o del cable en caso de que sea un prototipo) y la resistencia del contacto del propio interruptor. Esta resistencia total es minúscula, lo que provoca un pico transitorio de corriente demasiado alto.

Esta descarga tan rápida en el capacitor es producto de un cambio brusco de la corriente con respecto al tiempo dI/dt y esa tasa de cambio de la corriente con respecto al tiempo tan elevada y rápida puede generar interferencia electromagnética. Este pulso de ruido puede acoplarse capacitiva o inductivamente a pistas o pines adyacentes del microcontrolador o circuito integrado lo cual puede causar un comportamiento errático en el circuito, pudiendo causar por ejemplo lecturas falsas en los pines analógicos.

Por ejemplo, la nota de aplicación AN2519 menciona la necesidad de colocar una resistencia en serie con el interruptor, cabe decir que no sólo aplica para los dispositivos AVR o exclusivamente en el pin de Reset del uC.

Por ejemplo, esta es una simulación del circuito que propusiste. En este caso, la resistencia de Pull-up tiene un valor de 10kOhm y el capacitor un valor de 4.7uF, con un voltaje inicial de 0V (IC=0). Imagina que todos los componentes que se encuentran dentro del rectángulo punteado representan el modelo de un simple interruptor de 2 pines agregando el fenómeno de rebote.

Al simular dicho circuito obtenemos el siguiente resultado


Note como el capacitor se descarga suavemente a través de dicha resistencia de 330 Ohm.

Recuerda que el voltaje de un circuito RC sin fuente está dado por

image

La corriente en la resistencia está dada por:

image

y la corriente en el capacitor está dada por:

image

Donde tau = RC.

En un tiempo t = 0 (el instante de tiempo en el que comienza el periodo de descarga), la corriente en la resistencia y en capacitor estaría dada por:

Asumiendo un voltaje inicial V0 = 3.8V y una resistencia de 330, entonces:
I_R = 3.8/330 = 11.51 mA = -I_C

el cual es el pico de corriente que vemos en la gráfica roja.

Aquí se muestra una vista más cercana del interruptor simulando una serie de pulsos de rebote.

Ahora supongamos que eliminamos dicha resistencia de 330 Ohms, y tomamos sólo en cuenta la resistencia de los contactos del interruptor para que sea de 1 miliOhm, por poner un ejemplo, tal como se muestra a continuación

Al cerrar el interruptor, podrás observar cómo el capacitor se descarga abruptamente, y como consecuencia, se genera un pico de corriente grande.

Si bien los capacitores cerámicos (MLCC) son robustos, el someterlos constantemente a descargas de cortocircuito los expone a un estrés térmico y mecánico, aunque bien es cierto, es muy poco probable que se dañe el capacitor, no se aconseja abusar de las especificaciones de descarga de estos componentes, además de los posibles efectos que pueda inyectarle al pin donde esté conectada esta red.

Los capacitores de cuantos V deberían ser? El de 100 es un cerámico 104 y el otro?

Hi,
El otro capacitor es uno electrolitico.Si mira el esquematico tiene una indicacion positivoa El proposito de descargar el capacitor a zero es para que absoba los ruidos. Si usa una resistencia en serie con el switche entoces estas manteniendo con voltaje al condesador y elimina el proposito del capacitor para eliminar el ruido. Lo ideal seria de 1ufd a 4 ufd. Creo que en la simulacion no desmuestras usando un condesador electrolitico. As la prueba usando el condesador electrolico y el de ceramica.

Si usa una resistencia en serie con el switche entoces estas manteniendo con voltaje al condesador y elimina el proposito del capacitor para eliminar el ruido

Los resultados de la simulación y las recomendaciones del fabricante apuntan a una conclusión diferente a la que mencionas. Quizás sea buena idea repasar los fundamentos de los circuitos de primer orden, así como estudiar el subtema de la constante de tiempo y en cuantas constantes de tiempo se descarga un capacitor.

La resistencia es para permitir que el capacitor tenga un camino seguro de descarga. Disminuyendo así el pico de corriente (inrush current) que se genera al simplemente cortocircuitarlo. Y más tratándose de capacitores electrolíticos (sacrilegio total si colocasen un capacitor de tantalio e intentasen cortocircuitarlo).

La constante de tiempo en un circuito RC está dada por

imagen

Asumiendo un capacitor de 4.7 uF y una resistencia de 330 Ohms, la constante de tiempo es:

imagen

Así, es capacitor se descargará seguramente en aproximadamente 5 constantes de tiempo, es decir, 5tau = 5(1.551 ms) = 7.755 ms

Que se encuentra en el rango de tiempo, del tiempo que tarda el fenómeno de rebote en un interruptor (2 a 20 ms).

Esta diferencia de tiempo (idealmente 0 segundos cuando se cortocircuita un capacitor) a descargar el capacitor en un rango de tiempo de 2 a 20 ms a través de una resistencia, es la diferencia clave para evitar picos de voltaje y corriente excesivamente altos. Además, el pin de entrada de tu microcontrolador/circuito integrado te lo agradecerá.

Además, tú mismo puedes realizar la simulación en LTspice. Si presentas problemas en conocer cómo se modela un capacitor electrolítico, puede descargar esta librería de capacitores proporcionada por Wurth Elektronik, que incluye modelos LTspice de capacitores electrolíticos de aluminio, de polímero de aluminio, MLCC y de película.

AN2519-AVR-Microcontroller-Hardware-Design-Considerations-00002519B.pdf (1,2 MB) - page 8

Example of a resistor in series with the switch to provide a safe discharge path - ST Microelectronics

Hi,
No se pero yo estoy perdido ya que el esquematico que tu senalas en el cuadro rojo es igual al que yo presente..

Use el siguiente diagrama , que mandó @tauro0221 , lo vi parecido al de @belmont1591 pero agregando el condensador de 5uf (yo puse uno de 6,8uf xq no tenía ), también les dejo un par de fotos de cómo lo tengo armado y la lluvia que se viene para la prueba

En el caso del diagrama que presenté, perteneciente a ST Microelectronics. Es la resistencia R29, en este caso en serie con el capacitor, la que hace la diferencia que he estado comentado.

Independientemente de si es necesario una resistencia serie en el pin para evitar reducir 'picos' tal y como propone @belmont1591, después de ver las fotos veo 'cosas':

  • Lio de cables. Mucho lio de cables. Usa una protoboard y clemas para organizar las conexiones.

  • La torre está en alto, no se ve que hay encima de la torre, no será un aerogenerador? Independientemente veo que la estación está en un punto y luego hay una distancia de metros a la caja mal organizada. Ese cable hace de antena y está recibiendo algo.

  • La alimentación no se ve en la caja, con lo que deduzco que tienes un enchufe a casa y llevas un cable largo a la caja para alimentar el circuito. Puede hacer perdidas en ese cable.

Yo intentaría reducir la distancia estación-caja, la pondría justo debajo. Llevaría la tensión AC a la caja, poniendo el alimentador dentro y sobretodo haría una placa organizando componentes, montando condensadores de filtro para todas las señales: anemometro, veleta y pluviometro, mas otros sensores.

Es un proyecto que estoy armando con lo poco que tengo xq estoy lejos de una casa de electrónica pero si

Los cables están pronto a organizarse en una board si todo funciona

En al torre no hay nada, solamente está eso(solamente tiene agarrado un cable de fibra óptica y un respiradero de plástico), el largo de los cables es el que viene con los sensores de una estación ya armada que se quemó La board original

Tema alimentación: no veo seguro llevar 220AC hasta la caja, por el momento tengo puesto un adaptador de 5v a unos 2M.¿puedo poner dentro de la caja un LM2596 conectado a mi batería de 12v que tengo a 2M de la caja?

Hi,
Pregunta como estas alimentando el contacto? Mencionas que usas 3.3 volts? Viendo la fotografias creo que la distancia es muy grande para 3 voltios. Acuerdate que vaz a tener una perdida de voltaje en la resistencia de los cables especialmente cuando usas un voltaje DC.. Si es el caso entonces yo usaria un voltaje de 24 voltiios y para recibir la senal un opto coupler o un un divisor de voltaje usando resistencias. Es una sugerencia.

Use el circuito de @tauro0221 y ahora lo tengo un pullup, conecto el sensor a GND

Tu montaje, así como está, tiene más probabilidades de fallar que de funcionar correctamente, si esperás que funcione para organizarlo, estás dentro de un círculo vicioso.