Una verdadera Estación Meteorológica

Resulta que estoy intentando hacer una estación meteorológica con Arduino, y he revisado muchísimos proyectos similares, sin embargo hasta antes de ver el proyecto de alguién con el pseudónimo CHINCHU en un foro que se llama METEOCLIMATIC, lo único que había encontrado son proyectos cuyo producto final muestra lo que miden uno o más semsores en una pantalla LCD o muestran las lecturas en el monitor serial, como producto final del código...

Lamentablemente eso, pese a que a alguien le podría funcionar para determinados y específicos usos, la verdad dista mucho de lo que hace o el objetivo de una estación meteorológica (de hecho, con el debido respeto, no deberían llamarle a ese proyecto "Estación Meteorológica", porque realmente es una simple lectura de un sensor o varios sensores, pero algo básico que debe tener una estación meteorológica es la captura y registro de históricos de "n" sensores organizados por fecha (Año, mes, día) y hora (minuto y segundo), de la captura de cada variable, las cuales deben ser tomadas exactamente al mismo momento, por ejemplo, la estación debe mostrar las lecturas de todos los sensores presentes a la misma hora (coincidiendo minutos y segundos) y a intervalos de tiempo exactos pre-programados (y hora real).

Si una estación meteorológica no hace eso como mínimo (no es una estación meteorológica), es simplemente algo que mide y muestra un valor de un sensor "x" en tiempo real.

Dicho esto, me resta decir que soy demaciado nuevo en Arduino y para ser honesto lo único que he logrado hacer es tener las mediciones de los sensores en tiempo real y sacarlos por el monitor serial (lo mismo que otros han osado llamar una "estación meteorológica" pero yo no soy tan atrevido aparte de que eso no me sirve, he adelantado en comprar todos los accesorios que necesito para hacer mi proyecto (memoria SD y el reloj, lo más importante que me hacía falta), aparte de otros que ya tengo y/o he adaptado para el mismo fin.

Adicionalmente he visto que muchos tienen problemas con algunos sensores, o medición de variables como la radiación solar, y la presipitación (cuantificación de lluvia), debido a que no hay sensores Arduino que midan esto. Sin embargo son temas que yo he logrado resolver a un costo de menos de US$20, pero mi problema es el desarrollo del código.

En fín la pregunta o mi necesidad:

  1. Necesito que los datos que midan los sesores se registren y se almacenen en una SD cada 30 minutos exactos y de acuerdo a la hora real, pero adicionalmente debe respetarse la lógica de cada variable climática, y para esto voy a describir los detalles específicos a tomar en cuenta en cada variable, voy a describir solamente las 4 variables que a mi me interesa medir con la estación que quiero construir:

1.a. Variable precipitación: esta variable tiene la particularidad que debe SUMAR todos los datos desde el minuto cero segundo cero hasta el minuto 30 con cero segundos, almacenar esa suma en la SD, y comenzar de nuevo a sumar otra vez desde cero, pero ahora para registrar el dato siguiente partiendo del minuto 30 con un segundo y terminar en la hora 1 con cero minutos y cero segundos, y así sucecivamente...

1.b. Variable temperatura: esta variable tiene la particularidad que debe PROMEDIAR los valores que mida el sensor comenzando en el minuto cero segundo cero hasta el minuto 30 con cero segundos, almacenar ese promedio en la SD, y CONTINUAR promediando, pero ahora para registrar el dato siguiente partiendo del minuto 30 con un segundo y terminar en la hora 1 con cero minutos y cero segundos, y así sucecivamente... Alguien podría preguntar, bueno ese promedio podría realizarse cada minuto o cada segundo, la respuesta es que no me interesa tan específico (cada segundo), que sea cada minuto estaría perfecto para mí.

1 c. Variable radiación solar: aplica exactamente el mismo principio de la variable temperatura, es decir, el código sería el mismo...

1.d. Variable humedad del suelo: esta variable creo yo que es la más sencilla, ya que únicamente debe ir al minuto cero segundo cero tomar la lectura, registrarla en la SD y si quiere reposar hasta que llegue el minuto 30 minuto cero segundo cero, para ir tomar el dato registrarlo en SD y volver a reposar hasta que llegue la hora 1 minuto cero segundo cero, así sucesivamente...

Esas son las 4 variables que me interesan de momento, pero lamentablemente no tengo ni idea como hacer ninguno de los códigos, así que la ayuda específica que les pido a todos es la siguiente:

  1. Primero Muchas gracias de verdad por haber llegado hasta aquí leyendo este "monton" de texto.
  2. Con lo poquito que he aprendido en Arduino fracasando en mi intento por programar lo indicado, estoy seguro que con lo que conté cada uno de los expertos que hay aquí podrán haber pensado "Oh! esto que yo programé le podría funcionar para lo que necesita hacer con el sensor "x", ya que aunque usted lo programó para "y" fin, estoy seguro que muchos son el mismo principio de programación, a esos le pido el favor de que me compartan esea fracción de código y me indiquen (mira creo que esto te sirve para que tal sensor haga tal parte del requerimiento..., o para la base de organización de la información de los sensores en fecha (año, mes, día, hora, minuto, segundo). O cualquier cosa que ustedes vean que necesito y que ya tengan el código generado, se los gradeceré mucho.
  3. Creo que de esta forma cada uno me podría aportar un pedacito de mi Frankenstein...

Les agradezco mucho la ayuda que me puedan dar... ya he revisado mucho y me desmotivé cuando vi que la solución es indefectiblemente a través del uso de librerías (lo cual ni siquiera comprendo como realmente funciona), según yo iba a generar todo esto con las herramientas básicas (perdón porque seguro para ustedes una librería es una herramienta básica,), pero no para mi y ya me di cuenta de que no voy a ser capaz de desarrollar este código si ayuda y MUCHA!, y pues lo que intento hacer es realmente complejo para mi limitado conocimiento actual...

La estación de CHINCHU hasta se comunica con otras estaciones que están a 300 metros vía WIFI, yo en eso todavía no me interesa meterme, estoy seguro me interesaré, pero con solo que me almacene datos en una memoria SD organizada en (Año, mes, día, hora, minuto, segundo) es suficiente para mi por el momento, pero se que solo es es ya mucho trabajo...

Muchas gracias por su tiempo...

Bueno si tienes los sensores, el código no es problema. Lo iremos armando. Tiene sus peculiaridades pero no es mas que un código con características especiales como las que has señalado Asi que comienza indicando que sensores vas a usar. Agrega los links (usando tags), las características relevantes de cada sensor, como tensión de salida y rangos de medicion. Supongamos: precipitación supongo que en mmH2O o mmA (milimetros de agua). Que señal entrega el sensor que lo mide?

Temperatura ya sabemos, indique que sensor usarás.

Y asi con todos.

Y luego comenzamos con el programa.

pluviómetro: tal como lo describes, tus dos cables son similares a estar conectados a un pulsador asi que usa todo lo que sabes para un pulsador. Agrega una resistencia pull down (10k a gnd) y podras contar pulsos. Ahora debes hacer pruebas de cuanto tiempo permanece activo el sensor magntico cuando cae 0.1mm. Si tienes tiempo suficiente sigues como te comenté como un pulsador. Si no, abrá que conectarlo a una interrupción para no perder accionamientos pero no creo que haga falta.

Lo demás esta mas o menos controlado, son elementos conocidos.

Por lo visto tienes muy buen criterio electrico pero estas pobre en programación ya que no sabes por donde comenzar.

Aqui esta una pagina de un forista que esta publicando clases sobre Arduino. Puedes comenzar por allí. En el apartado Documentacion hay muchos tutoriales para todos los niveles. Luego te recomiendo un libro.

Todo esto no te lo sugiero para NO brindarte ayuda sino para que tengas herramientas para luego poder manejarte por tu cuenta con mayor solvencia. Como has descripto todo, creo que tienes capacidad para aprender con velocidad y ya verás que no es tan dificil. Luego te paso algunos libros en pdf que serán de ayuda tambien. Los lees y mientras seguimos avanzando en el proyecto.

El link parece estar bien pero lo vuelvo a poner.

Enlace practicas con Arduino

Que te dije.. es muy recomendable. Por eso quería abrirte los ojos para que tuvieras otra mirada y le pierdas el miedo si se quiere a la programación. Paso a paso, haces tus experiencias y te animas. Bien, ahora que tienes otra "visión", dime por cual quieres comenzar. Tu elije y yo te voy guiando/ayudando/sugiriendo al igual que los demás.

Pluviómetro: Supongo que es un reed switch (interruptor que cierra cada vez que un campo magnetico se aproxima lo suficiente). Entonces lo vemos como un pulsador. Circuito |500x428

Mientras te voy contando. Esa configuración la llamamos con resistencia pull down (porque tira para abajo). El pulsador o en tu caso el pluviómetro en reposo entregará al arduino un 0 digital. Cuando el pulsador (figura) o tu pluviómetro se balancee, el iman se acerca y cierra el reed switch y tienes un 1 digital o HIGH o 5V en esa entrada digital.

la forma de leerlo es usando la instrucción digitalRead(pinArduinoDondeConecteElPluviómetro) Que en el caso del dibujo es el 2.

Ese pin debe configurarse previamente como entrada digital ya que los pines de entrada/salida del arduino puede trabajar en diferentes modos de trabajo. Entrada o salida para comenzar.

Entonces que tenemos Definir el pin primero. Yo aprendí de leer grandes maestros que vienen de la época en que no sobraba nada en un micro entonces uso

const byte pinPluviometro = 2;

byte es un de los tipos de variable mas chicos va de 0 a 255 que me sobra para definir pines de un arduno incluso un MEGA o un DUE que tienen 54 I/O (entradas/salidas) const es una directiva que le dice al compilador que es una constante. Es decir no usa RAM y eso tambien es trabajar optimamente y pensando en cuidar la poca RAM que tengo, no lo digo para este programa pero los programas crecen y luego no tenemos mas RAM y no sabemos que hacer

Bien, ya definí el pin Ahora defino una variable que va a leer el estado 0 o 1 del pluviometro (switch). Como es 0 o 1, que mejor que una variable bool. Muchos usan int pero es un despropósito una vez más. bool alcanza y sobra.

bool Pluviometro; no le asigno valor porque es una variable que siempre leera el estado del pin asi que no hace falta inicializarla.

Ahora debo definir el tipo de pin que requiero y como es una entrada la forma de hacerlo es con pinMode(pin, TIPO); donde TIPO es INPUT para entradas y OUTPUT para salidas.

en nuestro caso

pinMode(pinPluviometro, INPUT);

esto se hace el en setup()

Acto seguido podemos leer en loop() la parte del programa que se ejecuta permanentemente el valor del Pluviometro con digitalRead.

Voy a poner todo en un sketch simple y vemos que me falta explicarte.

const byte pinPluviometro           = 2;        // Definición del pin donde conectarás el Pluviómetro
bool Pluviometro;                               // Estado actual del switch del pluviometro
bool PluviometroAnt  = LOW;                            // Estado anterior del switch del pluviometro
unsigned int cuentaPrecipitacion    = 0;        // Contador de precipitaciones
unsigned int cuentaPrecipitacionAnt = 0;        // Valor anterior del contador de precipitaciones 
                                                // solo para presentar cuando haya cambios
float Precipitacion;                            // variable que lleva los mm de agua caídos

void setup() {

  Serial.begin(9600);
  pinMode(pinPluviometro, INPUT);        

}

void loop() {

    Pluviometro = digitalRead(pinPluviometro);    // Leo el estado del pluviometro

    if (Pluviometro == HIGH && PluviometroAnt == LOW){ // solo voy a considera un cambio 0->1 en el Pluviometro
      cuentaPrecipitacion += 1;
    }      

    PluviometroAnt = Pluviometro;         // esto actualiza el estado anterior de Pluviometro
    if (cuentaPrecipitacion != cuentaPrecipitacionAnt) {
      Precipitacion = cuentaPrecipitacion * 0.1;    // cada pulso es 0.1mm 
      Serial.println("Lluvia caida = ");
      Serial.print(Precipitacion);
      Serial.print(" mm");
      cuentaPrecipitacionAnt = cuentaPrecipitacion;
    }
}

En setup() he definido Serial.bgin(9600); o sea el puerto serie (USB) del arduino enviará datos a 9600 bits por segundo En el loop()

Leo el estado del switch con Pluviometro = digitalRead(pinPluviometro);

Acá he tomado una decisión que luego veremos si se comparta bien. Yo creo que no habrán rebotes en el reed switch de modo que con ver la transición 0 a 1 en la entrada del arduino es suficiente para contar. supongo tambien que es algo lento y que la velocidad del arduino me asegura que hará muchas pasadas como para leer su estado sin perder cambios. Solo me interesa el cambio 0 a 1, eso lo logro con dos variables. La variable que me dice que valor tiene el switch ahora y la que me dice que valor tuvo antes de haberla leído. Esto me obliga a que PluviometroAnt debe inicializarse a 0, aunque creo que siempre las variables arrancan en 0 desde el compilador y el arranque. Cuando esto se da. cuando el switch pasa de 0 a 1, porque se desbalanceó el pluviómetro por el agua caida, se incrementa

cuentaPrecipitacion += 1;

Esto es lo mismo que escribir cuentaPrecipitacion = cuentaPrecipitacion + 1; Exactamente lo mismo pero mas facil de escribirlo. Cualquiera de las formas es válida. Incremento en 1 el contador que yo llamé cuentaPrecipitación;

Otra forma de hacer lo mismo es asi

cuentaPrecipitacion++;

Como ya terminé el if que solo espera el cambio 0 a 1 para incrementar cuentaPrecipitacion, ahora debo preparar cuentaPrecipitacionAnt con el valor que acaba de leer. Ya que en esta caso no es LOW sino HIGH porque si se ejecutó el if fue porque el switch esta ahora a +5V. Al recordar este estado en la proxima pasada si el switch sigue estando en 1 no va a incrmentar el contador.

Lo que sigue es la presentancion del resultado y de nuevo uso una técnica parecida pero ahora con el contador. Cada vez que el cuentaPrecipitacion cambie voy a presentar algo en el Monitor Serie usando Serial.print(XXX)

Eso lo logro preguntado si el contador tiene un valor distinto del que tuvo en la pasada anterior. Mismo que con el switch. Si es distinto presento e imprimo por puerto serie. Ahora calculo la precipitación que definí como float porque cada cuenta del switch (pluviómetro) es 0.1mm. 1 cuenta 0.1mm 10 cuentas 1.0 mm 123 cuentas 12.3 mm de agua caídas

A ver que te parece

Respuestas:

  1. el ! es un negador y como tal niega el igual. Entonces NO IGUAL es distinto. la sentencias simplemente dice. Si el contador tiene un valor distinto del anterior entoces presenta la nueva información. Si no lo pusieras tendrías repetición en cada paso del programa de muchas impresiones similares. Supongamos que no esta lloviendo o llueve y se detiene. Entonces solo verás cambios y no una continua presentación que se come justamente los cambios. A esta forma de presentar le puedes agregar la hora entonces la cosa empieza a tomar color.

  2. cuentaPrecipitacionAnt = cuentaPrecipitacion; Es la sentencia que ajsuta el ultimo valor del contador para que cuando consultemos el if del paso 6. solo se cumpla cuando sean diferentes. Y cuando son diferentes solo cuando el pluviómetro se acerca al reed swich y nos da un cambio 0 a 1. se entiende?

  3. Suma cada 30 min. Eso ya lo habias comentado al comienzo de tu post#1 No hay problema, Lo que no me queda claro es como mides los mm de agua caídos. El pluviómetro mide cuentas y cada cuenta es 0.1mm pero se establece un tiempo O tomo todas las cuentas en 30 minutos y te doy el resultado de esos 30 min de lluvia caida?

No hay problema Entonces te voy a explicar algo que facilita mucho la presentación.

Serial.print("cartel ");

cuando tienes que presentar Etiquetas y sus variables a mi personalmente me gusta mucho usar este elemento que te permite encapsular todo lo que quieres.

Se llama sprintf y puedes combinar Etiquetas y variables usando ciertos comandos especiales para esta instrucción. En realidad son los mismos que usa el C básico en su función printf (que no esta disponible en Arduino). La extensión sprinft termina convirtiendo etiquetas y variables en una cadena de caracteres que Serial.print puede enviar por elpuerto serie.

Veamos un ejemplo primero debes definir un array o vector de caracteres cuya longitud cubra tus necesidades. Supongamos que 30 caracteres sea justamente lo que necesitamos.

char buffer[30]; Esto defnie a buffer con un espacio de memoria del tipo char (caracter) desde 0 a la posicion 29. Esto es asi. Nunca comienza en 1. Siempre en 0. Todos los vectores y matrices comienzas en 0.

La función sprinf(buffer, "Lluvia caida = %d mm", dato); Este es un ejemplo. Esta función hace que el valor que tiene dato, que suponemos es 13 se ubique donde encuentra el caracter %d. segun el tipo de variable, tenemos diferentes letras especiales

d para enteros l para long c para caracteres s para strings o cadenas de caracteres f para float pero esta restringido en arduino, porque la librería float o imprimir float consume mucho espacio de memoria del arduino. x para hexadecimales hay mas opciones pero estas son suficientes por ahora.

Tambien se puede usar un número entre % y el caracter especial d para reservar espacios. Eso hace que si quieres imprimer enteros de 4 digitos uses %4d, y todos los valores se veran encolumnados.

Bien, no se si me he explicado parcialmente bien. Digo esto porque sprintf tiene muchas formas de uso. En nuestro caso queremos empaquetar la forma de presentar la información y de este modo tenemos todo bien organizado sin tener que escribir numerosas líneas para conseguir lo mismo con

Supongamos que variable1,2, y 3 son enteras

Serial.print("Etiqueta1");
Serial.print(variable1);
Serial.print("Etiqueta2");
Serial.print(variable2);
Serial.print("Etiqueta3");
Serial.print(variable3);

Esto se reemplaza por

sprinf(buffer, "Etiqueta1 = %d Etiqueta2 = %d Etiqueta3 = %d", variable1, variable2, variable3);
Serial.println(buffer);

Aca esa la corrección y ya lo toma cada 30 min
Te aclaro algo, yo ayudo pero no voy a hacer todo el trabajo, asi que ponte a colaborar.

const byte pinPluviometro 			= 2;		// Definición del pin donde conectarás el Pluviómetro
bool Pluviometro;								// Estado actual del switch del pluviometro
bool PluviometroAnt  = LOW;							// Estado anterior del switch del pluviometro
unsigned int cuentaPrecipitacion 	= 0;		// Contador de precipitaciones
unsigned int cuentaPrecipitacionAnt = 0;		// Valor anterior del contador de precipitaciones 
												// solo para presentar cuando haya cambios
float Precipitacion;							// variable que lleva los mm de agua caídos
unsigned long TreintaMin = 30*60*1000;
unsigned long t_LoggeoDatos;

void setup() {

  Serial.begin(9600);
  pinMode(pinPluviometro, INPUT);        
  t_LoggeoDatos = millis();                     // esta es la inicialización en tiempo para los 30 min. Presición 1 mseg
}

void loop() {

    Pluviometro = digitalRead(pinPluviometro);	// Leo el estado del pluviometro

    if (Pluviometro == HIGH && PluviometroAnt == LOW){ // solo voy a considera un cambio 0->1 en el Pluviometro
    	cuentaPrecipitacion += 1;
    }      

    if (millis() - t_LoggeoDatos > TreintaMin) {
    	Precipitacion = cuentaPrecipitacion * 0.1;    // cada pulso es 0.1mm 
    	Serial.println("Lluvia caida = ");
    	Serial.print(Precipitacion);
    	Serial.print(" mm");
        t_LoggeoDatos
    }
}

millis() es una función que devuelve un número en mseg que se incrementa desde el arranque del Arduino.
Antes he creado dos variables una que lucirá como rara
t_LoggeoDatos esto lo aprendí de las librerías siempre le asignan un t_ al nombre indicando que es una variable de tiempo.
TreintaMin debería ser mejor asi

#define TREINTAMIN 30601000

Te dejo para que modifiques el sketch para que use TREINTAMIN en lugar de TreintaMin variable que consume RAM al divino … sin palabras.

Cada vez que millis() - t_LoggeoDatos sea mayor en 1 mseg a TREINTAMIN, se ejecuta la parte de código que calcula la precipitación caída en esos 30 min, lo presenta y vuelve a setear t_LoggeoDatos con el valor de millis() para los siguientes 30 min.
Y asi por siempre.

surbyte: El link parece estar bien pero lo vuelvo a poner.

Enlace practicas con Arduino

Parece que lo has puesto con la etiqueta de email anterior mente.

Hola jvasquez05

Me gusta mucho tu proyecto, yo tengo pensado hacer algo un poco mas complejo pero por ahora tendrá que esperar un poco mas. Por lo que he leído veo que tienes mucha voluntad, y eso es de admirarse, no desesperes tampoco te subestimes veras que siendo constante junto con tu voluntad lo lograras.

Ya estas en buenas manos con surbyte pero yo comentare cuando tenga algo que aportar saludos, cierro mi comentario con algo que leí hace un par de días:

"Hay una fuerza motriz más poderosa que el vapor, la electricidad y la energía atómica: la voluntad" Albert Einstein

1) Presentar información cada 1 mseg es un tontería desde mi punto de vista. Yo te puse una condición para que el sistema muestra datos solo cuando hay una modificación de la lectura en el pluviómetro, y cada 30 minutos te arroja el resultado que esperas. Puedes hacer lo que gustes, que te presente cada 1seg o con el intervalo que desees, eso no alterará la suma que a los 30 min simpre será correcta. En tu código ya veo cambios que no me gustan. Has eliminado algo importante que renueva cada 30 minutos a t_LoggeoDatos con el valor de millis(). Mira mi código y reestablece esa línea.

No te lo voy a resolver para que tu aprendas del error que has cometido sin querer.

2) tabla de variables o estructura? En C se llaman estructuras. Mira este link sobre estructuras Busca Arduino structures o estructuras y encontrás mucha mas info.

3) Idem a 2 Mucha info pero luego te busco algo y lo posteo acá.

Exacto.. ese era el error, pero te dejo que te rompieras la cabeza porque a veces resulta estar delante nuestro y un dice: "Comooooo si son iguales y has comprobado que no lo eran". Ojo, a mi me ocurre y muy seguido.

t_LoggeoDatos; no hace nada en cambio t_LoggeoDatos= millis(); le permite ajustarse para el proximo ciclo de 30 min. Si quisieras ver datos cada 1 min se puede modificar para que lo haga

EL RTC que mencionas es poco preciso. Se ha dicho en este foro que es mejor usar el DS3231 que es mucho mas preciso que el 1307 por tener un crisal compensado en temperatura. Todo lo que has comentado del RTC se aplica a este que te menciono.

Hola

yo siempre acomodo la asignación justo después de la condición, así no se te olvida ponerla:

if ( millis() - lastMillis > lap){
lastMillis = millis();
.
.
.
Código
.
.
.
}

como vez todo lo que sigue es el código que quieres que se ejecute cada cierto tiempo, cuando se cumple la condición.

Respecto al RTC el 1307 y el 3231 son compatibles, el 3231 es mas preciso ya que tiene un sensor de temperatura que ajusta la resonancia del cristal, un sensor de temperatura que también puedes leer y agregarlo a tus datos. Lo que quiere decir que puedes continuar desarrollando el código usando el tiempo del 1307 hasta que tengas el 3231.

El punto 1c:

En treinta minutos hay 1,800,000 milisegundos.

Google tiene un conversor de unidades muy amplio en el buscador, solo que debes poner las unidades en ingles por ejemplo "30 minutes to milliseconds" = 1800000; de modo que 30*60*1000 es la respuesta correcta, por ahí debe haber algo que no se ha planteado.

Pensando lo bien, no deberías de poner un numero tan grande, por ahora es mas cómodo que uses un lapso de 30 segundos máximo para que hagas las pruebas y depuración de problemas.

Ya que tengas todo funcionando correctamente y que los datos aparezcan cada 30 segundos (30000 millisegundos) cambias el lapso a 30 minutos o lo que quieras, pero ya que tengas todos los procedimientos funcionando correctamente.

Esto aparece en la primera pagina del datasheet.

– Write/Erase Cycles: 10,000 Flash/100,000 EEPROM

http://www.atmel.com/Images/doc8161.pdf

Dice que la memoria flash aguanta hasta 10,000 programadas.

si reporgramas tu arduino unas 27 veces por día durante 365 días, estas cerca de dañarlo según la hoja de datos.

ehrja:
Esto aparece en la primera pagina del datasheet.
http://www.atmel.com/Images/doc8161.pdf

Dice que la memoria flash aguanta hasta 10,000 programadas.

si reporgramas tu arduino unas 27 veces por día durante 365 días, estas cerca de dañarlo según la hoja de datos.

He seguido el proyecto para ver que posibilidaes tengo de implementarlo en un Arduino Due. Respecto a ese comentario: para el SAM3X son 30,000@25C, eso equivale a unas 82 por día, durante un año XD, no creo llegar a tantas :art:

Pag 1434: http://www.atmel.com/Images/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf

Bueno, me llamaste y vine a ayudar. No se que le hiciste al código, solo tenias que ponerle a t_LoggeoDatos = millis();

Aca te pongo el código

const byte pinPluviometro= 2;       // Definición del pin donde conectarás el Pluviómetro
bool Pluviometro;           // Estado actual del switch del pluviometro
bool PluviometroAnt  = LOW;        // Estado anterior del switch del pluviometro
unsigned int cuentaPrecipitacion= 0;    // Contador de precipitaciones
unsigned int cuentaPrecipitacionAnt=0;  // Valor anterior del contador de precipitaciones 
                    // solo para presentar cuando haya cambios
float Precipitacion;            // variable que lleva los mm de agua caídos
unsigned long TREINTAMIN = 30*60*1000;
unsigned long t_LoggeoDatos;

void setup() {

  Serial.begin(9600);
  pinMode(pinPluviometro, INPUT);
  t_LoggeoDatos= millis();             // Esta es la iniciacion en tiempo para los 30 min. Presicion 1 mseg.  

}

void loop() {

    Pluviometro = digitalRead(pinPluviometro);    // Leo el estado del pluviometro

    if (Pluviometro == HIGH && PluviometroAnt == LOW){ // solo voy a considera un cambio 0->1 en el Pluviometro.
      cuentaPrecipitacion += 1;
    }      
    PluviometroAnt = Pluviometro;         // esto actualiza el estado anterior de Pluviometro
     
    if (cuentaPrecipitacion != cuentaPrecipitacionAnt) {
                 
         Precipitacion = cuentaPrecipitacion * 1.0;// solo para dejar válido el if.
    
        if (millis()-t_LoggeoDatos > TREINTAMIN){   //Cada vez que millis() - t_LoggeoDatos sea mayor en 1 mseg a TREINTAMIN, se ejecuta la parte de código que calcula la precipitación caída en esos 30 min. 
           
            t_LoggeoDatos = millis();     //y vuelve a setear t_LoggeoDatos con el valor de millis() para los siguientes 30 min. Y asi por siempre.
            Precipitacion = Precipitacion * 0.4257;// Ejecutar el cálculo de la caída de precipitacion..
             
            Serial.print("mm = "); //lo presenta en el monitor serial.
          Serial.print(Precipitacion);
          Serial.println(" mm");
            
            cuentaPrecipitacionAnt = cuentaPrecipitacion;
               
        }
    }
}

Una pregunta:

¿Tu circuito si tiene una resistencia pull up?

pull down la linea if (Pluviometro == HIGH && PluviometroAnt == LOW){

te asegura que normalmente estamos en LOW y cuando presiono el pulsador paso a HIGH

Veo que estas activo, asi que a responder y mejorar el códig
Agrega esto al setup

const byte pinPluviometro= 2;		// Definición del pin donde conectarás el Pluviómetro
bool Pluviometro;			// Estado actual del switch del pluviometro
bool PluviometroAnt  = LOW;		// Estado anterior del switch del pluviometro
unsigned int cuentaPrecipitacion= 0;	// Contador de precipitaciones
unsigned int cuentaPrecipitacionAnt=0;	// Valor anterior del contador de precipitaciones 
					// solo para presentar cuando haya cambios
float Precipitacion = 0.0;			// variable que lleva los mm de agua caídos
unsigned long TREINTAMIN = 30*60*1000;
unsigned long t_LoggeoDatos;

void setup() {

  Serial.begin(9600);
  pinMode(pinPluviometro, INPUT);
  t_LoggeoDatos= millis();             // Esta es la iniciacion en tiempo para los 30 min. Presicion 1 mseg.  
  Serial.println("Estacion Meteorologica v0.1");
  muestroLluviaCaida();
}

void loop() {
    
    Pluviometro = digitalRead(pinPluviometro);	// Leo el estado del pluviometro
 
    if (Pluviometro == HIGH && PluviometroAnt == LOW){ // solo voy a considera un cambio 0->1 en el Pluviometro.
    	cuentaPrecipitacion += 1;
    }      
    PluviometroAnt = Pluviometro;			// esto actualiza el estado anterior de Pluviometro
     
    if (cuentaPrecipitacion != cuentaPrecipitacionAnt) {
              	
       	Precipitacion = cuentaPrecipitacion * 0.4257;// solo para dejar válido el if.
       	muestroLluviaCaida();
    
	    if (millis()-t_LoggeoDatos > TREINTAMIN){   //Cada vez que millis() - t_LoggeoDatos sea mayor en 1 mseg a TREINTAMIN, se ejecuta la parte de código que calcula la precipitación caída en esos 30 min. 
	       
	        t_LoggeoDatos = millis();    	//y vuelve a setear t_LoggeoDatos con el valor de millis() para los siguientes 30 min. Y asi por siempre.
	        // algo tendras que hacer aca ademas de cambiar de ciclo
	        	           
	    }
	}
}

void muestroLluviaCaida() {
	Serial.print("Lluvia caida = "); //lo presenta en el monitor serial.
	Serial.print(Precipitacion);
	Serial.println(" mm");
}