Pluviómetro para cubeta basculante
Componentes y suministros
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
Herramientas y máquinas necesarias
| ||||
|
Acerca de este proyecto
Se trata de un pluviómetro de cubeta basculante, basado en pluviómetros que utilizan los meteorólogos profesionales. El dispositivo funciona canalizando el agua de lluvia en un balde basculante que se asemeja a un balancín, y cada extremo tiene un balde que contiene aproximadamente 2 ml de agua de lluvia.Cuando un lado se llena, el balde se inclina y el agua de lluvia comienza a acumularse en el balde opuesto. Cada vez que el cubo se inclina, un interruptor de lengüeta se enciende temporalmente y envía una señal a la interrupción del hardware de Arduino. El Arduino rastrea la 'punta' de cada cubo y convierte las 'puntas' en cantidad de lluvia (pulgadas de lluvia), según el volumen del cubo y el área de superficie del depósito de recolección (16,605 pulgadas cuadradas).
La unidad de visualización interior tiene una selección de menú para mostrar los totales de 'hora actual', 'hora anterior', 'día actual' y 'día anterior'.
Para cada propina del cubo, se escribe un evento con fecha estampada en un archivo de tarjeta SD. Este archivo se puede importar posteriormente a Excel para su análisis y creación de gráficos.
Aunque no tengo un video que muestre la "punta del balde" real, este video muestra un medidor que registra el evento de lluvia real.
Paso 1
Imprima todos los componentes enumerados. Usé PETG para todos los componentes, ya que es un material que se adapta bien a la exposición a los rayos UV y a la temperatura para uso en exteriores. Para el filtro superior, asegúrese de apagar todas las carcasas horizontales (superior e inferior) para crear el detalle poroso.
Paso 2
Antes de comenzar a ensamblar la placa de circuito del panel frontal, inserte la pantalla LCD en la placa PY-5 * 10CM (sin soldar) con el pin 1 de la pantalla LCD en la ubicación del orificio C-1 en la placa. Taladre a través de la placa de perforación en las ubicaciones de los cuatro orificios de montaje de la placa LCD. Ahora retire la pantalla LCD para ensamblarla más tarde.
Paso 3
Monte la placa de circuito del panel frontal. Coloque el circuito integrado de registro de desplazamiento 74HC595N, interruptores y resistencias como se muestra. Enrute todos los cables necesarios (consulte el diagrama de cableado) a los puntos de ubicación que se conectarán a la pantalla LCD, así como a una longitud de 6 "que se extenderá para luego conectarse a la segunda placa.
Paso 4
Monte la pantalla LCD en la placa del panel frontal, utilizando los espaciadores impresos para levantar la pantalla LCD y limpiar el IC. Fije con tornillos y tuercas de 3 mm x 15 mm. (Todos los sujetadores están disponibles a través de Fastenal y / o McMaster Carr)
Paso 5
Ensamble la placa de circuito principal insertando Arduino con el pin D12 en la ubicación del orificio R27 en la placa de circuito. Agregue condensadores y resistencias, y coloque todo el cableado en las ubicaciones antes de insertar los módulos SD y RTC. Consulte el esquema de cableado para obtener todos los detalles.
Paso 6
Monte el lector de tarjetas SD en las ubicaciones de los orificios A-3 a B-10. Monte el TinyRTC en las ubicaciones de los orificios C-24 a I-24. Suelde todas las conexiones.
Paso 7
En la caja de control de la unidad interior, taladre orificios en el lugar que mejor se adapte a sus necesidades para los dos cables que irán a la unidad exterior, así como orificios para los cables que provienen de una fuente de alimentación externa o verrugas en la pared. Pase los cables a través del gabinete y suelde en los lugares apropiados. Deslice la placa principal en la caja y fíjela con dos tornillos de 3 mm x 6 mm de largo. Inserte el botón pulsador para el interruptor a través de la cubierta frontal y fije la placa de circuito frontal al panel frontal con tornillos de 3 mm x 6 mm de largo. Nota:Usé una pequeña pieza de latón torneado para el botón del interruptor en lugar de la parte impresa, ya que me gustó más la "sensación".
Paso 8
Fije la cubierta frontal con un tornillo de cabeza plana M3-0,5 x 10 mm de largo
.
Paso 9
Conecte el USB a la PC y cargue el programa RTC para establecer la hora. Después de configurar el reloj, cargue el programa principal. Inserte la tarjeta SD. Pruebe la unidad poniendo en cortocircuito los cables que van al interruptor de lengüeta en la unidad exterior. Los totales de lluvia deben aumentar para cada evento de cortocircuito (contacto cerrado). Verifique que la tarjeta SD esté leyendo la fecha leyendo con un editor de texto como el Bloc de notas o WordPad en una computadora. Debe haber un archivo llamado "Text.txt". El archivo tendrá un sello de fecha para cada evento de 'sugerencia'.
Paso 10
Conecte el interruptor de lengüeta a la subbase. Use ataduras de alambre para mantenerlo en su lugar. Monte un imán en el buck y monte el balde con un trozo corto de tubo de latón de 1/8 "de diámetro (aproximadamente 2" de largo). Tenga en cuenta que antes de ensamblar, ejecute un taladro de 1/8 "a través de los orificios del balde para limpiar. El balde debe inclinarse fácilmente sin fricción. Utilice una lima redonda pequeña en los orificios del balde si es necesario. Agregue una arandela pequeña de 1/8" en el lado más exterior del balde para cerrar ligeramente el espacio. Determine cómo va a montar la unidad exterior. Usé un ángulo de aluminio de 1 ". Fije la base al ángulo o soporte usando pernos hexagonales de 1 / 4-20 instalados de adentro hacia afuera. Fije la subbase a la parte inferior de la unidad exterior con tornillos M3-0.5x 10mm.
Paso 11
Inserte el embudo en el recinto superior. Cortar aprox. 24 piezas de alambre galvanizado de 2 "de longitud de calibre 18. Sujetando un trozo de alambre con unos alicates, caliéntelo con un soplete o un encendedor y presione con cuidado en la parte superior de plástico. Estos cables evitarán que las aves se posen en la unidad. Desea medir la cantidad de lluvia no excremento de pájaro. Fije la parte superior al gabinete principal con (4) tornillos M3-0.5x 6mm. Instale el filtro en la parte superior del embudo. Este filtro mantendrá las hojas fuera y evitará obstrucciones. Recuerde revisar ocasionalmente y limpiar según sea necesario.
Paso 12
Monte la unidad exterior y tienda los cables a la unidad interior. Asegúrese de que la parte superior de la unidad exterior esté nivelada en ambas direcciones.
Paso 13
Encienda la unidad y agregue agua a la unidad exterior para verificar el funcionamiento.
Paso 14 (opcional)
Para verificar la precisión, puede agregar LENTAMENTE una taza de agua y verificar que la unidad mida 0.87 "de lluvia. (Una taza =14,44 pulgadas cúbicas. El área del colector es 16.605" [Precipitación =14.44 pulgadas cúbicas. /16.605"=0.87 "]. Puede ajustar el factor de corrección en el programa principal si su unidad difiere de la mía.
¡¡Felicidades!! Disfrute de poder realizar un seguimiento de sus precipitaciones.
Código
- Código Arduino para establecer la hora en RTC
- Código Arduino del programa principal para pluviómetro
Código Arduino para establecer la hora en RTC Arduino
Cargue este código primero para establecer la hora en RTC. Edite el código con la fecha y hora reales antes de cargarlo en Arduino.#include "Wire.h" #define DS1307_I2C_ADDRESS 0x68 // la dirección I2C de Tiny RTCbyte segundo, minuto, hora, día de la semana, día del mes, mes, año; / / Convertir números decimales normales en decimales codificados en binario decToBcd (byte val) {return ((val / 10 * 16) + (val% 10));} // Convertir números decimales codificados en binario en decimales normalesbyte bcdToDec (byte val) {return ((val / 16 * 10) + (val% 16));} // Función para establecer la hora actual, cambiar el segundo y minuto y hora a la hora correctavoid setDateDs1307 () {segundo =00; minuto =11; hora =12; dayOfWeek =5; dayOfMonth =24; mes =7; año =20; Wire.beginTransmission (DS1307_I2C_ADDRESS); Wire.write (decToBcd (0)); Wire.write (decToBcd (segundo)); // 0 al bit 7 inicia el clockWire.write (decToBcd (minuto)); Wire.write (decToBcd (hora)); // Si desea 12 horas am / pm, debe configurar // bit 6 (también necesita cambiar readDateDs1307) Wire.write (decToBcd (dayOfWeek)); Wire.write (decToBcd (dayOfMonth)); Wire.write (decToBcd (mes)); Wire.write (decToBcd (año)); Wire.endTransmission ();} // Función para obtener la fecha y hora del ds1307 e imprime resultvoid getDateDs1307 () {// Restablecer el registro pointerWire.beginTransmission ( DS1307_I2C_ADDRESS); Wire.write (decToBcd (0)); Wire.endTransmission (); Wire.requestFrom (DS1307_I2C_ADDRESS, 7); segundo =bcdToDec (Wire.read () &0x7f); minuto =bcdToDec (Wire.read () ); hora =bcdToDec (Wire.read () &0x3f); // Necesito cambiar esto si 12 horas am / pmdayOfWeek =bcdToDec (Wire.read ()); dayOfMonth =bcdToDec (Wire.read ()); month =bcdToDec (Wire.read ()); year =bcdToDec (Wire. leer ()); Serial.print (hora, DEC); Serial.print (":"); Serial.print (minuto, DEC); Serial.print (":"); Serial.print (segundo, DEC); Serial.print (""); Serial.print (mes, DEC); Serial.print ("/"); Serial.print (dayOfMonth, DEC); Serial.print ("/"); Serial.print (año, DEC); Serial.print (""); Serial.println (); // Serial.print ("Día de la semana:");} void setup () {Wire.begin (); Serial.begin (19200); setDateDs1307 (); // Establecer la hora actual;} void loop () {delay (2000); getDateDs1307 (); // obtener los datos de la hora de un pequeño RTC}
Código Arduino del programa principal para pluviómetro Arduino
Programa principal para pluviómetro. Asegúrese de instalar todas las bibliotecas asociadas antes de compilar su programa. Consulte el sitio web [https://roboindia.com/tutorials/arduino-3-pin-serial-lcd/] para obtener instrucciones sobre cómo actualizar la biblioteca LiquidCrystal./ * Tipping Bucket Rain Gauge Escrito por Bob Torrence * / # include#include #include #include "RTClib.h" #include // incluye la biblioteca LiquidCrystal (versión especial) ref https://roboindia.com/ tutoriales / arduino-3-pin-serial-lcd /// Definición de LCD y pines para la interfaz.LiquidCrystal_SR lcd (6, 5, 9); // Pin 6 - Habilitación de datos / SER, Pin 5 - Reloj / SCL, Pin 9 -SCKRTC_DS3231 rtc; retroiluminación int =7; // el pin que el LED está conectado al pin 7 (D7) // las constantes no cambiarán. Se utilizan aquí para establecer los números de pin:const byte interruptPin_bucket =3; const byte interruptPin_menu =2; // Las variables cambiarán:volatile int Bucket_Tip_Occurence; volatile int Menu_Select; float Bucket_tip_hour_total =0; float Bucket_tip_current_hour_hour; float Bucket_tip_current_hour_hour;; float Bucket_tip_current_day_total =0; float Bucket_tip_previous_day_total =0; int current_minute; int loop_minute; int current_hour; int loop_hour; int current_day; int loop_day; int tip_counter; float conversion_factor =.00854; // pulgadas de lluvia por punta - calculado midiendo el volumen del balde y el área del colector (16,605 pulgadas cuadradas). // duración (milisegundos) que la luz de fondo permanece encendida después de presionar el botón de selección de menúString print_time (fecha y hora de fecha y hora) {char message [120]; int Year =timestamp.year (); int Month =timestamp.month (); int Day =timestamp.day (); int Hora =marca de tiempo.hora (); int Minuto =marca de tiempo.minuto (); int Second =timestamp.second (); sprintf (mensaje, "% 02d:% 02d:% 02d% 02d /% 02d", hora, minuto, segundo, mes, día); mensaje de retorno;} Archivo myFile; void setup () {lcd.begin (16,2); // Inicializa la interfaz a la pantalla LCD y especifica las dimensiones (ancho y alto) de la pantalla lcd.home (); // Configuración del cursor en casa, es decir, 0,0 rtc.begin (); // iniciar el uso de las variables del reloj en tiempo real pinMode (10, OUTPUT); pinMode (luz de fondo, SALIDA); // Declara el LED como una salida digitalWrite (retroiluminación, HIGH); // enciende la retroiluminación de la pantalla LCD backlightOfftime =millis () + backlightOnDuration; // establece el retardo de tiempo inicial para que la luz de fondo de la pantalla LCD se encienda if (! SD.begin (4)) {lcd.print ("insertar tarjeta SD"); regreso; } // Configura nuestro pin digital como una interrupción para bucket pinMode (interruptPin_bucket, INPUT_PULLUP); attachInterrupt (digitalPinToInterrupt (interruptPin_bucket), cuenta, FALLING); // Configurar nuestro pin digital como una interrupción para bucket pinMode (interruptPin_menu, INPUT_PULLUP); attachInterrupt (digitalPinToInterrupt (interruptPin_menu), menú, RISING); myFile =SD.open ("test.txt", FILE_WRITE); if (myFile) {myFile.println ("Rain Gauge Ready - unidad encendida"); myFile.close (); } DateTime ahora =rtc.now (); minuto_actual =ahora.minuto (); loop_minute =ahora.minuto (); hora_actual =hora.hora (); loop_hour =ahora.hora (); lcd.setCursor (0,0); lcd.print (print_time (ahora)); // Imprime "Arduino" en la pantalla LCD lcd.setCursor (1,1); lcd.print ("Pluviómetro"); } bucle vacío () {Fecha y hora ahora =rtc.now (); minuto_actual =ahora.minuto (); loop_minute =ahora.minuto (); hora_actual =hora.hora (); loop_hour =ahora.hora (); dia_actual =dia_ahora (); loop_day =ahora.día (); // Comenzar el ciclo para determinar el recuento de los totales del día actual while (loop_day - current_day ==0) {// Iniciar el ciclo para determinar el recuento de los totales de las horas actuales while (loop_hour - current_hour ==0) {if (millis ()> backlightOfftime) {digitalWrite (luz de fondo, BAJA); } if (Bucket_Tip_Occurence ==1) {Bucket_Tip_Occurence =0; tip_counter =tip_counter + 1; DateTime ahora =rtc.now (); myFile =SD.open ("test.txt", FILE_WRITE); myFile.print ("Evento"); myFile.print (ahora.año (), DEC); myFile.print ('/'); myFile.print (ahora.mes (), DEC); myFile.print ('/'); myFile.print (ahora.día (), DEC); myFile.print (""); myFile.print (ahora.hora (), DEC); myFile.print (':'); myFile.print (ahora.minuto (), DEC); myFile.print (':'); myFile.print (ahora.segundo (), DEC); myFile.print (""); myFile.print (factor_conversión, 5); myFile.println (); myFile.close (); retraso (200); } else {// Verifica el estado de la hora actual DateTime now =rtc.now (); loop_hour =ahora.hora ();} cambiar (Menu_Select) {caso 1:lcd.clear (); lcd.setCursor (0,0); lcd.print ("Hora actual"); lcd.setCursor (0,1); lcd.print (tip_counter * conversion_factor); retraso (500); descanso; caso 2:lcd.clear (); lcd.setCursor (0,0); lcd.print ("Hora anterior"); lcd.setCursor (0,1); lcd.print (Bucket_tip_previous_hour_total); retraso (500); descanso; caso 3:lcd.clear (); lcd.setCursor (0,0); lcd.print ("Día actual"); lcd.setCursor (0,1); lcd.print (Bucket_tip_current_day_total + tip_counter * conversion_factor); retraso (500); descanso; caso 4:lcd.clear (); lcd.setCursor (0,0); lcd.print ("Día anterior"); lcd.setCursor (0,1); lcd.print (Bucket_tip_previous_day_total); // lcd.print (print_time (ahora)); retraso (500); descanso; }} DateTime ahora =rtc.now (); // Restablecer contadores para el ciclo de una hora siguiente current_hour =now.hour (); loop_day =ahora.día (); loop_hour =ahora.hora (); // Totalizar el total de la hora actual Bucket_tip_previous_hour_total =tip_counter * conversion_factor; Bucket_tip_current_day_total =Bucket_tip_previous_hour_total + Bucket_tip_current_day_total; tip_counter =0; / * Escritura de archivo opcional con solo el total por horas myFile =SD.open ("test.txt", FILE_WRITE); myFile.print ("Resumen por horas"); myFile.print (Bucket_tip_previous_hour_total); myFile.print (ahora.año (), DEC); myFile.print ('/'); myFile.print (ahora.mes (), DEC); myFile.print ('/'); myFile.print (ahora.día (), DEC); myFile.print (""); myFile.print (ahora.hora (), DEC); myFile.print (':'); myFile.print (ahora.minuto (), DEC); myFile.print (':'); myFile.print (ahora.segundo (), DEC); myFile.print (""); myFile.print (Bucket_tip_previous_hour_total); myFile.println (); myFile.close (); retraso (200); * /} // Totalizar el total de la hora actual Bucket_tip_previous_day_total =Bucket_tip_current_day_total; Bucket_tip_current_day_total =0; Bucket_tip_current_hour_total =0; tip_counter =0; / * Escritura de archivo opcional con el total del día anterior solamente myFile =SD.open ("test.txt", FILE_WRITE); myFile.print ("Total del día"); myFile.print (Bucket_tip_previous_day_total); myFile.print (print_time (ahora)); myFile.close (); * /} // iniciar la interrupción desde el depósito reed switchvoid count () {static unsigned long last_interrupt_time_bucket =0; unsigned long interrupt_time_bucket =millis (); // Si las interrupciones llegan más rápido que 300ms, asuma que es un rebote e ignore if (interrupt_time_bucket - last_interrupt_time_bucket> 300) {Bucket_Tip_Occurence =1; } last_interrupt_time_bucket =interrupt_time_bucket;} // iniciar interrupción desdem menú alternar switchvoid menu () {static unsigned long last_interrupt_time_menu =0; unsigned long interrupt_time_menu =millis (); // Si las interrupciones llegan más rápido que 300ms, asuma que es un rebote e ignore if (interrupt_time_menu - last_interrupt_time_menu> 300) {if (digitalRead (retroiluminación) ==LOW) {digitalWrite (backlight, HIGH); // enciende la luz de fondo si estaba previamente apagada} else Menu_Select =Menu_Select + 1; if (Menu_Select> 4) {Menu_Select =1; } backlightOfftime =millis () + backlightOnDuration; Menu_Select =Menu_Select; last_interrupt_time_menu =interrupt_time_menu; }}
Piezas y carcasas personalizadas
STL para impresión 3D Base de unidad exterior. Imprimí con PETG al 30% de relleno STL para imprimir en 3D la cubierta de la unidad exterior. Imprimí con PETG al 30% de relleno STL File for 3D Printing en el embudo de la unidad exterior. Imprimí usando PETG al 30% de relleno. Archivo STL para el filtro de la unidad exterior de impresión 3D. Imprimí usando PETG al 20% de relleno. Esta parte debe imprimirse SIN capas horizontales inferiores o superiores, creando un filtro 'poroso'. Archivo STL para impresión 3D de la subbase a la que se une el balde a través de la varilla de pivote. Imprimí usando PETG con 30% de relleno. Archivo STL para impresión 3D del cubo. Imprimí usando PETG con 30% de relleno. Archivo STL para imprimir el gabinete de la unidad interior. Imprimí con PETG al 30% de relleno. Archivo STL para impresión 3D de la cubierta frontal de la unidad interior. Imprimí con PETG al 30% de relleno. Archivo STL para imprimir espaciadores para mantener la unidad LCD elevada por encima del registro de desplazamiento IC. Imprimí con PETG al 30% de relleno. Modelo Fusion 360 de unidad exterior rain_gauge_assembly ___ small_profile_v15_CFg0dGwM8s.f3d.STP archivo de la unidad exterior rain_gauge_assembly ___ small_profile_v15_jWCS0hjSDq.stepSTEP Modelo Cad de la unidad interior controller_box_v1_fwltgu6D0S.stepFusion 36 Modelo CAD de unidad exterior controller_box_v1_NxtSrPG4Vo.f3zSTL archivo para la impresión 3D del botón pulsador del interruptorEsquemas
Esquema de cableado del proyecto rain_gauge_NtjqXF6QEw.fzzProceso de manufactura
- Manómetro
- Persianas inteligentes
- Reloj Word en italiano
- Medidor de kWh Sigfox
- Muéstrame un medidor de altura digital
- Comprender el calibre de tornillo micrométrico
- Comprender el manómetro
- Comprensión de la galga extensiométrica
- Comprender el calibre Pirani
- Comprender el manómetro de diafragma
- Comprender el manómetro de Bourdon