Construcción de una Estacion Meteorológica Utilizando ...
Transcript of Construcción de una Estacion Meteorológica Utilizando ...
Construcción De Una Estación Meteorológica
Utilizando Elementos De Bajo Costo Alimentado
Con Energía Fotovoltaica
Klemer Antonio Pabón Perea y Marlo Johan Zuleta Ruiz.
Santa Marta - Magdalena Universidad Antonio Nariño
[email protected], [email protected].
Resumen- El presente artículo hace énfasis en la construcción de
una estación meteorológica con elementos de bajo costo eficientes
y de una alta calidad alimentado con energía solar fotovoltaica
con sistema de adquisición de datos escrito en leguaje de
programación java que nos permite acceder al servidor del
equipo de una manera remota gracias a aplicaciones como base
de datos Mariadb, Logmein hamachi, PHPmiami, VNCviewer
para consultar y visualizarlos datos en una interfaz gráfica, con el
fin de ser instalada en el quinto piso de la Universidad Antonio
Nariño que sea capaz de medir la velocidad y dirección del viento,
temperatura, humedad relativa, Presión atmosférica,
precipitaciones y luz ambiente conectada a una red wifi al servicio
de la comunidad de la UAN.
Palabras Clave- Programación, variables, sensores, software,
hardware.
Abstract-The present article emphasizes in the construction of
a meteorological station made of efficient, high quality and low
cost elements, it is fed with photovoltaic solar energy with a data
acquisition system written in the programming language Java, it
allows to have access to the server's machine remotely thanks to
applications such as Mariadb database, Logmein hamachi,
PHPmiami, VNCviewer, they allow to consult and visualize data
in a graphic interface. In order to be installed in the fifth floor of
the Universidad Antonio Nariño in such way it could measure the
velocity and direction of wind, temperature, relative humidity,
atmospheric pressure, rainfall and ambient light, by being
connected to a WiFi network, and on service to the UAN
community. Keywords- Programming, variables, sensors, software,
hardware.
I. INTRODUCCIÓN
Una estación meteorológica es un dispositivo encargado de
medir las diferentes variables físicas como lo son temperatura,
humedad relativa, velocidad del viento, presión barométrica,
intensidad solar y lluvia etc. Pueden ser instaladas en cualquier
terreno para la toma de datos que son muy importantes a la
hora de hacer predicciones sobre el clima. Con el paso del
tiempo y los avances en la tecnología sean logrado grandes
progresos en ellas. Existen varios modelos de estaciones que
han venido evolucionando desde sus comienzos en los que
solo era posible registrar las variables de una forma analógica,
hasta lograr perfeccionar los instrumentos de medida que se
utilizaron en este proyecto para luego poderlos transmitir en
tiempo real a cualquier dispositivo electrónico como PC o
Laptop a cualquier parte del mundo [1]
Para la ejecución de este proyecto se utilizarán diferentes tipos
de sensores para medir las variables físicas que en particular
son: temperatura, humedad relativa, velocidad y dirección de
viento, presión barométrica, precipitaciones y luz ambiente.
[2] Estos sensores convierten estas variables físicas en señales
de voltaje o intensidad que a su vez llegan a un análogo digital
que realiza el proceso de conversión de la variable física a una
magnitud digital, esta es enviada al ordenador de tamaño
reducido de bajo costo RASPBERRY PI. Por medio del
protocolo de comunicación RS-232 Que a su vez se encuentra
intercomunicado con una aplicación escrita en el lenguaje de
programación en JAVA que permite leer el puerto serial,
escalar las variables e introducirlas a la base de datos que
pueden ser consultadas por medios de protocolos IP como el
HTML utilizando las librerías ya escritas desde cualquier
plataforma.
II. DESCRIPCION DEL PROBLEMA
En los tiempos actuales la información viaja de una forma muy
rápida, las herramientas de trabajo se encuentran
sistematizadas en la actualidad. Surgen nuevos problemas
como los errores de cuantización y precisión. Las mediciones
de las variables como el viento, su velocidad, presión
barométrica, humedad y temperatura son importantes para
intentar predecir el clima.
El clima es un sistema estocástico de difícil predicción y con
una alta importancia en los trabajos de construcción, en la
agricultura, la investigación y en la toda la faceta de la vida
diaria. En la actualidad existen estaciones meteorológicas que
varían desde el número de variables a medir, tamaño y sobre
todo costos.
El cambio climático es una realidad que estamos viviendo, a
nivel mundial podemos hablar del calentamiento global
producido por los gases de efecto de invernadero debido al
aumento de la población, la industria, la tala de los bosques
para la ampliación de la ganadería y la agricultura y que esto
ha llevado a que entidades de talla mundial como la
Organización De Naciones Unidas (ONU) se ponga al frente
de este problema que nos afectara a todos si no se toman
medidas drásticas. [3] Colombia no es la excepción puesto que
estamos viviendo los efectos producidos por un fenómeno
natural de variabilidad climática como el Niño. Que se ha
encargado de alargar el verano generando cambios drásticos en
la agricultura y la ganadería, por escases de lluvias sobre todo
en la región caribe que desde hace tiempo vemos los bajos
niveles de los ríos poniendo en riesgo su navegabilidad, el
aumento de temperatura del aire generando incremento de los
incendios forestales, y el desabastecimiento de agua para el
consumo humano. [4] Para mitigar la situación actual debemos
estudiar más de cerca el clima y buscar alternativas que nos
ayuden a mejorar la calidad de vida tomando como recurso la
tecnología y sus múltiples aplicaciones, la investigación
motivando a las generaciones futuras a crear nuevos proyectos
de mejora en el manejo de información que sea fácil de adquirir
e interpretar, llevando a la Universidad Antonio Nariño sede
santa marta ubicada en el sector de mamatoco en la Calle 30
#49-46 a estar a la vanguardia con las entidades que estudian
los problemas ambientales como el cambio climático
construyendo una estación meteorológica con elementos
eficientes de bajo costo pero de una alta calidad y tecnología
auto sostenible con panel solar y batería de respaldo
aprovechando la energía solar que es abundante casi todo el
año por la ubicación geográfica que tiene la ciudad de Santa
Marta evitando así las constantes fallas del operador de redes
eléctricas que en la actualidad lo han visto en el ciclo
interrumpido del servicio. Hoy en día se dan cuenta de las
afectaciones que trae consigo el cambio climático si no
actuamos rápido.
FORMULACIÓN DEL PROBLEMA.
Ante el cambio climático que vivimos hoy
¿Sera importante medir parámetros meteorológicos?
Construcción de una estación meteorológica con elementos de
bajo costo alimentado con energía fotovoltaica.
III. JUSTIFICACIÓN
La meteorología es una de las ciencias que más avance refleja
en la tecnología moderna implementada, el monitoreo de las
variables físicas son fundamentales para el estudio de
condiciones medio ambientales, dándole importancia a la
medición de las variables atmosféricas como son: velocidad,
dirección del viento, humedad relativa, temperatura,
precipitaciones, radiación solar entre otras, lo que permite
dejar bases para futuras investigaciones en energías
renovables para la solución de problemas técnicos.
Por lo que se efectuara análisis de la información registrada en
tiempo real y establecer datos precisos donde implementar
sistema de generación.
Con la construcción de la estación meteorológica en la
Universidad Antonio Nariño se pretende ubicarla en la azotea
del quinto piso el cual no está acondicionado con acometidas
eléctricas además se complementara con el diseño e
implementación de un sistema de panel solar con batería de
respaldo, creando un equipo independiente, auto sostenible que
pueda medir y registrar las diversas variables atmosféricas para
estudiar su comportamiento en un tiempo determinado sin que
se vea afectada por la interrupción de la energía. Llevando a
cabo la construcción de la estación meteorológica en la UAN
exponemos los siguientes conceptos.
A nivel teórico tomando como base la investigación ya que
los datos arrojados por la estación meteorológica sirven como
aporte para otros proyectos, y les permita tener acceso al
comportamiento de las variables en diferentes épocas del año
con fines académicos. En diferentes campos como son la
agricultura, construcción y su vínculo directo con las diferentes
variables atmosféricas las precipitaciones, la humedad relativa,
la velocidad y dirección del viento.
A nivel metodológico la Universidad Antonio Nariño queda
equipada con una herramienta importante que abrirá nuevas
puertas para el desarrollo de proyectos en busca de soluciones
alternativas basados en datos reales arrojados por la estación
meteorológica en sus diferentes variables atmosféricas que
ayudaran en proyectos de generación de energía limpia.
A nivel práctico trabajar con sensores, tarjetas de bajo costo,
pero una alta eficiencia y calidad e interactuar con la
programación nos permite avanzar en campo tecnológico.
A nivel social la puesta en práctica de los conocimientos
adquiridos en diferentes carreras como la ingeniería Electro
mecánica, industrial y sistemas juntos con los coordinadores
académicos, docentes y alumnos se podrá ofertar mejoras
tecnológicas en este tipo de proyectos que cuenta con
elementos de bajo costo, pero una alta calidad tecnológica.
IV. OBJETIVO.
A. OBJETIVO GENERAL.
Construir una estación meteorológica utilizando elementos de
bajo costo alimentado con energía fotovoltaica en la
universidad Antonio Nariño.
B. OBJETIVOS ESPECÍFICOS
Recopilar la información necesaria para la realización del
proyecto.
Identificar las variables a medir y Definir los componentes
instrumentales necesarios para la implementación.
Desarrollar la interfaz y el protocolo de comunicaciones.
Diseñar e implementar un sistema de panel solar y batería de
respaldo para la alimentación de la estación meteorológica.
Construir y puesta en funcionamiento de la estación
Meteorológica.
Estimar costos finales del proyecto.
V. ALCANCES Y LIMITACIONES
La estación meteorológica estará ubicada en el quinto piso de
la universidad Antonio Nariño sede santa marta, y se enfocará
en las mediciones propias de las variables, durante un tiempo
permanente que se prolongará en función de su respectivo
mantenimiento para ser visitada por el cuerpo docente y
alumnos que muestren interés en el tema para mejorar el
proyecto. Las limitaciones que se relacionan son las siguientes
La recopilación de información por estar en otros idiomas.
Los costos que se puedan presentar durante el diseño.
Disponibilidad de los componentes para cumplir con el
tiempo de la implementación.
La interpretación del lenguaje de programación y los errores
que se puedan cometer al escribir el código.
Las fuertes ráfagas del viento puedan causar daños y
deterioro a la estación.
VI. MARCO TEÓRICO.
En busca de alternativas para implementar en este proyecto se
tendrán en cuenta los siguientes componentes electrónicos
diseñados y construidos para medir las variables físicas tales
como: velocidad y dirección del viento, humedad relativa,
temperatura, presión barométrica, precipitaciones, luz
ambiente. Y a su vez un software libre multiplataforma que nos
ofrece un entorno de desarrollo integrado (IDE) para dar las
instrucciones al microcontrolador de las placas disponibles en
el mercado Arduino 1, raspberry pi, ESP8266 etc.
A. Sensor de presión, temperatura y humedad BME280
Este sensor tiene la capacidad de integrar en un solo
dispositivo los sensores de presión barométrica temperatura y
humedad relativa, en la (figura1) apreciaran su tamaño
comparado con una moneda, posee una gran precisión y con
un consumo de energía relativamente bajo, que promete una
alta precisión y linealidad a largo plazo, se puede conectar
directamente a un microcontrolador mediante protocolo 12c y
spi compatible con Arduino y raspberry pi.
Figura1:Sensor BME280 [5]
B. El sensor BME280:
Es un sensor digital que puede medir temperatura, humedad y
presión atmosférica, está disponible en el mercado de la
electrónica a un bajo costo y lo mejor es que nos ofrece una
solución integrada que satisface las necesidades que puedan
surgir para al implementar este proyecto.
A continuación, presentamos en la (Figura2) así como las
líneas de código en el lenguaje de programación payton, cabe
mencionar que este lenguaje es el que viene predeterminado
(figura3) con la placa, pero podemos utilizar otro lenguaje
como javas.
C. Raspberry pi:
el esquema de la conexión con la placa computadora raspberry
pi.
Figura2: Conexión de sensores [6]
PI GPIO BME280
17 (3v3) VIN
6(GND)
3(SDA) SDA(SDI)
5(SCL) SCL (SCK)
Figura3: Conexión de sensores [6]
D. Sensor BME 280 con Arduino:
Podemos conectar el sensor usando el bus SIP o 12S el bue sip
requiere cuatro cables más la alimentación y tierra. El bus 12c
lo requiere dos cables más alimentación y tierra. Ambos se
pueden cablear utilizando cables 5V o 3.3V como fuente de
energía, ya que la placa de conexión tiene un regulador de
potencia a bordo para regular a 3.3V para el sensor.
E. Conexión BME280 usando el bus I2C
Figura4: Conexión de los sensores [7]
En la (figura4) se ve el sensor BME280 conectado a una placa
Arduino uno así como su diagrama de conexión con la misma,
lo presentamos como una de las múltiples alternativas con la
que contamos para la implementación de este proyecto, como
lo mencionamos anterior mente este tipo de sensor el muy
funcional por que integra tres variable a medir en una sola
palca.
A. Marco de referencia
En el 2016 Oracle raspberry pi distribuyo cientos de estaciones
meteorológicas en todo el mundo, se trató de un proyecto que
buscaba acercar la tecnología a las personas principal mente a
la población estudiantil, tanto de escuelas como de
universidades, constaba de un kit para la construcción de una
estación meteorológica que era capaz de registrar y almacenar
datos, utilizando una variedad de sensores.
Los resultados de la implementación de este proyecto no
demoraron en acrece notar en todo el mundo entre los amantes
de la electrónica, iniciaba con una serie de pruebas con cables
y una placa de ensayo de circuitos, de tal manera que se lograba
comprobar el correcto funcionamiento de la estación
meteorológica, para posterior mente dar paso a la
construcción de una estación más robusta (Figura5) que fuera
capaz de soportar los embates del clima, y que sea confiable a
largo plazo.
Figura5: Estación meteorológica [8]
Alberto Tobajas García presento la tesis para optar al título de
master en ingeniería de telecomunicaciones de la universidad
Oberta de Catalunya [9] presento una tesis que tiene como
título, diseño e implementación de una estación meteorológica
con raspberry pi.
B. Bases teóricas
Variables:
A. Velocidad del viento:
En meteorología estudia el viento como aire en movimiento
tanto vertical como horizontal. En náutica se mide en nudos
mediante la escala de beaufort esta escala comprende 12 grados
de identidad creciente que describen el viento a partir del
estado del mar, con la llegada de modernos anemómetros a
cada grado de la escala se le ha asignado una banda de
velocidades medida por lo menos durante 10 minutos a 10
metros de altura.
B. Dirección del viento:
Se representa en grados de 0 a 360, 0 grados corresponde al
norte, 90 al este, 180 al sur, 270 al oeste, y 360grados
nuevamente al norte el instrumento más antiguo para conocer
la dirección del viento es la veleta que con la ayuda de la rosa
de los vientos, define la procedencia es decir desde donde
soplan.
C. Humedad:
La humedad es una propiedad que detalla el contenido de vapor
de agua que se relaciona con un gas el cual se puede reflejar en
términos de diversas magnitudes, [10] ya sea directamente o en
su defecto ser calculadas a partir de las dimensiones de dichas
magnitudes, donde la aplicación influye de manera
proporcional con la magnitud. En meteorología según la
Agencia Estatal De Meteorología (AEMET) la humedad se
expresa con la temperatura de bulbo húmedo y en otros casos
con la de punto de rocío, en otras prácticas como cámaras de
humedad o en cuarto limpios se usa la humedad relativa.
D. Temperatura:
En cuanto concierne a la temperatura como lo expresa [11]
todo se origina de las ideas cualitativas de lo relacionado con
caliente y frio, pero en términos científicos se describe la
temperatura como el movimiento de forma aleatoria entre los
átomos y las moléculas de una sustancia y que es directamente
proporcional a la energía cinética y esta varía dependiendo del
contacto con otros
Cuerpos.
E. Presión atmosférica
La presión atmosférica, se sustenta según [12] como la fuerza
que ejerce el aire por unidad de superficie que estructura la
atmosfera sobre el espacio terrestre.
Todo este sistema se dio por el principio del barómetro y
demostró que con obtener una medida de presión atmosférica
quizás no se puedan sacar muchas conclusiones, pero sin
embargo dicha información unida a otros datos meteorológicos
como (humedad, temperatura, precipitación) podría otorgar
una percepción pertinente del tiempo atmosférico.
F. Precipitación:
Se conoce la precipitación como un fenómeno atmosférico, por
medio del cual se presenta una condensación del vapor de agua
en las nubes en el momento en que estas atraviesan capas de
aire frio. [13] Se sobreentiende que la precipitación está ligada
a tres factores: radiación, temperatura y presión, cuando la
magnitud de la precipitación desborda la capacidad de
filtración del suelo se anuncia el deslizamiento superficial que
puede dar espacio a que se presenten inundaciones en las partes
más bajas.
G. Luminosidad:
En relación con las observaciones anteriores, se analiza lo que
sería la luminosidad que conforme a [14] se define como la
duración del brillo solar, haciendo representación al tiempo
que dura la incidencia de luz directa sobre un lugar
determinado, añadiendo que el total de horas de brillo solar
representa uno de los factores que delimita el clima de dicho
lugar.
H. ¿Qué es un software libre?
Un software para que se considere libre tiene que reunir cuatro
condiciones imprescindibles [15]:
La libertad de usar el programa para satisfacer cualquier
interés en cualquier sistema operativo.
Tener acceso al código fuente para conocer cómo funciona
y poder adaptarlo a las necesidades del interesado.
Autonomía para difundir copias.
Poder compartir las mejoras desarrolladas con la
comunidad interesada en el tema sin preocuparse por temas
legales.
Si los usuarios tienen acceso a estos cuatros condiciones
mencionadas se concluye que es un software libre.
I. Hardware libre:
Un hardware para que se considere libre la comunidad
interesada debe tener acceso a los diagramas esquemáticos, que
le permitan estudiar el funcionamiento del circuito y las
interconexiones internas de tal manera que cualquiera con
conocimiento y las maneras adecuadas pueda hacerles mejoras
e incluso compartirlas con la comunidad sin ningún problema.
[15]
J. Protocolo de comunicación:
Cuando se transmite información la podemos hacer de
diferentes formas, una de ellas es estableciendo una
comunicación serial que consiste en transmitir los datos bit a
bit es decir uno detrás del otro por un único canal, estos
protocolos solo difieren un poco en velocidad de transmisión,
paquetes de datos, voltaje los mensajes de conexión y
desconexión etc.
Entre los que se destacan y son más comunes y utilizados en
este proyecto tenemos I²C (Inter-integrated circuit) Es muy
utilizado en la industria principalmente para comunicar
circuitos integrados entre sí, utiliza dos líneas para transmitir
la información, una llamada el SDA sirve para transmitir los
datos y otra llamada SCL que sirve para enviar una señal reloj
con sus respectivas líneas de alimentación y tierra, la señal
reloj es la que determina cuando inicia la transmisión y cuando
se termina, cada dispositivo conectado al bus tiene una
dirección única que lo identifica y puede estar configurado
como maestro o como esclavo, el maestro es quien inicia la
transmisión de los datos y también genera la señal reloj y el
esclavo es el que recibe los datos.
K. Protocolo SPI (Serial peripheral interface):
Este protocolo utiliza cuatro líneas la SCK envía la señal reloj
a todos los dispositivos generadas por el maestro, la SS esta es
la utilizada por ese maestro para elegir el dispositivo esclavo
con quien se quiera comunicar, la MOSI es la línea utilizada
para enviar los datos del maestro hacia el esclavo elegido, y
otra llamada MISO que es utilizada para enviar los datos en
sentido contrario. [15]
VII. MARCO METODOLÓGICO
A. Tipo de Investigación
El proyecto se desarrolla bajo el tipo de investigación
descriptiva porque se especificó las propiedades y
características de una estación meteorológica, teniendo en
cuenta los perfiles de las personas que van a recoger la
información de manera independiente o conjuntas sobre los
conceptos y variables a las que se refieren.
Se [16] pretende describir una realidad a través de la
recolección de datos primarios y secundarios; es decir, busca
medir o recoger información de manera independiente o
conjunta sobre los conceptos o variables que se refiere, para
especificar características y procesos sometidos al análisis.
B. Nivel de la investigación
La investigación consiste en recolectar información de las
estaciones meteorológicas existentes, así como también los
diferentes componentes electrónicos (hardware) para la
construcción de la misma, disponibilidad en el mercado, las
librerías ya escritas (software) que nos faciliten el
almacenamiento, procesamiento y transporte de datos a la red.
De tal manera que la información recolectada por los sensores
pueda ser cuantificada y luego consultada en tiempo real o
fechas específicas a criterio del usuario final.
Cabe mencionar que el análisis y la interpretación de estos
datos, para poder emitir conceptos relacionados con el
comportamiento del clima no hacen parte de esta investigación
por el nivel de complejidad.
C. Diseño de la investigación
Para llevar a cabo los objetivos específicos antes mencionados
y así cumplir a plenitud el objetivo general se seguirán los
siguientes pasos:
Se recolecto información necesaria de estaciones
meteorológicas existentes para poder así establecer un
cumulo de información que nos permita marcar puntos de
referencia para desarrollar el proyecto.
Se identificó las variables a medir, teniendo en cuenta la
disponibilidad de los recursos en el mercado con el
propósito de que en el momento que se necesite un cambio
de componente este se pueda remplazar en el menor tiempo
posible.
Se realizó los diferentes ensayos que nos permita de forma
metódica y progresiva ensamblar los componentes
adquiridos y así dar forma a la estación meteorológica
como tal.
Es de conocimiento para la población involucrada para
obtener datos reales del consumo de energía de los
componentes electrónicos, es necesario hacer mediciones
cuando el equipo está trabajando a plena carga, es por ello
que se puso a prueba durante un tiempo para determinar los
ajustes que sean necesario hacerles para dar fe de la
completa autonomía de la estación.
D. Normativa legal
Como lo hemos mencionado anteriormente la construcción de
la estación meteorológica se basa en el concepto de software y
hardware libre, lo excluye de una normativa legal como tal por
razones obvias, en cuanto a la transmisión de los datos la
utilización del espectro en Colombia, el ente que la regula es
el ministerio de comunicaciones lo que llevo a pensar que con
solo tener un contrato con una compañía que ofrezcan estos
servicios de internet tenemos derecho a transmitir estos datos
de un lugar a otro.
VIII. RESULTADOS DE LA INVESTIGACIÓN
A. Recopilar la información necesaria para la realización
del proyecto.
Teniendo en cuenta las características de este proyecto internet
se convierte en una fuente de información muy diversa, para
no extendernos debido a que cuando iniciamos la búsqueda
desde cualquier navegador, se encontró un cumulo de
información que, si la plasmáramos en este documento, se
haría muy extenso lo que puede ocasionar un desgaste al lector
es por ello que a continuación se hará mención de los
componentes principales de este proyecto.
Todo esto porque este tipo de componentes para los
conocedores del tema es cierto que poseen características muy
similares, que solo difieren en potencia, capacidad de
almacenamiento, velocidad de transmisión de datos, protocolo
de comunicación que en este caso en particular no difieren
mucho.
La placa de circuito impreso ARDUINO UNO se convirtió en
la primera elección por su bajo costo y disponibilidad en el
mercado.
Si bien es cierto existen muchas placas en el mercado de
distintos fabricantes con variedad de microcontroladores, que
son similares a la placa antes mencionada y ofrecen una
funcionalidad similar, el entorno de desarrollo integrado de
ARDUINO es cómodo y posee un lenguaje de programación
completo y sencillo de utilizar, unas de las ventajas más
relevantes es que es (hardware + software) libre esto quiere
decir que cualquiera puede modificarlo de tal manera que
mejore su funcionalidad, su entorno de desarrollo integrado
tiene la ventaja de que se puede instalar y correr en varios
sistemas operativos (Windows, Mac OS X y Linux).
La siguiente opción, en esta parte del proyecto es el mini
ordenador raspberry pi que por sus características se convirtió
en una solución para este proyecto.
Una de las características más importantes, y que fue lo que
motivó para darle un lugar en el diseño es que es software libre,
lo que permite utilizar la placa no solo con el sistema operativo
raspbian, si no que nos permite utilizar otros sistemas
operativos que podemos luego configurar de tal manera que
satisfaga nuestras necesidades, esta placa en combinación con
la placa Arduino nos brindan una gama de posibilidades que
estaremos mencionando al detalle más adelante.
Sen0186 estación meteorológica: este producto te ofrece una
solución integral para el diseño de la estación, en cuanto a las
variables a medir ya que incluye una tarjeta de sensores lo que
nos favorece porque reduce las conexiones en la estación al
mínimo, las características de esta tarjeta las podemos
encontrar en la página [17] (DFROBOT) así como la
información de los sensores que se incorporan a la misma.
El principio de funcionamiento del sensor de velocidad del
viento (anemómetro), es un motor de cd en modo generador
que incrementa su voltaje en función de las revoluciones del
rotor a causa de las paletas que están acopladas al mismo eje
del rotor cuando estas son impulsadas por la energía cinética
del viento.
En cuanto a la dirección del viento, el principio de
funcionamiento es un sistema de posición de contacto que
cambia su posición en función de una veleta (Figura6). El
principio de funcionamiento del sensor de precipitaciones es
un sistema de paso magnético que está montado en una especie
de columpio de tal manera que da votes en función del llenado
a causa del agua lluvia que se deposita en el mismo esto es
escalado de tal manera que se traduce a la cantidad de agua que
cayó en pulgada
Figura6: estación meteorológica
Como lo mencionamos anterior mente este producto ofrece una
solución integrada para la necesidad, en cuanto a los sensores
que están ensamblados en la tarjeta para medir las variables
restantes son temperatura ambiente, presión barométrica,
humedad relativa y luz ambiente son.
Sensor de presión barométrica BMP085 también podemos
utilizar el BMP180, para la variable de temperatura podemos
utilizar el sensor DS18B20, para medir la variable de humedad
relativa podemos utilizar el sensor DHT22.
Todos estos sensores mencionados anterior mente son
compatibles con la placa Arduino, y consultando el datasheet
de cada uno de ellos podrán conocer sus especificaciones
técnicas.
B. Identificar las variables a medir y Definir los
componentes instrumentales necesarios para la
implementación.
Variables a medir
Después de haber hecho la investigación de los materiales y
herramientas, así como también se definieron las aplicaciones
que nos sirven de soporte para el sistema de adquisición de
datos, dichas aplicaciones las podemos descargar de la web de
manera gratuita el único requisito es estar conectado a una red
de internet, podemos decir en concreto que las variables a
medir son: Velocidad del viento, dirección del viento,
humedad relativa, temperatura, precipitaciones, presión
barométrica y luz ambiente.
C. Desarrollar la interfaz y el protocolo de
comunicaciones
La información mencionada anteriormente hace parte del
Hardware, pero para que esos datos sean mostrados al usuario
final de una manera agradable y comprensible es necesario
crear un software, o en su defecto utilizar los programas ya
escritos y que se encuentran disponibles en la red de una
manera gratuita, con la ventaja de que podemos hacer unos
cambios para que se ajusten a las necesidades.
Es en esta parte donde entra en juego la placa raspberry pi ya
que la función principal en este diseño es la de poner a correr
todos estos programas.
1. Base de datos MariaDB:
El servidor de base de datos MaríaDB es un software gratuito
y de código abierto de manera que cualquiera puede
descargarlo y usarlo de forma gratuita, es por ello que se decide
darle un lugar en este diseño
2. PhpMyAdmin:
Es una herramienta de software escrita en php que se puede
utilizar de forma gratuita destinada a manejar la administración
de MySQL en la web, es decir que nos proporciona una
interfaz, mientras aún tiene la capacidad de ejecutar cualquier
sentencia SQL, para poder conocer las características de estas
herramientas y las ventajas que nos ofrece su uso solo basta
con consultar en la web los tutoriales de la misma.
3. Logmein hamachi:
Es un servicio de redes virtuales que es fácil de instalar y que
nos permite acceder de manera remota a la red que hallamos
configurado, siempre y cuando estemos conectados a internet.
En la versión gratuita podemos conectar hasta cinco
ordenadores, para poder sacar ventaja de esta herramienta
podemos consultar en internet los tutoriales de cómo manejar
dicha herramienta, además que puede utilizarse con diferentes
sistemas operativos.
4. VNC viewer:
Es un programa de software libre basado en la estructura
cliente servidor que nos permite hacer una conexión entre dos
computadoras de tal manera que podamos tener acceso al
escritorio del ordenador que tengamos configurado en la red,
la única condición es que los dispositivos tengan instalado el
programa, de lo cual podemos consultar los tutoriales en
internet.
D. Diseñar e implementar un sistema modulo solar
fotovoltaico y batería de respaldo para la alimentación
de la estación meteorológica.
En cuanto a la alimentación de la estación meteorológica, y
después de haber hecho un cálculo del consumo de los
diferentes componentes de la estación incluyendo un Reuter se
consideró un módulo solar fotovoltaico de 50Wp con una
batería de 12v 9Ahdc, la caja en donde irán todos los
componentes es una PI65, así como sus respectivas
protecciones que se mostraran más tarde en el diagrama
esquemático. Para justificar la batería y el modulo se hizo de
la siguiente manera, en la (figura10) podemos ver el consumo
a plena carga (300mA) entonces así las cosas tenemos que,
consumo energético del sistema a plena carga es
12v×0,3A= 3,6Wh (Ecuacion1)
para que dure 24h se debe multiplicar el valor del consumo
energético por 24, por tal razón tenemos que,
24×3,6wh=86,4wh (Ecuacion2)
se instaló una batería de 9Ah Dc así que
12v×9Ah=108Wh (Ecuacion3)
que supera en un 30%el valor anterior, para cargar la batería
HSP (horas sol pico) es de 4,8 horas en esta región del país por
tal motivo tenemos que 108wh÷4,8h=22,5W considerando
perdidas por calentamiento nos queda un consumo energético
de 30W, por tal razón en las condiciones más desfavorables
nuestro sistema seguiría siendo funcional.
E. Estimar costos finales del proyecto
En esta parte del proyecto se hace una comparación de la
estación meteorológica (Figura7) WD-2900 de referencia
WD2900ET esta estación meteorológica es capaz de detectar
valores como dirección del viento, velocidad del viento,
temperatura, humedad relativa, e índice de pluviosidad con la
opción de que podemos añadir más sensores de acuerdo a
nuestra necesidad, los valores registrados pueden ser
almacenados con la posibilidad de decidir los intervalos de
tiempo para la toma de muestras, si el usuario lo desea puede
trasladar los datos memorizados desde la estación
meteorológica a un ordenador o también se puede transmitir
los datos de forma online directamente a un ordenador, la
encontramos en el mercado con un costo de ṩ17.334.730 pesos
colombianos [17]
Figura7: Estación Meteorológica WD2900ET.
Descripción UND Precio total
Raspberry PI 1 $ 175.000
Tarjeta SD 1 $ 40.000
Batería de 9Ah 1 $ 55.000
Cargador de batería 1 $ 45.000
sensor de humedad y temperatura 1 $ 20.000
Sensor de Presión Barométrica 1 $ 40.000
luz ambiente 1 $ 30.000
Nivel 1 $ 20.000
Anemómetro, SEN0186 1 $ 600.000
Caja IP 65 1 $ 350.000
Estructura tipo Trípode 1 $ 650.000
Arduino uno 1 $ 60.000
Expansión a Panel Solar 1 $ 200.000
Cables, canaletas y borneras 1 $ 150.000
Breakers y barraje 1 $ 85.000
TOTAL $ 2.520.000
Tabla1: Costos de la estación
Cabe resaltar que esto es con el ánimo de justificar nuestro
lema que la estación meteorológica que se construyo es de bajo
costo en ningún momento se tiene la intención de desprestigiar
este muy buen producto, ni su diseño que a nuestro criterio es
excelente.
La estación meteorológica que se construyó como un proyecto
de investigación para aspirar al título de tecnólogo en
mantenimiento electromecánico industrial en la universidad
Antonio Nariño sede santa marta, es capaz de detectar valores
como velocidad del viento, dirección del viento, humedad
relativa, presión atmosférica, temperatura, precipitaciones y
luz ambiente estos valores se pueden almacenar en una base de
datos con un intervalo de tiempo de 5 minutos por muestra , los
podemos trasladar a nuestro ordenador para su posterior
análisis en forma online, la ejecución de proyecto tuvo un costo
total de 2.520.000 pesos colombianos (tabla1).
F. Construcción y puesta en funcionamiento de la
estación meteorológica.
En función del diagrama esquemático de la estación
meteorológica y que posterior mente estaremos compartiendo
en el anexo (1) se muestra el registro fotográfico (Fifura8) se
fijaron a la caja los rieles omegas, el regulador de voltaje, y
bornera este es un paso del armado de la estación
meteorológica, así como se detalla el desarrollo del sistema de
adquisición de datos ya antes mencionado.
Figura8: Armado de la estación.
Se empezó con el montaje de la estación como tal, se trata de
ser lo más adjetivos posibles en lo que corresponde a las
imágenes para no desmejorar la calidad del documento, en la
(figura9) es el resultado de un recurso técnico propio para
facilitar las conexiones.
Figura9: Fabricación de placa de circuito.
Se fabricó una placa de circuito muy sencilla y funcional que
nos permite conectar la tarjeta de sensores y también el sensor
de luz ambiente que no viene incorporado en la placa, para
posterior mente conectarse con la placa Arduino en las entradas
correspondientes.
Esta placa se fabricó artesanalmente teniendo en cuenta
algunos aspectos técnicos para sí obtener resultados lo más
profesionales posibles. En la (figura10) se muestra la lectura
del consumo a plena carga. .
Figura10: Armado de la estación
Como se mencionó anterior mente el sistema operativo que se
le instalo a la raspberry pi ya que es software libre permite
hacer ajustes con el objetivo de deshabilitar funciones que no
se necesitan, con esto logramos disminuir un poco el consumo
de energía, la estación funciona con una batería de12voltios
9Ah DC que está conectada a un módulo solar fotovoltaico de
50W, que durante las horas del día el modulo solar carga la
batería por lo que no presento problema en la noche cuando no
se cuenta con la irradiación solar la batería tiene que asumir
toda la carga, en las lectura que se tomaron can la estación
trabajando a plena carga nos da un consumo 300mA, entonces
se utilizó la siguiente fórmula para calcular que tanto se
descarga la batería durante la noche.
TD=CDAh/consumoA (ecuación 4)
Para este caso que la batería es de12 voltios 9Ahdc y el
consumo real es de 300mA aplicando la formula se encontró
que la batería se descarga en 30 horas, se dedujo que la batería
se está descargando en un 50%, un resultado favorable con lo
que se concluye que se cumplen las recomendaciones del
fabricante y la vida útil de la batería se alarga al máximo.
1. Sistema de adquisición de datos
Hasta esta parte solo se ha desarrollado la parte tangible de la
estación o continuación se muestran detalles de la parte no
tangible de la estación meteorológica.
Muchas de las alternativas Open hardware, se hacen con
Arduino, pero Arduino es un sistema muy limitado, su
hardware, por tal motivo se debe pensar en un sistema de
desarrollo basado en una tiny PC empotrada. Estas tarjetas tiny
pc ofrecen mayores prestaciones que una Arduino
convencional, además que se pueden utilizar sistemas
avanzados de almacenamiento de datos como son, SQLite,
MariaDB, MySQL y otros motores de bases de datos para
organizar, almacenar y comprimir la información atravez de un
sistema entidad relación para una posterior visualización
atreves de sus librerías ya hechas, o se pueden consultar
haciendo dentro de la tiny PC un servidor Apache HTTML y
el uso de PHP u otro lenguaje basado en servidor para realizar
el diseño de una página web que pueda recopilar la
información.
A continuación, el diagrama de datos. A bajo nivel.
Figura11: Diagrama de datos a bajo nivel.
Como se observa en la gráfica anterior los sensores de
velocidad del viento, temperatura, humedad, dirección del
viento, precipitación, y presión barométrica, se encuentran en
la tarjeta de sensores, que es una tarjeta open hardware y open
software cuya información de operación y de código se
encuentran en la página web
https://wiki.dfrobot.com/Weather_Station_with_Anemometer
_Wind_vane_Rain_bucket_SKU_SEN0186.
Esta tarjeta recoge la información de los sensores a través de
sus análogos digitales, que se encuentran dentro de un
microcontrolador STC12L5608AD (anexo2) de la marca STC,
este micro recoge todos los datos analógicos a través de sus
ADC incorporados y digitales a través de comunicación I2C y
los envía de manera serial utilizando el siguiente formato.
c000s000g000t086r000p000h53b10020
donde
c000:Dirección del Viento, Grados Centígrados ºC
s000:Velocidad del Viento (1 minuto), 0.1 millas por Hora
g000:Velocidad del Viento (5 minuto), 0.1 millas por Hora
t086:temperatura, Grados Fahrenheit ºF
r000:Precipitación (1 Hora), 0.01 Pulgadas
p000:Precipitación (24 Hora), 0.01 Pulgadas
h53:Humedad, % (00%= 100)
b10020:atmosfera,0.1 hpa
esto es recibido por la placa arduino uno (anexo3)que recibe
10 muestras por segundo, de las cuales solo procesa 2 y le
añade a la cadena el sensor de luz que se encuentra ubicado
dentro del gabinete junto con el término “-E” que para el
software dentro de la raspberry pi (anexo4) entienda que ese es
el fin de la trama y pueda separar las variables, la aplicación de
estas dos constantes no es necesaria, pero por buenas
costumbres de programación se terminan colocando para poder
diferencial el principio de la trama del final, siendo la “c” el
principio y la “-E” el final.
El formato de la trama que sale de Arduino es el siguiente.
c000s000g000t086r000p000h53b10020i1000-E
Cadena 1 +
i1000:Intensidad de la Luz dentro del Gabinete de 0 a 1023
-E:Fin de la cadena
Que es la concatenación de la cadena anterior agregándole el
calor del sensor. El diagrama de flujo es el siguiente.
Figura12: Diagrama de flujo
Se observó en el diagrama de flujo anterior, primero se
inicializan las variables, y los puertos, después se evalúa si hay
un elemento en el buffer RS232, si no hay simplemente vuelve
y pregunta, si existe un valor en el puerto serial, lo analiza si es
un “Enter” código anscii “13” entonces incrementa una
variable si no vuelve y pregunta, al incrementar el contador el
analiza si es el 4to “Enter” para poder enviar la trama entera,
al 5to incremento se envía el valor del sensor junto con el valor
“-E” que significa el final de la trama y vuelve y comienza el
código de nuevo. El código Arduino lo encontramos en él
(anexo5).
En la raspberry pi se diseña un software que capture los datos,
no se utilizara el puerto serial de la raspberry pi por defecto,
debido a que el puerto trabaja a 3.3V, el puerto serial de la
raspberry pi se utilizar con un reductor de voltaje, pero por
motivos académicos y de alimentación de la tarjeta Arduino se
utiliza el puerto USB, esto reduciendo conexiones en la placa,
alimentando y comunicando la tarjeta por el mismo cable.
2. El software del servidor
I. Base de datos mariadb:
La base de datos mariadb es una base de datos, con diferentes
motores de búsqueda, y almacenamiento optimizado, también
posee integrado un conector especial que permite convertir un
computador en un servidor SQL, por tal motivo se utiliza
MariaDB anteriormente MYSQL debido a que es Open Source
y permite su uso sin necesidad de comprar una licencia,
además de convertir al PC en un servidor y el mismo
encargarse de las operaciones de buscaqueda y
almacenamiento a traves de un Conector especial hecho en
lenguaje Java llamado JConector, este conector funciona en
java utilizando para la comunicación con mariadb un lenguaje
llamado QUERY, debido a esto primero se debe modelar la
base de datos en un software de modelamiento de bases de
datos, MariaDB no trae una Interfax visual para la generación
de bases de datos como su antecesor, por tal motivo se utiliza
un software llamado Katrakuntur para el modelamiento y
obtención del código QUERY, que permite crear la tabla en la
Base de datos. Creación de la Base de datos con Katakuntur.
Kata kuntur es un software de modelamiento de bases de datos
gráfico, en el cual se pueden hacer un sistema entidad relación,
que permiten la compresión de la información, relacionando un
dato con una variable de menor valor, ahorrando espacio,
además de enlazar gran cantidad de datos con un registro
optimizando las búsquedas para el motor INO de la Base de
datos MariaDB
Figura13: Modelo entidad relación.
Se analizó en el modelo entidad relación anterior, se crean 2
tablas, una que es fechas, esta fecha genera una ID auto
incrementable que es una llave primaria al mismo tiempo que
no se puede repetir , con la cual cada vez que se ingrese una
fecha, ella se auto incrementara, efectuando la operación
automáticamente cada vez que se inserte un valor en fecha, este
valor de id será el valor de identificación de la siguiente tabla,
para poder extraer rápidamente los valores en una consulta y
así evitar que se repita un dato de varios bytes en la misma. La
tabla datos tiene los valores de temperatura, humedad,
precipitación, velocidad del viento, presión barométrica, en
formato decimal y para ahorrar espacio en los decimales, así
asegurando muchos datos en poco espacio, logrando así una
gran cantidad de valores en muy poco espacio.
El código que se introducirá en mariadb para la creación de las
tablas se encuentra en el (anexo6)
3. Instalación y puesta en marcha de mariaDb en la
raspberry PI.
Como la raspberry pi es un computador de bolsillo con sistema
operativo Linux, este puede ser manipulado por comandos, así
que la instalación de mariaDB se hará desde un repositorio por
tal motivo primero se abre una ventana de línea de comandos
desde el escritorio con privilegios de administrador root.
Figura14: Sentencias Mariadb
Se digita el anterior comando y se inicia el proceso se
instalación.
Al terminar el proceso de instalación se ingresa dentro de
mariaDB con el comando:
Figura14: Sentencias Mariadb
Se crea el usuario admin con el siguiente comando.
Figura14: Sentencias Mariadb
Donde va moisés se coloca uan. Y donde va ‘mi-super-
password’ colocar el password de la base de datos para el caso
de este proyecto ‘Admin123’.
Después se crea la base de datos con el nombre de estación con
el siguiente comando créate database mi-base-de-datos.
Después se copia el código QUERY de katakuntur en el
terminal finalizando al final con un ‘;’ para que ejecute el scrip
de manera línea.
Al finalizar colocar el comando ‘quit’ para salir de maria DB.
Para poder observar de manera gráfica la base de datos, se
descarga e instala la Aplicación PHPMYADMIN, que nos
permite darle una interfaz gráfica a la base de datos para poder
ser manipulada con mayor facilidad, debido a que es más
cómodo manipular los datos desde una interfaz gráfica los
datos.
Para instalar PHPmyadmin solo hay que digitar en la terminal
el siguiente comando y seguir los pasos.
sudo apt install phpmyadmin php-mbstring php-
gettext
Para poder probar los comandos QUERY, se ingresa en el
Reuter de la estación meteorológica, o se coloca en la misma
red donde se encuentre la rapberry pi y se digita la dirección IP
de la misma en un navegador web, /phpmyadmin. Es decir
http://192.168.1.100/phpmyadmin/
Figura15: Dirección IP
Al digitar y presionar enter, se iniciará el servidor web apache
integrado en la raspberry pi abriendo la interfaz instalada
. Figura16: Ingreso a PHPmyadmin
En la interfaz gráfica se coloca el nombre del usuario
anteriormente colocado en mariadb y la contraseña de la base
de datos ‘uan’ como usuario y la contraseña ‘admin123’, al
ingresar se obtendrá la interfaz gráfica del script anteriormente
ingresado desde la consola Linux.
Figura17: Ingreso a PHPmyadmin
Observen en la parte superior izquierda de la (figura14) se
pueden visualizar las bases de datos, una que es estación y la
otra que es un demo de Mariadb por defecto y que no es
borrado por motivos de estudio para las demás personas que
ingresen dentro de la estación meteorológica.
Figura18: Ingreso a PHPmyadmin
Al abrir la base de datos se puede visualizar las tablas junto con
las columnas ingresadas, que son los datos que mariaDB
maneja
Figura19: Ingreso a PHPmyadmin
Si se ingresa dentro de la tabla, se podrán observar los datos
dentro de la misma a manera de Excel, pudiendo visualizar sus
valores.
. Figura20: Código QUERY
En la parte inferior derecha se observan los datos almacenados
dentro de la base de datos y en la parte resaltada se observa la
sentencia en el lenguaje QUERY, que muestra todos los
resultados de una tabla.
Al visualizar la tabla de datos, también se observa el código
QUERY que entrega todos los resultados de la tabla.
Figura21: Datos almacenados
Para aprender a manejar el código QUERY Orientado a maria
db se aconseja buscar la documentación de la misma base de
datos
http://mysql.conclase.net/curso/?cap=013
Ahora se prueban la sentencia necesaria para el desarrollo del
proyecto, como lo son:
INSERT INTO fechas (fecha) VALUES ('02/03/2020');
Todas las sentencias se prueban dentro de la interfaz gráfica de
phpmyadmin
Figura22: Editor de sentencias
Como se puede observar PHPmyadmin también tiene un editor
de sentencias integrado, por tal motivo es una herramienta
apropiada para los novatos.
Implementación de MariaDB En java.
Primero se crean 2 clases llamadas Fecha y Datos, estas clases
contendrán toda la información para ser procesada, además
servirán de guía para no desordenar los datos, debido a que se
ajuntaran en un ARRAYSLIST, que es una clase de java que
permite un Arrays dinamico con objetos.
El código con el que se crearon las clases fecha y datos lo
encontramos en el (Anexo7).
Se crea la clase MariaDB dentro del programa para organizar
todas las sentencias, teniendo como entrada los objetos
formados por las clases lo encontramos en el(Anexo8).
En esta clase se encuentran las funciones necesarias para la
creación de listas largas a travez de ciclos y acumulación de
objetos gracias a la clase Arrayslist.
Ya habiendo comprobado que las funciones trabajan, se
procede a la adquisición de los datos y a la implementación de
estas sentencias tanto en el programa de adquisición de datos
en el servidor, como en el software consultas e incluso se
pueden utilizar en Android, debido a que java es standard para
todo.
4. Interfaz de adquisición.
El software del servidor debe recoger los datos. Por tal motivo
se realiza un diagrama de flujo básico para su funcionamiento.
Cabe resaltar las propiedades del sistema operativo Linux para
manejar varios procesos de manera paralela o lo que se conoce
en programación como el multithread o multihilo.
Figura23: Diagrama de flujo hilo principal
En el diagrama de flujo anterior se observan los procesos que
se desprenden del hilo principal, como se puede observar el
hilo principal tiene comunicación con los hilos segundarios,
todos los hilos pueden sacar la información uno del otro gracias
a las funciones declaradas en las clases, y a las interfaces que
permiten modificar datos del programa principal desde el hilo
segundario. El Hilo proceso RS232 es el proceso que se
encarga de leer los datos de la tarjeta Arduino a través del
puerto USB y los lee, a través de la librería serial RXTX de
lectura de puertos seriales para el lenguaje Java, esta librería se
encarga de administrar el Puerto “ttyUSB0” perteneciente al
puerto serial usb en Linux.
El hilo segundario Proceso de almacenamiento se encarga de
adquirir los datos cada determinado tiempo e insertarlos en la
tabla de la base de datos a través de un subproceso hecho con
el Jconector de mariaDB.
El proceso de almacenamiento es el proceso de
5. El hilo El proceso RS 232.
de adquisición de datos tendrá el formato mostrado en el
siguiente diagrama de flujo
Figura24: Diagrama de flujo hilo RS232
Apreciamos en el diagrama de flujo, primero se reciben los
datos y después se almacenan en una variable para separarlos,
se habilita un ciclo para recorrer cada uno de los elementos del
arrayslist y cuando se tope con una de las letras que simboliza
el inicio de cada variable y lo almacena en un objeto de la clase
Datos, al final limpia el bufer y duerme el hilo para evitar un
excesivo consumo de la CPU. El código desarrollado del hilo
en la IDE eclipse lo encontramos en el (Anexo9).
Para ejecutar el muestreo cada determinado tiempo, se hizo
otro hilo que trabajan paralelo junto a los anteriores, este hilo
tiene la siguiente forma.
El proceso que guarda la información dentro de la base de datos
cada determinado tiempo, se llama “CargadorData”, esta es de
la Clase heredada Thread, básicamente lo que hace es esperar
un tiempo e inmediatamente ejecuta una interface, que se
declara dentro el programa principal, esto debido, a que el hilo
“AdquisicionData” se encuentra declarado en el menú
principal y el programa pueda ser leído fácilmente desde el
programa principal sin necesidad de introducir a las personas
que deseen conocer el funcionamiento del sistema de una
manera desordenada, además es de buena costumbre de
programación que el código sea lo más claro posible el código
de proceso CargadorData lo encontramos en el (anexo10).
El programa principal es está regido por el siguiente diagrama
de flujo.
Figura25: diagrama de flujo cargador data
Se puede observar primero se inicializan las variables y los
hilos, después se hace una operación para leer el día en que se
inicia, si no está, entonces se inserta el día en la tabla “fechas”
en la base de datos mariaDB, después se inicializan los
botones, las tablas de la interfaz principal y por ultimo arranca
los hilos y el programa principal, hasta que el usuario cierre la
ventana, que cierra el hilo padre y forzara a cerrar a los hilos
hijos o creados el programa principal lo encontramos en el
(anexo11).
En el programa principal el método “initialize” equivale a la
parte de inicialización en el diagrama de flujo, aquí se inician
las acciones de los botones, que invocan los menús, además de
cargar la configuración guardada anteriormente, también se
inician los hilos invocando al método “IniciarHilos” como se
explicó anteriormente.
El resto de métodos son rutinas de apoyo, dentro del método
“iniciarHilos” se puede observarla inicializacion del puerto
serial y en el método “iniciarRutinas” se puede observar la
rutina de inserción a la base de datos utilizando el objeto creado
para ese fin que es derivado de la clase MariaDB el código
iniciar rutina lo encontramos en el (Anexo12).
Al conectarse a la tarjeta vía protocolos SSH, con el software
VNC, se observará la interfaz gráfica escrita en el código
anterior, este interfaz muestra las variables del puerto serial
actualizadas por el timer inicializado, este actualiza los datos
cada segundo.
Figura26: Interfax grafica
Como se muestra en la interfaz los Jlables (textos de la interfaz)
cumplen la función de avisarnos que muestran los sensores
escalados junto con el día y la hora, el dibujo fue hecho en
PAINT e insertado en los botones por medio de programación.
6. Comunicaciones con otros dispositivos A través de
los Protocolos TCP-IP.
Como la raspberry pi contiene un puerto Ethernet y contiene
una tarjeta inalámbrica Wifi, la tarjeta tiene todo lo necesario
para las comunicaciones vía protocolos TCP-IP, además de
contener un sistema operativo competente para el mismo fin.
A continuación, se presenta el diagrama de comunicaciones.
Figura27: Diagrama de comunicaciones
Analizando el diagrama de comunicaciones observamos, la
tarjeta externa se comunica por puerto serial con el arduino
agregándole un valor a la trama serial, el arduino se comunica
a manera serial con la raspberry pi dentro del gabinete, donde
se encuentra instalado el software de adquisición de datos, este
a su vez se encarga de hacer un puente con el Jconector con la
base de datos mariaDb que se encarga de las entradas y salidas
de la información, además de las consultas y gestión de puertos
e información, Mariadb en teoría puede soportar el número de
clientes que el hardware permita, para este prototipo se han
probado hasta 5 personas a manera simultánea y no se ha
colocado lenta la comunicación, esta a su vez a través del
puerto Ethernet permite la comunicación en la red local, a la
rapberry pi se le instala un software privativo gratuito que es el
Hamachi, este genera una VNP tipo tuneling que permite crear
redes LAN a través de internet, dándole la posibilidad a la
rapberry pi de comunicarse a través de internet desde una VNP
o si se le coloca a la rapberry Pi una IP publica no es necesario
el Hamachi, pero para este proyecto se decidió utilizar tal
software por efectos de costos.
El protocolo TCP-IP se encargará de la comunicación
bidireccional y MariaDb se encargará de atender las peticiones
de los clientes, por tal motivo se pasa al software de los
clientes.
7. Software Clients PC Windows-Mac.
Java es un lenguaje multiplataforma que permite reutilizar
código solo haciendo pocas modificaciones al código fuente,
este software funciona de la misma manera que el software
instalado en el servidor. Por tal motivo se van a reciclar todas
las clases, anteriormente mencionadas y se añadirá una más
que es la clase que se encarga de transformar las variables de
java en Excel A través de unas librerías llamadas APACHE
POI.
Primerio se debe pedir la dirección IP de la raspberry pi para
que el jconector se haga cargo de las consultas, posteriormente
se diseña la interfaz gráfica con una Jtable la cual debe ser
cargada con los días disponibles en la base de datos, para que
el usuario selecciones los que quiere adquirir, seleccione la ruta
de destino y por último genere el documento en Excel. .
Figura28: Interfax grafica
El botón con la sirve para borrar las muestras
seleccionadas con la sentencia QUERY escrita en la clase
MariaDB, y sirve para escribir los datos seleccionados.
El diagrama de flujo de la aplicación cliente es el siguiente.
Figura29: Diagrama de flujo cliente
El diagrama de flujo es un programa parecido al del servidor y
se reutilizo la mayoría de código, excepto que en este no se
utilizó la inserción ni tampoco la lectura del puerto serial, este
programa lee las fechas en la base de datos y las ingresa en un
Excel atreves del botón ok, también permite borrar fechas que
ya no son necesarias que estén dentro del sistemas y así pueden
borrar si quieren toda la base de datos remotamente.
El código principal del cliente lo encontramos en el (Anexo13).
Mirando el diagrama no se les hicieron modificaciones a las
clases creadas para el servidor por tal motivo es sencillo
entender este programa, como se puede observar en el evento
del botón, aceptar, se invoca una clase llamada Excel, después
de realizar las consultas de las muestras de los días
seleccionados.
A continuación, se presenta el diagrama de flujo de la clase
Excel.
Figura30: Diagrama de flujo clase Excel
Analizando se puede observar la clase Excel contiene métodos
que se ejecutaran en un hilo independiente el cual se tomara el
tiempo de almacenar todo el contenido en un archivo xls
gracias a la librería Apache POI.
A continuación, se muestra el código principal en el (anexo14).
IX. Recomendaciones
Podemos recomendar en un futuro hacer las siguientes mejoras
Un diseño más compacto con menos volumen.
mejorar la interfaz gráfica al igual que el software de
adquisición de datos ya que en esta parte del proyecto la
única limitación en la imaginación del programador.
El proyecto se centró en que los componentes fuesen de
bajo costos, al igual que las aplicaciones para el acceso
remoto a la estación meteorológica solo se pueden conectar
en tiempo real a la estación meteorológica un número
limitado de personas.
Utilizar aplicaciones pagas que nos ofrecen una IP publica
que establece un número ilimitado de usuarios.
El mantenimiento de la estación meteorológica se
recomienda hacer limpieza al gabinete con un intervalo de
tiempo de 90 días para eliminar el acceso de polvo esto se
puede hacer con una herramienta de soplado para no
maltratar las tarjetas.
Adaptar más sensores a la estación en un futuro.
X. CONCLUSIONES
De la construcción de la estación meteorológica se concluye
desde el contexto de los objetivos específicos lo siguiente.
a) La información recaudada para la realización del artículo
contribuyo de manera importante para la selección de los
componentes principales como la tarjeta Arduino Uno y
Raspberry pi, por su bajo costo disponibilidad en el
mercado alta eficiencia y compatibilidad con varios
sistemas operativos (Windows, Mac, Linux), las variables
a medir y la tarjeta de recopilación de señales análogos
digitales.
b) Las variables de velocidad, dirección del viento y
precipitaciones por medio del sensor 0186. Para la variable
de temperatura se utilizó el sensor DS18B20. Para la
variable de presión barométrica se utilizó el sensor
BMP180. Para medir la variable de humedad relativa se
utilizó el sensor DHT22. Para la variable luz ambiente el
sensor TEMT6000. Todos los sensores mencionados son
compatibles con la placa Arduino Uno.
c) Se desarrolló sistema de adquisición de datos e Interfax con
las aplicaciones MariaDB: Servidor instalado en la
Raspberry pi, PHPMyadmin: Proporciona Interfax grafica
para la visualización de los datos. Longmain ha machi: Para
crear una red de ordenadores. VNC viewer: acceso al
escritorio de manera remota. los protocolos de
comunicación son: I²C (Inter-integrated circuit) y SPI
(Serial peripheral interface).
d) De acuerdo con los cálculos eléctricos el sistema
seleccionado tiene un consumo de 3.6Wh (ecuacion1).
Teniendo un consumo total en 24 horas de 86.4Wh
(ecuacion2). La batería seleccionada es de 9AhDc. 12v su
capacidad es de 108Wh (ecuacion3) conexión en serie. El
panel seleccionado es de 50W poli cristalino marca powest
su conexión es en serie.
e) Se construyó la estación meteorológica de acuerdo al
diagrama esquemático (Anexo1) el proceso de armado de
la caja se puede evidenciar en el registro fotográfico
(figuras8,9,10), Se desarrolló sistema de adquisición de
datos cuando se conecten al servidor se puede visualizar la
Interfax grafica que muestra lectura de las variables
(figuras26 y 28) y posteriormente se pueden descargarlos
datos en un ordenador y se puso a prueba para hacer los
ajustes pertinentes.
f) El costo final de la estación meteorológica haciende a un
valor ṩ2,520,000 pesos tomando en cuenta que uno de los
objetivos es que sea de bajo costo se realizó comparación
con una estación WD2900ET (figura7) con un costo
aproximado de 17.334.730 pesos valor en el mercado actual
con características similares a la anterior mencionada dado
como principal objetivo el bajo costo este objetivo es
cumplido.
XI. Bibliografía
[1] «METEOCULTURA,» 26 02 2019. [En línea]. Available:
https://estaciondemeteorologia.com/que-es-una-estacion-
meteorologica/. [Último acceso: 02 02 2020].
[2] «enviraiot,» 19 07 2019. [En línea]. Available:
https://enviraiot.es/que-son-sensores-meteorologicos/.
[Último acceso: 02 02 2020].
[3] «Cambio Climatico Naciones Unidas,» 06 05 2020. [En
línea]. Available: https://www.un.org/es/sections/issues-
depth/climate-change/index.html.
[4] «Fenomeno de EL NIÑO en colombia,» 27 05 2020. [En
línea]. Available:
https://www.minagricultura.gov.co/atentos-
clima/Paginas/default.aspx.
[5] «NAYLAMP MECHATRONIC,» 11 02 2020. [En línea].
Available: https://naylampmechatronics.com/sensores-
posicion-inerciales-gps/357-sensor-de-presiontemperatura-
humedad-bme280.html.
[6] «cactus.io,» [En línea]. Available:
https://projects.raspberrypi.org/en/projects/build-your-own-
weather-station/2.
[7] «cactus.io,» 11 05 2020. [En línea]. Available:
http://cactus.io/hookups/sensors/barometric/bme280/hookup-
arduino-to-bme280-barometric-pressure-sensor-spi.
[8] «Build your own weather station,» 27 04 2020. [En línea].
Available: https://projects.raspberrypi.org/en/projects/build-
your-own-weather-station/2.
[9] A. Tobajas García, « openaccess.uoc.edu,» 09 06 2016. [En
línea]. Available: http://hdl.handle.net/10609/52761.
[10] E. Martinez L, «DEFINICIONES DE HUMEDAD Y SU
EQUIVALENCIA,» 27 04 2020. [En línea]. Available:
http://www.cenam.mx/dme/pdf/TM02.pdf.
[11] H. D. YOUNG y R. A. freedman, Fisica Universitaria Vol 13,
Pearson, 2014.
[12] «Meteorología , óptica y Precisión. Raig,» 29 10 2016. [En
línea]. Available: https://www.raig.com/blog/barometros-y-
presion-atmosferica-4b/.
[13] «Taller Virtual de Meteorología y Clima,» 27 04 2020. [En
línea]. Available:
http://meteolab.fis.ucm.es/meteorologia/precipitacion-y-
nubes.
[14] «IDEAM,» 27 04 2020. [En línea]. Available:
http://www.ideam.gov.co/documents/24155/123679/16-
90+HM+Brillo+solar+3+FI.pdf/612e0afe-928d-417c-99ed-
49e5fd792f38.
[15] O. Torrete Artero, Curso Practico de Arduino, Mexico:
AifaOmega, 2013.
[16] R. H. Sampieri, METODOLOGIA DE LA
INVESTIGACION, Mexico DF: Mc Graw Hill, 2014.
ANEXO(1) diagrama esquematico estacion meteorologica
ANEXO (2) diagrama esquemático de la tarjeta de sensores
ANEXO (3) diagrama esquemático Arduino uno
ANEXO (4) diagrama esquemático raspberry pi
ANEXO (5) código de Arduino
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX, inicialización del puerto serial
char x;
int sensorPin = A0;
int iluminacion=0;
int cont=0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
mySerial.begin(2400);
}
void loop() {
// put your main code here, to run repeatedly:
if (mySerial.available()) {
x=mySerial.read();
if(x==13){
cont++;
if(cont>=5){
Serial.print('i');
Serial.print(analogRead(sensorPin));
Serial.println('E');
cont=0;
}
}
else{
if(cont>=4){
Serial.write(x);
}
}
}
}
ANEXO (6) código katakuntur
CREATE TABLE `fechas` (
`fecha` TEXT NOT NULL,
`id` INTEGER NOT NULL,
PRIMARY KEY(`id`)
) ENGINE=INNODB;
CREATE TABLE `Datos` (
`direccionW` DECIMAL NOT NULL,
`humedad` DECIMAL NOT NULL,
`velW` DECIMAL NOT NULL,
`presipi` DECIMAL NOT NULL,
`direccionW` DECIMAL NOT NULL,
`presionBar` DECIMAL NOT NULL,
`hora` TEXT NOT NULL,
`fechas_id` INTEGER NOT NULL,
KEY(`fechas_id`)
) ENGINE=INNODB;
# GENERANDO RELACIONES
ALTER TABLE `Datos` ADD CONSTRAINT `datos_fechas_fechas_id` FOREIGN KEY (`fechas_id`) REFERENCES `fechas`(`id`) ON
DELETE NO ACTION ON UPDATE CASCADE;
ANEXO (7) Código de las clases fechas y datos
package uan.Tesis.Clases; public class Fechas { int id; String fecha; public Fechas(int id, String fecha) { super(); this.id = id; this.fecha = fecha; } public int getId() { return id; public void setId(int id) { this.id = id; public String getFecha() { return fecha; } public void setFecha(String fecha) { this.fecha = fecha; } } Clase Datos.
package uan.Tesis.Clases; public class Datos { private float temperatura,humedad,velW,presipi,direccionW,presionBar,luzAmb; private int fecha_datos; private String hora; public Datos() { super(); // TODO Auto-generated constructor stub } public Datos(float temperatura, float humedad, float velW, float presipi, float direccionW, float presionBar, float luzAmb,int fecha_datos, String hora) { super(); this.temperatura = temperatura; this.humedad = humedad; this.velW = velW; this.presipi = presipi; this.direccionW = direccionW; this.presionBar = presionBar; this.luzAmb = luzAmb; this.fecha_datos = fecha_datos; this.hora = hora; public float getTemperatura() { return temperatura; } public void setTemperatura(float temperatura) { this.temperatura = temperatura; } public float getHumedad() { return humedad; } public void setHumedad(float humedad) { this.humedad = humedad; } public float getVelW() { return velW; } public void setVelW(float velW) { this.velW = velW; } public float getPresipi() { return presipi; } public void setPresipi(float presipi) { this.presipi = presipi; } public float getDireccionW() { return direccionW; } public void setDireccionW(float direccionW) { this.direccionW = direccionW; } public float getPresionBar() { return presionBar; } public void setPresionBar(float presionBar) { this.presionBar = presionBar; } public String getHora() { return hora; } public void setHora(String hora) {
this.hora = hora; } public float getLuzAmb() { return luzAmb; } public void setLuzAmb(float luzAmb) { this.luzAmb = luzAmb; } public int getFecha_datos() { return fecha_datos; } public void setFecha_datos(int fecha_datos) { this.fecha_datos = fecha_datos; } }
ANEXO (8) código clase maría DB
package uan.Tesis.BD; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import uan.Tesis.Clases.Datos; import uan.Tesis.Clases.Fechas; public class MariaDB { private Connection conexion; public MariaDB(String ubicacionServidor) { // TODO Auto-generated constructor stub try { setConexion(DriverManager.getConnection("jdbc:mariadb://"+ubicacionServidor+":3306/estacion","uan", "admin123")); } catch (Exception e) { e.printStackTrace(); } } public void insertarFechas(Fechas datos) throws SQLException{ PreparedStatement pstmt = conexion.prepareStatement("INSERT INTO fechas (fecha) VALUES ("+ "'"+datos.getFecha()+"'" +" );"); pstmt.executeUpdate(); } public void insertarDatos(Datos datos) throws SQLException{ PreparedStatement pstmt = conexion.prepareStatement("INSERT INTO Datos (temperatura,humedad,velW,presipi,direccionW,luzAmb,presionBar,hora,fecha_datos) VALUES ("+ "'"+String.valueOf( datos.getTemperatura())+"',"+ "'"+String.valueOf( datos.getHumedad())+"',"+ "'"+String.valueOf( datos.getVelW())+"',"+ "'"+String.valueOf( datos.getPresipi())+"',"+ "'"+String.valueOf( datos.getDireccionW())+"',"+ "'"+String.valueOf( datos.getLuzAmb())+"',"+ "'"+String.valueOf( datos.getPresionBar())+"',"+ "'"+datos.getHora()+"',"+ "'"+String.valueOf( datos.getFecha_datos())+"'" +" );"); pstmt.executeUpdate(); } public void borrarDatosHora(Datos datos) throws SQLException{ PreparedStatement pstmt = conexion.prepareStatement("DELETE from Datos where fecha_datos="+String.valueOf(datos.getFecha_datos())+" AND hora="+datos.getHora()+";"); pstmt.executeUpdate(); } public void borrarFecha(Fechas datos) throws SQLException{ PreparedStatement pstmt = conexion.prepareStatement("DELETE from fechas where fecha="+datos.getFecha()+";"); pstmt.executeUpdate(); } public void borrarFechaXid(Fechas datos) throws SQLException{ PreparedStatement pstmt = conexion.prepareStatement("DELETE from fechas where id="+String.valueOf(datos.getId())+";"); pstmt.executeUpdate(); } public void borrarDatosFecha(Datos datos) throws SQLException{ PreparedStatement pstmt = conexion.prepareStatement("DELETE from Datos where fecha_datos="+String.valueOf(datos.getFecha_datos())+";"); pstmt.executeUpdate(); } public ArrayList<Fechas> consultarFechas(Datos datos) throws Exception { // TODO Auto-generated method stub ArrayList<Fechas> salida=null; PreparedStatement pstmt = conexion.prepareStatement("SELECT *FROM fechas;"); ResultSet rs=pstmt.executeQuery(); salida= rs2Fechas(rs); return salida; }
public ArrayList<Fechas> consultarFechas(String in) throws Exception { // TODO Auto-generated method stub ArrayList<Fechas> salida=null; PreparedStatement pstmt = conexion.prepareStatement("SELECT *FROM fechas where fecha='"+in+"';"); ResultSet rs=pstmt.executeQuery(); salida= rs2Fechas(rs); return salida; } public ArrayList<Fechas> consultarFechas(Datos datos,int limite) throws Exception { // TODO Auto-generated method stub ArrayList<Fechas> salida=null; PreparedStatement pstmt = conexion.prepareStatement("SELECT *FROM fechas LIMIT "+String.valueOf(limite)+";"); ResultSet rs=pstmt.executeQuery(); salida= rs2Fechas(rs); return salida; } public ArrayList<Datos> consultarAllDatos(Datos datos) throws Exception { // TODO Auto-generated method stub ArrayList<Datos> salida=null; PreparedStatement pstmt = conexion.prepareStatement("SELECT *FROM Datos LIMIT 15;"); ResultSet rs=pstmt.executeQuery(); salida= rs2Datos(rs); return salida; } public ArrayList<Datos> consultarDia(Datos datos) throws Exception { // TODO Auto-generated method stub ArrayList<Datos> salida=null; PreparedStatement pstmt = conexion.prepareStatement("SELECT *FROM Datos WHERE fecha_datos='"+String.valueOf(datos.getFecha_datos())+"';"); ResultSet rs=pstmt.executeQuery(); salida= rs2Datos(rs); return salida; } public ArrayList<Datos> consultarDia(String fecha) throws Exception { // TODO Auto-generated method stub ArrayList<Datos> salida=null; PreparedStatement pstmt = conexion.prepareStatement("SELECT *FROM Datos WHERE fecha='"+fecha+"';"); ResultSet rs=pstmt.executeQuery(); salida= rs2Datos(rs); return salida; } private ArrayList<Datos> rs2Datos(ResultSet rs) throws SQLException{ ArrayList<Datos> salida=new ArrayList<>(); while (rs.next()) { Datos row=new Datos(Float.valueOf(String.valueOf(rs.getObject(1))), Float.valueOf(String.valueOf(rs.getObject(2))), Float.valueOf(String.valueOf(rs.getObject(3))), Float.valueOf(String.valueOf(rs.getObject(4))), Float.valueOf(String.valueOf(rs.getObject(5))), Float.valueOf(String.valueOf(rs.getObject(6))), Float.valueOf(String.valueOf(rs.getObject(7))), Integer.valueOf(String.valueOf(rs.getObject(9))), String.valueOf(rs.getObject(8))); salida.add(row); } return salida; } private ArrayList<Fechas> rs2Fechas(ResultSet rs) throws SQLException{ ArrayList<Fechas> salida=new ArrayList<>(); while (rs.next()) { Fechas row=new Fechas(Integer.valueOf(String.valueOf(rs.getObject(2))), String.valueOf(rs.getObject(1))); salida.add(row); } return salida; } public Connection getConexion() { return conexion; } public void setConexion(Connection conexion) { this.conexion = conexion; }
ANEXO (9) código hilo adquisición de datos
import uan.Tesis.Clases.Datos; import uan.Tesis.Comunicacion.SerialPort; public class AdquisicionData extends Thread{ private Datos datos; private SerialPort puertoSerie; private boolean running,status; private int delayNoport; private int delaySiport; public AdquisicionData(SerialPort puertoSerie) throws Exception { super(); this.puertoSerie = puertoSerie; setDatos(new Datos())
inicializar(); } private void inicializar() throws Exception { // TODO Auto-generated method stub puertoSerie.openPort(); setRunning(true); } @Override public void run() { // TODO Auto-generated method stub super.run(); while(isRunning()){ if(puertoSerie.isAvaible()){ try { if(puertoSerie.getChar()=='c'){//lee la c sino manda un error de lectura setStatus(true); try { Thread.sleep(200); } catch (Exception e) { // TODO: handle exception System.out.println(e.getMessage()); System.out.println("Error Tiempo"); } String tempArray =leeVar('s'); getDatos().setDireccionW(Float.valueOf(eliminarZeros(tempArray))); tempArray=leeVar('g'); tempArray=leeVar('t'); getDatos().setVelW(Float.valueOf(eliminarZeros(tempArray))); tempArray=leeVar('r'); getDatos().setTemperatura(Float.valueOf(eliminarZeros(tempArray))); tempArray=leeVar('p'); tempArray=leeVar('h'); getDatos().setPresipi(Float.valueOf(eliminarZeros(tempArray))); tempArray=leeVar('b'); getDatos().setHumedad(Float.valueOf(eliminarZeros(tempArray))); tempArray=leeVar('*'); getDatos().setPresionBar(Float.valueOf(eliminarZeros(tempArray))); tempArray=leeVar('i'); tempArray=leeVar('E'); getDatos().setLuzAmb(Float.valueOf(eliminarZeros(tempArray))); puertoSerie.eliminarBuffer(); } else{ setStatus(false); } } catch (Exception e) { // TODO Auto-generated catch block System.out.println(e.getMessage()); System.out.println("Error Mayor"); } } else{ try { while(!puertoSerie.isAvaible()){ Thread.sleep(delayNoport); } } catch (InterruptedException e) { // TODO Auto-generated catch block System.out.println(e.getMessage()); } } } } private String eliminarZeros(String in){ try { in=in.replaceFirst("^0*", ""); in=in.replaceAll(". [^\\dA-Za-z]", ""); if((in=="")||(in.isEmpty())){ return "0"; } else { in=String.valueOf(Integer.parseInt(in)); return in; } } catch (Exception e) { // TODO: handle exception System.out.print(e.getMessage()); return "0"; } } private String leeVar(char tempVal) throws Exception{ String sal = ""; char temChar='A'; while((temChar=puertoSerie.getChar())!=tempVal){ Thread.sleep(5); sal+=temChar; } return sal; } public SerialPort getPuertoSerie() { return puertoSerie; } public void setPuertoSerie(SerialPort puertoSerie) {
this.puertoSerie = puertoSerie; } public boolean isRunning() { return running; } public void setRunning(boolean running) { this.running = running; } public int getDelayNoport() { return delayNoport; } public void setDelayNoport(int delayNoport) { this.delayNoport = delayNoport; } public boolean isStatus() { return status; } public void setStatus(boolean status) { this.status = status; } public int getDelaySiport() { return delaySiport; } public void setDelaySiport(int delaySiport) { this.delaySiport = delaySiport; } public Datos getDatos() { return datos; } public void setDatos(Datos datos) { this.datos = datos; }
ANEXO (10) código cargador data
package uan.Tesis.AdquisicionDatos; public class CargadorData extends Thread{ private AccionesCargadorData accionCargar; private int tiempo; private boolean stop,exit; public CargadorData(AccionesCargadorData cargar, int tiempo) { super(); this.accionCargar = cargar; this.tiempo = tiempo; } @Override public void run() { // TODO Auto-generated method stub super.run(); do{ if(!stop){ try { Thread.sleep(getTiempo()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(accionCargar!=null){ accionCargar.cargar(); } } else{ try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }while(!exit); } public int getTiempo() { return tiempo; } public void setTiempo(int tiempo) { this.tiempo = tiempo; } public boolean isExit() { return exit; } public void setExit(boolean exit) { this.exit = exit; } public boolean isStop() { return stop; } public void setStop(boolean stop) { this.stop = stop; } public AccionesCargadorData getAccionCargar() { return accionCargar; }
public void setAccionCargar(AccionesCargadorData accionCargar) { this.accionCargar = accionCargar; }
ANEXO (11) programa principal
package uan.Tesis.Main; import java.awt.Color; import java.awt.EventQueue; import java.awt.Image; import javax.swing.JFrame; import uan.Tesis.AdquisicionDatos.AccionesCargadorData; import uan.Tesis.AdquisicionDatos.AdquisicionData; import uan.Tesis.AdquisicionDatos.CargadorData; import uan.Tesis.BD.MariaDB; import uan.Tesis.Clases.Datos; import uan.Tesis.Clases.Fechas; import uan.Tesis.Comunicacion.SerialPort; import uan.Tesis.Herramientas.Herramientas; import uan.Tesis.Herramientas.JPFondoMain; import uan.Tesis.Herramientas.OpArchivos; import uan.Tesis.InterfazGrafica.Ajuste; import javax.swing.ImageIcon; import javax.swing.JButton; import java.awt.event.ActionListener; import java.io.File; import java.sql.SQLException; import java.util.ArrayList; import java.util.Calendar; import java.awt.event.ActionEvent; import javax.swing.Timer; import javax.swing.JLabel; public class MainForm { private static String comLinux="/dev/ttyUSB0"; private static String dirRaiz="/home/pi/Documents/tesis/"; private static String dirConf="Conf/"; private static String archConf="conf.txt"; private static String archTimer="time.txt"; private AdquisicionData lector; private SerialPort puertoSerial; private Timer timer; private CargadorData cargador; private Fechas hoy; private Datos datoActual; private String servidor="192.168.1.65";//"localhost"; private float[] escalamiento; private JFrame frame; private JLabel txtVelw; private JLabel txtTemp; private JLabel txtHum; private JLabel txtDirWind; private JLabel txtPresBar; private JLabel txtLuz; private JLabel txtPresipi; private JLabel lblDate; private JLabel lblHora; private JButton btnStopplay; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { MainForm window = new MainForm(); window.frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the application. */ public MainForm() { initialize(); } /** * Initialize the contents of the frame. */ private void initialize() { datoActual=new Datos(); frame = new JFrame();
JPFondoMain fondo=new JPFondoMain("/uan/Tesis/Artes/artes pc.png"); frame.setContentPane(fondo); frame.setBounds(0, 0, 656, 416); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().setLayout(null); JButton btnSalir = new JButton(); formatIcon(btnSalir, "/uan/Tesis/Artes/iconsalir.png"); btnSalir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { puertoSerial.closePort(); System.exit(0); } }); btnSalir.setBounds(369, 314, 67, 75); frame.getContentPane().add(btnSalir); JButton btnPrueba = new JButton(); formatIcon(btnPrueba, "/uan/Tesis/Artes/conf.png"); btnPrueba.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Ajuste ventana=new Ajuste(OpArchivos.readTp(dirRaiz+dirConf+archConf)); ventana.setVisible(true); if(ventana.isOk()){ String[] conf=ventana.getOpciones(); OpArchivos.writeTp(conf, dirRaiz+dirConf+archConf); escalamiento=asignarEscalamientos(conf); cargador.setTiempo(Integer.valueOf(conf[2])*1000); } } }); btnPrueba.setBounds(283, 314, 67, 75); frame.getContentPane().add(btnPrueba); txtVelw = new JLabel(); txtVelw.setBounds(350, 263, 86, 20); frame.getContentPane().add(txtVelw); txtTemp = new JLabel(); txtTemp.setBounds(224, 127, 77, 20); frame.getContentPane().add(txtTemp); txtHum = new JLabel(); txtHum.setBounds(224, 167, 77, 20); frame.getContentPane().add(txtHum); txtDirWind = new JLabel(); txtDirWind.setBounds(473, 169, 86, 20); frame.getContentPane().add(txtDirWind); txtPresBar = new JLabel(); txtPresBar.setBounds(473, 207, 86, 20); frame.getContentPane().add(txtPresBar); txtLuz = new JLabel(); txtLuz.setBounds(473, 127, 86, 20); frame.getContentPane().add(txtLuz); txtPresipi = new JLabel(); txtPresipi.setBounds(224, 207, 77, 20); frame.getContentPane().add(txtPresipi); lblDate = new JLabel("Date"); lblDate.setBounds(430, 90, 155, 14); fondo.add(lblDate); lblHora = new JLabel("Date"); lblHora.setBounds(82, 90, 155, 14); fondo.add(lblHora); btnStopplay = new JButton(); btnStopplay.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { String[] opciones=OpArchivos.readTp(dirRaiz+dirConf+archConf); if(cargador.isStop()){ opciones[1]="false"; formatIcon(btnStopplay, "/uan/Tesis/Artes/cancelar.png"); } else{ opciones[1]="true"; formatIcon(btnStopplay, "/uan/Tesis/Artes/ok.png"); } cargador.setStop(Boolean.valueOf(opciones[1])); OpArchivos.writeTp(opciones, dirRaiz+dirConf+archConf); } }); btnStopplay.setBounds(508, 227, 77, 69); fondo.add(btnStopplay); frame.setUndecorated(true); frame.setLocationRelativeTo(null); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); inicializarPuertos(); inicializarHilos(); inicializarTimers(); iniciarRutinas(); //rutinas de archivos y arranque } private boolean dirSinoexistLocrea(String dir){ File tempArc=new File(dir); if(!tempArc.exists()){ return tempArc.mkdirs(); } else return false; } private void formatIcon(JButton in,String dir){
in.setIcon(new ImageIcon(new ImageIcon(getClass(). getResource(dir)).getImage().getScaledInstance(74, 60, Image.SCALE_SMOOTH))); in.setBackground(new Color(0, 0, 0, 0)); in.setBorder(null); } private void iniciarRutinas() { // TODO Auto-generated method stub //verificando directorios. dirSinoexistLocrea(dirRaiz); dirSinoexistLocrea(dirRaiz+dirConf); //verificar configuracion File tempArc=new File(dirRaiz+dirConf+archConf); if(!tempArc.exists()){ String[] opcionesDefault={"localhost","true","1000","1","1","1","1","1","1"}; if(!OpArchivos.writeTp(opcionesDefault,dirRaiz+dirConf+archConf)){ Herramientas.ventanaAlerta("No Guardo Conf", "no guardo a configuracion."); System.exit(0); } } //Cargar configuracion String[] conf=OpArchivos.readTp(dirRaiz+dirConf+archConf); servidor=conf[0]; escalamiento=asignarEscalamientos(conf); //insertar dia insertarDias(); cargador=new CargadorData(new AccionesCargadorData() { @Override public void cargar() { // TODO Auto-generated method stub MariaDB tempInsertar=new MariaDB(servidor); try { tempInsertar.insertarDatos(datoActual); System.out.println("dato Insertado"); } catch (SQLException e) { // TODO Auto-generated catch block //e.printStackTrace(); System.out.print(e.getMessage()); Herramientas.ventanaAlerta("no esta Insertando Datos", "Insertar Datos"); } } }, (Integer.valueOf(conf[2])*1000)); cargador.setStop(Boolean.valueOf(conf[1])); if(cargador.isStop()){ formatIcon(btnStopplay, "/uan/Tesis/Artes/ok.png"); } else{ formatIcon(btnStopplay, "/uan/Tesis/Artes/cancelar.png"); } cargador.start(); private float[] asignarEscalamientos(String[] datos){ float[] temp=new float[7]; for(int cont=0; cont<=5; cont++){ temp[cont]=Float.valueOf(datos[3+cont]); } return temp; } private void insertarDias(){ setHoy(new Fechas(0, verDiaMesAño())); MariaDB tempCons=new MariaDB(servidor); ArrayList<Fechas> tempFechas=null; try { tempFechas =tempCons.consultarFechas(getHoy().getFecha()); if(tempFechas.size()>=1){ setHoy(tempFechas.get(0)); } else{ tempCons.insertarFechas(getHoy()); tempFechas =tempCons.consultarFechas(getHoy().getFecha()); if(tempFechas.size()>=1){ setHoy(tempFechas.get(0)); } else{ throw new Exception(); } } } catch (Exception e) { // TODO Auto-generated catch block System.out.print(e.getMessage()); Herramientas.ventanaAlerta("Error inicio rutinas", "Contacte al desarrollador,Insertar dias"); System.exit(0); } } private void inicializarTimers() { // TODO Auto-generated method stub timer = new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub datoActual.setDireccionW(lector.getDatos().getDireccionW()); datoActual.setVelW(lector.getDatos().getVelW()*((float) 0.44704)*escalamiento[0]); datoActual.setHumedad(lector.getDatos().getHumedad()*escalamiento[1]); datoActual.setTemperatura((float) (((lector.getDatos().getTemperatura()-32)*(0.56))*escalamiento[2])); datoActual.setPresipi(lector.getDatos().getPresipi()*((float) 0.254)*escalamiento[3]); datoActual.setPresionBar((lector.getDatos().getPresionBar()/10)*escalamiento[4]);
datoActual.setLuzAmb(lector.getDatos().getLuzAmb()*escalamiento[5]/10); datoActual.setFecha_datos(getHoy().getId()); datoActual.setHora(verHoraMinSeg()); txtDirWind.setText(String.valueOf(datoActual.getDireccionW())); txtVelw.setText(String.valueOf(datoActual.getVelW())); txtHum.setText(String.valueOf(datoActual.getHumedad())); txtTemp.setText(String.valueOf(datoActual.getTemperatura())); txtPresipi.setText(String.valueOf(datoActual.getPresipi())); txtPresBar.setText(String.valueOf(datoActual.getPresionBar())); txtLuz.setText(String.valueOf(datoActual.getLuzAmb())); lblDate.setText(verDiaMesAño()); lblHora.setText(datoActual.getHora()); if(cargador.isStop()){ } else{ } if(!verDiaMesAño().equals(getHoy().getFecha())){ insertarDias(); } } }); timer.start(); } private String verDiaMesAño(){ Calendar calendario = Calendar.getInstance(); String salida=(calendario.get(Calendar.DAY_OF_MONTH)<10) ? "0":"" ; salida+=String.valueOf(calendario.get(Calendar.DAY_OF_MONTH))+"/"; salida+=(calendario.get(Calendar.MONTH)<9) ? "0":"" ; salida+=String.valueOf(calendario.get(Calendar.MONTH)+1)+"/"; salida+=String.valueOf(calendario.get(Calendar.YEAR)); return salida; } private String verHoraMinSeg(){ Calendar calendario = Calendar.getInstance(); String salida=(calendario.get(Calendar.HOUR_OF_DAY)<10) ? "0":"" ; salida+=String.valueOf(calendario.get(Calendar.HOUR_OF_DAY))+":"; salida+=(calendario.get(Calendar.MINUTE)<10) ? "0":"" ; salida+=String.valueOf(calendario.get(Calendar.MINUTE)+1)+":"; salida+=(calendario.get(Calendar.SECOND)<10) ? "0":"" ; salida+=String.valueOf(calendario.get(Calendar.SECOND)); return salida; } private void inicializarPuertos() { // TODO Auto-generated method stub puertoSerial=new SerialPort(comLinux,9600);//"COM5",9600); } private void inicializarHilos() { // TODO Auto-generated method stub try { lector=new AdquisicionData(puertoSerial); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } lector.setDelayNoport(1000); lector.start(); } public static String getDirRaiz() { return dirRaiz; } public static void setDirRaiz(String dirRaiz) { MainForm.dirRaiz = dirRaiz; } public static String getDirConf() { return dirConf; } public static void setDirConf(String dirConf) { MainForm.dirConf = dirConf; } public static String getArchConf() { return archConf; } public static void setArchConf(String archConf) { MainForm.archConf = archConf; } public static String getArchTimer() { return archTimer; } public static void setArchTimer(String archTimer) { MainForm.archTimer = archTimer; } public Timer getTimer() { return timer; } public void setTimer(Timer timer) { this.timer = timer; } public String getServidor() { return servidor; } public void setServidor(String servidor) { this.servidor = servidor; } public Fechas getHoy() {
return hoy; } public void setHoy(Fechas hoy) { this.hoy = hoy; } public Datos getDatoActual() { return datoActual; } public void setDatoActual(Datos datoActual) { this.datoActual = datoActual; } }
ANEXO (12) código iniciar rutinas
private void iniciarRutinas() { // TODO Auto-generated method stub //verificando directorios. dirSinoexistLocrea(dirRaiz); dirSinoexistLocrea(dirRaiz+dirConf); //verificar configuracion File tempArc=new File(dirRaiz+dirConf+archConf); if(!tempArc.exists()){ String[] opcionesDefault={"localhost","true","1000","1","1","1","1","1","1"}; if(!OpArchivos.writeTp(opcionesDefault,dirRaiz+dirConf+archConf)){ Herramientas.ventanaAlerta("No Guardo Conf", "no guardo a configuracion."); System.exit(0); } } //Cargar configuracion String[] conf=OpArchivos.readTp(dirRaiz+dirConf+archConf); servidor=conf[0]; escalamiento=asignarEscalamientos(conf); //insertar dia insertarDias(); cargador=new CargadorData(new AccionesCargadorData() { @Override public void cargar() { // TODO Auto-generated method stub MariaDB tempInsertar=new MariaDB(servidor); try { tempInsertar.insertarDatos(datoActual); System.out.println("dato Insertado"); } catch (SQLException e) { // TODO Auto-generated catch block //e.printStackTrace(); System.out.print(e.getMessage()); Herramientas.ventanaAlerta("no esta Insertando Datos", "Insertar Datos"); } } }, (Integer.valueOf(conf[2])*1000)); cargador.setStop(Boolean.valueOf(conf[1])); if(cargador.isStop()){ formatIcon(btnStopplay, "/uan/Tesis/Artes/ok.png"); } else{ formatIcon(btnStopplay, "/uan/Tesis/Artes/cancelar.png"); } cargador.start(); }
ANEXO (13) código del cliente
package uan.Tesis.Main; import java.awt.EventQueue; import java.awt.Image; import javax.swing.JFrame; import uan.Tesis.BD.MariaDB; import uan.Tesis.Clases.Datos; import uan.Tesis.Clases.Fechas; import uan.Tesis.Herramientas.Herramientas; import uan.Tesis.Herramientas.JPFondoMain; import uan.Tesis.Herramientas.Loading; import uan.Tesis.Tablas.ATMFechas; import uan.Tesis.Tablas.RenderFechas; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JLabel; import java.awt.event.ActionListener; import java.util.ArrayList; import java.awt.event.ActionEvent; import javax.swing.JScrollPane; import javax.swing.JTable; public class MainClient { private JFrame frame; private JTable tablaDias; private String ip; private ATMFechas contenidotabla;
private String rutaGuardado; private JLabel lblIP; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { MainClient window = new MainClient(); window.frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the application. */ public MainClient() { initialize(); } /** * Initialize the contents of the frame. */ private void initialize() { rutaGuardado=""; frame = new JFrame(); JPFondoMain fondo=new JPFondoMain("/uan/Tesis/Artes/maincliente.png"); frame.setContentPane(fondo); frame.setBounds(0, 0, 1080, 720); frame.setLocationRelativeTo(null); frame.setUndecorated(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().setLayout(null); JButton btnSeleccionar = new JButton(); btnSeleccionar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JFileChooser tempventana=new JFileChooser(); try { if(tempventana.showSaveDialog(null)==JFileChooser.APPROVE_OPTION){ setRutaGuardado(tempventana.getSelectedFile().getAbsolutePath()+".xls"); } } catch (Exception e2) { // TODO: handle exception } } }); btnSeleccionar.setIcon(new ImageIcon(new ImageIcon(getClass(). getResource("/uan/Tesis/Artes/archivo.png")).getImage().getScaledInstance(74, 60, Image.SCALE_SMOOTH))); //btnSeleccionar.setBackground(new Color(0, 0, 0, 0)); btnSeleccionar.setBorder(null); btnSeleccionar.setBounds(808, 311, 127, 74); fondo.add(btnSeleccionar); JButton btnAjustes = new JButton(); btnAjustes.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { inicioRutinas(); } }); btnAjustes.setIcon(new ImageIcon(new ImageIcon(getClass(). getResource("/uan/Tesis/Artes/conf.png")).getImage().getScaledInstance(74, 60, Image.SCALE_SMOOTH))); //btnAjustes.setBackground(new Color(0, 0, 0, 0)); btnAjustes.setBorder(null); btnAjustes.setBounds(764, 453, 75, 67); fondo.add(btnAjustes); JButton btnSalir = new JButton(); btnSalir.setIcon(new ImageIcon(new ImageIcon(getClass(). getResource("/uan/Tesis/Artes/iconsalir.png")).getImage().getScaledInstance(74, 60, Image.SCALE_SMOOTH))); //btnSalir.setBackground(new Color(0, 0, 0, 0)); btnSalir.setBorder(null); btnSalir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { System.exit(0); } }); btnSalir.setBounds(902, 453, 75, 67); fondo.add(btnSalir); JButton btnGenerar = new JButton(); btnGenerar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(tablaDias.getSelectedRowCount()>=1){ if(!getRutaGuardado().isEmpty()){ MariaDB consulTemp=new MariaDB(getIp()); ArrayList<Datos> datosTotales=new ArrayList<>(); ArrayList<Fechas> fechasParciales=new ArrayList<>(); int[] listaSeleccionados=tablaDias.getSelectedRows(); for(int cont=0; cont<=listaSeleccionados.length-1; cont++){
fechasParciales.add(contenidotabla.getDatos().get(listaSeleccionados[cont])); try { datosTotales.addAll(consulTemp.consultarDia(String.valueOf(fechasParciales.get(cont).getId()))); } catch (Exception e1) { // TODO Auto-generated catch block Herramientas.ventanaAlerta(e1.getMessage(), "Seleccion"); } } Loading cargador=new Loading(datosTotales, fechasParciales, getRutaGuardado()); cargador.start(); } else{ Herramientas.ventanaAlerta("No ha seleccionado la rura de guardado", "Error de Guardado"); setRutaGuardado(""); } } else{ Herramientas.ventanaAlerta("No se Han seleccionado Fechas", "No ha Seleccionado una Fecha"); } } }); btnGenerar.setIcon(new ImageIcon(new ImageIcon(getClass(). getResource("/uan/Tesis/Artes/ok.png")).getImage().getScaledInstance(74, 60, Image.SCALE_SMOOTH))); //btnGenerar.setBackground(new Color(0, 0, 0, 0)); btnGenerar.setBorder(null); btnGenerar.setBounds(470, 453, 75, 67); fondo.add(btnGenerar); lblIP = new JLabel(""); lblIP.setBounds(333, 580, 333, 31); fondo.add(lblIP); JScrollPane scrollPane = new JScrollPane(); scrollPane.setBounds(94, 282, 352, 245); fondo.add(scrollPane); tablaDias = new JTable(); setContenidotabla(new ATMFechas()); tablaDias.setModel(contenidotabla); tablaDias.setDefaultRenderer(String.class, new RenderFechas() ); scrollPane.setViewportView(tablaDias); JButton btnEliminar = new JButton(); btnEliminar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(tablaDias.getSelectedRowCount()>=1){ int[] listaSeleccionados=tablaDias.getSelectedRows(); MariaDB tempconsult=new MariaDB(getIp()); for(int cont=0; cont<=listaSeleccionados.length-1; cont++){ try { tempconsult.borrarDatosFecha(String.valueOf((contenidotabla.getDatos().get(listaSeleccionados[cont]).getId()) ) ); tempconsult.borrarFecha(contenidotabla.getDatos().get(listaSeleccionados[cont])); } catch (Exception e2) { // TODO: handle exception Herramientas.ventanaAlerta(e2.getMessage(), "Borrado de datos"); } llenadoTablas(); } } else{ Herramientas.ventanaAlerta("No se Han seleccionado Fechas", "No ha Seleccionado una Fecha"); } } }); btnEliminar.setIcon(new ImageIcon(new ImageIcon(getClass(). getResource("/uan/Tesis/Artes/cancelar.png")).getImage().getScaledInstance(74, 60, Image.SCALE_SMOOTH))); btnEliminar.setBorder(null); //btnEliminar.setBackground(new Color(0, 0, 0, 0)); btnEliminar.setBounds(470, 343, 75, 67); fondo.add(btnEliminar); inicioRutinas(); llenadoTablas(); } private void llenadoTablas() { // TODO Auto-generated method stub try { MariaDB tempConsulta=new MariaDB(getIp()); contenidotabla.setDatos(tempConsulta.consultarFechas()); for(int cont=0; cont<=contenidotabla.getDatos().size()-1; cont++){ tempConsulta.consultarFechasCantidadDatos(contenidotabla.getDatos().get(cont)); } contenidotabla.fireTableDataChanged(); } catch (Exception e) { // TODO Auto-generated catch block Herramientas.ventanaAlerta("no se conecto al servidor, reinicie la aplicacion", "Arranque del Sistema"); System.exit(0); } } private void inicioRutinas() { // TODO Auto-generated method stub PedirIP tempVentana=new PedirIP(); tempVentana.setVisible(true); if(!tempVentana.isOk()){ Herramientas.ventanaAlerta("Salida Anormal del Programa", "Intente de nuevo");
System.exit(0); } if(tempVentana.getIp().isEmpty()){ Herramientas.ventanaAlerta("Direccion IP Vacia", "Intente de nuevo"); System.exit(0); } setIp(tempVentana.getIp()); lblIP.setText(getIp()); } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public ATMFechas getContenidotabla() { return contenidotabla; } public void setContenidotabla(ATMFechas contenidotabla) { this.contenidotabla = contenidotabla; } public String getRutaGuardado() { return rutaGuardado; } public void setRutaGuardado(String rutaGuardado) { this.rutaGuardado = rutaGuardado; } }
ANEXO (14) código principal Excel
package uan.Tesis.Herramientas; import java.util.ArrayList; import uan.Tesis.Clases.Datos; import uan.Tesis.Clases.Fechas; public class GenerarExcel extends Thread{ private ArrayList<Datos> Muestras; private String salida; private Acciones states; private ArrayList<Fechas> fechas; public GenerarExcel(ArrayList<Datos> muestras,ArrayList<Fechas> fechas, String salida) { super(); Muestras = muestras; this.salida = salida; this.setFechas(fechas); } @Override public void run() { // TODO Auto-generated method stub super.run(); try { sleep(1500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //int numMuestras=getMuestras().size(); String[] titulos={"Hora:Min:Seg", "Humedad","Temperatura","Int Luz", "Vel Viento","Dir Viento","Presion Bar","Presipitacion"}; setMSN("Separando Muestras"); setPorc(0); ArrayList<ArrayList<Datos>> datos=new ArrayList<>(); setMSN("Preparando Objetos"); int contFinal=0; for(int cont=0; cont<= fechas.size()-1; cont++){ datos.add(new ArrayList<>()); for(int contaux=0; contaux<= fechas.get(cont).getCant()-1; contaux++){ datos.get(cont).add(Muestras.get(contFinal)); contFinal++; } } setPorc(50); setMSN("Preparando Excel"); Excel excel =new Excel(getSalida()); excel.setAcciones(new Excel.Acciones() { @Override public void actualizarPorc(int ent) { // TODO Auto-generated method stub setPorc(ent); } }); for(int cont=0; cont<= fechas.size()-1; cont++){ setMSN("Escribiendo Datos Estacion Meteorologica"); excel.CrearHoja("Datos "+fechas.get(cont).getFecha().replace('/', '-') ); escribirND(excel, m2object(datos.get(cont)), titulos, cont); } excel.SeleccionarHoja(0); excel.GuardarLibro(); if(states!=null){ states.finExcel(); } } private void escribirND(Excel excel,ArrayList<ArrayList<Object>> objI1,String[] titulos ,int leaf){
excel.SeleccionarHoja(leaf); excel.escribirLinea(titulos, 1, 1); if(objI1.size()>=1){ excel.escribirTabla(objI1, 2, 1); }else{ excel.unionCeldas(leaf, 2, 4, 1, 5); excel.escribirCeldaC("No Hay Datos", 2, 1); } excel.ajustarColumnas(1, 5); } private void setMSN(String msn){ if(states!=null){ states.mensaje(msn); } } private void setPorc(int msn){ if(states!=null){ states.actualizarPorc(msn); } } // String[] titulos={"Hora:Min:Seg", "Humedad","Temperatura","Int Luz", "Vel Viento","Dir Viento","Presion Bar","Presipitacion"}; private ArrayList<ArrayList<Object>> m2object(ArrayList<Datos> temp){ ArrayList<ArrayList<Object>> salida=new ArrayList<>(); for(int cont=0; cont<=temp.size()-1; cont ++){ salida.add(new ArrayList<>()); salida.get(cont).add(temp.get(cont).getHora()); salida.get(cont).add(String.valueOf(temp.get(cont).getHumedad())); salida.get(cont).add(String.valueOf(temp.get(cont).getTemperatura())); salida.get(cont).add(String.valueOf(temp.get(cont).getLuzAmb())); salida.get(cont).add(String.valueOf(temp.get(cont).getVelW())); salida.get(cont).add(String.valueOf(temp.get(cont).getDireccionW())); salida.get(cont).add(String.valueOf(temp.get(cont).getPresionBar())); salida.get(cont).add(String.valueOf(temp.get(cont).getPresipi())); } return salida; } public ArrayList<Datos> getMuestras() { return Muestras; } public void setMuestras(ArrayList<Datos> muestras) { Muestras = muestras; } public String getSalida() { return salida; } public void setSalida(String salida) { this.salida = salida; } public Acciones getStates() { return states; } public void setStates(Acciones states) { this.states = states; } public ArrayList<Fechas> getFechas() { return fechas; } public void setFechas(ArrayList<Fechas> fechas) { this.fechas = fechas; } public interface Acciones{ public void actualizarPorc(int ent); public void mensaje(String msn); public void finExcel(); } }