Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Botella de agua con tecnología Arduino

Componentes y suministros

SparkFun Arduino Pro Mini 328 - 5V / 16MHz
× 1
Sensor ultrasónico impermeable
× 1
Reloj en tiempo real (RTC)
× 1
SparkFun Pantalla de 7 segmentos de 4 dígitos de cátodo común
× 1
Buzzer
× 1
Interruptor de botón SparkFun de 12 mm
× 1
Transistor de uso general NPN
× 1
Batería de iones de litio de 1000 mAh
× 1
Cargador de batería de iones de litio USB Adafruit
× 1
Resistencia de 221 ohmios
× 8
Resistencia 1k ohm
× 4
Resistencia de 4,75 k ohmios
× 2

Herramientas y máquinas necesarias

Soldador (genérico)
Pistola de pegamento caliente (genérica)

Aplicaciones y servicios en línea

Arduino IDE

Acerca de este proyecto

Introducción:

Beber suficiente agua es muy importante para nuestra salud. Beber más agua puede dar lugar a una piel más clara, una mejor salud en general, una mayor productividad y función cerebral, un aumento de los niveles de energía e incluso la pérdida de peso.

En nuestras vidas ocupadas, es muy difícil recordar beber suficiente agua. Y la mayoría de las veces nos olvidamos de beber suficiente agua, ya sea que estemos en el hogar, la oficina o en movimiento. Alrededor del 75% de los estadounidenses están crónicamente deshidratados todo el tiempo.

Por lo tanto, para desarrollar un hábito saludable de beber agua, es importante realizar un seguimiento de su consumo de agua todos los días.

Para rastrear mi consumo de agua, hice mi botella de agua inteligente usando Arduino. Puede:

1. Realice un seguimiento de mi ingesta diaria de agua

2. Realice un seguimiento de mi ingesta de agua promedio semanal

3. Recuérdame tomar agua

4. Realice un seguimiento del tiempo de la última ingesta

5. Ejecute más de un mes con una sola carga.

Realización del módulo RTC

Para registrar o rastrear la información de la ingesta de agua, se requiere que se almacene la información de fecha y hora actual junto con los datos acumulados. Se puede utilizar un chip de reloj en tiempo real (RTC) como DS1307 con una batería de respaldo adecuada para proporcionar la información requerida. El proceso de programación del chip RTC (en software) también es muy simple y es compatible con la mayoría de los entornos de programación.

Aquí está el diseño de un módulo RTC compacto, basado en el popular RTC IC DS1307, para sus proyectos diarios de microcontroladores. El reloj en tiempo real (RTC) serie DS1307 es un reloj / calendario decimal codificado en binario completo (BCD) de baja potencia más 56 bytes de SRAM NV. La dirección y los datos se transfieren en serie a través de un bus bidireccional I2C. El reloj / calendario con formato de 24 horas / 12 horas proporciona información sobre segundos, minutos, horas, día, fecha, mes y año, incluidas las correcciones para los años bisiestos.

Hagamos el módulo de reloj en tiempo real de acuerdo con el esquema adjunto. DS1307 RTC requiere un cristal externo para funcionar correctamente. Se requieren dos resistencias pull-up para el pin SCL y SDA del IC. El valor de la resistencia puede estar entre 2k y 10k. Usé 4.7k. Durante la soldadura, traté de mantener el módulo lo más pequeño posible porque el espacio es limitado para mi circuito. Puede usar DS3231 en lugar de DS1307 y el IC tiene un oscilador de cristal interno. Por lo tanto, no es necesario que agregue ningún cristal externo. También puede comprar un pequeño módulo RTC listo para usar si no le gusta hacerlo propio. Como el sistema completo funcionará con batería, por esa razón conecté el pin VBAT del RTC a tierra sin usar una celda de botón.

Pines importantes de DS1307:

  • Pin de 5 V :Cuando este pin está alto, entonces el ds1307 envía los datos, y cuando está bajo, se ejecuta en la celda del botón de respaldo.
  • GND :Este es el pin de tierra del módulo. Tanto la tierra de la batería como la fuente de alimentación están unidas.
  • SCL :Es el pin de reloj I2C, que se comunica con el microcontrolador. Debe conectarse con el pin Arduino SCL.
  • SDA :Es el pin de datos I2C, que se comunica con el microcontrolador. Debe conectarse con el pin Arduino SDA.
  • VBAT :Entrada de batería para cualquier celda de litio estándar de 3 V u otra fuente de energía. Debe estar conectado a tierra si no se usa.

Hacer un tablero de exhibición de siete segmentos

Para el módulo de visualización aquí utilicé un módulo de cátodo común compacto y autónomo que contiene cuatro pantallas numéricas LED de 7 segmentos que sirven para mostrar datos numéricos con algún carácter simple.

Cada segmento del módulo de visualización está multiplexado, lo que significa que comparte los mismos puntos de conexión de ánodo. Y cada uno de los cuatro dígitos del módulo tiene su propio punto de conexión de cátodo común. Esto permite activar o desactivar cada dígito de forma independiente. Además, esta técnica de multiplexación convierte la enorme cantidad de pines de microcontrolador necesarios para controlar una pantalla en solo once o doce (en lugar de treinta y dos).

Los segmentos LED de la pantalla requieren resistencias de limitación de corriente cuando se alimentan desde un pin lógico de 5 V. El valor de la resistencia suele estar entre 330 y 470 ohmios para 5 V. Para el funcionamiento con batería de iones de litio, puede ser 220 ohmios. Y, se recomiendan transistores de controlador para proporcionar corriente de conducción adicional a los segmentos de LED, porque cada pin de un microcontrolador puede generar o hundirse cerca de 40 mA de corriente solamente. Cuando todos los (siete) segmentos de la pantalla se encienden a la vez (el número 8), la demanda de corriente excederá este límite de 40 mA. La imagen que se muestra a continuación indica el diagrama de cableado básico de las resistencias limitadoras de corriente y los transistores del controlador.

Esta sección de visualización de 4 dígitos y 7 segmentos está conectada alrededor de cuatro pantallas LED de cátodo común de 7 segmentos y cuatro transistores NPN 2N2222. Las resistencias de 1K se utilizan para limitar la corriente de base y las resistencias de 220R limitan la corriente de funcionamiento de los segmentos de la pantalla LED.

En la placa Arduino, las salidas digitales de D10 a D17 se utilizan para controlar los segmentos (aa g &dp), y las salidas digitales D6 a D9 se utilizan para los dígitos (D0-D3) de la pantalla LED 4 × 7.

Se agrega un interruptor de botón con el módulo de visualización para acceder a diferentes opciones. También se utilizará para despertar el Arduino del modo de suspensión mediante una interrupción de hardware externa. por lo tanto, el botón está conectado al pin digital n. ° 2 de Arduino (INT0).

Conexión de la placa de visualización con Arduino Mini Pro

De acuerdo con el esquema proporcionado antes de soldar todos los pines de los segmentos al mini pin de Arduino. Luego suelde 4 pines comunes al pin colector del transistor. Las bases del transistor están conectadas al pin Arduino. Después de conectar la pantalla, conecte el interruptor de botón con el pin digital 2 de Arduino (INT 0). Asegúrese de haber conectado el botón al pin 2 de Arduino porque implementaremos una interrupción de hardware externa para despertar a Arduino del modo de suspensión usando este botón.

Conexión del módulo RTC y el zumbador

Ahora, conecte el módulo RTC que hizo anteriormente a la placa Arduino. El pin SDA del módulo debe estar conectado al pin SDA (A4) del pin Arduino y el pin SCL del módulo debe estar conectado al pin SCL (A5) del Arduino. Luego, conecte el zumbador a la placa Arduino.

Conexiones:

RTC ------> Arduino Mini Pro

  • SDA ------> A4
  • SCL ------> A5
  • Zumbador ------> D3

Colocación del sensor ultrasónico con tapa de botella

Haga un agujero en la tapa de la botella como se muestra en la imagen. Saque cuatro cables del sensor ultrasónico a través del orificio y fije el sensor ultrasónico en el medio de la tapa de la botella. El sensor debe colocarse en el lado interior de la tapa de la botella y debe colocarse en la posición central.

Conexiones:

Sensor ultrasónico ------> Arduino Mini Pro

  • VCC ------> VCC
  • GND ------> GND
  • Activador ------> D4
  • Eco ------> D5

Carga de programa y pruebas

Después de completar toda la conexión, es el momento adecuado para cargar el programa en la placa Arduino y probar la funcionalidad. Se le requerirán varias bibliotecas para que el programa funcione correctamente. Para la interfaz de botones, debe agregar la biblioteca OneButton. Como el dispositivo funcionará con batería, el consumo de energía es un tema importante. Implementé el modo de suspensión en mi boceto de Arduino. Se utilizó un temporizador de vigilancia y una interrupción de hardware externa para reactivar el Arduino del modo de suspensión. Arduino toma la lectura del sensor tres veces, promedia y calcula la información necesaria y muestra la información durante 10 segundos y luego pasa al modo de suspensión durante 1 minuto. Se despierta en cualquier momento con el botón presionado conectado a INT0 (pin digital 2). Por lo tanto, si desea ver la información sobre su consumo de agua, simplemente presione el botón de opción en cualquier momento. Se despertará por ti. Sin presionar ningún botón, tomará una lectura cada 1 minuto. Para implementar el modo de suspensión utilicé la biblioteca Arduino Low-Power. Para leer el tiempo del módulo DS1307 RTC utilicé la biblioteca DS1307RTC. Entonces, para compilar el programa adjunto, agregue toda la biblioteca a su entorno.

Explicaré aquí sólo brevemente el algoritmo de cálculo. Vea el relleno adjunto para un boceto completo. El cálculo se realiza a partir del promedio de cinco lecturas del sensor para que sea lo suficientemente preciso. La lectura diaria se restablece a las 24 horas y se prepara para una nueva lectura para el nuevo día.

La ingesta media de agua se prepara a partir de la media de la ingesta diaria de los siete días anteriores. Si pasaron 2 horas sin ingerir agua, alertará al usuario con un doble pitido cada 15 minutos y se detendrá durante las siguientes 2 horas después de ingerir agua.

Descarga el código adjunto y cárgalo en tu Arduino Mini Pro. Conecte todo el módulo y enciéndalo para probar si todos los componentes funcionan correctamente o no. Si la pantalla muestra algún resultado, ¡felicitaciones! Ya hiciste las cosas difíciles.

Arduino con tapa de botella

Usando pegamento caliente, pegue Arduino mini a la parte superior de la tapa de la botella. Tenga en cuenta que debe fijar todos los componentes en la tapa de la botella. Agregue suficiente pegamento para que quede bien adherido a la tapa de la botella.

Instalación del módulo de carga y batería

Ahora, arregle la batería de iones de litio en la parte superior del Arduino. Tenga cuidado de no poner en cortocircuito la batería con cualquier patilla abierta. Luego conecte el módulo del cargador con la tapa. Mantenga el puerto USB de fácil acceso desde el lado exterior para que pueda conectarse fácilmente al cargador.

Hacer todos los circuitos impermeables

Después de conectar todos los componentes y modularlo, es el momento adecuado para que nuestro dispositivo sea completamente impermeable. Es muy importante porque es botella de agua y en cualquier momento se puede caer agua al circuito y dañar el circuito. Para hacerlo completamente impermeable, agregue suficiente pegamento en cada parte exterior de los circuitos sin el puerto USB. Puede hacer que la tapa sea agradable con pegamento para redondearla en la tapa original.

No hunda la tapa de la botella en el agua.

Disfrútalo

Código

  • Bosquejo de Arduino
Arduino Sketch Arduino
 // Las funciones de fecha y hora que utilizan un RTC DS1307 conectado a través de I2C y Wire lib # incluyen  #include  #include  #include  #include " LowPower.h "#include" OneButton.h "OneButton button (2, true); const byte interruptPin =2; volatile int state =0; const int trigPin =4; const int echoPin =5; int piezoPin =3; const int digit [4] ={9,6,7,8}; int digit_value [4]; int digit_value1 [4]; int button_press_count =1; const int segmento [8] ={16,10,12,14,15, 17,11,13}; número de byte constante [10] [8] ={{1,1,1,1,1,1,0,0}, // 0 {0,1,1,0,0, 0,0,0}, // 1 {1,1,0,1,1,0,1,0}, // 2 {1,1,1,1,0,0,1,0}, / / 3 {0,1,1,0,0,1,1,0}, // 4 {1,0,1,1,0,1,1,0}, // 5 {1,0,1 , 1,1,1,1,0}, // 6 {1,1,1,0,0,0,0,0}, // 7 {1,1,1,1,1,1,1 , 0}, // 8 {1,1,1,1,0,1,1,0}}; // 9 byte constante d [8] ={0,1,1,1,1,0,1,1}; byte constante a [8] ={1,1,1,0,1,1,1,1 }; byte constante r [8] ={0,0,0,0,1,0,1,1}; byte constante t [8] ={0,0,0,1,1,1,1,1 }; int segundos, minutos, horas; int water_in_ounch [15]; int water_intake_ounch [15]; int water_intake_days [7]; int water_intake_times =0; int anterior_agua_amount =0; int total_water_intake_today =0; int average_intake_last_week =0; int inatke_day =1; flotar nivel_agua_promedio =0; // almacena el promedio de lecturas múltiples en water_amount_in_ounce =0; // almacena la cantidad calculada de agua en idle_time =0; int input_day =1; int previous_value =0; void setup () {Serial.begin (9600); pinMode (interruptPin, INPUT_PULLUP); // ponga su código de configuración aquí, para que se ejecute una vez:for (int i =6; i <=17; i ++) pinMode (i, OUTPUT); pinMode (trigPin, SALIDA); pinMode (echoPin, ENTRADA); button.attachClick (presionado); button.attachDoubleClick (doble clic); button.attachLongPressStart (longPressStart); button.attachDuringLongPress (longPress);} long previous_state =millis (); int count =1; int daily_intake =0; int semanal_intake =0; long sleep_time =millis (); void loop () {read_time (); button.tick (); // sigue mirando los pulsadores:cálculo (); diaria_intake =total_water_intake_in_day (); semanal_intake =average_water_intake_last_week (); if (button_press_count ==1) {display_d (); display_number (entrada_diaria); } más si (button_press_count ==2) {display_a (); display_number (semanal_intake); } más si (button_press_count ==3) {display_r (); display_number (cantidad_agua_en_ounce); } else if (button_press_count ==4) {display_first_2 (horas); display_last_2 (minutos); } if (idle_time> =120) {alerta (); alerta(); } if ((millis () - tiempo_de_nocimiento)> =15000) {display_off (); attachInterrupt (digitalPinToInterrupt (interruptPin), en blanco, FALLING); LowPower.powerDown (SLEEP_8S, ADC_OFF, BOD_OFF); LowPower.powerDown (SLEEP_8S, ADC_OFF, BOD_OFF); LowPower.powerDown (SLEEP_8S, ADC_OFF, BOD_OFF); LowPower.powerDown (SLEEP_8S, ADC_OFF, BOD_OFF); LowPower.powerDown (SLEEP_8S, ADC_OFF, BOD_OFF); LowPower.powerDown (SLEEP_8S, ADC_OFF, BOD_OFF); detachInterrupt (digitalPinToInterrupt (interruptPin)); sleep_time =millis (); }} vacío display_digit (int dígito) {for (int i =0; i <8; i ++) {digitalWrite (segmento [i], número [dígito] [i]); }} void display_number (int número) {int i =0; while (número> 0) {valor_dígito [2-i] =número% 10; número =número / 10; i ++; } digitalWrite (dígito [1], ALTO); digitalWrite (dígito [2], BAJO); digitalWrite (dígito [3], BAJO); display_digit (digit_value [0]); retraso (5); digitalWrite (dígito [1], BAJO); digitalWrite (dígito [2], ALTO); digitalWrite (dígito [3], BAJO); display_digit (digito_valor [1]); retraso (5); digitalWrite (dígito [1], BAJO); digitalWrite (dígito [2], BAJO); digitalWrite (dígito [3], ALTO); display_digit (digit_value [2]); retraso (5); digitalWrite (dígito [3], BAJO); valor_dígito [0] =0; valor_dígito [1] =0; valor_dígito [2] =0; } void display_first_2 (int número) {digitalWrite (dígito [2], BAJO); digitalWrite (dígito [3], BAJO); int i =0; while (número> 0) {valor_dígito [1-i] =número% 10; número =número / 10; i ++; } digitalWrite (dígito [0], ALTO); digitalWrite (dígito [1], BAJO); display_digit (digit_value [0]); retraso (3); digitalWrite (dígito [0], BAJO); digitalWrite (dígito [1], ALTO); display_digit (digit_value [1]); retraso (3); } void display_last_2 (int número) {digitalWrite (dígito [0], BAJO); digitalWrite (dígito [1], BAJO); int i =0; while (número> 0) {digit_value1 [1-i] =número% 10; número =número / 10; i ++; } digitalWrite (dígito [2], ALTO); digitalWrite (dígito [3], BAJO); display_digit (digit_value1 [0]); retraso (3); digitalWrite (dígito [2], BAJO); digitalWrite (dígito [3], ALTO); display_digit (digit_value1 [1]); retraso (3); } void display_d () {digitalWrite (dígito [0], ALTO); para (int i =0; i <8; i ++) {digitalWrite (segmento [i], d [i]); } retraso (5); digitalWrite (dígito [0], BAJO); } void display_a () {digitalWrite (dígito [0], ALTO); para (int i =0; i <8; i ++) {digitalWrite (segmento [i], a [i]); } retraso (5); digitalWrite (dígito [0], BAJO); } void display_r () {digitalWrite (dígito [0], ALTO); para (int i =0; i <8; i ++) {digitalWrite (segmento [i], r [i]); } retraso (5); digitalWrite (dígito [0], BAJO); } void display_t () {digitalWrite (dígito [0], ALTO); para (int i =0; i <8; i ++) {digitalWrite (segmento [i], t [i]); } retraso (5); digitalWrite (dígito [0], BAJO); } void display_off () {digitalWrite (dígito [0], BAJO); digitalWrite (dígito [1], BAJO); digitalWrite (dígito [2], BAJO); digitalWrite (dígito [3], BAJO); para (int i =0; i <8; i ++) {digitalWrite (segmento [i], BAJO); } retraso (5); } void read_time () {tmElements_t tm; if (RTC.read (tm)) {segundos =tm.Second; minutos =tm.Minuto; horas =tm.Hora; }} int distancia_en_cm () {larga duración, cm; // El sensor se activa con un pulso ALTO de 10 microsegundos o más. // Dar un pulso BAJO corto de antemano para asegurar un pulso ALTO limpio:digitalWrite (trigPin, LOW); delayMicroseconds (2); digitalWrite (trigPin, HIGH); delayMicroseconds (10); digitalWrite (trigPin, BAJO); // Leer la señal del sensor:un pulso ALTO cuya // duración es el tiempo (en microsegundos) desde el envío // del ping hasta la recepción de su eco de un objeto. duración =pulseIn (echoPin, HIGH); // convierte el tiempo en una distancia cm =microsecondsToCentimeters (duración); volver cm; } microsegundos largos a centímetros (microsegundos largos) {// La velocidad del sonido es de 340 m / so 29 microsegundos por centímetro. // El ping viaja hacia afuera y hacia atrás, así que para encontrar la distancia del objeto // tomamos la mitad de la distancia recorrida. devuelve microsegundos / 29/2; } alerta de vacío () {tono (piezoPin, 2000, 50); tono (piezoPin, 2000, 200); // retraso (10); } vacío en blanco () {// tono (piezoPin, 2000, 100); // state ++;} // Esta función se llamará cuando el botón1 se presionó una vez (y no se siguió ninguna 2. presión de botón) .void pressed () {//Serial.println("Button 1 click. "); button_press_count ++; alerta(); if (button_press_count ==5) {button_press_count =1; }} // haga clic // Esta función se llamará cuando el botón1 se presionó 2 veces en un período de tiempo corto.void doubleclick () {Serial.println ("Button 1 doubleclick.");} // doubleclick // Esta función ser llamado una vez, cuando se presiona el botón1 durante un tiempo prolongado. void longPressStart () {Serial.println ("Botón 1 longPress start");} // longPressStart // Esta función se llamará con frecuencia, mientras que el button1 está presionado por mucho tiempo.void longPress () {Serial.println ("Botón 1 longPress ..."); water_intake_ounch [water_intake_times - 1] =0; // ignorar el último valor} // cálculo longPressvoid () {float water_level =0; // nivel de almacenamiento en cada paso int read_value =0; // leer la lectura del sensor en cm para (int i =0; i <5; i ++) {// tomar cinco lecturas read_value =distance_in_cm (); if (read_value> 16 || read_value <3) {// retorno de lectura inestable; // volver a la función de llamada porque la lectura es inestable} else if (read_value <=16 &&read_value> =3) {// valor válido water_level =water_level + read_value; } retraso (10); } nivel_de_agua_promedio =17 - nivel_de_agua / 5; // encontrar el promedio de cinco lecturas, 17 =altura de la botella water_amount_in_ounce =int (average_water_level * 1.87); // 16 cm de nivel de agua =30 onzas if (water_intake_times ==0) {previous_water_amount =water_amount_in_ounce; water_intake_times =1; } if ((water_amount_in_ounce  previous_water_amount) {// el agua se vuelve a llenar // el agua se vuelve a llenar aquí previous_water_amount =water_amount_in_ounce; } else if (water_amount_in_ounce ==previous_water_amount) {// no se consume agua o se vuelve a llenar el tiempo de inactividad + =1; } if (hours ==23 &&minutes ==59) {// un día ha terminado y todos los valores comienzan desde cero para el nuevo día para (int i =0; i <15; i ++) {water_intake_ounch [i] =0; } water_intake_times =0; ingesta_día ++; if (ingesta_día ==8) {ingesta_día =1; }}} int total_water_intake_in_day () {// calcula la ingesta total de agua en un día total_water_intake_today =0; for (int i =0; i   

Esquemas


Proceso de manufactura

  1. Aspersor para césped
  2. Lavavajillas
  3. Pistola de agua
  4. Inodoro
  5. Boca de incendios
  6. Botella térmica
  7. Agua
  8. Champú
  9. Panel de yeso
  10. Circuito integrado
  11. MOSMusic