View
5
Download
0
Category
Preview:
Citation preview
CONTROL REMOTO DE UNA BIOCHIMENEA POR MEDIO DE
UNA APLICACIÓN ANDROID
PRESENTADO POR: CARLOS ALBERTO MANTILLA NOVA
CODIGO: 20082005038
DIRECTOR: Prof. JULIAN ROLANDO CAMARGO LOPEZ
PROYECTO DE GRADO
UNIVERSIDAD DISTRITAL FRANCISCO JOSE DE CALDAS
PROYECTO CURRICULAR DE INGENÍERIA ELECTRÓNICA
BOGOTA D.C.
2019
2
AGRADECIMIENTOS
Mis más sinceros agradecimientos a todos mis amigos, familiares, maestros, grupos de
trabajo que me acompañaron en la realización de esta meta, por aportarme grandes conocimientos
en el trascurso de esta carrera universitaria y de la vida. La culminación de este proyecto es también
el triunfo de todos aquellos a que me dedicaron el tiempo para asesorarme, enseñarme y
corregirme.
A mis padres por toda la paciencia y sabiduría que me han trasmitido, por enseñarme a
perseverar y a soñar, por enseñarme a creer que cualquier cosa es posible con dedicación y esfuerzo
continuado.
A mis hermanos que son mi ejemplo a seguir desde que tengo uso de conciencia, por
aportarme tantos conocimientos e ideas, por ser una guía y un faro a seguir.
Muchos agradecimientos a todos mis maestros, no solo por sus conocimientos sino además
por su experiencia y sabiduría en varios ámbitos de la ingeniería electrónica. Por su paciencia para
enseñar y por excelentes métodos de aprendizaje que son las que hacen grande esta carrera de
Ingeniería electrónica.
A la Universidad Distrital por permitirme cumplir mi sueño de ser Ingeniero Electrónico,
por facilitarme de todo el material de estudio como libros, computadores, equipos de laboratorio
etc. así como espacios para la socialización y el deporte.
Por último, pero no menos importante, al Fabricante de Biochimeneas CLIMALIVE, por
facilitarme varios elementos materiales de este proyecto, sin los cuales habría sido imposible llevar
a cabo este proyecto de grado.
3
Índice
1. INTRODUCCION .................................................................................................... 9
2. PLANTEAMIENTO DEL PROBLEMA ............................................................... 10
3. OBJETIVOS ........................................................................................................... 11
3.1. Objetivo General ................................................................................................. 11
3.2. Objetivos Específicos .......................................................................................... 11
4. JUSTIFICACION ................................................................................................... 12
5. MARCO TEORICO................................................................................................ 13
5.1. Biochimenea ........................................................................................................ 13
5.1.1. Quemador ...................................................................................................... 13
5.1.2. Combustible .................................................................................................. 13
5.1.3. Seguridad ...................................................................................................... 13
5.1.4. Rendimiento .................................................................................................. 13
5.2. Microcontrolador ................................................................................................. 14
5.2.1. Comunicación UART.................................................................................... 15
5.2.2. Conversor Analógico Digital ........................................................................ 16
5.2.3. Protocolo de Comunicación SPI ................................................................... 17
5.2.4. Protocolo de Comunicación I2C ................................................................... 18
5.2.5. PWM ............................................................................................................. 19
5.2.6. Fuentes de interrupción ................................................................................. 20
5.3. Visualizador LCD ............................................................................................... 21
5.4. Lenguaje de programación C .............................................................................. 21
5.4.1. Entorno de programación de PIC C Compiler .............................................. 22
5.5. Sensores de distancia de Tiempo de vuelo (TOF)............................................... 23
5.6. Acelerómetro ....................................................................................................... 23
5.7. Termocupla.......................................................................................................... 24
5.8. Transformador Flyback ....................................................................................... 24
5.9. Aplicaciones Android .......................................................................................... 25
5.9.1. Actividades .................................................................................................... 26
5.9.2. Servicios ........................................................................................................ 26
5.9.3. Entorno de programación de Android Studio ............................................... 27
4
5.10. Comunicación inalámbrica .............................................................................. 28
5.10.1. Bluetooth ..................................................................................................... 28
5.10.2. Bluetooth Low Energy(BLE) ...................................................................... 28
6. ESTADO DEL ARTE............................................................................................. 29
7. METODOLOGIA ................................................................................................... 30
7.1. FASE 1 Análisis de requerimientos .................................................................... 30
7.2. FASE 2: Acondicionamiento de sensores, módulos y comunicación con la
aplicación Android .................................................................................................................... 30
7.3. FASE 3: Diseño electrónico y de la aplicación Android .................................... 32
7.3.1. Bomba de combustible .................................................................................. 32
7.3.2. Generador de alto voltaje .............................................................................. 33
7.3.3. Fuente de poder y reguladores de tension ..................................................... 33
7.3.4. Diseño del programa del microcontrolador................................................... 33
7.4. FASE 3: Autonomía ............................................................................................ 34
7.5. FASE 4: Elaboración del Prototipo ..................................................................... 34
7.6. FASE 5: Comprobación y Validación ................................................................. 34
7.7. Diagrama de bloques ........................................................................................... 35
8. ANALISIS Y DESARROLLO ............................................................................... 37
8.1. Sensor de distancia .............................................................................................. 38
8.2. Baterías de Litio .................................................................................................. 39
8.3. Medición de carga de la batería........................................................................... 40
8.4. Termocupla.......................................................................................................... 42
8.5. Acelerómetro ....................................................................................................... 43
8.6. Módulo de comunicación Bluetooth ................................................................... 44
8.7. Circuito Electrónico ............................................................................................ 45
8.7.1. Control PWM de la bomba de combustible .................................................. 45
8.7.2. Generador de alta tensión .............................................................................. 45
8.7.3. Circuito Anti rebote para el pulsador ............................................................ 47
8.7.4. Circuito de alimentación y de carga de las baterías ...................................... 47
8.8. Microcontrolador ................................................................................................. 48
8.8.1. Configuración del microcontrolador ............................................................. 49
8.8.2. Variables y métodos del programa ................................................................ 50
8.8.3. Interrupciones ................................................................................................ 51
5
8.8.4. Proceso principal ........................................................................................... 52
8.8.5. Funciones ...................................................................................................... 56
8.9. Interfaz ICSP (In-circuit serial programming) .................................................... 64
8.10. Aplicación Android ......................................................................................... 65
8.11. Visualizador LCD ............................................................................................ 73
8.12. Impreso PCB.................................................................................................... 74
8.13. Autonomia ....................................................................................................... 74
8.14. Diseño del prototipo Encapsulado ................................................................... 75
8.15. Flotador ............................................................................................................ 80
9. ANALISIS DE RESULTADOS ............................................................................. 82
9.1. Costos de producción y desarrollo ...................................................................... 90
10. Conclusiones ........................................................................................................... 91
11. ALCANCES Y LIMITACIONES .......................................................................... 92
11.1. Alcances ........................................................................................................... 92
11.2. Limitaciones .................................................................................................... 92
12. REFERENCIAS ...................................................................................................... 93
13. ANEXOS ................................................................................................................ 96
13.1. Circuito electrico ............................................................................................. 96
13.2. Aplicacion Android ......................................................................................... 97
13.2.1. DeviceList.java............................................................................................ 97
13.2.2. BluetoothLeService.java ........................................................................... 103
13.2.3. Home.java ................................................................................................. 109
13.2.4. ONCH.java ................................................................................................ 122
13.3. Manual de operación ..................................................................................... 133
6
Índice de Figuras
Comparación entre chimenea tradicional y ecológica. [8] ................................................ 14
Trama con 6 bits de datos, dos bits de parada y sin bit de paridad a 9600 BAUD [15] ... 15
Esquema de conexiones entro dos dispositivos con puerto UART [16] ........................... 16
Circuito de muestreo y retención, y registro de aproximaciones sucesivas [18] .............. 17
Conexión Maestro-esclavo entre dos dispositivos SPI[18] ............................................... 17
Topología típica de una comunicación I2C maestro y esclavos [19] ................................ 18
Variación de la potencia según en ciclo de trabajo de la señal PWM [20] ....................... 19
Señal analógica luego de aplicar un filtro RC a la señal PWM [20]................................. 20
Componentes del módulo Cristal líquido ML016L [17] .................................................. 21
Proceso de compilación de un lenguaje de alto nivel a bajo nivel [21] ............................ 22
Espacio de trabajo de PIC C [22] ...................................................................................... 22
topología de un sensor TOF (tiempo de vuelo) [24] ......................................................... 23
Esquema eléctrico básico para hacer funcionar un transformador Flyback [27] .............. 25
Entorno de programación de Android Studio ................................................................... 27
Diagrama de bloques, estructura del sistema .................................................................... 35
Arreglo de resistencias para un divisor resistivo que medirá el nivel de carga de las baterías
....................................................................................................................................................... 40
Esquema de conexión para comunicar el modulo con el microcontrolador[26] ............... 43
Esquema de pines del módulo de comunicación Bluetooth HM-10 ................................. 45
Esquema eléctrico para controlar la bomba de combustible por medio de la señal PWM 45
Esquema eléctrico de potencia para controlar el encendido del arco eléctrico en el
transformador flyback ....................................................................................................... 46
Circuito Antirrebote para controlar la biochimenea por medio de un pulsador ................ 47
Esquema eléctrico para regular el voltaje del sistema y de carga de las baterías ............. 48
Interfaz ICSP para facilitar la programación del microcontrolador[38] ........................... 64
Diagrama de flujo general entre las actividades, servicio de enlace de la aplicación y
microcontrolador en la biochimenea ................................................................................. 65
Diagrama de flujo de la clase DeviceList.java .................................................................. 66
diagrama de flujo de las excepciones y permisos de la aplicación ................................... 67
Diagrama de flujo de la clase BluetoothLeService.java ................................................... 68
Diagrama de flujo de la clase Home.java.......................................................................... 69
Diagrama de flujo de la clase ONCH.java ........................................................................ 70
Interfaz gráfica de las actividades Devicelist y Home ...................................................... 71
Interfaz gráfica de la actividad ONCH.............................................................................. 71
Evento de desconexión esporádica y conexión con el modulo bluetooth en la biochimenea
....................................................................................................................................................... 72
La aplicación recibe una alerta de vibración durante la combustión, o una temperatura alta
antes de la combustión ...................................................................................................... 72
7
Modulo que se encarga de convertir la comunicación en paralelo a una serial I2C ......... 73
Diseño del circuito impreso (PCB) ................................................................................... 74
Diseño y dimensiones de la estructura principal de la biochimenea ................................. 76
Tapa superior donde se ubican los botones, LCD y la entrada para recargar el tanque de
combustible ....................................................................................................................... 76
Canal donde ocurre la combustión del etanol ................................................................... 77
Tapa de orificios por donde saldrá la llama proveniente de la combustión que ocurre en la
canal inferior ..................................................................................................................... 77
Tapa del tanque de combustible donde se ubica el sensor de distancia ............................ 78
Tanque de combustible donde se ubica la bomba de combustible y el flotador ............... 78
Biochimenea semi-ensamblada ......................................................................................... 79
Biochimenea completamente ensamblada ........................................................................ 79
Flotador terminado en base a los cálculos realizados ....................................................... 81
Log de mensajes de la aplicación Android en el escaneo de dispositivos bluetooth ........ 82
Log de mensajes de la aplicación Android cuando se conecta a un dispositivo bluetooth 83
Log de mensajes cuando se programa un tiempo específico y es enviado al
microcontrolador ............................................................................................................... 84
Log de mensajes cuando termina el tiempo programado .................................................. 85
(a):Log de mensajes en el evento de desconexión esporádica y posterior
reconexión.(b)Mensaje emergente mientras la aplicación se conecta nuevamente .......... 85
Log de mensajes cuando se actualiza el tiempo en la actividad ONCH ........................... 86
Log de mensajes cuando el usuario desea apagar la combustión de la llama por medio de
actividad ONCH ................................................................................................................ 86
Log de mensajes cuando se programa un tiempo de combustión para consumir todo el
combustible disponible ..................................................................................................... 87
Log de mensajes cuando la biochimenea recibe una vibración y es enviada una alerta a la
aplicación .......................................................................................................................... 87
Mensaje de alerta cuando la aplicación recibe una alerta de vibración ............................ 88
Log de mensajes donde la aplicación consulta al microcontrolador si la biochimenea está
quemando combustible...................................................................................................... 88
Log de mensajes cuando el microcontrolador envía una alerta de temperatura alta y la
aplicación la muestra con un mensaje e impide la ignición del combustible.................... 89
8
Índice de Tablas
Tabla 1: Comparativa entre los diferentes sensores considerados para desarrollar el
proyecto ............................................................................................................................. 38
Tabla 2: Características principales de la batería principal y secundaria.......................... 40
Tabla 3: comparativa entre los dos módulos de termocupla mejor aptos para el sistema 43
Tabla 4: Comparación del consumo eléctrico en diferentes tecnologías inalámbricas [33]
....................................................................................................................................................... 44
Tabla 5: Comparativa de los diferentes tipos de microcontroladores considerados para ser
implementado en el sistema .............................................................................................. 49
Tabla 6: Consumo eléctrico de cada componente electrónico en cada estado de
funcionamiento .................................................................................................................. 75
Tabla 7: Consume eléctrico de los componentes que consumen energía de la batería
secundaria .......................................................................................................................... 75
Tabla 8: Datos físicos de los materiales que componen el flotador .................................. 80
Tabla 9: Detalle de los costos de producción y desarrollo. ............................................... 90
9
1. INTRODUCCION
Las biochimeneas cumplen la función de generar energía calorífica a base de un
combustible líquido como el etanol, a una baja emisión de CO2, sin instalaciones externas de
electricidad o combustible, que en el mercado nacional se encuentran a la venta para ser
manipuladas de forma manual, por lo que se desea innovar tecnológicamente la operación y el
funcionamiento de una biochimenea, aumentando sus capacidades generales tanto en autonomía,
comodidad y funcionalidad.
La implementación de un control a distancia a una biochimenea a base de combustible
etílico, se trata directamente como desarrollar un proyecto de IOT(Internet of things), en el que es
necesario el uso de la electrónica digital y comunicación a distancia, se deben utilizan sensores y
actuadores debido a la naturaleza liquida del combustible, por el concepto básico del quemador de
combustible, y de los requerimientos del prototipo final. Se deben tener en cuenta diferentes
parámetros y umbrales de seguridad para cumplir con un estándar de calidad que se le debe
proporcionar al usuario. El sistema toma las señales de los sensores y las señales de entrada
operadas por el usuario y este avanza de un evento a otro.
Se analiza que tipos de sensores son los más adecuados para este proyecto, que sean
económicos y de fácil adquisición, y el tipo de microcontrolador que tenga las capacidades de
recibir las señales de los sensores y controlar los componentes que interviene directamente con la
combustión del combustible.
Una parte fundamental del proyecto es la aplicación Android, que se comunica
inalámbricamente con el microcontrolador y que envía tanto las decisiones del usuario como
recibir las señales de los sensores en la biochimenea.
El sistema requiere de una estructura rígida y resistente al calor, que se desarrolla en la
etapa final del proyecto, porque se trata de una estructura que necesita las métricas físicas de la
placa de circuitos electrónicos.
10
2. PLANTEAMIENTO DEL PROBLEMA
Las Chimeneas de etanol ofrecen características que las chimeneas tradicionales y de gas
no tienen, son ecológicas, económicas, se instalan fácilmente, y su portabilidad para trasportarlas
a otra área debido a su fácil instalación. [1][2]
En la actualidad, en la región Colombiana, la interacción entre el usuario y una
biochimenea adquirida en el mercado nacional, se hace de manera manual, el usuario mismo se
encarga de verter el combustible en el quemador de la biochimenea, debe encargarse de encender
la llama, por medio de un ignitor, como un encendedor, involucrando su integridad física y
poniendo en potencial peligro su alrededor, con una posible propagación de una llama indeseada.
[1][3]
Es por esto que se hace necesaria encontrar una forma de que la interacción entre el usuario
y la chimenea sea mínima, darle mayor seguridad al usuario en el manejo del combustible y del
encendido de la chimenea, reduciendo al mínimo la posibilidad de que el combustible haga
ignición por fuera del quemador, y lo más importante reducir el contacto que tiene el usuario con
el combustible y la llama, dándole seguridad y practicidad al momento de operar su chimenea.
Además, el usuario al estar familiarizado con operar dispositivos de su hogar de manera
remota, como televisores, equipos de sonido, etc. También resultaría practico operar su
biochimenea de manera remota.
Al automatizar electrónicamente la chimenea se logra alejar al usuario de la chimenea, sin
embargo, para poder controlarla remotamente se puede hacer uso de un control remoto específico
para esta función, como el caso fuera de un televisor o un equipo de sonido, por lo que surge la
pregunta: ¿Es posible operar todas las funciones de una Biochimenea de manera segura y eficiente
de manera que pueda ser operada remotamente como si fuera un televisor u otro equipo de
entretenimiento?
Se plantea automatizar todas las funciones de la chimenea a partir de un microcontrolador,
sensores, actuadores, y con una comunicación inalámbrica a un dispositivo móvil Android, el
usuario podrá interactuar con la biochimenea, por medio de una aplicación.
11
3. OBJETIVOS
3.1. Objetivo General
Diseñar e Implementar un sistema para controlar, monitorizar y proveer combustión segura
en una biochimenea.
3.2. Objetivos Específicos
Diseñar el sistema eléctrico y electrónico que controle las acciones y procesos de la
biochimenea que garantice seguridad, calidad y bajos costos.
Facilitar el uso de una biochimenea por medio de una aplicación Android, por la cual se
controla y se monitoriza los procesos que se llevan a cabo.
Comprobar y validar el funcionamiento del sistema de acuerdo a los requerimientos.
12
4. JUSTIFICACION
En la realización de este proyecto se hará uso de áreas de la ingeniería electrónica, como
la instrumentación industrial, el diseño digital con microcontroladores, electrónica básica, y
electrónica de potencia, además de áreas como la programación orientada a objetos, herramientas
con las cuales se desea buscar comodidad y practicidad. En la actualidad resulta practico la
implementación de un control remoto que esté integrado como una aplicación en un Smartphone
o cualquier dispositivo móvil. Es por medio de esta dispositivo que se desea que el usuario
interactué con la biochimenea, por practicidad.
Ecológicamente, una biochimenea tiene una gran ventaja sobre cualquier otro tipo de
calefacción, al quemarse el etanol este emite bajos niveles de CO2 y H2O [4], al contrario del gas
y la madera, que emite altos niveles de CO2, siendo un contaminante natural y que requiere de
ductos de escape o de zonas muy ventiladas [5], además, el aire acondicionado presenta también
una desventaja porque que el aire debe pasar por filtros que acumulan suciedad del ambiente
circundante, además de tener un alto consumo eléctrico debido a la naturaleza de su
funcionamiento. [6]
Socialmente, la comodidad y la seguridad que provee una solución que controle los
procesos de una chimenea, presenta una ventaja para el usuario, porque el proyecto se enfoca en
implementar una mejora tecnológica para hacer más fácil la operación de la biochimenea.
Se desea realizar este proyecto, debido a que en la actualidad el mercado nacional de las
biochimeneas aún es reciente, no se ha modernizado tecnológicamente el funcionamiento, la
operación de la biochimenea aún se realiza de forma manual y además se tiene la oportunidad de
implementar este proyecto para un fabricante de biochimeneas local.
De manera personal, este proyecto se eligió debido a que se pueden aplicar varias áreas de
la ingeniería electrónica donde se me facilita resolver problemas y donde tengo más afinidad,
también por la posibilidad de poder aplicar esta tecnología de resolver este problema en particular
a otros problemas de la ingeniería.
13
5. MARCO TEORICO
5.1. Biochimenea
Las chimeneas de etanol son un concepto relativamente nuevo que por la naturaleza del
combustible no requiere ductos para la emisión de gases tóxicos al exterior; debido al estado
líquido del etanol, no necesita una acometida o suministro constante ya que es retenido por el
quemador en compartimientos internos, gracias a estas características permite una fácil instalación,
movilidad y reubicación, de la misma manera las posibilidades de diseños son muy amplias.
Todas las chimeneas están compuestas por una estructura y uno o varios quemadores de
etanol que son el principal elemento de la chimenea. [2]
5.1.1. Quemador
Parte fundamental de la chimenea, su función de almacenamiento y de recamara de
combustión, que permite la quema segura de etanol, construido en acero inoxidable de alta
densidad, ofrece longevidad a través de los años de uso, ofreciendo la seguridad necesaria sin
riesgos.
El quemador es una recamara de combustión en acero inoxidable que absorbe y almacena
el combustible y lo libera lentamente en la combustión.
Completamente sellado garantiza la seguridad de la llama protegiéndolo al usuario y a las
personas o animales que se encuentran cerca.
Es la investigación y la elección de los materiales para el adecuado funcionamiento, lo que
permite un mejoramiento en el rendimiento y funcionalidad. El uso de modernos compuestos para
la estabilidad de la combustión y el control de calidad permiten una sólida construcción de este
elemento de vital importancia para la chimenea. [2]
5.1.2. Combustible
Combustible de origen vegetal, en forma líquida y almacenable, que al hacer combustión
se convierte en energía calórica con bajos índices de CO2 (comparable a 2 velas encendidas o 3
personas respirando en una misma habitación), sus llamas se caracterizan por el color amarillo en
las crestas y azul celeste en la base. [2]
5.1.3. Seguridad
Cada chimenea incorpora un robusto quemador en acero inoxidable que permite la
combustión segura del etanol soportando altas temperaturas sin que se altere ni se pierdan
propiedades funcionales, estructurales o estéticas. [7]
5.1.4. Rendimiento
El bioetanol, al hacer combustión, genera un alto poder calorífico, que se proyecta más por
convección que por radiación, y lo que es más importante, el 100% de las calorías emitidas
permanecen dentro de la sala en donde esté en funcionamiento, puesto que el hecho de no generar
humo, provoca que no haya ningún tipo de escape energético. Por lo tanto, una biochimenea en
14
funcionamiento puede suponer un ahorro en calefacción. En la figura 1 se observa una
comparación entre una chimenea tradicional y una Ecológica. [8]
Figura 1: Comparación entre chimenea tradicional y ecológica. [8]
El cálculo de la potencia calorífica requerida para una estancia puede determinarse con la
siguiente fórmula: Volumen = largo x ancho x alto (en metros). Potencia calorífica requerida en
Kw/h = Volumen x 0.04. Para una habitación de unos 30 metros cuadrados con una altura de techo
estándar de 2,5metros (volumen=75), una chimenea de bioetanol con una capacidad calorífica de
3 kW/h más que suficiente como sistema de calefacción. [2]
5.2. Microcontrolador
Un microcontrolador es un circuito integrado digital que puede ser usado para diversos
propósitos debido a sus registros programables. Está compuesto por una unidad central de proceso
(CPU), memorias (ROM y RAM) y líneas de entrada y salida (periféricos).
Un microcontrolador puede usarse para muchas aplicaciones algunas de ellas son: manejo
de sensores, controladores, juegos, calculadoras, agendas, avisos lumínicos, secuenciador de luces,
cerrojos electrónicos, control de motores, relojes, alarmas, robots, entre otros.
Como el hardware ya viene integrado en un solo chip, para usar un microcontrolador se
debe especificar su funcionamiento por software a través de programas que indiquen las
instrucciones que el microcontrolador debe realizar. En una memoria se guardan los programas y
un elemento llamado CPU se encarga de procesar paso por paso las instrucciones del programa.
Los lenguajes de programación típicos que se usan para este fin son ensamblador y C, pero antes
de grabar un programa al microcontrolador hay que compilarlo a hexadecimal que es el formato
con el que funciona el microcontrolador.
Para diseñar programas es necesario conocer los bloques funcionales básicos del
microcontrolador, estos bloques son:
CPU (Unidad central de proceso)
Memoria ROM (Memoria de solo lectura)
Memoria RAM (Memoria de acceso aleatorio)
15
Líneas de entrada y salida (Periféricos)
La CPU posee, de manera independiente, una memoria de acceso rápido para almacenar
datos denominada registros, si estos registros son de 8 bits se dice que el microcontrolador es de 8
bits. [9]
5.2.1. Comunicación UART
El transmisor y receptor asíncrono universal es el dispositivo que controla los puertos y
dispositivos serie. Se encuentra integrado en los microcontroladores, es comúnmente conocido
como puerto serial.
La función principal de un puerto serial, es la de empacar y des-empacar paquetes de datos
binarios seriales. Como resultado, la serialización significa convertir un dato paralelo (byte) a un
conjunto de pulsos seriales que puedan ser recibidos y enviados por una línea de transmisión.
En primer lugar, el protocolo serial opera mediante tres condiciones digitales básicas: inicio
de transmisión (IT), paridad (P) y fin de transmisión (FT). Estas condiciones son sincronizadas
mediante un oscilador interno. El generador permite controlar la velocidad del puerto serial. Por
lo tanto, la velocidad se mide en baudios
Para configurar al módulo se requiere indicar la velocidad de operación. Los BAUDios que
es una medida de cuantos bits por segundo se van a transmitir, se configuran mediante un registro
de propósito específico. Dependiendo del lenguaje de programación la configuración puede ser
relativamente sencilla. (Valdes Perez & Pallas Areny, 2007)
También es necesario configurar cuantos bits de parada y si habrá o no bit de paridad. Una
de las configuraciones más usadas para un puerto serial es:
8 bits de datos
1 bit de parada
Sin bit de paridad
1 bit de inicio
Velocidad de 9600 BAUD
En la figura 2 se observa una trama conformada por los bits antes mencionados y su velocidad
Figura 2: Trama con 6 bits de datos, dos bits de parada y sin bit de paridad a 9600 BAUD [15]
16
Para que pueda haber una sincronización de los datos enviados, se requiere que ambos
dispositivos que usen el mismo puerto serial, tengan la misma configuración como se muestra en
la figura 3.
Figura 3: Esquema de conexiones entro dos dispositivos con puerto UART [16]
5.2.2. Conversor Analógico Digital
La conversión analógica-digital consiste básicamente en realizar de forma periódica
medidas de la amplitud de una señal, redondear sus valores a un conjunto finito de niveles
preestablecidos de tensión conocidos como niveles de cuantificación y registrarlos como números
enteros en cualquier tipo de memoria o soporte.
El funcionamiento de la conversión analógico - digital se caracteriza por tener información
analógica que no es directamente manipulable, ni procesable, mediante sistemas digitales o a través
de un ordenador, pero sí lo son las señales digitales que pueden almacenarse indefinidamente, y
pueden incluso reproducir la señal analógica sin error apreciable.
La cuantificación de una señal analógica es el proceso por el cual los valores continuos de
una señal analógica se convierten en series de valores numéricos discretos correspondientes a los
diferentes niveles o variaciones de voltajes que contiene la señal analógica original. Por tanto,
cuantificar representa el componente de muestreo de las variaciones de valores de tensiones o
voltajes tomados en diferentes puntos de la onda sinusoidal, que permite medirlos y asignarles sus
correspondientes valores en el Sistema numérico, antes de convertir esos valores en sistema
numérico binario.
El puerto ADC de un microcontrolador se compone de circuitos de muestreo y retención
que se utilizan para muestrear una señal analógica en un instante dado y mantener el valor de la
muestra durante tanto tiempo como sea necesario. Luego con ayuda de los registros de
aproximaciones sucesivas, se obtiene una conversión Analógico-Digital de forma precisa. (Valdes
Perez & Pallas Areny, 2007)
Tal circuito está representado en la Figura 4, la señal analógica entra a un circuito de
muestreo y retención, y luego al convertidor Analogico-Digital que se compone de un registro de
aproximaciones sucesivas.
17
Figura 4:Circuito de muestreo y retención, y registro de aproximaciones sucesivas [18]
Después de realizada la cuantificación, los valores de las tomas de voltajes se representan
numéricamente por medio de códigos y estándares previamente establecidos. Lo más común es
codificar la señal digital en código numérico binario.
5.2.3. Protocolo de Comunicación SPI
El protocolo de comunicación SPI (Serial Peripheral Interface) trabaja de forma sincrónica
en modo full duplex para recibir y transmitir información, permitiendo que dos dispositivos puedan
comunicarse entre sí al mismo tiempo utilizando canales diferentes o líneas diferentes en el mismo
cable. Al ser un protocolo síncrono el sistema cuenta con una línea adicional a la de datos encarga
de llevar el proceso de sincronismo.
Figura 5: Conexión Maestro-esclavo entre dos dispositivos SPI[18]
18
Dentro de este protocolo se define un maestro que será aquel dispositivo encargado de
transmitir información a sus esclavos. Los esclavos serán aquellos dispositivos que se encarguen
de recibir y enviar información al maestro. El maestro también puede recibir información de sus
esclavos, cabe destacar. Para que este proceso se haga realidad es necesario la existencia de dos
registros de desplazamiento, uno para el maestro y uno para el esclavo respectivamente. Los
registros de desplazamiento se encargan de almacenar los bits de manera paralela para realizar una
conversión paralela a serial para la transmisión de información. (Valdes Perez & Pallas Areny,
2007)
5.2.4. Protocolo de Comunicación I2C
El protocolo de comunicación I2C (Inter-Integrated Circuit) es uno de los modos de trabajo
del módulo SSP (puerto serial síncrono) del microcontrolador PIC, en la comunicación I2C se
utilizan dos hilos a lo que se conoce como bus I2C, a estos hilos se conectan los dispositivos que
se puedan comunicar mediante el protocolo I2C, por uno de los hilos se enviará una señal de reloj
para la sincronización y por el otro hilo se enviarán o recibirán datos, se pueden conectar varios
dispositivos de los que uno de ellos será el maestro, es el que generará la señal de reloj además de
decidir cuándo se inicia o finaliza la comunicación y si la comunicación será de recepción o
transmisión de datos, los demás dispositivos conectados al bus I2C se conocen como esclavos.
Cada uno de los dispositivos tiene una dirección, cuando el maestro necesita comunicarse
con alguno de los esclavos lo hará enviando la dirección del esclavo a través del bus I2C, cuando
el esclavo reciba su dirección podrá comunicarse con el maestro, el maestro además tiene que
enviar un bit mediante el cual le indica al esclavo si quiere enviarle un dato o quiere recibir un dato
del esclavo.
Las conexiones tienen que hacerse de tal manera que los nombres de los pines coincidan,
en la figura 6 se muestra cómo será la conexión para la comunicación I2C PIC, al ser utilizado el
PIC como maestro, con otros dispositivos capaces de comunicarse con el protocolo I2C. (Valdes
Perez & Pallas Areny, 2007)
Figura 6: Topología típica de una comunicación I2C maestro y esclavos [19]
19
5.2.5. PWM
Una señal PWM (modulación por ancho de pulsos) es aquella en la que su periodo
representado por T se tiene que mantener constante, dentro de este periodo hay momentos en que
la señal estará en alto o a uno y momentos en que la señal estará en bajo o cero, en la señal PWM
el tiempo que la señal está en alto se le conoce como ancho de pulso y si está expresado en
porcentaje como ciclo de trabajo, este tiempo que la señal está en alto se puede modificar, de esta
manera si la señal PWM se conecta a una carga, sobre esta dependiendo del T alto le llegará una
tensión media, cuando mayor sea T alto más será la tensión media que le llegue a la carga siendo
la mayor cuando T alto ocupa todo el periodo de la señal, y menor cuando T alto sea 0, con lo
que la tensión media también será 0, por ejemplo si la carga es un motor de continua al variar la
tensión media que le llegará mediante la señal PWM, se puede variar la velocidad de giro de ese
motor.
Al configurar el módulo CCP del PIC en el modo PWM, esto es una modulación por ancho
de pulso, en esta forma de trabajo del módulo CCPx donde x puede ser 1 o 2 dependiendo del
módulo CCP utilizado, lo que se logra con el uso del módulo CCP en modo PWM es obtener por
el pin CCPx una señal periódica, este pin debe ser configurado como una salida digital mediante
el correspondiente TRISC, con parte de la señal obtenida en alto y parte de la señal en bajo, lo
interesante de este modo de trabajo del módulo CCP PIC modo PWM es que de la señal periódica
obtenida por el pin CCPx se puede modificar el tiempo que la señal estará en alto.
Las señales de frecuencia y de un ciclo de trabajo variables tienen una amplia gama de
aplicaciones en automatización. Un ejemplo típico es un circuito de control de potencia. Refiérase
a la figura 7. Si un cero lógico (0) indica un interruptor abierto y un uno lógico (1) indica un
interruptor cerrado, la potencia eléctrica que se transmite a los consumidores será directamente
proporcional a la duración del pulso. Esta relación se le denomina ciclo de trabajo. (Verle, 2017)
Figura 7:Variación de la potencia según en ciclo de trabajo de la señal PWM [20]
Un ejemplo común en la práctica, es el uso de señales PWM en un circuito para generar
señales de forma de onda arbitraria como una onda sinusoidal. Como en la figura 8:
20
Figura 8: Señal analógica luego de aplicar un filtro RC a la señal PWM [20]
Los dispositivos que funcionan según este principio se utilizan con frecuencia en la práctica
como variadores de frecuencia ajustable que controlan la velocidad, aceleración y desaceleración
de los motores eléctricos.
5.2.6. Fuentes de interrupción
Una interrupción es un evento que hace que el microcontrolador deje de ejecutar la tarea
que está realizando para atender un acontecimiento, para luego regresar y continuar la tarea que
estaba realizando antes de que se presentara la interrupción.
La ventaja de utilizar interrupciones es que mientras se espera a que se presente el evento
que produce la interrupción el microcontrolador puede estar ejecutando cualquier otra tarea. De
ese modo el microcontrolador no estará procesando una sola tarea, sino que puede seguir
trabajando en otras hasta que una interrupción haga que el programa salte y ejecute la tarea que se
quiera y al terminarla el programa continuara su ejecución en el punto en el que se encontraba en
el momento de presentarse la interrupción. (Valdes Perez & Pallas Areny, 2007)
En este proyecto se utilizan dos fuentes de interrupción, las cuales son:
Interrupción por desborde del timer 1 (TMR1)
Interrupción del receptor del USART
Interrupción externa por medio del pin RB0
21
5.3. Visualizador LCD
Es frecuente la necesidad de mostrar mensajes que tienen que ver con el estado de algo o
el valor de un instrumento de medida electrónico. Para estos casos la utilización de una pantalla
de cristal líquido LCD ofrece como ventaja con respecto a los displays de 7 segmentos, su bajo
consumo de corriente y la no necesidad de multiplexar, gracias al microcontrolador integrado de
referencia HD44780, además de soportar caracteres alfanuméricos en el estándar ASCII.
Esta pantalla LCD como la que se muestra en la figura 9, consta de dos líneas de
visualización de 16 caracteres cada una, donde cada carácter está conformado por una matriz de
caracteres de 5x7 puntos, controlada por el driver HD44100 (Valdes Perez & Pallas Areny, 2007)
Figura 9: Componentes del módulo Cristal líquido ML016L [17]
5.4. Lenguaje de programación C
El lenguaje C dispone de todas las ventajas de un lenguaje de programación de alto nivel,
y permite realizar algunas operaciones tanto sobre los bytes como sobre los bits (operaciones
lógicas, desplazamiento etc.). Las características de C pueden ser muy útiles al programar los
microcontroladores. Además, C está estandarizado (el estándar ANSI), es muy portable, así que el
mismo código se puede utilizar muchas veces en diferentes proyectos. Lo que lo hace accesible
para cualquiera que conozca este lenguaje sin reparar en el propósito de uso del microcontrolador.
C es un lenguaje compilado, lo que significa que los archivos fuentes que contienen el código C
se traducen a lenguaje máquina por el compilador. Todas estas características hicieron al C uno de
los lenguajes de programación más populares. (Verle, 2017)
Cuando se tiene escrito un programa en lenguaje C, se compila el archivo y se generan un
nuevo archivo en lenguaje ensamblador con extensión ASM. De ahí se generan dos archivos más
que contienen el código ejecutable en el sistema hexadecimal y binario, tal como se muestra en la
figura 10.
22
La figura 10 muestra el proceso de compilación y de programación de un microcontrolador
a partir de un archivo con extensión.
Figura 10: Proceso de compilación de un lenguaje de alto nivel a bajo nivel [21]
5.4.1. Entorno de programación de PIC C Compiler
PIC C es una herramienta que permite programar un microcontrolador por medio de
lenguaje C, a diferencia del lenguaje máquina o ensamblador (ASM) que se maneja por defecto,
este hace los programas más fáciles de escribir, analizar y comprender. PIC C ha sido desarrollado
por PIC CMU, y cuenta con una gran cantidad de librerías o drivers que permiten optimizar los
programas en el momento de manejar dispositivos externos, tales como pantallas LCD, memorias,
conversores, etc.
Figura 11: Espacio de trabajo de PIC C [22]
23
5.5. Sensores de distancia de Tiempo de vuelo (TOF)
Su funcionamiento consiste en enviar un pulso láser de luz infrarroja y medir el tiempo
necesario en el haz en volver al sensor.
El integrado incorpora un emisor laser 940nm VCSEL (Vertical Cavity Surface-Emitting
Laser), un detector SPAD (Single Photon Avalanche Diodes) y la electrónica interna (denominada
FlightSenseTM) que realiza los cálculos necesarios.
Un sensor de tiempo de vuelto tiene una precisión superior que los sensores de ultrasonidos
e infrarrojos, porque no se ve alterado por las condiciones del ambiente como los ecos o la
reflactancia de los objetos. Además, es capaz de operar incluso con elevada luz ambiental
infrarroja, e incorpora un sistema de compensación de la medición que le permite hacer funcionar
incluso detrás de un cristal protector.
Por otro lado, el ángulo de medición es relativamente estrecho. Esto es una ventaja en la
mayoría de circunstancias, donde se desea leer la distancia justo en frente del sensor. (Datasheet
VL6180X, 2016)
En la figura 12 se observa la topología de un sensor de tiempo de vuelo, que se conforma
de un microcontrolador que calcula la distancia mediante un emisor laser y el receptor de fotones,
además de gestionar el protocolo de comunicación I2C con un microcontrolador en modo maestro.
Figura 12: topología de un sensor TOF (tiempo de vuelo) [24]
5.6. Acelerómetro
Un acelerómetro es un dispositivo que mide la vibración o la aceleración del movimiento
de una estructura. La fuerza generada por la vibración o el cambio en el movimiento (aceleración)
hace que la masa "comprima" el material piezoeléctrico, generando una carga eléctrica que es
proporcional a la fuerza ejercida sobre él.
El acelerómetro que se utilizó para este proyecto es de un sensor de micrcomecanizado o
acelerómetro de capacidad de detección, micromecanizados de placas capacitivas que forman una
masa de unos 50 microgramos. Como la aceleración deforma las placas, un cambio de capacitancia
es medible. (Datasheet ADXL345, 2015)
24
Pero los acelerómetros piezoeléctricos son quizás los dispositivos más prácticos para medir
impactos y vibraciones. Similar a un sensor mecánico, este dispositivo incluye una masa que,
cuando se acelera, ejerce una fuerza inercial en un cristal piezoeléctrico.
5.7. Termocupla
Las sondas de temperatura basadas en termopar determinan la temperatura midiendo la
pequeña fuerza electromotriz que origina la unión de dos metales (conductores) distintos a distintas
temperaturas; el llamado efecto termoeléctrico o efecto Seebeck. Son muy eficaces para trabajar
con amplios rangos de temperaturas, especialmente en los tramos altos.
Las sondas de tipo K (cromel–alumel), las más usadas, entre otras razones por su relación
entre precio y prestaciones, son capaces, en teoría, de medir temperaturas entre −180 °C y +1300
°C, aunque frecuentemente se utilizan para medir temperaturas, aproximadamente, entre los +50
°C y los +800 °C
A la eficacia del sistema de medida de temperatura basado en termopar, le acompaña la
necesidad de resolver tres cuestiones para poder ser explotado:
capacidad de gestionar tensiones muy bajas (del orden de µV) o amplificar la respuesta del
termopar para que un microcontrolador pueda trabajar con ella
corrección de la medida de la sonda para equipararla a una distribución lineal (linealización
de la respuesta del termopar)
compensación de unión fría para corregir la dependencia que existe entre la temperatura
medida por la sonda y la temperatura ambiente.
El IC MAX31855 o el MAX6675 cumplen las condiciones para resolver de manera sencilla
estos tres aspectos y además, gracias a que utiliza un protocolo de comunicación SPI, es sencillo
de implementar en una aplicación basada en microcontrolador, por tener el punto de medida
separado del punto donde se procesan los datos y del CUF (compensador de unión fría) (Datasheet
MAX31855, 2015)
5.8. Transformador Flyback
Un transformador convencional de baja tensión se diseña para que la transferencia de
energía desde el primario al secundario sea óptima. Mientras que un transformador Flyback se
diseña con el propósito de guardar energía comportándose como un inductor.
Si se alimenta un transformador normal con una onda que no es pura, por ejemplo, una
onda cuadrada, esta tiene armónicos; frecuencias espurias más allá de los 50Hz para las que no
está diseñado, y se traduce en pérdidas y calor, y cambios bruscos de eficiencia, pero si se alimenta
un transformador Flyback de esta forma, este acumularía energía en forma de campo magnético
en su núcleo para inducirla y descargarla a una alta tension, como en un arco eléctrico de unos
milímetros o centímetros, dependiendo de la diferencia de potencial. (Goldwasser, 2001)
Un transformador flyback no está optimizado para transferir energía sino para acumular un
campo magnético muy fuerte en su núcleo. Se trata de alimentar el primario a pulsos, crear el
25
campo magnético y luego cortar la corriente lo más rápido posible para que se induzca un campo
enorme y se transfiera al secundario.
Como el campo magnético es más fuerte cuanto más rápido sea el cambio de la corriente,
el resultado es que en el secundario pueden inducirse miles de voltios. Aun cuando la tensión en
el primario sea pequeña, lo que importa es el cambio brusco de tensión.
El transformador flyback es de utilidad en este proyecto para generar el arco eléctrico que
sea capaz de encender el combustible, a partir de un voltaje continuo y a una corriente que pueda
ser suministrada por la batería a un circuito de potencia que se encargara de las oscilaciones de
tensión en el primario del transformador y en el devanado de realimentación como se muestra en
la figura 13.
Figura 13: Esquema eléctrico básico para hacer funcionar un transformador Flyback [27]
5.9. Aplicaciones Android
Las aplicaciones se desarrollan habitualmente en el lenguaje Java con Android Software
Development Kit (Android SDK), pero están disponibles otras herramientas de desarrollo,
incluyendo un Kit de Desarrollo Nativo para aplicaciones o extensiones en C o C++, Google App
Inventor, un entorno visual para programadores novatos y varios marcos de aplicaciones basadas
en la web multiteléfono. También es posible usar las bibliotecas Qt.
El desarrollo de aplicaciones para Android no requiere aprender lenguajes complejos de
programación. Todo lo que se necesita es un conocimiento aceptable de Java y estar en posesión
del kit de desarrollo de software o «SDK» provisto por Google el cual se puede descargar
gratuitamente. Todas las aplicaciones están comprimidas en formato APK, que se pueden instalar
sin dificultad desde cualquier explorador de archivos en la mayoría de dispositivos. (AndroidDev,
2018)
Las aplicaciones Android se caracterizan por:
Múltiples aplicaciones, se pueden ejecutar simultáneamente.
El usuario puede cambiar de aplicaciones cuando lo desee.
Servicios del sistema operativo.
26
5.9.1. Actividades
Una Actividad dentro del ambiente de programación de Android Studio es un componente
de la aplicación que contiene una pantalla con la que los usuarios pueden interactuar para realizar
una acción, como marcar un número telefónico, tomar una foto, enviar un correo electrónico o ver
un mapa. A cada actividad se le asigna una ventana en la que se puede dibujar su interfaz de
usuario. La ventana generalmente abarca toda la pantalla, pero en ocasiones puede ser más pequeña
que esta y quedar "flotando" encima de otras ventanas.
Una aplicación generalmente consiste en múltiples actividades vinculadas de forma
flexible entre sí. Normalmente, una actividad en una aplicación se especifica como la actividad
"principal" que se presenta al usuario cuando este inicia la aplicación por primera vez. Cada
actividad puede a su vez iniciar otra actividad para poder realizar diferentes acciones. Cada vez
que se inicia una actividad nueva, se detiene la actividad anterior, pero el sistema conserva la
actividad en una pila. (AndroidDev, 2018)
5.9.2. Servicios
Un Servicio es un componente de una aplicación que puede realizar operaciones de larga
ejecución en segundo plano y que no proporciona una interfaz de usuario. Otro componente de la
aplicación puede iniciar un servicio y continuará ejecutándose en segundo plano, aunque el usuario
cambie a otra aplicación. Además, un componente puede enlazarse con un servicio para interactuar
con él e incluso realizar una comunicación entre procesos.
Un servicio puede ser un servicio iniciado o un servicio de enlace:
Un servicio está "iniciado" cuando un componente de aplicación (como una actividad) lo
inicia llamando a startService(). Una vez iniciado, un servicio puede ejecutarse en segundo plano
de manera indefinida, incluso si se destruye el componente que lo inició. Por lo general, un servicio
iniciado realiza una sola operación y no devuelve un resultado al emisor. Por ejemplo, puede
descargar o cargar un archivo a través de la red. Cuando la operación está terminada, el servicio
debe detenerse por sí mismo.
Un servicio es de “de enlace” cuando un componente de la aplicación se vincula a el
llamando a bindService(). Un servicio de enlace ofrece una interfaz cliente-servidor que permite
que los componentes interactúen con el servicio, envíen solicitudes, obtengan resultados e incluso
lo hagan en distintos procesos con la comunicación entre procesos (IPC). Un servicio de enlace se
ejecuta solamente mientras otro componente de aplicación está enlazado con él. Se pueden enlazar
varios componentes con el servicio a la vez, pero cuando todos ellos se desenlazan, el servicio se
destruye. (AndroidDev, 2018)
27
5.9.3. Entorno de programación de Android Studio
Android Studio es el entorno de desarrollo integrado (IDE) oficial para el desarrollo de
aplicaciones para Android y se basa en IntelliJ IDEA . Además del potente editor de códigos y las
herramientas para desarrolladores de IntelliJ, Android Studio ofrece aún más funciones que
aumentan tu productividad durante la compilación de apps para Android, como las siguientes: .
Un sistema de compilación basado en Gradle flexible
Un emulador rápido con varias funciones
Un entorno unificado en el que puedes realizar desarrollos para todos los dispositivos
Android
Instant Run para aplicar cambios mientras la app se ejecuta sin la necesidad de compilar
un nuevo APK
Integración de plantillas de código y GitHub para ayudar a compilar funciones comunes de
las apps e importar ejemplos de código
Gran cantidad de herramientas y frameworks de prueba
Herramientas Lint para detectar problemas de rendimiento, usabilidad, compatibilidad de
versión, etc.
Compatibilidad con C++ y NDK
Soporte incorporado para Google Cloud Platform, lo que facilita la integración de Google
Cloud Messaging y App Engine (AndroidDev, 2018)
Figura 14: Entorno de programación de Android Studio
28
5.10. Comunicación inalámbrica
5.10.1. Bluetooth
La tecnología Bluetooth revoluciona el mercado de la conectividad personal, proveyendo
ínter conectividad entre cualquier tipo de dispositivo que cumpla con las especificaciones
inalámbricas Bluetooth.
Además, éste es un estándar libre lo que simplifica su uso para diseñar y sacar al mercado
nuevos productos innovadores que se beneficien de la conectividad inalámbrica.
A diferencia de otros estándares inalámbricos, la especificación Bluetooth incluye dos
capas, la capa de enlace y la de aplicación para los desarrolladores de productos que soportan
datos, voz, y aplicaciones de contenido centralizado. [11]
5.10.2. Bluetooth Low Energy(BLE)
Bluetooth Low Energy (BLE), a veces conocido como “Bluetooth Smart”, se introdujo
como parte de la especificación de Bluetooth 4.0. Aunque existe cierto solapamiento con el
Bluetooth clásico, BLE proviene de un proyecto inicialmente desarrollado por Nokia y conocido
como ‘Wibree’ antes de que fuera adoptado por Bluetooth SIG (Special Interest Group).
Existen varios protocolos wireless para uso en IOT, pero lo que hace que BLE sea
interesante es que sea relativamente más sencillo de implementar la comunicación entre pequeños
dispositivos y una aplicación en cualquier plataforma móvil actual (iOS, Android, etc.), y
particularmente en el caso de los dispositivos Apple, es el único método que permite la interacción
de periféricos con aplicaciones, sin necesidad de certificaciones MFI y otros requisitos legales que
exige iOS. [12]
29
6. ESTADO DEL ARTE
En el mercado de las biochimeneas existen soluciones que logran el objetivo de controlar
y monitorizar una biochimenea, remotamente se tiene acceso a la chimenea por medio de cualquier
dispositivo sobre cualquier sistema operativo, como Android, Apple, Windows, etc. La interfaz
entre el controlador y el usuario se hace por medio de un servidor TCP/IP que tiene lugar en el
microcontrolador, por lo que la biochimenea debe conectarse a un punto de acceso a la red local
por cable Ethernet, y a partir de este, el usuario puede conectarse desde cualquier dispositivo
conectado a la red local privada, accediendo a la IP privada de la biochimenea por medio del
navegador de internet e interactuar con esta, controlando el suministro de combustible de la
chimenea y el encendido. Esta chimenea posee tanque de reserva de combustible y encendido de
la llama, y es fabricado por la marca Planika en Europa, que tienen un costo desde los 6000 euros
y varía según tamaños del quemador y del tanque de combustible. [13]
Otra solución en el mercado para biochimeneas de etanol, es por medio de un control
remoto de sensor infrarrojo, este solo tiene la función de encender o apagar la chimenea por medio
de un pulsador ubicado en un control remoto, adicionalmente la biochimenea posee una pequeña
pantalla LCD que muestra información sobre procesos de la chimenea, como la temperatura y
tanque de combustible de reserva. Este tipo de biochimenea es fabricado y vendido por distintos
fabricantes, como Cleanflames en Estados Unidos, con precios desde los 1900 dólares, A-fire en
Gran Bretaña con un catálogo de precios desde 3100 Euros, Con garantía de 3 años. [14]
En lo que se refiere a comunicación Bluetooth entre un dispositivo de control y una
biochimenea aún no hay un fabricante de biochimeneas que lo desarrolle y lo comercialice, que es
el propósito de este proyecto a largo plazo.
30
7. METODOLOGIA
7.1. FASE 1 Análisis de requerimientos
De acuerdo a los objetivos del proyecto, inicialmente se tendrán en cuenta algunos
requerimientos y unas dimensiones aproximadas de la estructura del quemador, proveído por el
fabricante de biochimeneas CLIMALIVE. Fabricante al cual va dirigido este sistema, los
requerimientos son:
Debe ser operable mediante una aplicación ANDROID.
Dimensiones 400mm x 130mm x 100mm
El tiempo de operación debe ser programable: si el usuario desea programar (x) tiempo el
sistema debe informarle para cuanto tiempo le alcanza el combustible.
Si el combustible esta por acabarse debe mostrar una advertencia
El sistema debe detenerse si se detecta un movimiento accidental o un sismo
El sistema debe mostrar los niveles de batería
El sistema eléctrico debe tener un sistema de carga y alimentación directa
El sistema debe impedir que pueda ser abastecido en operación o a una temperatura
superior a los 50ºc
La aplicación debe mostrar todas las advertencias y alertas
El quemador debe mostrar en pantalla integrada todas las advertencias y alertas.
Una alerta puede ser que se halla apagado por una vibración.
Las advertencias pueden ser que esta por acabarse el combustible.
Estos requerimientos surgen de la investigación del estado del arte de este tipo de sistemas
en el mercado, no es un estándar establecido por algún fabricante en específico, pero si generan
una sensación de mayor seguridad y calidad al usuario final.
7.2. FASE 2: Acondicionamiento de sensores, módulos y comunicación con la aplicación
Android
Debido a los objetivos, el planteamiento del problema y los requerimientos del proyecto de
la fase de análisis de requerimientos, es indispensable el uso de sensores para la medición de
magnitudes, que luego son interpretadas por un microcontrolador
Aunque los sensores con salida analógica son muy prácticos para poder ser cuantificados
y mostrados por el microcontrolador por no requerir librerías codificadas en el programa principal,
estos sensores son escasos en el mercado, como lo son los sensores de distancia y los
acondicionadores de termocuplas. La medición de la carga de la batería se realiza por medio de
divisores resistivos para acondicionar la señal a niveles dentro del rango de cuantificación del
puerto analógico del microcontrolador.
El uso del microcontrolador resulta muy útil para la temporización precisa del tiempo,
mediante las interrupciones y el cristal oscilador a 32Khz, son fundamentales si se desea una
contabilización precisa del tiempo, además el uso de interrupciones resulta muy útil para la
31
recepción y envió de datos por medio del puerto de comunicación serial RS232 con otros
dispositivos.
Se realiza la investigación de encontrar los sensores más adecuados para cumplir con los
requerimientos del proyecto y que soporten las condiciones bajo las que se va a trabajar, además
de un microcontrolador que disponga de los puertos y especificaciones suficientes para el
desarrollo de este proyecto.
Para poder visualizar el tiempo, la carga de las baterías y las alertas del sistema sin depender
de una conexión inalámbrica, estas se deben poder ver en un visualizador instalado en la
biochimenea, debido a que existe la posibilidad de que se pierda la conexión o que el usuario
decida no usar la aplicación y encender la biochimenea por medio del pulsador ubicado en la
biochimenea.
El módulo de comunicación inalámbrico que se encargue de establecer un enlace entre el
dispositivo Android y el microcontrolador debe ser de bajo consumo eléctrico en sus estados de
descubrimiento y de conexión para no comprometer la autonomía de la biochimenea, no es
necesario que tenga un radio de cobertura amplia porque la interacción entre un usuario y la
biochimenea se da en algunos metros de distancia para que esta provea calor en la habitación en
donde se encuentra el usuario o en la propia vivienda donde se encuentra.
Se adquieren los sensores, microcontrolador, módulo de comunicación, el visualizador
LCD, se monta físicamente el circuito en una protoboard y se codifica un programa sencillo para
programar el microcontrolador de manera que pueda enviar y recibir datos del dispositivo Android
por medio del módulo de comunicación inalámbrico.
Se realizan lecturas de los sensores para comprobar su funcionamiento, cada uno por uno
por separado con el microcontrolador para comprobar su caracterización mostrada en la hoja de
datos del fabricante y que pueda cumplir con los requerimientos del proyecto.
Se programa una aplicación Android sencilla, para conectarse al módulo de comunicación
y para que reciba y envié datos al microcontrolador por medio de este módulo, como por ejemplo
de los sensores, esto con el fin de comprobar el buen funcionamiento de la comunicación entre el
dispositivo Android y microcontrolador.
Se simulan las condiciones sobre las que trabajara la biochimenea de acuerdo a los
requerimientos, por ejemplo, el sensor de distancia mide la cantidad de combustible que hay en el
tanque de combustible, como aún no se dispone del tanque del combustible, se simula esa magnitud
utilizado otros objetos ubicándolos enfrente del sensor para que este los detecte y así simular la
cantidad de combustible en un tanque de combustible. Provisionalmente lo actuadores como la
bomba de combustible y el generador de arco eléctrico se simulan como si fueran solamente salidas
digitales con indicadores luminosos.
32
7.3. FASE 3: Diseño electrónico y de la aplicación Android
Luego de tener configurados los sensores, y codificar el programa del microcontrolador, se
procede a codificar el programa para cumplir los objetivos y requerimientos del proyecto, de
manera que reciba datos del buffer por el puerto UART, leer las señales de los sensores, se
codifican condicionales en el programa del microcontrolador con estos datos, habilitar o no salidas
digitales y enviara datos de los sensores al dispositivo Android por medio del módulo bluetooth y
al visualizador LCD.
En el diseño electrónico ahora se introducen los actuadores que influye directamente en la
combustión del etanol, que son operados por las salidas digitales del microcontrolador, que son la
bomba de combustible, para mover el combustible de un lugar a otro y el generador de alto voltaje
para crear el arco eléctrico que encenderá la llama , además se introducen los módulos que se
encargan de mantener los diferentes voltajes en el circuito, en esta fase del proyecto ya se tienen
caracterizados los sensores sobre el programa del microcontrolador, también los parámetros de
comunicación del microcontrolador con el módulo de comunicación ya elegido, asi como los pines
y configuraciones vía código que facilitan la función de los protocolos de comunicación con los
sensores y visualizador LCD.
La aplicación Android se desarrolla sobre el ambiente de programación de Android Studio,
esta aplicación se instala sobre el dispositivo Android ASUS ZS570KL con sistema operativo
Android Versión 8.0. Contiene una actividad para crear una conexión con un dispositivo cercano,
una segunda actividad que muestra los datos de los sensores en forma gráfica, opciones para
determinar el tiempo de quemado, según el combustible disponible, una tercera actividad donde
muestra el tiempo restante que fue elegido por el usuario y otras opciones que el usuario puede
manejar para controlar el tiempo de quemado.
7.3.1. Bomba de combustible
Se debe mover el combustible del tanque de combustible, ubicado en la parte inferior de la
estructura, hacia el quemador que se encuentra en la parte superior de la biochimenea,
normalmente se requiere una bomba de combustible especial que no sea de plástico, pero estas
bombas especiales para bombear un combustible como el etanol son de aplicación industrial para
mover grandes caudales de este líquido, por lo que no es posible agregar una bomba de este tipo
al proyecto.
Como alternativa, es posible utilizar bombas de agua sumergibles, el único inconveniente
es que el etanol corroe el plástico, sin embargo, se realizó un test pruebas de una bomba de agua
fabricada en plástico, que consistió en ponerla en funcionamiento sobre etanol, 240 horas seguidas,
luego se deja en reposo por 10 horas para luego ponerla en funcionamiento por 10 horas, repitiendo
el ciclo hasta completar 10 ciclos. Se observó que efectivamente en algunos sectores de la carcasa
de plástico de la bomba, esta se estaba corroyendo de manera superficial, aunque al comprobar su
funcionamiento con otra bomba similar sin horas de uso, no se observaron diferencias en cuanto a
su alcance longitudinal, disponiendo juntas bombas de manera que evacuen el líquido de forma
vertical.
33
7.3.2. Generador de alto voltaje
Para encender un combustible como el etanol se requieren de dos elementos además de
este, oxígeno y una ignición incandescente. Este último se puede lograr por medio de un
encendedor de cigarrillos, un fosforo u otra llama encendida, en estos tres eventos se requiere de
la intervención directa del usuario, por lo que, para lograrlo de manera remota sin intervención
manual, se debe hacer mediante la generación de un arco eléctrico incandescente.
Para crear un arco eléctrico hace falta una tensión del orden de varios kilovoltios entre dos
terminales separadas por un medio gaseoso, para lograrlo se debe tomar una tensión de entre 5v a
8v continuos que provienen de la batería, generar una oscilación en forma de onda cuadrada entre
el transistor de potencia y el devanado de realimentación, del transformador Flyback para generar
una tensión sinusoidal en el secundario, de esa manera, las dos terminales necesitan estar solo a
unos cuantos milímetros de distancia para crear un arco eléctrico, que es suficiente para encender
el etanol.
Ya se fabrican este tipo de transformadores flyback solo hace falta completar el circuito
con un transistor de potencia, un diodo de conmutación rápida y una resistencia para limitar la
ganancia en el lazo de realimentación. La batería debe tener la capacidad de suministrar una
corriente de entre 1 a 3 amperes, dependiendo de la distancia a la que se encuentren las terminales,
a mayor distancia, mayor corriente va a necesitar el devanado secundario para crear el arco
eléctrico.
7.3.3. Fuente de poder y reguladores de tension
Normalmente una biochimenea a base de combustible de etanol operada manualmente
tiene la versatilidad de poder ser trasportada de un sitio a otro sin tener que preocuparse de tener
cerca un suministro de combustible ni eléctrico, por lo que se desea que una biochimenea operada
electrónicamente conserve esa misma versatilidad, y la única forma de lograrlo es incluyendo
baterías lo suficientemente durables, que necesiten ser recargadas luego de varias recargas de
combustible después.
La estructura de la biochimenea posee compartimientos para las baterías y el circuito
eléctrico pero las baterías no pueden ser voluminosas porque tienden a acumular calor y ademas
se debe aprovechar el espacio para acomodar el cableado de manera que haya un buen flujo de aire
en el área donde se encuentre el circuito eléctrico, y que se disipe el aire caliente que se pueda
acumular.
7.3.4. Diseño del programa del microcontrolador
El programa se diseñó de manera que se ejecutaron pruebas, simulando las condiciones
físicas que tendrá a lugar el circuito en la biochimenea, tanto físicamente en el montaje de
protoboard como en el simulador.
El simulador utilizado para emular las condiciones externas y del circuito, fue el programa
Proteus 8 Profesional, versión 8.6 y el compilador donde se codifico el programa del
microcontrolador, fue PIC C Compiler versión 5
34
Con ayuda del programador Pickit2 de microchip, se programó el microcontrolador cada
vez que se hicieron pruebas tanto en la protoboard como en el circuito impreso
La aplicación Android se codifico en el programa Android Studio en sus diferentes
versiones, en el que es posible codificar, compilar y depurar la aplicación por medio de la
depuración USB del dispositivo Android.
7.4. FASE 3: Autonomía
El sistema contara con baterías recargables, se disponen de manera que pueda ser cargada
y al mismo tiempo pueda poner en funcionamiento la biochimenea. Al tener una cantidad de
combustible máxima, determinada por el tamaño del encapsulado y el tanque de combustible, se
debe garantizar que la carga de la batería sea suficiente para varias cargas completas de
combustible, dándole una autonomía que depende de la capacidad de las baterías, y de la corriente
que consuma el circuito, utilizando un microcontrolador de bajo consumo de energía, al igual que
los sensores, los actuadores, y un módulo de comunicación que maneje un protocolo de
comunicación de bajo consumo eléctrico.
7.5. FASE 4: Elaboración del Prototipo
En cuanto a la estructura del encapsulado, el fabricante de biochimeneas se encarga de la
fabricación de acuerdo a las especificación y dimensiones ya establecidas de acuerdo al tamaño de
los componentes eléctricos y electrónicos en su conjunto. El material de este encapsulado será en
acero inoxidable al igual que el quemador, de preferencia por su rigidez estructural, estética y
resistencia térmica. Todos los componentes estarán ubicados en una sola placa de circuitos y los
actuadores como la bomba de combustible y el generador de arco eléctrico en diferentes
ubicaciones dentro de la biochimenea.
Se tendrá en cuenta las dimensiones de cada elemento como la batería y el circuito
electrónico para hacer un modelo 3D en el programa de diseño Autodesk Inventor. Para su
posterior elaboración y ensamble.
7.6. FASE 5: Comprobación y Validación
Se requiere hacer pruebas del sistema en conjunto para la validación del sistema.
Estableciendo umbrales en la medición de los sensores para el control automático del sistema, o el
ajuste de los actuadores como el generador de arco eléctrico o la bomba de combustible como por
ejemplo la velocidad de giro del motor que influirá directamente en el consumo de combustible.
Se pondrán a prueba diferentes eventos del sistema, como vibración espontaneas, excesos
de temperatura, alarmas de advertencia, pruebas en largos periodos de funcionamiento, de
fiabilidad y seguridad de todo el sistema en su conjunto.
Para la construcción de todo el prototipo, el presupuesto aproximado es de $ 1.500.000
COP
35
7.7. Diagrama de bloques
En el siguiente diagrama de bloques en la figura 15. Describe de manera general la
estructura del sistema.
Figura 15: Diagrama de bloques, estructura del sistema
Encapsulado chimenea: Estructura en acero inoxidable, que contiene el quemador, el
tanque de combustible, los actuadores, sensores, el control electrónico, el circuito eléctrico
y la batería
Quemador: compartimiento donde ocurre la combustión de etanol, donde también se
encuentra el generador de arco eléctrico.
Tanque de combustible: compartimiento donde se almacena el combustible, y en donde se
encuentra la bomba de combustible, que bombeara el etanol del tanque hacia el quemador,
y donde también se encuentra el sensor de nivel de combustible.
Actuadores: Bomba de combustible y generador de arco eléctrico.
Sensores: Sensores de temperatura, distancia y acelerómetro.
Control Electrónico: Microcontrolador y transistores, etc.
Circuito Eléctrico: Conversores DC-DC
ENCAPSULADO,
BIOCHIMENEA QUEMADOR
TANQUE DE
COMBUSTIBLE
DISPOSITIVO
MOVIL ANDROID
SENSORES ACTUADORES
CONTROL
ELECTONICO
COMUNICACIÓN
INALAMBRICA
CIRCUITO
ELECTRICO
BATERIAS
APLICACIÓN
ANDROID
36
Baterías: Fuente de energía recargable, que provee energía a todos los circuitos del sistema
Comunicación inalámbrica: interfaz de comunicación entre el control electrónico y un
dispositivo móvil Android
Dispositivo móvil Android: Ya sea Tablet o Smartphone Android
Aplicación Android: Programa desarrollado sobre la plataforma Android, capaz de recibir
y mostrar información del microcontrolador por medio de la comunicación inalámbrica, y
enviar instrucciones también por el mismo medio.
37
8. ANALISIS Y DESARROLLO
Siguiendo la metodología para resolver el problema que se plantea, y los requerimientos
que exige el fabricante, se investiga que sensores son los más adecuados para cumplir con los
requerimientos y lograr los objetivos para resolver el problema que se plantea.
Como proyección a futuro del proyecto, para ser considerado el diseño a una producción
en serie, se requieren que los componentes electrónicos sean de fácil obtención tanto en el mercado
nacional como internacional y a un precio económico.
Antes de elegir los sensores para el diseño electrónico, se realizó el trabajo de investigación
sobre el microcontrolador, es decir el primer elemento que se elige en el diseño es el
microcontrolador, las razones para elegirlo fueron descritas en la metodología, se plantearon
preguntas como: ¿Cuántas formas existen para comunicar un sensor con un microcontrolador?, ¿es
posible usar los dos protocolos de comunicación I2C y SPI del microcontrolador al tiempo? Para
la primera pregunta, se recurre a la documentación de los microcontroladores de mejores
características que se pueden obtener en el mercado nacional, como por ejemplo los
microcontroladores de Microchip, PIC16F877A, PIC18F4550 o el PIC 18F2550, en los que se
encontró que es posible establecer una interfaz de comunicación con los protocolos I2C o SPI.
(PIC18F2455/2550/4455/4550 Datasheet, 2009)
Sin embargo, se encontró que estos microcontroladores gestionan la comunicación I2C o
SPI por medio un solo módulo MSSP, lo que significa que solo se puede utilizar uno de estos dos
protocolos sobre el mismo puerto MSSP, este es debido a que ambos protocolos comparten las
mismas salidas y registros en el módulo MSSP, por lo que no es posible utilizar ninguno de los
microcontroladores que en el mercado nacional se ofrece. (PIC18F2455/2550/4455/4550
Datasheet, 2009)
Se recurre entonces al buscador de microcontroladores de microchip, con el cual se
configura una búsqueda para encontrar un microcontrolador que posea dos módulos MSSP,
además, que tenga un bajo consumo de energía y que cumpla con los requerimientos del proyecto.
Así entonces la familia de microcontroladores de Microchip que mejor se ajusta a los
requerimientos del proyecto, es de referencia PIC18F47J13, específicamente el microcontrolador
PIC18F26J13. (Datasheet PIC18F47J13 FAMILY, 2017)
La oferta en el mercado de los sensores que se utilizan para este proyecto, existen sensores
que tienen como medición de una magnitud medida, una señal analógica, comunicación I2C o SPI,
que, como dato particular, las termocuplas que se ofertan en el mercado solo manejan el protocolo
de comunicación SPI.
En la oferta de sensores de distancia, se encuentran de tipo ultrasonido, infrarrojo y de
tiempo de vuelo (TOF), los primeros manejan una señal digital de eco que es interpretada por la
distancia que está midiendo en un intervalo de tiempo. También otras referencias del mismo sensor
en el que el sensor genera una señal analógica, interpretando la distancia al objeto. En cuanto a los
sensores infrarrojos estos manejan un funcionamiento similar con la diferencia, que la onda
infrarroja no se ve afectada por los cambios de densidad del medio, problema que, si afecta a los
38
sensores de ultrasonido, aunque la desventaja del sensor IR es que se ven afectados por la
reflectancia del objeto a medir. Por último los sensores de tiempo de vuelo no se ven afectado por
ninguna de los problemas antes mencionados. (Leibson, 2018)
En la oferta de acelerómetros en el mercado, hay un mayor rango posibilidades, se
encuentran los que manejan ambos protocolos de comunicación I2C, SPI, y los analógicos.
Gracias a que se dispone de un microcontrolador en el que se pueden configurar los dos
protocolos I2C y SPI para que funcionen al mismo tiempo, se pueden utilizar sensores que manejen
cualquiera de estos dos protocolos, descartando así los sensores analógicos.
Ya elegidos los sensores, el siguiente paso es codificar un programa sencillo para el
microcontrolador para recibir las señales de los sensores y acondicionarlos en caso de ser
necesario, al mismo tiempo se muestran los datos de los sensores en el visualizador LCD. Además
de una aplicación sencilla para instalar en el dispositivo Android para poder conectarse, enviar y
recibir datos por el modulo bluetooth de esté al módulo bluetooth que se comunicara con el
microcontrolador.
A Continuación, se describe como fue implementado y diseñado cada elemento del sistema,
y como fueron integrados para funcionar en conjunto.
8.1. Sensor de distancia
El sensor de distancia resulta útil para medir la distancia entre este y un objeto en frente,
que no solo funciona con objetos solidos si no también con líquidos, como en este proyecto, que
es el etanol. Se elige un sensor de distancia con tecnología Time-of-Flight del fabricante ST, dicha
tecnología es la que determina la distancia a la que se encuentra el objeto basándose en la diferencia
de tiempo entre que el fotón salió del láser emisor(VCSEL) y el sensor SPAD lo recibió, Dentro
de la gama de sensores que comparten la tecnología de ST, existe el sensor de referencia VL6180x,
especial en sus características debido a que el fabricante asegura una medición con muy bajo
margen de error independiente de la reflectancia del objeto y de la cantidad de iluminación
ambiental en el rango de 0 a 10cm, que es exactamente la medida que tiene de fondo el tanque de
combustible de la biochimenea. (Leibson, 2018)
En la tabla 1 se muestra los sensores que se consideraron para ser utilizados para sensar el
nivel de líquido en el interior del tanque de combustible.
HC-SR4(US) GP2Y0A41SK0F(IR) VL6180x(TOF)
Rango de medicion 2cm a 400cm 4cm a 30cm 0.5cm a 20cm
Afectado por
densidad del medio
SI NO NO
Reflactancia del
objeto
NO SI NO
Comunicación Ecos Analógico I2C
Icc 15mA 33mA 5mA Tabla 1: Comparativa entre los diferentes sensores considerados para desarrollar el proyecto
39
Debido a que el interior del tanque de combustible se encuentra completamente oscuro, el
fabricante especifica que para un rango de medición cada vez mayor, por encima de los 10cm la
ausencia de iluminación puede afectar la medición y también la falta de reflectancia del objeto a
medir puede afectar la medición, pero para la aplicación de este proyecto, los problemas de
iluminación y de reflectancia del flotador no son relevantes. (Datasheet VL6180X, 2016)
Para tomar los datos de distancia del sensor se debe usar una librería la cual inicializa el
sensor con la configuración de unos registros para calibrar el sensor y este pueda funcionar de
manera correcta, calibración que está indicada en la hoja de datos del fabricante. El programa que
se utiliza para codificar en lenguaje C ya incluye esta librería, solo hace falta incluirla en el
programa principal, inicializar la librería y llamar el método para mostrar los datos de distancia
expresada en milímetros.
El fondo del tanque mide 100mm, y cuando se tiene esta lectura en el sensor quiere decir
que el tanque está completamente vacío, por otro lado, si se tiene una lectura de 0mm quiere decir
que el tanque está completamente lleno, considerando esto, si se desea expresar la cantidad de
combustible restante dentro del tanque en una medida porcentual, solo hace falta hacer una
conversión inversamente proporcional a lectura del sensor, de la siguiente forma en la ecuación
(1)
𝑁𝑖𝑣𝑐𝑜𝑚𝑏𝑢𝑠𝑡𝑖𝑏𝑙𝑒% = 100 − 𝐿𝑒𝑐𝑡𝑢𝑟𝑎𝑆𝑒𝑛𝑠𝑜𝑟 (1)
8.2. Baterías de Litio
Dentro de los diferentes tipos de baterías, existen varias de ellas que cumplirían con los
requerimientos del sistema, como por ejemplo las baterías de plomo, siendo bastante durables,
resistentes a la temperatura y económicas; sin embargo son bastante voluminosas y pesadas como
para incluirlas en una estructura donde el espacio y el flujo de aire son muy importantes, es por
esto que se requieren unas baterías que ocupen poco espacio y lo suficientemente durables como
para dar una larga autonomía a la biochimenea sin recargar las baterías. (RSC Power Technology,
2003)
Se eligió usar dos baterías con el objetivo de tener una mayor autonomía y durabilidad de
la batería principal, separando el circuito electrónico que demanda menos corriente del circuito
eléctrico que demanda mayor corriente. La batería principal suministrar corriente a los sensores,
microcontrolador, el módulo de comunicación bluetooth, transistores, bomba de combustible y
demás elementos electrónicos que demanden un corriente baja, por debajo de los 100mA, y una
batería secundaria que da alimentación al circuito generador del arco eléctrico y del ventilador que
disipada el aire caliente que se acumule en el área de la placa de circuitos.
Se elige una batería principal de litio de especificación 18650 de 3.7v a 3400mAH de la
marca Panasonic, que comercialmente, para esta especificación dimensional (18650) es la batería
de mayor capacidad que se pueda fabricar. (Sanyo energy, 2012)
La batería secundaria se compone de dos baterías de litio de especificación dimensional
18650 de 3.7v cada una, a 2500mAH, que, conformando un arreglo en serie, resultaría en una
batería de de 7.4v de tensión nominal a una capacidad de 2500mAH .
40
En la tabla 2 se muestra las capacidades y los rangos que manejan cada batería
Batería
Principal
Batería
Secundaria
Referencia NCR18650B
Voltaje Nominal 3.7v 7.4v
Capacidad 3400mAH 2500mAH
Voltaje máximo 4.2v 8.4v
Voltaje mínimo 2.7v 5.4v
Corriente de drenado
Max.
4 Amperios 4 Amperios
Tabla 2: Características principales de la batería principal y secundaria
8.3. Medición de carga de la batería
La medición de la carga de la batería se logra mediante un divisor resistivo con el objetivo
de que juntas señales analógicas puedan ser cuantificables por medio del puerto ADC del
microcontrolador.
En la figura 16 se observa el esquema del divisor resistivo, Vin es la tensión de la batería,
pero cuando se conecta el cargador esa tensión es de aproximadamente 5v, que es un voltaje
nominal para cargar la batería, pero no el voltaje máximo que puede dar esta, así que se considera
dicha tensión para calcular un divisor resistivo que tendrá un voltaje de salida máximo de 3.3v,
que es la máximo tensión que puede cuantificar el puerto ADC.
Figura 16: Arreglo de resistencias para un divisor resistivo que medirá el nivel de carga de las baterías
𝑉𝑜𝑢𝑡 =𝑅2
𝑅2 + 𝑅1∗ 𝑉𝑖𝑛 (1)
3.3𝑣 = (2𝑘Ω
𝑅1 + 2𝐾Ω) ∗ 5𝑣 (2)
𝑅1 = 2𝐾Ω ∗ (5𝑣3.3𝑣⁄ − 1) = 1030Ω ≈ 1𝐾Ω (3)
En (1) se tiene la fórmula del divisor resistivo, basada en la ley de ohm, en (2) se elige el
valor de la resistencia R2, la tensión máxima (Vbateria o Vcargador), y la tensión máxima
cuantificable por el conversor ADC, así luego se despeja R1 en (3), el valor de la resistencia es de
1KΩ.
41
De la misma forma se calcula un divisor resistivo para la batería secundaria
𝑉𝑜𝑢𝑡 =𝑅2
𝑅2 + 𝑅1∗ 𝑉𝑖𝑛 (4)
3.3𝑣 = (5𝑘Ω
𝑅1 + 5𝐾Ω) ∗ 9𝑣 (5)
𝑅1 = 5𝐾Ω ∗ (9𝑣3.3𝑣⁄ − 1) = 8200Ω ≈ 10𝐾Ω (6)
Luego de este acondicionamiento de la señal, se muestrea, se cuantifica por el puerto ADC
y mediante las siguientes operaciones de linealizacion se expresa en forma porcentual, la medición
de esta magnitud.
𝑉𝑟𝑒𝑓 = 3.3𝑣, 𝑅𝑒𝑠𝑜𝑙𝑢𝑐𝑖𝑜𝑛 = 4095𝑐𝑡𝑎𝑠
Con estas condiciones iniciales, voltaje máximo y mínimo de la batería después de aplicar
el divisor resistivo, se calcula con el siguiente procedimiento un rango porcentual que comprenda
todo el rango medible de la batería. En (7) se tiene el voltaje de cada ventana del cuantificador
ADC,en (8) el número de cuentas máximo para el voltaje máximo de la batería.
𝑉. 𝑁𝑖𝑣𝐴𝐷𝐶 =3.3𝑣
4095= 0.0008058𝑣 (7)
𝐶𝑢𝑒𝑛𝑡𝑎𝑀𝑎𝑥 𝐵𝑎𝑡𝑒𝑟𝑖𝑎 =2.8𝑣
0.0008058𝑣≅ 3475𝑐𝑡𝑎𝑠 (8)
En (9) se tienen el número de cuentas mínimo para una tensión mínima de la batería luego
del divisor resistivo, en (10) se calcula el valor de un escalar para convertir el valor máximo de
cuentas del cuantificador a porcentaje:
𝐶𝑢𝑒𝑛𝑡𝑎𝑀𝑎𝑥 𝐵𝑎𝑡𝑒𝑟𝑖𝑎 =1.82
0.0008058≅ 2259𝑐𝑡𝑎𝑠 (9)
%𝐸𝑠𝑐𝑎𝑙𝑎𝑟 =100
3475 ∗ 3.34095
= 35.7142 (10)
Se calcula en (11) y (12) un valor de offset para que el valor mínimo de cuentas pase por
el cero porcentual:
%𝑜𝑓𝑓𝑠𝑒𝑡(𝑐𝑡𝑎𝑠) = 𝑐𝑡𝑎𝑠 ∗3.3
4095∗ 35.7142 (11)
%𝑜𝑓𝑓𝑠𝑒𝑡 =2259 ∗ 3.3
4095∗ 35.7142 = 65.015 (12)
Se calcula un nuevo escalar en (13) debido a que agregar un offset traslada la recta y el
valor máximo de la recta porcentual a un valor que debe ser corregido. En (14) se tiene una
ecuación que pasa un rango de cuentas del cuantificador ADC que mide la batería a una medida
porcentual.
42
%𝐸𝑠𝑐𝑎𝑙𝑎𝑟 = 3475 ∗3.3
4095= 2.800366 (13)
%𝐶𝐵𝑎𝑡𝑒𝑟𝑖𝑎 = (%𝑜𝑓𝑓𝑠𝑒𝑡(𝑐𝑡𝑎𝑠) − 65.015) ∗ 2.800366 (14)
En (15) y (16) se demuestra le ecuación para el valor de tensión máximo de la batería, y en
(17) y (18) para un valor de tensión mínimo.
%𝐶𝐵𝑎𝑡𝑒𝑟𝑖𝑎𝑀𝑎𝑥 = 3475 ∗3.3
4095∗ 35.7142 = 100.012 (15)
%𝐶𝐵𝑎𝑡𝑒𝑟𝑖𝑎𝑀𝑎𝑥 = (100.012 − 65.015)2.800366 = 98.006% (16)
%𝐶𝐵𝑎𝑡𝑒𝑟𝑖𝑎𝑀𝑎𝑥 = 2259 ∗3.3
4095∗ 35.7142 = 65.015 (17)
%𝐶𝐵𝑎𝑡𝑒𝑟𝑖𝑎𝑀𝑎𝑥 = (65.015 − 65.015)2.800366 = 0% (18)
Se realiza el mismo procedimiento para la batería secundaria, y para detectar si el cargador
de corriente DC se ha conectado al sistema, solo es necesario aplicar la ecuación (7), que convierte
las cuentas del cuantificador, a la tensión del cargador luego de aplicar el correspondiente divisor
de voltaje, cuando es mayor que cero entonces es porque el cargador de corriente se ha conectado
al sistema.
8.4. Termocupla
La termocupla se encarga de sensar la temperatura del tanque de combustible y del
quemador, su función consiste en que, si la temperatura del tanque o del quemador sobrepasa el
umbral de 50 grados Celsius, y la chimenea no se ha encendido, el microcontrolador no va permitir
que se encienda, debido que el combustible al estar caliente si se enciende causaría una explosión
o una llamarada que puede salirse de control.
Generalmente este evento se da a lugar cuando, por ejemplo; en un primer estado la
chimenea está encendida, la alta temperatura generada por la llama se acumula dentro de la
chimenea, en un segundo evento, esta se apaga por decisión del usuario o por terminación del
tiempo programado, esa alta temperatura acumulada se queda dentro de la chimenea y es ahí donde
el microcontrolador detecta esa alta temperatura y no permite avanzar al siguiente estado de
encendido.
En el mercado se consigue en un solo conjunto, la termocupla y el compensador de unión
fría junto con el acondicionador en un solo integrado que tiene como salida la temperatura en un
buffer serial de datos que se comunica con un receptor, por comunicación SPI, un
microcontrolador, por lo que solo es necesario codificar con una librería el microcontrolador para
tomar los datos de temperatura. El rango de medición de las termocuplas es mayor al de un sensor
RTD, y más económico, por eso se consideró esta elección.
Existen los módulos acondicionadores de termocuplas de referencia MAX6675 y
MAX31855, esta última es una versión mejorada del primero, que el fabricante ha catalogado
como obsoleto respecto de su versión más reciente, que tiene como su principal mejora tener un
rango de medición mayor, aislamiento de la termocupla respecto a la tierra y lectura de temperatura
43
del compensador de unión fría (CUF), expresado como temperatura ambiente y ubicado en el
propio modulo. (Datasheet MAX31855, 2015)
En la tabla 3 se comparan las características de estos dos tipos de módulos de termocuplas
Modulo MAX6675 MAX31855
Rango de medición 0°c a +1024°c -200°c a +1350°c
Voltaje de operación 3.0v a 5.5v 3.0v a 3.6v
Resolución 12 bit 14 bit
Icc 700uA 900uA
Rango de operación del IC -20°c a +85°c -40°c a 125°c
Lectura del CUF No Si
Termocupla a tierra Si No Tabla 3: comparativa entre los dos módulos de termocupla mejor aptos para el sistema
En la figura 17 se observa la configuración de los pines del MAX31855 con la termocupla
y el microcontrolador.
Figura 17: Esquema de conexión para comunicar el modulo con el microcontrolador[26]
8.5. Acelerómetro
Para protección, seguridad del entorno y del usuario, se deben prevenir las vibraciones que
puedan ser ocasionadas por eventos externos, como por ejemplo una persona, un animal o un
temblor, es por eso que es necesario el uso de un acelerómetro de tres ejes que pueda detectar
cambios de posición en alguno de estos.
Para cumplir esta función no se requiere un acelerómetro de alta precisión, solo hace falta
encontrar un sensor que funcione con una librería que pueda ser incluida en el programa principal
y que maneje un protocolo de comunicación I2C o SPI.
El sensor ADXL345 mide la magnitud de las aceleraciones en cada eje, envía las lecturas
de las magnitudes de cada eje por medio del protocolo de comunicación I2C hacia el dispositivo
Maestro, función de la que se ocupa el microcontrolador, allí, el programa multiplica por un escalar
las lecturas de la aceleración para que esta sea expresada en gravedades.
44
Para la detección de vibraciones, se codifica una función en el programa del
microcontrolador como la que se muestra en la siguiente ecuación (1) para detectar las diferencias
de magnitud en el tiempo, si la diferencia sobrepasa el umbral entonces se considera como una
vibración y el programa envía una alerta.
∆𝑒𝑗𝑒𝑋 = 𝑒𝑗𝑒𝑋2 − 𝑒𝑗𝑒𝑋∆𝑒𝑗𝑒𝑌 = 𝑒𝑗𝑒𝑌2 − 𝑒𝑗𝑒𝑌∆𝑒𝑗𝑒𝑍 = 𝑒𝑗𝑒𝑍2 − 𝑒𝑗𝑒𝑍
𝑒𝑗𝑒𝑠 = ∆𝑒𝑗𝑒𝑋 + ∆𝑒𝑗𝑒𝑌 + ∆𝑒𝑗𝑒𝑍𝑒𝑗𝑒𝑋2 = 𝑒𝑗𝑒𝑋𝑒𝑗𝑒𝑌2 = 𝑒𝑗𝑒𝑌𝑒𝑗𝑒𝑍2 = 𝑒𝑗𝑒𝑍
(1)
Esta alerta se visualiza tanto en la pantalla LCD como a la aplicación Android.
8.6. Módulo de comunicación Bluetooth
La comunicación entre el microcontrolador y dispositivo Android se logra por medio de un
módulo de comunicación Bluetooth LE (Low Energy), el cual fue elegido por su bajo consumo
energético en los diferentes estados de conexión, en cambio un módulo de comunicación Wi-Fi
posee un consumo energético más elevado que no sería practico implementar si se desea tener una
larga autonomía eléctrica.
El modulo Bluetooth estándar, versión 2.0 cumpliría con los requerimientos del proyecto,
pero su alto consumo eléctrico en cualquiera de sus estados de conexión reduciría rápidamente la
carga de la batería, aunque es muy relativamente sencillo de implementar en una aplicación
Android, como desventaja no es soportada por dispositivos Apple, que es uno de los alcances que
se desea tener en un proyecto futuro.
En la tabla 4 se observa una comparativa orientada al consumo eléctrico y campo de
cobertura de los diferentes protocolos de comunicación inalámbrica considerados.
Wi-fi ZigBee Bluetooth 2.0 Bluetooth LE V4.0
Range(m) 100 100 60 30
Rx potencia(mW) 270 84 200 53
Tx potencia(mW) 350 72 200 60
Potencia promedio cada
10 mensajes por dia
(uW)
500 414 500 50
Sleep(uW) 300 4 500 8
Dispostivos Android Si No Si Si Tabla 4: Comparación del consumo eléctrico en diferentes tecnologías inalámbricas [33]
El modulo en este proyecto, es un módulo BLE(Bluetooth Low Energy), traducido de sus
siglas, bluetooth de baja energía, o de bajo consumo eléctrico, este tipo de módulos bluetooth se
usa para aplicaciones IOT, control a distancia, emisión y recepción de datos de control, debido a
que solo se pueden trasmitir cadenas de 20 bytes por trama, no es eficiente para enviar grandes
paquetes de datos. (Currey, 2017)
45
Se eligió el modulo Bluetooth HM-10 para desarrollar este proyecto, que maneja el
protocolo de comunicación UART, en la figura 18 se observan los pines de comunicación TX y
RX, los pines de alimentación y el pin STATE, que se activa en alto cuando se enlaza con un
dispositivo, muy útil en el diseño del circuito para este proyecto, porque le indica al
microcontrolador cuando se ha conectado o desconectado el dispositivo.
Figura 18: Esquema de pines del módulo de comunicación Bluetooth HM-10
8.7. Circuito Electrónico
8.7.1. Control PWM de la bomba de combustible
La bomba de combustible básicamente es un motor de corriente continua al que se le puede
controlar la velocidad de giro por medio de una señal PWM, que, al variar su ciclo útil, varia el
nivel dc que alimenta el motor. El circuito que se implementó se muestra en la figura, y se compone
de una etapa de dos transistores NPN en modo de corte y saturación, uno para dar la suficiente
corriente al Mosfet y otro para negar lógicamente el primer transistor. Luego está el MOSFET que
controlara la alimentación del motor mediante la señal PWM, el condensador ayuda a filtrar la
señal pwm y el diodo ayuda a proteger el mosfet de corrientes indeseables. (Verle, 2017)
Figura 19: Esquema eléctrico para controlar la bomba de combustible por medio de la señal PWM
8.7.2. Generador de alta tensión
El generador de alto voltaje se compone de un transformador flyback que debido a su
complejidad en la fabricación no es posible diseñarlo e implementarlo de forma manual, se
requiere de un proceso industrial para que sea completamente funcional.
46
Aunque no sea posible diseñar un trasformador y fabricarlo especialmente para este
proyecto, si es posible adquirir uno que se ajuste a las requerimientos y capacidades eléctricas de
las baterías. Existen transformadores flyback de gran capacidad, pero requieren una corriente que
excede la capacidad de las baterías. (Goldwasser, 2001)
El transformador flyback que se adquirió para este proyecto posee un devanado primario,
uno secundario y uno de realimentación, cuyo fabricante especifica cómo debe conectarse, los
componentes, parámetros de tensión y corriente también los especifica el fabricante del
transformador, para conseguir así un generador de voltaje de 15Kv que genera un arco eléctrico
incandescente de algunos milímetros lo suficientemente amplio como para encender el
combustible con una tensión en la alimentación de 7.4v. ("15kV Transformer - Custom
Electronics, PWM Circuits, Induction Heating, and DIY Science Projects", 2019)
En la imagen se muestran el esquema eléctrico del módulo generador de alto voltaje,
obtenido del fabricante.
Figura 20: Esquema eléctrico de potencia para controlar el encendido del arco eléctrico en el transformador flyback
El transistor de potencia TIP3055 entra en saturación permitiendo el flujo magnético del
primario al secundario, cuando se carga magnéticamente el núcleo, este crea un corriente en
sentido contrario por el devanado de realimentación, una corriente que apaga el transistor por
medio de la base de éste. Al apagarse, el campo magnético en el núcleo se descarga en el
secundario con una tensión de 15kv. Se repite el ciclo periódicamente, y como resultado se tiene
una señal cuadrada en el devanado primario, generando armónicos en el secundario, obteniendo
una señal sinusoidal con una amplitud de 15KV debido a la relación de vueltas del transformador
y al campo magnético almacenado en el núcleo, este se descarga en las terminales cuando la
tensión en el primario es cero. (Goldwasser, 2001)
El pin del microcontrolador que controla el circuito es aislado mediante un optotransistor
para protección de corrientes altas de la etapa potencia en la que se encuentra el generador de alta
tensión. Por último, el mosfet controla el encendido y el apagado del generador de alta tensión.
47
8.7.3. Circuito Anti rebote para el pulsador
La biochimenea también debe poder ser operada sin el uso de aplicaciones Android,
mediante un botón pulsador se puede pasar de un estado a otro. El circuito anti rebote como el que
se muestra en la figura se compone de dos resistencias dispuestas en un arreglo pull-up con el
pulsador, un condensador para filtrar el ruido inducido por el pulsador y por ultimo un transistor
NPN en modo de corte y saturación para tener un flanco de subida y de bajada completamente
recto a la entrada del pin RB0, en donde se da la interrupción para indicar que se ha pulsado el
botón.
Figura 21: Circuito Anti rebote para controlar la biochimenea por medio de un pulsador
8.7.4. Circuito de alimentación y de carga de las baterías
La fuente de poder del circuito se compone de dos baterías, la batería primaria al tener una
tensión de 3.7v, no tiene la tensión suficiente para alimentar los sensores que funcionan con niveles
lógicos de 0 a 5v por lo que es necesario elevar la tensión a 5v mediante el modulo elevador
MT3608.
El microcontrolador es un integrado que maneja una electrónica de bajo consumo eléctrico
por lo que su tensión nominal no debe superar los 3.3v, esto se logra mediante un regulador
LM1117 de 3.3v que es alimentado por el modulo elevador MT3608. El diodo que existe entre
estos dos dispositivos cumple con la función de proteger o aislar la línea de 3.3v de la de 5v en el
momento que se necesite programar el microcontrolador mediante la interfaz ICSP que se crea
cuando se conecta el modulo programador PICKIT2 al microcontrolador, debido a que el modulo
programador tiene su propia fuente de poder de 3.3v y el diodo evita que no se alimenten los
dispositivos conectados a la línea de tensión de 5v, solo se alimentaria el microcontrolador que es
el único dispositivo alimentado a 3.3v.
48
Los módulos reductores de voltaje de referencia MT1584 cumplen con la función de
mantener una tensión nominal en los terminales de las baterías, en la batería primaria de 4.7v y en
la secundaria de 9v cuando se conecta el cargador.
Para poder medir el nivel de carga de las baterías, se realizaron los cálculos de los divisores
resistivos en la sección 8.3, para cada batería y así obtener un valor de tensión dentro de los valores
de referencia del puerto ADC del microcontrolador, de 0 a 3.3v, y con el fin de identificar si se ha
conectado una fuente de poder externa para cargar las baterías se ha calculado igualmente un
divisor resistivo para tomar la tensión de ese cargador o fuente de poder externa.
El circuito de alimentación y de carga es mostrado en la figura 22.
Figura 22: Esquema eléctrico para regular el voltaje del sistema y de carga de las baterías
8.8. Microcontrolador
El microcontrolador se encarga de todas las operaciones lógicas del sistema, recibe los
datos de los sensores por el puerto I2C y SPI, recibe y envía comandos del módulo bluetooth,
controla la LCD y los mensajes que aparecen, utiliza salidas digitales, una en modo PWM para
controlar la velocidad de giro de la bomba de combustible y otra para controlar el circuito
generador de arco eléctrico. Se utilizan tres fuentes de interrupción, una por el buffer de entrada
de datos RS232, interrupción por el timer 1 para una base de tiempo precisa y una interrupción
externa para el uso de un botón auxiliar en caso de que el usuario desee operar la chimenea sin el
uso de dispositivos Android.
Se elige trabajar con el PIC18f26j13 de microchip por la facilidad de poder usar protocolos
de comunicación I2C y SPI al mismo tiempo, además de su particular característica de mapeo de
pines para asignar la salida de un puerto a cualquiera de lo pines del microcontrolador asignados
para esta funcionalidad, y por ultimo por su bajo consumo energético.
49
En la tabla 5 se muestra una comparación de los diferentes Microcontroladores
considerados para este proyecto por su fácil adquisición y por sus características.
Microcontrolador PIC 16F877A 18F4550 18F2550 18F26J13
CPU 8 bit 8 bit 8 bit 8 bit
ROM 14K 32K 32K 64K
#Pines 40 40 28 28
Resolucion ADC 10 bit 10 bit 10 bit 12 bit
Puertos SPI 1 1 1 2
Puertos I2C 1 1 1 2
Voltaje operación 5v 5v 5v 3.3v
Pines remapeables No No No Si
Disponibilidad comercial Local Local Local Importado Tabla 5: Comparativa de los diferentes tipos de microcontroladores considerados para ser implementado en el
sistema
Tanto la configuración del microcontrolador como la codificación del programa del
microcontrolador se realizó sobre el ambiente de programación y compilador PIC C Compiler de
la empresa CCS, en este compilador se codifica como lenguaje de programación en código C, que
compila a código en lenguaje ensamblador y a su vez la configuración de registros en el sistema
hexadecimal con el que se programa el microcontrolador.
8.8.1. Configuración del microcontrolador
La configuración del microcontrolador es la forma como los registros de configuración de
microcontrolador son establecidos de manera que este pueda trabajar de la manera deseada. Al
codificar en PIC C Compiler no solo se especifican los registros de configuración de manera
indirecta, sino además se especifican las librerías donde se encuentran las funciones que se
utilizaran para incluirlas en el programa y que ayudaran a compilarlo.
En el siguiente código se especifican las librerías del microcontrolador, de los sensores
MAX31855, VL6180x, ADXL345 y LCD , además de librerías para manejo de funciones en C,
fusibles de configuración, configuración del puerto USART, I2C, SPI, configuración del mapeo
de pines para el puerto SPI2 y configuración de los registros para el timer 1.
#include <18F26J13.h> #device ADC=12 #fuses NOWDT,NODSWDT,SOSC_HIGH // configura fuses #fuses INTRC_IO #use delay(clock=8000000) //Reloj interno a 8Mhz #use i2c(Master,Fast=400000, sda=PIN_C4, scl=PIN_C3,force_sw) //Configuracion puerto I2C #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,errors) //Configuracion del puerto serial #use spi(SPI2,FORCE_SW) //Configuracion del puerto SPI #PIN_SELECT SCK2OUT=PIN_B4 //Mapeo del puerto SPI a los pines del Microcontrolador #PIN_SELECT SDI2=PIN_B5 #PIN_SELECT SS2OUT=PIN_B3 #include <max31855.c> //Libreria para leer los datos de la termocupla #include <VL6180x.h> //Libreria para leer el sensor de proximidad
50
#include <Adxl345l.c> //Libreria para leer los datos del acelerometro #include <i2c_Flex_LCD.h> //Libreria para controlar el visualizador LCD #include <stdlib.h> //Librerias estandar de funciones en lenguaje C #include <string.h> #include <stdio.h> #include <lcdcustomchars.c> #Byte TMR1H = 0xFCF // TIMER1 HIGH BYTE LOOK DATASHEET //Configuracion del reloj en timer 1 a 32768 #Byte T1CON = 0xFCD //TIMER1 CONFIG REGISTER LOOK DATASHEET //Registro de configuracion del TIMER1
8.8.2. Variables y métodos del programa
Las variables que se describen en el siguiente código incluye, declaración de variables
enteras, variables de estado booleanas o banderas, variables en la memoria RAM y declaración de
métodos o funciones, cada uno con comentarios.
// CONSTANTES Y VARIABLES ///////////////////////////////////////////////////////////////// signed int16 ejeX2=0,DejeX=0,ejeY2=0,DejeY=0,ejeZ2=0,DejeZ=0,ejes=0,x,y,z;//Variables acelerometro int16 nivbat1=0,t,c,con=0; //Nivel de combustible,Bateria,Tiempo restante,Transcurrido y voltaje de conexion BT int16 k=0; //Contador para mensaje de vibracion int16 tempvalue,charger,nivbat2,vconex; //Valores de temperatura, de Voltaje del cargador, de la bateria 2 y del voltaje del estado de conexion BT int16 cpulsador=0; //Tiempo de quemado cuando se usa el pulsador int8 niv; //Nivel de combustible int const lenbuff=32; // Longitud de buffer, Ajustar int16 howLong; //Tiempo total restante en segundos int16 howLong1; //Tiempo total trascurrido en segundos int16 hour; //Horas restantes int16 hour1; //Horas trascurridas int16 min; //Minutos restantes int16 min1; //Minutos trascurridos int16 sec; //Segundos restantes int16 sec1; //Segundos trascurridos int1 flg=false; //Bandera pulsador externo int contador=0; //Contador de pulsaciones // VARIABLES EN RAM ///////////////////////////////////////////////////////////
int xbuff=0x00; // dice: siguiente char en cbuff char cbuff[lenbuff]; // Buffer char rcvchar=0x00; // ltimo caracter recibido int1 flagcommand=0; // Flag para indicar comando disponible int1 flagacel=0; //Bandera acelerometro int1 flagtemp=0; //Bandera termocupla int1 flagtime=0; //Bandera tiempo habilitado int1 flagacelmsg=0; //Bandera mensaje de vibracion int1 chimenea=0; //bandera para encender la bomba int1 encendido=0; //bandera para encender la chispa
51
int1 pulsador1=0; //bandera para indicar pulsador oprimido int1 apagado=0; //bandera para indicar que se ha apagado el sistema int1 arranqueM=0; //Bandera Arranque del motor float xg, yg, zg; //Variable del acelerometro float pbatt1; float pbatt2; // Declaracie Funciones /////////////////////////////////////////////////// void leer_adc(void); //Leer el puerto ADC void battcharge(void); void battcharge2(void); float convertir (int16 dato); //Metodo para convetir cuentas en voltaje float convertirporc (int16 datob); float convertirporcinv (int16 datoc); //Para convertir cuentas en porcentaje invertido float convertirporc1 (int16 datob); //Convierte cuentas a porcentaje de la bateria 1 float convertirporc2 (int16 datob); //Convierte cuentas a porcentaje de la bateria 1 void acelerometro(void); //Evalua las variables del acelerometro void ChimeneaM(void); //Para encender la bomba y la chispa void tiempo_ch(void); //Para imprimir el tiempo restante en la LCD void tiempo_ch1(void); //Para imprimir el tiempo trascurrido en la LCD void apagar_ch(void); //Para apagar la chimenea void inicbuff(void); // Borra buffer int addcbuff(char c); // a caracter recibido al buffer void echos(char c); // Eco selectivo sobre RS232 void procesa_comando(void); // Procesa comando void mensageLCD1(void); //Para imprimir mensaje de vibracion en la LCD void mensageLCD2(void); //Para imprimir mensaje de alta temperatura en la LCD void mensageLCD3(void); //Para imprimir mensaje en blanco en la LCD
8.8.3. Interrupciones
Las interrupciones que se habilitan para este programa son por el Timer 1, por conteo del
registro TMR1H con el cristal oscilador externo a 32768Hz. Interrupción de recepción de datos
por el puerto serial, cuando recibe un dato lo añade al buffer. Por ultimo una interrupción externa,
que da a lugar si se recibe un flanco de subida por el pin RB0, y así se pone en alto una bandera.
#int_TIMER1 void TIMER1_isr(void) {
bit_clear(T1CON,7); //Enable access to the individual bytes of the timer register set_timer1(32768); //Bit_Set(TMR1H,6); //Add 32768 to timer1 by setting high bit or timer register Bit_Set(T1CON,7); //Disable access to the individual bytes of the timer register t--; // Decremento de segundos c++; // Incremento de segundos k++; //Incremento de segundos }
#int_rda
52
void serial_isr() { // Interrupciecepcierie USART
rcvchar=0x00; // Inicializa caracter recibido if(kbhit()){ // Si hay algo pendiente de recibir ... rcvchar=getc(); // lo recibe y ... addcbuff(rcvchar); // lo a al buffer
}
}
#int_EXT void EXT_isr(void) //Interrupcion externa por medio del pin RB0
{
flg=true; }
8.8.4. Proceso principal
En el proceso principal se encuentra la configuración inicial de las salidas digitales, la
inicialización de las librerías de los sensores y LCD, configuración del puerto ADC y la
habilitación de las interrupciones a utilizar. Luego, el bucle donde se encuentran los condicionales
y referencias a funciones que tienen como finalidad lograr resolver los que se plantea como
problemática en este proyecto, cumpliendo con los objetivos del mismo. El bucle funcionara hasta
que se produzca la interrupción por el puerto USART, si se produce, el programa va al método
para procesar la información recibida.
El código a continuación tiene comentarios para comprender el código con facilidad.
void main() {
delay_ms(200);
setup_oscillator(OSC_8MHZ); //Oscilador a 8Mhz enable_interrupts(INT_TIMER1); //Habilita interrupcion por TIMER1 setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_ENABLE_SOSC );//Configuracion del TIMER1 con el crystal oscilador de 32khz ext_int_edge(H_TO_L); enable_interrupts(INT_EXT); //Habilita interrupciones externas enable_interrupts(int_rda); //Habilita Interrupcie recepcion de datos por el puerto serial enable_interrupts(GLOBAL); //Habilita interrupciones globalmente setup_spi2(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_64);//Configuracion del puerto SPI setup_adc(ADC_CLOCK_INTERNAL); //Configura en DAC con el reloj interno setup_adc_ports(sAN0|sAN1|sAN2|sAN3|VSS_VDD); //Configura los pines RA0 a RA3 como entradas analogicas
53
SET_TRIS_C(0b10010011); //Configuracion de los pines del puerto C setup_ccp6(CCP_PWM); //Habilita el el modulo CCP6 en modo PWM setup_timer_2(T2_DIV_BY_1,255,1); //FPwm=11.718,8 Khz lcd_init(); //Inicializa el visualizador LCD por medio de la libreria adxl345_init(); //Inicializa el acelerometro por medio de la libreria init_proximity_sensor(); //Inicializa el sensor de distacia por medio de la libreria lcd_backlight_led(OFF); //estado inicial del LED de iluminacion del visualizador Output_low(PIN_A6); //estado inicial del pin que habilita el encendedor Output_high(PIN_A7); //estado inicial del pin que habilita la bocina Output_low(PIN_C2); //estado inicial del pin que habilita el ventilador SET_TRIS_B(0b00100001); //Configuracion de los pines del puerto B arranqueM=0; c=0; t=0; set_pwm6_duty(1); //Estado inicial de la sePWM que controla la bomba de combustible lcd_load_custom_chars(); do{
leer_adc(); adxl345_read(&x, &y, &z); //Lectura de las magnitudes medidas de los ejes del acelerometro por medio de la libreria delay_ms(50); xg = (float)x * 0.0039; //Magnitud multiplicada por un escalar para expresarla en gravedades yg = (float)y * 0.0039; zg = (float)z * 0.0039; acelerometro(); //metodo para evaluar diferencias en las magnitudes para interpretar las vibraciones pbatt1=convertirporc1(nivbat1); pbatt2=convertirporc2(nivbat2); if(convertir(charger)>=0.1){ lcd_gotoxy(14,2); lcd_putc(CHARGING); lcd_gotoxy(16,2); lcd_putc(CHARGING); }else if(convertir(charger)==0){ battcharge(); battcharge2(); }
if(vconex>=3){ lcd_gotoxy(10,1); lcd_putc(BTTH); }else{
54
lcd_gotoxy(10,1); lcd_putc(" "); }
do{
readMAX(); //Habilita el puerto SPI para recibir los datos de la termocupla por medio de la libreria }while(tempFault()!=0); //mientras no existan errores tempvalue=readExtTemp(); //lectura de las temperatura por medio de la libreria de la termocupla if(tempvalue<=50){ //Condicional para mostrar alerta de temperatura alta flagtemp=0; }
else{
flagtemp=1; }
if(tempvalue>=40){ Output_high(PIN_C2); //Condiciones para encender el ventilador }else{
Output_low(PIN_C2); }
Output_high(PIN_A7); if((flg==true)&&(vconex<3)){ //Evalua la entrada digital por el pulsador delay_ms(51); //SI -> retardo para evitar los rebotes if((flagtime==0)||(flagtime==1&&c>10))contador++; //Variable para contar pulsaciones flagacelmsg=0; if(contador==1){ printf(lcd_putc,"\f"); }
if(contador==2){ //Segundo Estado flg=false; mensageLCD3(); apagado=0; }
if(contador==3&&flagtemp==0){ //Encendido de la chimenea por medio del pulsador flg=false; chimenea=1; //Banderas flagtime=1; c=0; cpulsador=(int16)convertirporcinv(niv)*180;//Porcentaje de combustible a tiempo de quemado t=cpulsador; tiempo_ch(); //Metodo para imprimir el tiempo en la LCD pulsador1=1;
}
55
if(contador==4){ //Apagado de la chimenea por medio del pulsador flg=false; chimenea=0; flagtime=0; encendido=0; pulsador1=0; arranqueM=0;
}
if(contador==5){ flg=false; }
if(contador==6){ contador=1; flg=false; }
}
vconex=convertir(con); if(vconex>=3||flagtime==1||contador==2||contador==3||contador==4){ //Segundo estado lcd_backlight_led(ON); niv = proximity_sensor_read(); if(flagacelmsg==0){ //Si no hay mensaje de vibracion, imprime datos de los sensores lcd_gotoxy(12,1); printf(lcd_putc,"C%02.0g ",convertirporcinv(niv)); //LCD Combustible lcd_gotoxy(16,1); printf(lcd_putc,"%%"); //Porcentaje lcd_gotoxy(12,2); printf(lcd_putc,"B1"); lcd_gotoxy(15,2); printf(lcd_putc,"2");
La siguiente línea de código se especifica como una cadena de datos que se trasmite por el
puerto USART del microcontrolador al módulo bluetooth, sirve para la monitorización de datos
por parte de la aplicación Android, en orden; primero se encuentra el nivel de combustible medido
por el sensor de nivel, luego el nivel de carga de la batería, expresados porcentualmente, luego, las
variables booleanas que indican si hubo una vibración y por ultimo una alerta que indica si existe
una temperatura alta en la biochimenea.
printf("#%03.0g+%03.0g+%1u+%1u+~\r",convertirporcinv(niv),convertirporc1(nivbat1),flagacel,flagtemp);//Datos de los sensores enviado por el puerto serial delay_ms(10); }else if(vconex<3||flagtime==0){ //Primer estado cuando no esta conectado lcd_backlight_led(OFF); //LCD Y sensores apagados printf(lcd_putc,"\f"); //Limpiar LCD
}
56
howLong= t; hour = howLong / 3600; //Segundos/3600=hora howLong = howLong % 3600; //Segundos modulo 3600 min = howLong / 60; //segundos/60=minutos howLong = howLong % 60; //minutos modulo 60 sec = howLong; howLong1 = c; hour1 = howLong1 / 3600; howLong1 = howLong1 % 3600; min1 = howLong1 / 60; howLong1 = howLong1 % 60; sec1 = howLong1;
if(t>0&&flagtime==1&&(vconex>=3||contador==3))tiempo_ch(); //Condiciones para imprimir tiempo restante if(t==0&&flagtime==1)apagar_ch(); //Condiciones para apagar chimenea if((pulsador1==1||flagtime==1)&&flagacelmsg==0)tiempo_ch1(); //Condiciones para imprimir tiempo trascurrido if((encendido==1||apagado==1)&&(flagacelmsg==1||flagacel==1))mensageLCD1(); //Condiciones para imprimir mensaje de vibracion if(flagtemp==1&&flagacelmsg==0&&chimenea==0)mensageLCD2(); //Condiciones para imprimir mensaje de temperatura if(flagtemp==0&&flagacelmsg==0&&chimenea==0)mensageLCD3(); //Condiciones para limpiar LCD
if(flagcommand) procesa_comando(); // Si hay comando pendiente ChimeneaM(); // de procesar ... lo procesa. }while (TRUE);{
}
}
8.8.5. Funciones
Además del proceso principal, se crearon otras funciones o métodos que cumplen con la
finalidad del proyecto, métodos, funciones aritméticas y un método para procesar comandos, que
se describirán a continuación.
Crea buffer para recepción de los caracteres que se reciben por el puerto USART,
colocando todos los caracteres en cero.
void inicbuff(void){ // Inicia a \0 cbuff -------------------
int i;
57
for(i=0;i<lenbuff;i++){ // Bucle que pone a 0 todos los cbuff[i]=0x00; // caracteres en el buffer }
xbuff=0x00; // Inicializo el indice de siguiente // caracter }
Función para añadir los caracteres recibidos en el buffer, y habilita bandera para llamar el
método que procesa los comandos, en el caso de que el ultimo caracter sea “\0”, que significa fin
de la cadena.
int addcbuff(char c){ // Añade a cbuff -----------------------
switch(c){ case 0x0D: // Enter -> Habilita Flag para procesar flagcommand=1; // Comando en Main break; default: cbuff[xbuff++]=c; // Añade caracter recibido al Buffer }
}
Función aritmética para convertir una variable cuantificada por el ADC a un valor en
voltaje, utilizada para medir la tensión del pin STATE del módulo bluetooth, de 3.3v cuando el
modulo está conectado a un dispositivo, también se utiliza para medir la tensión del cargador con
el objetivo de indicarle al usuario que las baterías se están cargando.
float convertir (int16 dato){ //Metodo para convetir cuentas en voltaje
float aux=0; aux = dato; aux =(aux*3.3)/4095; return aux;
Función aritmética para convertir una variable cuantificada por el puerto ADC a un valor
porcentual, utilizada para convertir las cuentas del ADC del nivel de carga de la batería a una
expresión porcentual, linealizando el rango de medición y estableciendo los rangos donde se
encontraría cargada completamente la batería o descargada.
float convertirporc1 (int16 datob){ //Para convertir cuentas a porcentaje 3475-2259//Bateria 1 float auxb=0; if(nivbat1>=4000)auxb=150; if(nivbat1>=3475&&nivbat1<4000)auxb=100; if(nivbat1<3475&&nivbat1>2259){ auxb = datob; auxb =((auxb*3.3)/4095)*35.7142857; auxb = (auxb-64.2857143)*2.80033604; }
if(nivbat1<=2259)auxb=0;
58
return auxb; }
Una segunda función, similar a la anterior que es utilizada para la batería secundaria.
float convertirporc2 (int16 datob){ //Para convertir cuentas a porcentaje 3438-2283 //Bateria 2 float auxb=0; if(nivbat2>=3700)auxb=150; if(nivbat2>=3438&&nivbat2<3700)auxb=100; if(nivbat2<3438&&nivbat2>2283){ auxb = datob; auxb =((auxb*3.3)/4095)*36.101083; auxb = (auxb-65.8483754)*2.92811839; }
if(nivbat2<=2283)auxb=0; return auxb; }
La siguiente función es utilizada para tomar la lectura de nivel de combustible en
milímetros y lo convierte a porcentaje dentro de los rangos medibles dentro del tanque de
combustible, fuera de esos rangos se establece como un tanque de combustible vacío o como un
tanque de combustible lleno.
float convertirporcinv (int16 datoc){ //Para convertir cuentas en porcentaje invertido //Niv combustible float auxc=0; if(datoc<=5)auxc=100; if(datoc<=100){ auxc = datoc; auxc =100-auxc; }
if(datoc>=101)auxc=0; return auxc; }
Método para Encender la biochimeneas mediante un orden especifico de activación de la
bomba de combustible y el generador de alto voltaje, la bomba de combustible comienza bombear
el combustible del tanque de reserva al quemador a su máxima velocidad de giro, luego de 500ms
la velocidad de giro se reduce para dosificar el consumo de combustible, inmediatamente se activa
el generador de alto voltaje durante seis segundos creando un arco eléctrico durante este tiempo ,
suficiente para encender el combustible.
void ChimeneaM(void){ //Para encender la bomba y la chispa if(chimenea==1&&flagtemp==0&&niv<=95){ if(arranqueM==0){ set_pwm6_duty(1023); delay_ms(500); arranqueM=1; }
if(encendido==0){ set_pwm6_duty(27);
59
if(c>0&&c<=6){ //Enciende el arco electrico durante 6 segundos output_high(PIN_A6); }
if(c>6&&c!=0){ output_low(PIN_A6); encendido=1; }
}
}else if(chimenea==0){ set_pwm6_duty(1); }
}
Método para imprimir el tiempo restante de encendido en el visualizador LCD.
void tiempo_ch(void){ //Para imprimir el tiempo restante en la LCD lcd_gotoxy(1,1); lcd_putc(""); printf(lcd_putc,"R=%01lu:%02lu:%02lu",hour,min,sec); }
Método para imprimir el tiempo trascurrido que lleva encendido el quemador, en el
visualizador LCD.
void tiempo_ch1(void){ //Para imprimir el tiempo trascurrido en la LCD lcd_gotoxy(1,2); lcd_putc(""); printf(lcd_putc,"T=%01lu:%02lu:%02lu",hour1,min1,sec1); }
Método para apagar el quemador de la biochimenea, en caso de estar conectado a un
dispositivo, se envía un comando a la aplicación Android, para que esta envié el comando de
apagado, y si no se encuentra conectado, se cambia de estado las variables booleanas o banderas
que mantienen encendido el quemador.
void apagar_ch(void){ //Para apagar la chimenea if(vconex>=3){ //Si existe una conexion BT printf("Over~\r"); }
else{ //Si es operado por el pulsador contador=4; chimenea=0; flagtime=0; encendido=0; pulsador1=0; arranqueM=0; }
}
Método para configurar el puerto ADC, los canales ADC que se habilitaran para ser
cuantificados y es referenciado en cada ciclo del bucle del proceso principal.
60
void leer_adc(void){ //Leer el puerto ADC Read_ADC(ADC_START_ONLY); Set_ADC_Channel(0); delay_ms(1); con=read_adc(); //Lectura del pin analogico que indica el estado de conexion del modulo BT Set_ADC_Channel(1); delay_ms(1); Read_ADC(ADC_START_ONLY); nivbat1=read_adc(); //Lectura del pin analogico que indica el nivel de carga de la beteria 1 Set_ADC_Channel(2); delay_ms(1); Read_ADC(ADC_START_ONLY); charger=read_adc(); //Lectura del pin analogico que indica si el cargador se ha conectado Set_ADC_Channel(3); delay_ms(1); Read_ADC(ADC_START_ONLY); nivbat2=read_adc(); //Lectura del pin analogico que indica el nivel de carga de la beteria 2 }
Método aritmético que almacena las variables del acelerómetro, para realizar un delta o un
diferencial entre el valor pasado y el presente del valor de los tres ejes del acelerómetro, se
referencia cada ciclo del bucle del proceso principal , si hay una diferencia entre los dos valores
medidos de cada eje del acelerómetro se da a lugar el condicional y activara una bandera para
indicar que hubo una vibración en la biochimenea, que tiene como finalidad, no poner en peligro
el entorno donde se ubique la biochimenea.
void acelerometro(void){ //Evalua las variables del acelerometro DejeX=ejeX2-xg; DejeY=ejeY2-yg; DejeZ=ejeZ2-zg; ejes=DejeX+DejeY+DejeZ; ejeX2=xg; ejeY2=yg; ejeZ2=zg; if((ejes>0.05)||(ejes<-0.05)){ //Si la diferencia supera el umbral, se considera como una vibracion y envia la alerta flagacel=1; k=0; flagtime=0; }else{
flagacel=0; }
}
Método que muestra un mensaje de alerta en el visualizador LCD, que se detectó una
vibración en la biochimenea, mensaje que tiene una duración de 30 segundos cuantificados por el
timer 1.
61
void mensageLCD1(void){ //Para imprimir mensaje de vibracion en la LCD chimenea=0; c=0; t=0; printf(lcd_putc,"\f"); lcd_gotoxy(1,1); lcd_putc("VIBRACION"); lcd_gotoxy(1,2); lcd_putc("DETECTADA"); flagacelmsg=1; pulsador1=0; if(k==30){ //El mensaje de vibracion dura 30 segundos printf(lcd_putc,"\f"); flagacelmsg=0; pulsador1=0; apagado=0; }
}
Método condicional para mostrar un mensaje de advertencia de alta temperatura en el que
se recomienda no recargar ni encender la biochimenea, se visualiza mientras el quemador no este
encendido, debido a que es normal tener una temperatura alta mientras este encendida, tiene como
finalidad prevenir una explosión de combustible, porque el etanol reacciona violentamente cuando
se encuentra a una alta temperatura y se expone a una ignición.
void mensageLCD2(void){ //Para imprimir mensaje de alta temperatura en la LCD lcd_gotoxy(1,1); lcd_putc("Alta Temp"); lcd_gotoxy(1,2); lcd_putc("NoRecNoEnc"); }
Método para limpiar la LCD de los mensajes de alerta.
void mensageLCD3(void){ //Para imprimir mensaje en blanco en la LCD lcd_gotoxy(1,1); lcd_putc(" "); lcd_gotoxy(1,2); lcd_putc(" "); }
Método para procesar los comandos que se encuentran en el buffer y que se describe en
varios segmentos a continuación:
El método consiste en comparar el buffer que recibe los datos del puerto USART con el
buffer almacenado en la memoria ROM que contiene el comando con el que se ejecutaran las
sentencias u ordenes
Se pone en cero la variable string (arg) donde se almaceno el comando anterior, si hubo o
no alguno. Luego se compara los dos primeros caracteres del buffer de entrada de datos para
62
discriminar cualquier comando invalido, si coinciden con los caracteres “\w” se almacena el
contenido del buffer en la variable string (arg) hasta el carácter “\0”.
void procesa_comando(void){ // Procesa comando
int i; char arg[lenbuff]; // Argumento de comando (si lo tiene) char s3[]="apagarch"; char s4[]="encenderch"; char s5[]="tiempo?"; flagcommand=0; // Desactivo flag de comando pendiente. // printf("\r\nProcesando ... "); // Monitorizo procesando ...
for(i=0;i<lenbuff;i++){ // Bucle que pone a 0 todos los arg[i]=0x00; // caracteres en el argumento }
if(cbuff[0]=='\\'&&cbuff[1]=='w'){ // Comparo inicio del buffer con comando "\w"
i=2; do{ // Extraemos argumento del buffer arg[i-2]=cbuff[i]; // a partir del 3er byte y hasta \0. }while(cbuff[++i]!=0x00); // Aqui lo que deseemos hacer con comando "\w" // Monitorizamos el argunmento.
Condicional para comparar el comando “apagarch”, si se cumple, habilita las banderas para
apagar la chimenea.
if(strcmp(s3,arg)==0){ //Se recibe comando apagarch t=0; printf(lcd_putc,"%05lu",t); chimenea=0; flagtime=0; encendido=0; apagado=1; }
Condicional para encender el quemador de la biochimenea, se activan banderas para
encender el quemador.
if(strcmp(s4,arg)==0){ //Se recibe comando encenderch chimenea=1; flagacelmsg=0; apagado=0;
Condicional para responder solicitud de tiempo por parte de la aplicación Android, en el
caso de que la aplicación se reinicie por parte del usuario o se cierre accidentalmente y la
biochimenea continúe encendida, se envía el valor del tiempo en segundos que restan para apagar
la biochimenea.
}
if(strcmp(s5,arg)==0){ //Se recibe comando tiempo?
63
if(flagtime==1){ delay_ms(200); printf("#000+000+0+0+~\r"); //Imprime mensaje primario en el
puerto serial delay_ms(200); printf("T%05lu~\r",t); //Envia el tiempo restante por el
puerto serial }
}
}
Condicional para recibir la cantidad de tiempo que se encenderá el quemador de la
biochimenea, se comparan los dos primeros caracteres, si el buffer comparado coincide con los
caracteres “\t” se almacena el valor string en una variable entera que da inicio al conteo temporal
restante que durara encendido el quemador de la biochimenea
if(cbuff[0]=='\\'&&cbuff[1]=='t'){ //Se recibe el tiempo por el puerto serial
i=2; do{ // Extraemos argumento del buffer arg[i-2]=cbuff[i]; // a partir del 3er byte y hasta \0. }while(cbuff[++i]!=0x00); t=atol(arg); //Pasa de string a long lcd_gotoxy(1,1); lcd_putc(""); printf(lcd_putc,"%05lu",t); //Imprime el tiempo recibido en la LCD if(flagtime==0)c=0; flagtime=1; }
inicbuff(); // Borro buffer. }
El siguiente método utiliza la librería “lcdcustomchars.c” donde se crearon unos caracteres
personalizados para mostrar el estado de carga de las baterías.
void battcharge(void){ //Metodo para mostar la carga de la bateria meidante caracteres especiales lcd_gotoxy(14,2); if(pbatt1>0&&pbatt1<=5)lcd_putc(FIVE); else if(pbatt1>5&&pbatt1<=16)lcd_putc(SIXT); else if(pbatt1>16&&pbatt1<=32)lcd_putc(THIR); else if(pbatt1>32&&pbatt1<=50)lcd_putc(FIFT); else if(pbatt1>50&&pbatt1<=75)lcd_putc(SVTF); else if(pbatt1>75&&pbatt1<=102)lcd_putc(HUND); }
void battcharge2(void){ lcd_gotoxy(16,2); if(pbatt2>0&&pbatt2<=5)lcd_putc(FIVE); else if(pbatt2>5&&pbatt2<=16)lcd_putc(SIXT); else if(pbatt2>16&&pbatt2<=32)lcd_putc(THIR); else if(pbatt2>32&&pbatt2<=50)lcd_putc(FIFT); else if(pbatt2>50&&pbatt2<=75)lcd_putc(SVTF);
64
else if(pbatt2>75&&pbatt2<=102)lcd_putc(HUND); }
8.9. Interfaz ICSP (In-circuit serial programming)
La interfaz ICSP ofrece la posibilidad de programar el microcontrolador en el circuito de
aplicación, que es de gran utilidad en ámbitos de desarrollo, donde es necesario programar el PIC
repetidamente y testear inmediatamente. Al no tener que remover el integrado de un zócalo a otro,
se ahorra tiempo, torcedura de pines e inducción de corrientes electrostáticas. En la figura 23 se
muestra el circuito que se implementó, que consiste en aislar los pines de alimentación y de
programación del resto del circuito de aplicación por medio de resistencias y diodos. ("Como
programar un PIC 12Fxxx/16Fxxx con ICSP", 2019)
Figura 23: Interfaz ICSP para facilitar la programación del microcontrolador[38]
65
8.10. Aplicación Android
La aplicación Android se realizó en conjunto y a la par con el desarrollo del programa del
microcontrolador, sobre el entorno de desarrollo de Android Studio. Como condiciones iniciales
para el desarrollo de la aplicación se desea que sea compatible con la mayor cantidad de
dispositivos móviles en cuanto uso de librerías y herramientas de desarrollo SDK como proyección
a futuro del proyecto, porque se plantea la posibilidad de que pueda ser instalado en casi cualquier
dispositivo Android, aunque haga falta desarrollo para la compatibilidad de los diferentes tamaños
de pantalla, la compatibilidad con las API’s más utilizadas por dispositivos Android está
garantizada, gracias a la versatilidad del ambiente de programación de Android Studio.
Al ser una aplicación que hace uso extensivo de la comunicación Bluetooth para trabajar,
las clases, servicios y métodos de la aplicación se diseñaron alrededor de esta característica.
Al ser un programa tan extenso en cuanto a líneas de código, se anexará el código completo
en la parte final de este documento, pero a continuación se describe el programa mediante un
diagrama de flujo en la figura 24, que muestra como está compuesta la aplicación y como se
comunican cada actividad. La actividad DeviceList muestra los dispositivos BLE cercanos para
conectarse, una vez conectado la aplicación continua en la actividad Home, donde el usuario
configura el tiempo que dura encendida la llama de combustible y monitoriza los sensores. En la
actividad ONCH se muestra el tiempo restante de encendido de la llama y la monitorizan de los
sensores.
El envío y recepción de comandos de las actividades con el modulo HM-10 se gestiona por
medio del servicio BLEservice, que se enlaza con el módulo BLE en el hardware del dispositivo
Android para comunicarse con el modulo HM-10.
El modulo HM-10 por medio del protocolo UART envía y recibe la información del
microcontrolador que esté procesa de acuerdo a su programación.
Aplicación Android Comunicación
Home Bluetooth
BLE Modulo Modulo
DeviceList Service BLE HM-10
ONCH
Figura 24: Diagrama de flujo general entre las actividades, servicio de enlace de la aplicación y microcontrolador en
la biochimenea
66
En las figuras a continuación se muestran los diagramas de flujos de cada clase en JAVA
resumiendo en forma de comentarios los métodos que componen cada clase de la aplicación.
Figura 25: Diagrama de flujo de la clase DeviceList.java
El diagrama de flujo en la figura 25 muestra el procedimiento que realiza la clase
DeviceList para escanear dispositivos Bluetooth, mostrarlos en un listado y al pulsar uno de los
elementos, la aplicación se conectara con ese dispositivo, enviando la dirección MAC a la clase
servicio de la aplicación para mantener la conexión bluetooth.
67
El diagrama de flujo de la figura 26 muestra las excepciones que la clase Devicelist debe
realizar para que la aplicación se pueda conectar con un dispositivo Bluetooth, como en el caso de
que la aplicación este instalada en un sistema operativo Android Marshmallow, en el que se deben
conceder permisos de localización, además la aplicación debe verificar si el dispositivo soporta
conexiones bluetooth y verificar que este habilitado para buscar dispositivos cercanos.
Figura 26: diagrama de flujo de las excepciones y permisos de la aplicación
68
La siguiente clase dentro de la aplicación es el servicio BLEService, que mantiene y
gestiona la comunicación Bluetooth entre el dispositivo Android y el módulo BLE, es
particularmente importante para mantener el enlace y la comunicación entre los dos dispositivos
cuando se pasa de una actividad a otra, además de contener todos los métodos bluetooth para ser
referenciados desde otras clases, leer y escribir datos de recepción y envió.
En la figura 27 se describen los principales métodos de la clase BLEService.
Figura 27: Diagrama de flujo de la clase BluetoothLeService.java
La actividad Home , es la segunda actividad después de la activad DeviceList. En Home,
se determina la cantidad de tiempo que se encenderá la biochimenea, se muestra el nivel de
combustible que determina el tiempo máximo de encendido y el nivel de carga de la batería.
69
En la figura 28 a continuación se describen los métodos y funciones más importantes que
conforman la actividad Home.
Figura 28: Diagrama de flujo de la clase Home.java
70
Siendo la actividad donde se configura el encendido de la biochimenea, la siguiente
actividad, ONCH es donde se muestra el tiempo restante para terminarse el tiempo programado
por el usuario, donde se recibe la advertencia de la vibración y alerta al usuario de esta alerta
volviendo a la actividad Home como se observa en el diagrama de flujo de la figura 29.
Figura 29: Diagrama de flujo de la clase ONCH.java.
71
En la figura 30 se observa la interfaz gráfica de la actividad DeviceList y Home, en donde
existe la opción de elegir programar el tiempo de quemado hasta que se agote el combustible o
programar un tiempo elegido por el usuario, que es menor al tiempo disponible.
Figura 30: Interfaz gráfica de las actividades Devicelist y Home
En la figura 31 se observa la interfaz gráfica para la clase ONCH, funciona de manera
similar a la actividad Home pero en vez de encender el quemador de la biochimenea, esta actividad
posee la función de actualizar el tiempo mientras está encendida la biochimenea.
Figura 31: Interfaz gráfica de la actividad ONCH
72
Luego en la figura 32 se observa lo que sucede si es desconectado el dispositivo Android
con el modulo bluetooth, el servicio BLEservice busca reconectarse al módulo tanto si ocurre en
esta actividad Home o en la actividad ONCH.
Figura 32: Evento de desconexión esporádica y conexión con el modulo bluetooth en la biochimenea
La figura 33 a continuación muestra las alertas que muestra la aplicación, tomando las dos
variables booleanas que envía el microcontrolador a la aplicación Android, a la izquierda, la
advertencia por vibración detectada y a la derecha una alerta por alta temperatura.
Figura 33: La aplicación recibe una alerta de vibración durante la combustión, o una temperatura alta antes de la
combustión
73
8.11. Visualizador LCD
Para poder visualizar los datos más importantes en los estados de funcionamiento de la
biochimenea, se desea utilizar una pantalla LCD donde se visualizarán en todo momento la lectura
de los sensores, y cuando este encendida la llama se mostrará el tiempo restante y el tiempo
trascurrido.
El visualizador empleado en este proyecto es una LCD de 16x2, en el que normalmente se
crea una interfaz de comunicación en paralelo con el microcontrolador, pero con ayuda del módulo
PCF8574, como se muestra en la figura 34 es posible convertir la comunicación en paralelo al
protocolo de comunicación I2C, disminuyendo la cantidad de cables, simplificando la
comunicación a un par de cables más la alimentación. También es de gran utilidad para no tener
conjuntos de cables voluminosos que ocupen espacio y acumulen calor.
Figura 34: Modulo que se encarga de convertir la comunicación en paralelo a una serial I2C
Por medio de la librería i2c específica para un visualizador lcd con módulo PCF8574 se
incluyen todos los métodos para manejar la pantalla como si se utilizara una comunicación en
paralelo, no hace falta configuración adicional en el programa del microcontrolador más allá de
declarar pines del microcontrolador para establecer el protocolo de comunicación i2c junto con los
sensores.
74
8.12. Impreso PCB
Cuando el circuito previamente montado en la protoboard funciona adecuadamente según los
requerimientos, entonces es momento de diseñar un circuito impreso y fabricarlo. El cual fue
diseñado como se muestra en la figura 35, en el programa de diseño PCB Wizard, las pistas se
enrutan manualmente y los componentes que no se encuentren en las librerías deben ser agregados
manualmente
Figura 35: Diseño del circuito impreso (PCB)
8.13. Autonomia
Al determinar la autonomía de la biochimenea se tuvo en cuenta el ahorro de energía en
cada estado de funcionamiento del sistema, identificando en que estados es útil usar los sensores,
en el primer estado solo se necesitan que estén activados el modulo bluetooth y el
microcontrolador, luego cuando el sistema está conectado a un dispositivo Android o cuando el
oprime el pulsador para pasar de estado manualmente, se necesitan los sensores y mostrar su
lectura en el visualizador LCD. Luego en el tercer estado se usan bomba de combustible y el
generador de alto voltaje.
En la tabla 6 y 7 se muestra el consumo eléctrico de cada componente eléctrico según la
hoja de datos de cada componente en mA por cada batería
75
Batería 1:
1er-2do Estado 3er Estado
Microcontrolador 6uA 16mA
Modulo HM-10(conectado)
16mA 16mA
Acelerómetro ADXL345
140uA 140uA
LCD (LED encendido) 4mA
S. Distancia VL6180x 5ma 5mA
MAX31855 900uA 900uA
Bomba de combustible
104mA
Total 22.7mA 146mA Tabla 6: Consumo eléctrico de cada componente electrónico en cada estado de funcionamiento
Batería 2:
3er estado
Generador de alto
voltaje
2000mA(6s)
Ventilador 80mA Tabla 7: Consume eléctrico de los componentes que consumen energía de la batería secundaria
La batería tiene una capacidad de 3.4Ah, es decir que puede mantener una corriente
máxima de 5amperes por una hora antes de que se descargue por completo, eso quiere decir que,
si se enciende el quemador por una hora, se habrán consumido 146mAH de los 3400mAH de la
batería. Entonces en la ecuación (1) se puede determinar:
3400𝑚𝐴𝐻146𝑚𝐴𝐻⁄ = 23.28𝐻𝑜𝑟𝑎𝑠 (1)
Cantidad suficiente para recargar el combustible un total cuatro veces, siendo que cada
recarga de combustible consta de un galón, que es la capacidad máxima del tanque de combustible.
2500𝑚𝐴𝐻
80𝑚𝐴𝐻= 31.25𝐻𝑜𝑟𝑎𝑠 (2)
Considerando que el generador de alto voltaje consume una corriente muy alta, pero en
intervalos de tiempo muy pequeños, no se incluye dentro de los cálculos por ser un promedio de
consumo bajo, pero si el cálculo de consumo del ventilador en la ecuación (2) para la duración de
la batería secundaria, que es mayor que la batería secundaria.
8.14. Diseño del prototipo Encapsulado
El diseño del prototipo encapsulado en acero inoxidable, incluye tanque de combustible de
reserva y quemador de combustible en un solo conjunto cerrado. Este diseño se obtiene luego de
concluir el diseño electrónico con todos los componentes soldados sobre el circuito impreso. De
76
allí se obtienen las dimensione tanto de este como de los demás componentes que no están unidos
físicamente sobre la placa de circuitos, como el sensor de ultrasonido, el generador de alto voltaje,
el visualizador LCD y la bomba de combustible, así como pulsadores y puerto de carga de la
batería
En las figuras se muestra el diseño de la estructura en acero inoxidable parte por parte,
importadas del programa de diseño Autodesk Inventor 2020.
Figura 36: Diseño y dimensiones de la estructura principal de la biochimenea
Figura 37: Tapa superior donde se ubican los botones, LCD y la entrada para recargar el tanque de combustible
77
Figura 38: Canal donde ocurre la combustión del etanol
Figura 39: Tapa de orificios por donde saldrá la llama proveniente de la combustión que ocurre en la canal inferior
78
Figura 40: Tapa del tanque de combustible donde se ubica el sensor de distancia
Figura 41: Tanque de combustible donde se ubica la bomba de combustible y el flotador
80
8.15. Flotador
El sensor de nivel VL6180x como sus especificaciones indican puede detectar líquidos, sin
embargo, aunque el etanol es líquido, este sensor no es capaz de detectarlo, debido a que la
densidad del etanol es más baja que por ejemplo los líquidos a base de agua, lo que da a lugar que
la tensión superficial del etanol sea muy baja y el fotón emitido por el emisor del sensor no
devuelve un eco sobre la superficie del líquido como si lo haría cualquier superficie solida o
incluso el agua que posee una mayor densidad que el etanol. (Kane & Sternheim, 2016)
Por lo que se requiere diseñar un flotador solido con un compartimiento en su interior de
aire sellado, que pueda ser detectado por el sensor de nivel y así tener una referencia del nivel de
combustible que resta en el tanque.
El flotador debe tener una forma cubica de manera que su cara superior tenga el área
suficiente como para ser detectado por el sensor de distancia, que, de acuerdo al funcionamiento
del sensor, el haz de fotones solo necesitaría un área de unos pocos centímetros cúbicos para
reflejarse en la superficie y ser sensado en el módulo.
La mejor forma de fabricar un flotador a medida de un material específico, es diseñar un
modelo 3D en un programa de diseño CAD e imprimirlo por medio de una impresora 3D.
Se debe considerar la densidad del material en el que será impreso, junto con la densidad
del aire, que en combinación se logra tener una densidad total menor que la del etanol y de esa
manera es posible que el flotador permanezca suspendido en la superficie del combustible.
En la tabla 8 se muestran los datos de masa, densidad y volumen de los materiales del
flotador que el fabricante uso para diseñar y fabricar el flotador en impresión 3D, datos que fueron
obtenidos del programa de diseño 3D Autodesk Inventor de acuerdo a las dimensiones del flotador
Densidad(Kg/m3) Masa(Kg) Volumen(mm3)
Plastico PET 1270 0.005 3829
Aire 1.22 0.000004209 3450
Etanol 789
Flotador 687.49 Tabla 8: Datos físicos de los materiales que componen el flotador
En las ecuaciones (1) y (2) se muestra el cálculo para encontrar la densidad del flotador
𝐷𝑒𝑛𝑠𝑖𝑑𝑎𝑑 𝑓𝑙𝑜𝑡𝑎𝑑𝑜𝑟 =𝑀𝑎𝑠𝑎 𝑃𝑙𝑎𝑠𝑡𝑖𝑐𝑜 + 𝑀𝑎𝑠𝑎 𝐴𝑖𝑟𝑒
𝑉𝑜𝑙𝑢𝑚𝑒𝑛 𝑃𝑙𝑎𝑠𝑡𝑖𝑐𝑜 + 𝑉𝑜𝑙𝑢𝑚𝑒𝑛 𝐴𝑖𝑟𝑒 (1)
𝐷𝑒𝑛𝑠𝑖𝑑𝑎𝑑 𝐹𝑙𝑜𝑡𝑎𝑑𝑜𝑟 =0.005 + 0.000004209
3829109⁄ + 3450
109⁄= 687.49
𝑘𝑔𝑚3⁄ (2)
81
En la figura 44 se muestra el flotador terminado, con dimensiones 35mm X 30mm X 7mm
Figura 44: Flotador terminado en base a los cálculos realizados
Se comprueba que el valor de densidad del flotador es menor que la densidad del etanol, lo
que resulta en que este objeto se mantenga suspendido en la superficie del líquido y pueda ser
sensado por el sensor de distancia, y de una muestra del nivel de combustible restante en el tanque
de combustible.
82
9. ANALISIS DE RESULTADOS
Con ayuda del programa Android Studio y los mensajes de depuración del logcat mientras
el dispositivo Android está ejecutando la aplicación, es posible ver como se está comportando el
programa tanto del microcontrolador como el del aplicativo Android y su comunicación entre
ambos dispositivos. En las figuras a continuación se muestran estos mensajes y luego se describe
brevemente como están interactuando ambos dispositivos.
Figura 45: Log de mensajes de la aplicación Android en el escaneo de dispositivos bluetooth
En la figura 45 se muestran los mensajes Log, en el primer recuadro, la aplicación es
iniciada y comienza el escaneo de dispositivos bluetooth, luego en el segundo recuadro la
aplicación reconoce el dispositivo Android e inicia la interfaz gráfica, y por último en el tercer
recuadro, el escaneo de dispositivos bluetooth se detiene después de cinco segundos escaneando.
83
Figura 46: Log de mensajes de la aplicación Android cuando se conecta a un dispositivo bluetooth
En el primer recuadro de la figura 46 se muestra lo que sucede cuando es seleccionado un
dispositivo bluetooth de la lista de dispositivos bluetooth cercanos, se obtiene la dirección MAC
del dispositivo bluetooth y se conecta a este por medio del servicio que BluetoothLeService,
cuando la conexión es establecida, se cierra la actividad DeviceList y se visualiza la ventana Home.
En el segundo recuadro, la aplicación envía el mensaje “\wtiempo?” por medio de la conexión
bluetooth, que sirve para consultar al microcontrolador por medio del puerto serial si la
biochimenea se encuentra en estado de consumo de combustible, como no lo está, entonces el
microcontrolador no envía ningún dato, solamente envía un streaming de datos, referentes a la
carga de la batería, nivel de combustible, y las banderas que indican si existe una vibración o un
exceso de temperatura.
84
Figura 47: Log de mensajes cuando se programa un tiempo específico y es enviado al microcontrolador
Cuando se configura el tiempo que se quemará el combustible, en la actividad Home, se
podrá avanzar a la actividad ONCH por medio del botón “Encender”, cuando es presionado el
botón, se toma el tiempo del widget de contador de tiempo, se calcula el tiempo en segundos y se
envía ese dato por medio de la conexión bluetooth al microcontrolador como se muestra en la
figura 47, donde justo antes fue enviado el comando “\wencenderch” para indicarle al
microcontrolador que encienda la biochimenea. En la misma figura, se observa el visualizador
LCD con el tiempo restante “R=”, transcurrido “T=”, el porcentaje de combustible y la carga de
las baterías “B1” y “2”.
85
Figura 48: Log de mensajes cuando termina el tiempo programado
Si el tiempo de encendido de la biochimenea termina, el microcontrolador envía el mensaje
“Over~” por medio de la conexión bluetooth a la aplicación, que significa que el tiempo
previamente programado termino y ahora la aplicación retrocederá a la activada Home como se
muestra en la figura 48.
(a)
(b)
Figura 49 (a):Log de mensajes en el evento de desconexión esporádica y posterior reconexión.(b)Mensaje emergente
mientras la aplicación se conecta nuevamente
En el primer recuadro de la la figura 49 se muestra lo que ocurre si la conexión bluetooth
se pierde entre el dispositivo Android y el modulo bluetooth, la aplicación entra en un modo de
86
espera como el que se muestra en la figura hasta que se restablezca la conexión. Y en el segundo
recuadro de la figura, se muestran los mensajes de conexión una vez la aplicación encontró el
dispositivo con el que había perdido la conexión.
Figura 50: Log de mensajes cuando se actualiza el tiempo en la actividad ONCH
Cuando la biochimenea está encendida y quemando combustible y se desea aumentar el
tiempo programado sobre el tiempo previamente establecido en la actividad ONCH, esta envía el
comando “\Txxxx” por medio de la conexión bluetooth al microcontrolador, siendo “x” el tiempo
de quemado establecido por el usuario en la aplicación como se muestra en la figura 50, donde el
tiempo es enviado en segundos.
Figura 51: Log de mensajes cuando el usuario desea apagar la combustión de la llama por medio de actividad
ONCH
En el caso de que el usuario desee apagar la biochimenea por medio del botón “Apagar
chimenea”, la aplicación enviara el comando “\wapagarch” por medio del enlace bluetooth al
microcontrolador, así este cerrará el suministro de combustible al quemador y la aplicación volverá
a la actividad Home como lo muestra el log de la figura 51.
87
Figura 52: Log de mensajes cuando se programa un tiempo de combustión para consumir todo el combustible
disponible
Si el usuario desea que se todo el combustible del tanque de combustible sea consumido
en su totalidad, es posible hacerlo seleccionando la opción ”Tiempo Libre” tanto en la actividad
Home como en ONCH, así la aplicación realiza el cálculo del tiempo restante de combustible en
base al nivel de combustible restante. Como se muestra en el log de la figura 52, se envía el
comando “\wencenderch” y adicionalmente el comando “\t16920” que es el tiempo en segundos
máximo que puede durar la biochimenea encendida.
Figura 53: Log de mensajes cuando la biochimenea recibe una vibración y es enviada una alerta a la aplicación
Si la estructura de la biochimenea recibe un movimiento lateral como un golpe o una
vibración, el acelerómetro detecta este movimiento, el microcontrolador la identifica como una
vibración y coloca en alto la variable booleana y se envía en el streaming de datos a la aplicación
como se observa en la figura 53, la biochimenea se apaga inmediatamente mientras que la
aplicación vuelve a la actividad home como se observa en la figura 54, donde a la derecha se
muestra un mensaje del evento que ha ocurrido en la biochimenea y a la izquierda se observa lo
que muestra el visualizador LCD al apagarse la biochimenea por una vibración.
88
Figura 54: Mensaje de alerta tanto en el visualizador como en la aplicación Android cuando la aplicación recibe una
alerta de vibración
Figura 55: Log de mensajes donde la aplicación consulta al microcontrolador si la biochimenea está quemando
combustible.
Si la biochimenea se encuentra en funcionamiento, consumiendo combustible y se desea
establecer una conexión, la aplicación se conecta normalmente por medio de la actividad
Devicelist, cuando se conecta, envía el comando “\wtiempo?” hacia el microcontrolador como se
89
observa en la figura 55, que identifica este mensaje y devuelve el mensaje “Txxxxx~” siendo
“xxxxx” el tiempo restante de combustión, la aplicación recibe este mensaje y pasa directamente
a la actividad ONCH donde se mostrara el mismo tiempo restante de quemado que se muestra en
el visualizador LCD.
Figura 56: Log de mensajes cuando el microcontrolador envía una alerta de temperatura alta y la aplicación la
muestra con un mensaje e impide la ignición del combustible.
Si la temperatura de la biochimenea sobrepasa los 50°c antes de volver a ser encendida o
recargada, el microcontrolador pondrá en alto la variable booleana que indica esta alerta, y que se
encuentra en el streaming de datos como se observa la figura 56, la aplicación recibe la alerta,
muestra un mensaje de alerta que impide encender la biochimenea, y al mismo tiempo en el
visualizador.
90
9.1. Costos de producción y desarrollo
Los costos de cada elemento que hacen parte del circuito electrónico, así como el costo de
la estructura en acero inoxidable, el desarrollo de la Aplicación Android y del programa del
microcontrolador aparecen en la tabla 9.
Componentes Costo($COP) Desarrollo Costo($COP)
Microcontrolador PIC 20.000 Aplicación
Android y
Programa PIC
(10 meses)
15.000.000
Sensor de distancia 36.000 Estructura Acero
Inox.
700.000
Módulo termocupla 70.000
Acelerómetro 15.000
Visualizador LCD 15.000
Modulo Bluetooth 20.000
Bomba combustible 40.000
Transformador Flyback 5.000
Transistores y Mosfet 18.000
Ventilador 80cm 10.000
Conversores DC-DC 15.000
Baterias de litio 100.000
Condensadores y Resistencias 5.000
Otros componentes electronicos 10.000
Placa PCB 15.000
Funda cables, manguera 25.000
Flotador 3D 35.000
Mano de obra, soldadura y
ensamble
50.000
Total componentes 504.000 Total 16.204.000
Tabla 9: Detalle de los costos de producción y desarrollo.
El costo de producción de todo el sistema incluye el desarrollo del software, aunque para
una producción en serie el costo es diferente, solo se tienen en cuenta el costo de los componentes
y de la estructura en acero inoxidable, el software o el programa, es replicable y se le considera un
costo diferente para una producción en serie que no se ha estudiado.
91
10. Conclusiones
Se cumplen los objetivos del proyecto, comunicando una aplicación Android con el
microcontrolador por medio de la comunicación UART, a través de una conexión
bluetooth, no solo comandos que se pueden interpretar como ordenes, sino cifras enteras
para indicar tiempos específicos, en ambos sentidos de la comunicación.
Con la ayuda de los sensores de aceleración y de temperatura se logra tener un sistema
seguro y confiable para el usuario, respetando los umbrales seguros a los que se debe
conservar el combustible en el interior de la biochimenea y en el área de combustión.
El proyecto desarrollado es un proyecto de IOT (Internet of Things), por lo que su nivel de
aplicación es bastante amplio, esta solución a este problema puede ser útil para resolver
problemas similares que requieran un control a distancia.
Conociendo la tecnología bluetooth de cuarta generación y la forma de ser implementada
en una aplicación Android es posible implementar las mismas funcionalidades al momento
de desarrollar una aplicación Apple, gracias a que comparten compatibilidades.
Las amplias capacidades del microcontrolador elegido para este proyecto, permiten la
posibilidad de implementar más funcionalidades como por ejemplo un control a distancia
infrarrojo, un visualizador LCD más amplio o un control a distancia por medio de una red
LAN, etc.
Debido al relativo bajo costo de los componentes electrónicos utilizados en este proyecto
es posible pasar del desarrollo del prototipo realizado en este proyecto a una producción
en serie, aunque no se ha realizado un estudio de mercado, existe una ventaja al ser el
primer y único fabricante a nivel nacional de biochimeneas que implemente esta
innovación tecnológica.
92
11. ALCANCES Y LIMITACIONES
11.1. Alcances
Con ayuda de este proyecto se puede actualizar tecnológicamente la operación del usuario
con la biochimenea, obteniendo un crecimiento en el mercado nacional de las biochimeneas.
Que sea posible lograr una implementación a bajo coste, en lo posible con la obtención de
recursos de proveedores nacionales, para que sea rentable económicamente y atraiga al
consumidor.
Siendo este un proyecto muy versátil de cara a largo plazo, se puede lograr una
actualización de sus componentes tanto de hardware como de software para, la optimización de
los recursos y la innovación tecnológica.
La oportunidad de poder implementar el sistema para que pueda ser controlado y
monitorizado por medio de una aplicación IOS, además de la aplicación Android
Académicamente e investigativa, se puede llevar a cabo una implementación como
solución a diferentes problemas, que requiera la operación y monitorización remota por medio de
una comunicación directa, visualizado por una aplicación Android.
11.2. Limitaciones
La posible entrada de competidores extranjeros que ya implementen un sistema
automatizado de biochimeneas y ponga en riesgo la competencia de los fabricantes nacionales, y
como consecuencia de este proyecto. Además de una posible innovación tecnológica de los
competidores nacionales.
93
12. REFERENCIAS
[1] Mantilla Nova, m. (2012). manual de operacion. [ebook] Bogota: Diego Fernando
Mantilla Nova, pp.2,5,7. Disponible en: http://www.chimeneasclimalive.com/
[2]D. Mantilla Nova, "Chimeneas en Bogotá Climalive - Chimeneas de Bioetanol en
Bogotá", Chimeneasclimalive.com, 2018. [Online]. Disponible en:
http://www.chimeneasclimalive.com/.
[3]"Chimeneas Bioetanol - Página Oficial - Chimeneas de
Colombia", Chimeneasdecolombia.com, 2018. [Online]. Disponible en :
http://www.chimeneasdecolombia.com/es/chimeneas/bioetanol.
[4]"ABHSscience - Combustion of Ethanol", Abhsscience.wikispaces.com, 2018. [Online
Disponible en: https://abhsscience.wikispaces.com/Combustion+of+Ethanol.
[5]"Combustión gas natural | Industria | Metrogas", Metrogas.cl, 2018. [Online].
Disponible en: http://www.metrogas.cl/industria/asesoria_tecnica_1.
[6]"El mal uso del aire acondicionado puede ser perjudicial para la salud", Telam.com.ar,
2018. [Online]. Disponible en: http://www.telam.com.ar/notas/201502/94348-el-mal-uso-del-
aire-acondicionado-puede-ser-perjudicial-para-la-salud.php.
[7]Catalogo CLIMALIVE, 1st ed. Bogota: Diego Mantilla, 2018, p. 2.
[8]"Ventajas y Desventajas de las Chimeneas Bioetanol - ElBlogVerde.com",
ElBlogVerde.com, 2018. [Online]. Disponible en: https://elblogverde.com/chimeneas-bioetanol/.
[9]"1. ¿Qué es un microcontrolador? | Sherlin.xBot.es", Sherlin.xbot.es, 2018. [Online].
Disponible en: http://sherlin.xbot.es/microcontroladores/introduccion-a-los-
microcontroladores/que-es-un-microcontrolador.
[10]M. Erik Angeles Segundo, "Aplicación para telefonía móvil Android -
Monografias.com", Monografias.com, 2018. [Online]. Disponible en:
http://www.monografias.com/trabajos-pdf5/aplicacion-android/aplicacion-android.shtml.
[11]M. arocha, "Tecnología Inalámbrica Bluetooth - Monografias.com",
Monografias.com, 2018. [Online]. Disponible en:
http://www.monografias.com/trabajos12/tecninal/tecninal.shtml.
[12]J. Macias, "Bluetooth BLE: el conocido desconocido", Solidgear, 2018. [Online].
Disponible en: https://solidgeargroup.com/bluetooth-ble-el-conocido-desconocido?lang=es.
[13]"Ethanol Fireplace by Planika. 🔥 Automatic & Ventless 🔥", Planika, 2018. [Online].
Disponible en: https://www.planikafires.com/.
[14]"Chimeneas Inteligentes AFIRE: ¡Porque Su Chimenea Es Unica!", AFire, 2018.
[Online]. Disponible en: https://www.a-fireplace.com/es/.
94
[15] ATMEL 8-BIT MICROCONTROLLER DATASHEET. (2019). Disponible en
https://www.hobbytronics.co.za/Content/external/156/Atmel-8271-8-bit-AVR-Microcontroller-
ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf
[16] UART Protocol. (2019). Disponible en https://roverrobotics.com/blogs/news/uart-
protocol
[17] Valdes Perez, F., & Pallas Areny, R. (2007). Microcontroladores (pp. 258-261,303-
305,265-266,224,180-182). Mexico: Alfaomega Grupo Editor.
[18] Microchip. (2017). Datasheet PIC18F47J13 FAMILY [Ebook] (3rd ed., p. 363,287).
Disponible en http://ww1.microchip.com
[19] C, S. (2019). ▷ Comunicación I2C PIC Explicación Fácil - [julio, 2019 ]. Disponible
en https://controlautomaticoeducacion.com/microcontroladores-pic/comunicacion-i2c/
[20] Verle, M. (2017). Modulos-ccp - MikroElektronika. Disponible en
https://www.mikroe.com/ebooks/microcontroladores-pic-programacion-en-c-con-
ejemplos/modulos-ccp
[21] Verle, M. (2017). Lenguajes-de-programacion - MikroElektronika. (2017).
Disponible en https://www.mikroe.com/ebooks/microcontroladores-pic-programacion-en-c-con-
ejemplos/lenguajes-de-programacion
[22] ¿Cómo programar un microcontrolador con PIC C? - INCOELECTRONICA.
Disponible en https://sites.google.com/site/incoelectronicasas/mini-tutos/-como-programar-un-
microcontrolador-con-pic-c
[23] STMicroelectronics. (2016). VL6180X [Ebook] (7th ed.). Disponible en
https://www.st.com/resource/en/datasheet/vl6180x.pdf
[24] STMicroelectronics. (2019). VL53L0X [Ebook] (2nd ed.). Disponible en
https://www.st.com/resource/en/datasheet/vl53l0x.pdf
[25] Analog Devices. (2015). ADXL345 [Ebook] (1st ed.). Disponible en
https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf
[26] Maxim Integrated. (2015). MAX31855 [Ebook] (5th ed., p. 8). Disponible en
https://datasheets.maximintegrated.com/en/ds/MAX31855.pdf
[27] Goldwasser, S. (2001). El Flyback - Principios, funcionamiento, comprobaci�n.
Disponible en https://www.comunidadelectronicos.com/articulos/flyback.htm
[28] AndroidDev. (2018). Actividades | Android Developers. Disponible en
https://developer.android.com/guide/components/activities.html?hl=ES
[29] AndroidDev. (2018). Conoce Android Studio | Android Developers. Disponible en
https://developer.android.com/studio/intro?hl=es-419
95
[30] Microchip. (2003). PIC16F877A [Ebook] (p. 71). Microchip. Disponible en
http://ww1.microchip.com/downloads/en/devicedoc/39582b.pdf
[31] RSC Power Technology. (2003). CP1250 [Ebook] (9th ed.). vision-batt. Disponible
en https://www.vision-batt.eu/sites/default/files/public/docs/products/manuals/CP1250.pdf
[32] Sanyo energy. (2012). NCR18650b [Ebook] (13th ed.). Sanyo energy. Disponible en
https://www.batteryspace.com/prod-specs/NCR18650B.pdf
[33]SensMaster profile rev 028. (2014). Disponible en
https://www.slideshare.net/martinharnevie/sensmaster-profile-rev-028
[34] Currey, M. (2017). HM-10 Bluetooth 4 BLE Modules | Martyn Currey. Disponible en
http://www.martyncurrey.com/hm-10-bluetooth-4ble-modules/
[35] Microchip. (2009). PIC18F2455/2550/4455/4550 Datasheet [Ebook] (5th ed., p. 197).
Disponible en https://ww1.microchip.com/downloads/en/devicedoc/39632e.pdf+
[36] Leibson, S. (2018). Principios básicos sobre la medición a distancia y el
reconocimiento de gestos al usar los sensores ToF| DigiKey. Disponible en
https://www.digikey.com.mx/es/articles/techzone/2018/nov/fundamentals-distance-
measurement-gesture-recognition-tof-sensors
[37] Kane, J., & Sternheim, M. (2016). Física (2a. ed.) (2nd ed., pp. 332,333). Barcelona:
Editorial Reverte.
[38] C�mo programar un PIC 12Fxxx/16Fxxx con ICSP. (2019). Disponible en
http://webs.uolsinectis.com.ar/nancy/pic/icsp_es.html
97
13.2. Aplicacion Android
13.2.1. DeviceList.java
package com.led.ControlR;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.TextView;
import android.content.Intent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.led.led.R;
public class DeviceList extends ListActivity {
private LeDeviceListAdapter mLeDeviceListAdapter;
private boolean mScanning;
private Handler mHandler;
String sen2t="0";
private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 5 seconds.
private static final long SCAN_PERIOD = 5000;
Button btnPaired, exit;
ListView devicelist;
private BluetoothAdapter myBluetooth = null;
boolean isBtConnected;
98
private static final String TAG = "BroadcastTest";
private Intent intent;
final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS=124;
@SuppressLint("ResourceType")
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setTitle(R.string.title_devices);
mHandler = new Handler();
if (Build.VERSION.SDK_INT >= 23) {
// Marshmallow+ Permission APIs
MarshMallow();
}
setContentView(R.layout.activity_device_list);
btnPaired = (Button) findViewById(R.id.button2);
exit = (Button) findViewById(R.id.button9);
devicelist = (ListView) findViewById(R.id.listView);
// Use this check to determine whether BLE is supported on the
device. Then you can
// selectively disable BLE-related features.
if
(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE))
{
Toast.makeText(this, R.string.ble_not_supported,
Toast.LENGTH_SHORT).show();
finish();
}
final BluetoothManager bluetoothManager = (BluetoothManager)
getSystemService(Context.BLUETOOTH_SERVICE);
myBluetooth = bluetoothManager.getAdapter();
if (myBluetooth == null) { //Condicion
para habilitar dispositivo BT
//Show a mensag. that the device has no bluetooth adapter
Toast.makeText(getApplicationContext(), "Bluetooth Device Not
Available", Toast.LENGTH_LONG).show();
//finish apk
finish();
} else if (!myBluetooth.isEnabled()) { //Ask to the user turn the
bluetooth on
Intent turnBTon = new
Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnBTon, 1);
}
// Initializes list view adapter.
mLeDeviceListAdapter = new LeDeviceListAdapter();
setListAdapter(mLeDeviceListAdapter);
scanLeDevice(true);
btnPaired.setOnClickListener(new View.OnClickListener() { //Metodo
para boton escanear
@Override
public void onClick(View v) {
scanLeDevice(true);
//method that will be called
}
});
99
exit.setOnClickListener(new View.OnClickListener() { //Metodo
para boton de salir de la aplicacion
@Override
public void onClick(View view) {
finish();
System.exit(0);
}
});
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
private void updateUI(Intent intent) {
isBtConnected = intent.getBooleanExtra("status", false);
Log.d("BT1", String.valueOf(isBtConnected));
if (isBtConnected) {
unregisterReceiver(broadcastReceiver);
} else {
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
protected void onListItemClick(ListView l, View v, int position, long id)
{//Metodo para cuando se da click a un elemento de la lista
final BluetoothDevice device =
mLeDeviceListAdapter.getDevice(position);
if (device == null) return;
final Intent intent = new Intent(this, Home.class);
intent.putExtra(Home.EXTRAS_DEVICE_NAME, device.getName());
intent.putExtra(Home.EXTRAS_DEVICE_ADDRESS, device.getAddress());
intent.putExtra(Home.EXTRAS_ACELEROMETRO,String.valueOf(sen2t) );
if (mScanning) {
myBluetooth.stopLeScan(mLeScanCallback);
mScanning = false;
}
startActivity(intent);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
// User chose not to enable Bluetooth.
if (requestCode == REQUEST_ENABLE_BT && resultCode ==
Activity.RESULT_CANCELED) {
finish();
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
if(keyCode == KeyEvent.KEYCODE_BACK)
{
100
finish();
System.exit(0);
}
return false;
}
// Adapter for holding devices found through scanning.
private class LeDeviceListAdapter extends BaseAdapter {
private ArrayList<BluetoothDevice> mLeDevices;
private LayoutInflater mInflator;
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList<BluetoothDevice>();
mInflator = DeviceList.this.getLayoutInflater();
}
public void addDevice(BluetoothDevice device) {
if(!mLeDevices.contains(device)) {
mLeDevices.add(device);
}
}
public BluetoothDevice getDevice(int position) {
return mLeDevices.get(position);
}
public void clear() {
mLeDevices.clear();
}
//@Override
public int getCount() {
return mLeDevices.size();
}
// @Override
public Object getItem(int i) {
return mLeDevices.get(i);
}
//@Override
public long getItemId(int i) {
return i;
}
//@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
// General ListView optimization code.
if (view == null) {
view = mInflator.inflate(R.layout.list, null);
viewHolder = new ViewHolder();
viewHolder.deviceAddress = (TextView)
view.findViewById(R.id.device_address);
viewHolder.deviceName = (TextView)
view.findViewById(R.id.device_name);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
BluetoothDevice device = mLeDevices.get(i);
final String deviceName = device.getName();
if (deviceName != null && deviceName.length() > 0)
viewHolder.deviceName.setText(deviceName);
101
else
viewHolder.deviceName.setText(R.string.unknown_device);
viewHolder.deviceAddress.setText(device.getAddress());
return view;
}
}
static class ViewHolder {
TextView deviceName;
TextView deviceAddress;
}
@SuppressLint("RestrictedApi")
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@SuppressLint("RestrictedApi")
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void run() {
mScanning = false;
myBluetooth.stopLeScan(mLeScanCallback);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
myBluetooth.startLeScan(mLeScanCallback);
} else {
mScanning = false;
myBluetooth.stopLeScan(mLeScanCallback);
}
invalidateOptionsMenu();
}
public BluetoothAdapter.LeScanCallback mLeScanCallback = new
BluetoothAdapter.LeScanCallback() { //
@Override
public void onLeScan(final BluetoothDevice device, final int rssi,
byte[] scanRecord) {
runOnUiThread(new Runnable() {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
@Override
public void onRequestPermissionsResult(int requestCode, String[]
permissions, int[] grantResults) {
102
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<String, Integer>();
// Initial
perms.put(Manifest.permission.ACCESS_FINE_LOCATION,
PackageManager.PERMISSION_GRANTED);
// Fill with results
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for ACCESS_FINE_LOCATION
if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED
) {
// All Permissions Granted
// Permission Denied
Toast.makeText(DeviceList.this, "All Permission GRANTED
!! Thank You :)", Toast.LENGTH_SHORT)
.show();
} else {
// Permission Denied
Toast.makeText(DeviceList.this, "One or More Permissions
are DENIED Exiting App :(", Toast.LENGTH_SHORT)
.show();
finish();
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
@TargetApi(Build.VERSION_CODES.M)
private void MarshMallow() { //Permisos de localisacion,
si es SO Marshmallow
List<String> permissionsNeeded = new ArrayList<String>();
final List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList,
Manifest.permission.ACCESS_FINE_LOCATION))
permissionsNeeded.add("Show Location");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
// Need Rationale
String message = "App need access to " +
permissionsNeeded.get(0);
for (int i = 1; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
showMessageOKCancel(message,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int
which) {
requestPermissions(permissionsList.toArray(new
String[permissionsList.size()]),
103
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
});
return;
}
requestPermissions(permissionsList.toArray(new
String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
return;
}
Toast.makeText(DeviceList.this, "No new Permission Required-
Launching App .You are Awesome!!", Toast.LENGTH_SHORT)
.show();
}
private void showMessageOKCancel(String message,
DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(DeviceList.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
@TargetApi(Build.VERSION_CODES.M)
private boolean addPermission(List<String> permissionsList, String
permission) {
if (checkSelfPermission(permission) !=
PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
// Check for Rationale Option
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
return true;
}
}
13.2.2. BluetoothLeService.java
package com.led.ControlR;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
104
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.RequiresApi;
import android.util.Log;
import java.util.UUID;
public class BluetoothLeService extends Service {
private final static String TAG =
BluetoothLeService.class.getSimpleName();
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
private BluetoothGatt mBluetoothGatt;
private int mConnectionState = STATE_DISCONNECTED;
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
public final static String ACTION_GATT_CONNECTED =
"com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED =
"com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED =
"com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE =
"com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA =
"com.example.bluetooth.le.EXTRA_DATA";
//public final static UUID UUID_HEART_RATE_MEASUREMENT =
UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);
// Implements callback methods for GATT events that the app cares about.
For example,
// connection change and services discovered.
private final BluetoothGattCallback mGattCallback = new
BluetoothGattCallback() {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int
status,
int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful
connection.
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
105
} else if (newState ==
BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
@Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int
status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
} else {
Log.w(TAG, "onServicesDiscovered received: " +
status);
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
// Result of a characteristic read operation
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE,
characteristic);
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
};
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic
characteristic) {
final Intent intent = new Intent(action);
final byte[] data = characteristic.getValue();
106
//Log.d("data", Arrays.toString(data));
intent.putExtra(EXTRA_DATA, new String(data));
sendBroadcast(intent);
}
public class LocalBinder extends Binder {
BluetoothLeService getService() {
return BluetoothLeService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public boolean onUnbind(Intent intent) {
// After using a given device, you should make sure that
BluetoothGatt.close() is called
// such that resources are cleaned up properly. In this particular
example, close() is
// invoked when the UI is disconnected from the Service.
close();
return super.onUnbind(intent);
}
private final IBinder mBinder = new LocalBinder();
/**
* Initializes a reference to the local Bluetooth adapter.
*
* @return Return true if the initialization is successful.
*/
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public boolean initialize() {
// For API level 18 and above, get a reference to BluetoothAdapter
through
// BluetoothManager.
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager)
getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
Log.e(TAG, "Unable to initialize BluetoothManager.");
return false;
}
}
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
return false;
}
return true;
}
/**
* Connects to the GATT server hosted on the Bluetooth LE device.
*
* @param address The device address of the destination device.
107
*
* @return Return true if the connection is initiated successfully. The
connection result
* is reported asynchronously through the
* {@code
BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt
, int, int)}
* callback.
*/
//@TargetApi(Build.VERSION_CODES.M)
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified
address.");
return false;
}
// Previously connected device. Try to reconnect.
if (mBluetoothDeviceAddress != null &&
address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
Log.d(TAG, "Trying to use an existing mBluetoothGatt for
connection.");
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device =
mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w(TAG, "Device not found. Unable to connect.");
return false;
}
// We want to directly connect to the device, so we are setting the
autoConnect
// parameter to false.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mBluetoothGatt = device.connectGatt(this, false,
mGattCallback,2);
}else{
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
}
Log.d(TAG, "Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
108
return;
}
mBluetoothGatt.disconnect();
}
/**
* After using a given BLE device, the app must call this method to
ensure resources are
* released properly.
*/
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void readCustomCharacteristic() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
/*check if the service is available on the device*/
BluetoothGattService mCustomService =
mBluetoothGatt.getService(UUID.fromString("0000FFE0-0000-1000-8000-
00805f9b34fb"));
if(mCustomService == null){
Log.w(TAG, "Custom BLE Service not found1");
return;
}
/*get the read characteristic from the service*/
BluetoothGattCharacteristic mReadCharacteristic =
mCustomService.getCharacteristic(UUID.fromString("0000FFE1-0000-1000-8000-
00805f9b34fb"));
UUID uuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
BluetoothGattDescriptor descriptor =
mReadCharacteristic.getDescriptor(uuid);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
mBluetoothGatt.setCharacteristicNotification(mReadCharacteristic,
true);
Log.d("Notification","true");
//mReadCharacteristic =
mCustomService.getCharacteristic(UUID.fromString("0000FFE1-0000-1000-8000-
00805f9b34fb"));
if(mBluetoothGatt.readCharacteristic(mReadCharacteristic) == false){
Log.w(TAG, "Failed to read characteristic");
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void writeCustomCharacteristic(byte[] value) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
109
}
/*check if the service is available on the device*/
BluetoothGattService mCustomService =
mBluetoothGatt.getService(UUID.fromString("0000FFE0-0000-1000-8000-
00805f9b34fb"));
if(mCustomService == null){
Log.w(TAG, "Custom BLE Service not found2");
return;
}
/*get the read characteristic from the service*/
BluetoothGattCharacteristic mWriteCharacteristic =
mCustomService.getCharacteristic(UUID.fromString("0000FFE1-0000-1000-8000-
00805f9b34fb"));
mWriteCharacteristic.setValue(value);
if(mBluetoothGatt.writeCharacteristic(mWriteCharacteristic) ==
false){
Log.w(TAG, "Failed to write characteristic");
}
}
}
13.2.3. Home.java
package com.led.ControlR;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import java.io.UnsupportedEncodingException;
import java.util.Objects;
import android.os.Handler;
import com.akexorcist.roundcornerprogressbar.IconRoundCornerProgressBar;
110
import com.led.led.R;
import cn.iwgang.countdownview.CountdownView;
import me.itangqi.waveloadingview.WaveLoadingView;
public class Home extends AppCompatActivity implements View.OnClickListener {
Button btnOn, btnDis;
TextView lumn ;
String
sensor0,sensor1,sensor2,sensor3,txttiempoch,datafield,sensorView0,sensorView1
,sensorView2,txtStringLength,txtString;
long time,tfree,time2;
int sen0;
int sen1;
int sen3,sen2ti=0;
String sen2t;
boolean conectado=true;
//
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
public static final String EXTRAS_ACELEROMETRO = "ACELEROMETRO";
private final static String TAG = Home.class.getSimpleName();
private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
private String mDeviceName;
private String mDeviceAddress;
private BluetoothLeService mBluetoothLeService;
private boolean mConnected = false;
private StringBuilder recDataString = new StringBuilder();
//
private IconRoundCornerProgressBar progressOne;
private IconRoundCornerProgressBar progressTwo;
private CountdownView mCvCountdownView;
ImageView bt,wrng,temp;
ProgressDialog progress;
private WaveLoadingView waveLoadingView;
public static String combustible = "tiempo";
public static String modo = "modo";
final int handlerState = 0; //used to identify handler
message
public Handler mUiHandler = null;
boolean mBound;
boolean ledcontrol=true;
private RadioGroup rdgGroup;
private LinearLayout l2;
boolean sMode=false;
boolean mIsServiceRunning;
boolean prdflag=false;
private boolean ConnectSuccess=false;
boolean prdflag2=false;
private Reconnect bth;
boolean runtime=false;
public void onClick(View v) {
int id=v.getId();
111
if(id== R.id.button6){
decreaseProgress();
}else if (id==R.id.button7){
increaseProgress();
}
}
private void increaseProgress(){ //Metodo para incrementar
la barra de progreso de combustible
progressTwo.setProgress(progressTwo.getProgress()+10);
updateTextProgressTwo();
}
private void decreaseProgress(){ //Metodo para decrementar
la barra de progreso de combustible
progressTwo.setProgress(progressTwo.getProgress()-10);
updateTextProgressTwo();
}
private void updateTextProgressTwo(){ //Metodo para
actualizar el timer
txttiempoch=(String.valueOf((int) progressTwo.getProgress()));
String tm = txttiempoch;
time=Long.parseLong(tm);
time=time*60000;
mCvCountdownView.updateShow(time);
mCvCountdownView.pause();
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); //receive the address of
the bluetooth device
Bundle datos = this.getIntent().getExtras();
setContentView(R.layout.activity_home); //call the widgtes
btnOn = (Button) findViewById(R.id.button3);
final Intent intent = getIntent();
mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
sen2t = intent.getStringExtra(EXTRAS_ACELEROMETRO);
sen2ti = Integer.valueOf(sen2t);
Objects.requireNonNull(getSupportActionBar()).setTitle(mDeviceName);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
Intent gattServiceIntent = new Intent(this,
BluetoothLeService.class);
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
btnDis = (Button) findViewById(R.id.button5);
final WaveLoadingView mWaveLoadingView = (WaveLoadingView)
findViewById(R.id.waveLoadingView);
mCvCountdownView =
(CountdownView)findViewById(R.id.cv_countdownViewTest2);
rdgGroup = (RadioGroup)findViewById(R.id.rdgGrupo);
l2 = (LinearLayout)findViewById(R.id.linearLayout2);
l2.setVisibility(View.INVISIBLE);
bt =(ImageView)findViewById(R.id.imageView1);
112
wrng = (ImageView)findViewById(R.id.imageView);
temp = (ImageView)findViewById(R.id.imageView3);
if(sen2ti==1){
wrng.setColorFilter(Color.parseColor("#FFA500"));
}
else if(sen2ti==0){
wrng.setColorFilter(Color.parseColor("#FFFFFF"));
}
temp.setOnClickListener(new View.OnClickListener() {//Metodo para
cuando se da click en la imagen
@Override
public void onClick(View view) {
if(sen3==1){
msg("Alta temperatura, no es seguro encender la
chimenea");
}
else if(sen3==0){
msg("Es seguro encender la chimenea");
}
}
});
wrng.setOnClickListener(new View.OnClickListener() {//Metodo para
cuando se da click en la imagen
@Override
public void onClick(View view) {
if(sen2ti==1){
msg("Asegurese de limpiar la fuga de combustible antes de
enceder");
sen2ti=0;
sen2t= String.valueOf(0);
wrng.setColorFilter(Color.parseColor("#FFFFFF"));
}else{
}
}
});
bt.setOnClickListener(new View.OnClickListener() {//Metodo para
cuando se da click en la imagen
@Override
public void onClick(View view) {
if(conectado){
msg("Conectado");
}
else{
msg("Desconectado");
}
}
});
btnOn.setOnClickListener(new View.OnClickListener() {//Metodo para
caundo se da click en el boton de encender
@Override
public void onClick(View v) {
try {
turnOnLed(); //method to turn on
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
113
}
});
btnDis.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Disconnect(); //close connection
}
});
rdgGroup.setOnCheckedChangeListener(new
RadioGroup.OnCheckedChangeListener() { //Radiogroup para
seleccionar el modo de funcionamiento de la biochimenea
public void onCheckedChanged(RadioGroup group, int checkedId){
if(checkedId == R.id.radioButton1){
l2.setVisibility(View.INVISIBLE);
sMode=false;
}
else if (checkedId == R.id.radioButton2){
l2.setVisibility(View.VISIBLE);
sMode=true;
progressTwo.setProgress(0);
mCvCountdownView.allShowZero();
}
}
});
progressOne = (IconRoundCornerProgressBar)
findViewById(R.id.progress_One);
progressOne.setSecondaryProgressColor(Color.parseColor("#BDDDDC"));
progressOne.setIconBackgroundColor(Color.parseColor("#3399ff"));
progressOne.setProgressBackgroundColor(Color.parseColor("#808080"));
progressTwo = (IconRoundCornerProgressBar)
findViewById(R.id.progress_Two);
progressTwo.setProgressColor(Color.parseColor("#6BB120"));
progressTwo.setIconBackgroundColor(Color.parseColor("#478244"));
progressTwo.setProgressBackgroundColor(Color.parseColor("#808080"));
updateTextProgressTwo();
findViewById(R.id.button6).setOnClickListener(this);
findViewById(R.id.button7).setOnClickListener(this);
mUiHandler = new Handler() { //Handler para
recibir el Handler del servicio de conexion
public void handleMessage(Message msg) {
String readMessage = (String) msg.obj;
recDataString.append(readMessage);
int endOfLineIndex = recDataString.indexOf("~");
if (endOfLineIndex > 0) {
String dataInPrint = recDataString.substring(0,
endOfLineIndex);
txtString = "Datos recibidos = " + dataInPrint;
int dataLength = dataInPrint.length(); //get length
of data received
txtStringLength = "Tamaño del String = " +
String.valueOf(dataLength);
//Log.d("handler",dataInPrint);
if (dataInPrint.charAt(0) == '#') //if it starts
with # we know it is what we are looking for
114
{if(dataLength==13) {
sensor0 = dataInPrint.substring(1, 4);
//get sensor value from string between indices 1-5
sensor1 = dataInPrint.substring(5, 8);
sensor2 = dataInPrint.substring(9, 10);//same
again...
sensor3 = dataInPrint.substring(11,12);
sensorView0 = sensor0 + "%";
sensorView1 = sensor1 + "%";
sensorView2 = sensor2;
sen0 = Integer.valueOf(sensor0);
sen1 = Integer.valueOf(sensor1);
sen3 = Integer.valueOf(sensor3);
if(sen3==1){//Si la temperatura es muy alta para
encenderla
temp.setColorFilter(Color.parseColor("#ff0000"));
}
else if(sen3==0){
temp.setColorFilter(Color.parseColor("#FFFFFF"));
}
mWaveLoadingView.setCenterTitle(sensor0 + " %");
mWaveLoadingView.setProgressValue(sen0);
progressOne.setProgress(sen1);
if (!sMode) {
progressTwo.setMax(100);
progressTwo.setProgress(sen0);
} else if (sMode) {
progressTwo.setMax(sen0 * 3 - 10);
}
float progress = progressOne.getProgress();
if (progress <= 30) {
progressOne.setProgressColor(Color.parseColor("#CC3131"));
} else if (progress > 30 && progress <= 60) {
progressOne.setProgressColor(Color.parseColor("#FFA500"));
} else if (progress > 60) {
progressOne.setProgressColor(Color.parseColor("#3399ff"));
}
}else if (((String) msg.obj).isEmpty()){
mBluetoothLeService.readCustomCharacteristic();
}
} else if (dataInPrint.charAt(0) == 'T') {//Si hay tiempo
pendiente en la chimenea
Intent i = new Intent(Home.this, ONCH.class);
txttiempoch = dataInPrint.substring(1, 6);
ledcontrol = false;
i.putExtra(combustible, txttiempoch);
i.putExtra(modo, true);
i.putExtra(ONCH.EXTRAS_DEVICE_ADDRESS,
String.valueOf(mDeviceAddress));
i.putExtra(ONCH.EXTRAS_DEVICE_NAME,String.valueOf(mDeviceName));
115
i.putExtra(ONCH.EXTRAS_ACELEROMETRO,String.valueOf(sen2t));
startActivity(i);
unregisterReceiver(mGattUpdateReceiver);
finish();
}
recDataString.delete(0, recDataString.length());
//clear all string data
dataInPrint = " ";
}
}
};
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Disconnect();
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){//Metodo para
cuando se da click en el boton back del hardware de cualquier celular
if(keyCode == KeyEvent.KEYCODE_BACK)
{
Disconnect();
}
return false;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void myRunnable2() {//Hilo para preguntar por el tiempo si esta
encendida la chimenea
if(mBluetoothLeService!=null){
try {
Thread.sleep(1000);
String tiempo = stringToHex("\\wtiempo?");
byte[] hex=hexStringToByteArray(tiempo+"0D");
mBluetoothLeService.writeCustomCharacteristic(hex);
Log.d("tiempo?","enviado");
runtime=true;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
116
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
protected void onResume() {
super.onResume();
registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
if (mBluetoothLeService != null) {
final boolean result =
mBluetoothLeService.connect(mDeviceAddress);
Log.d(TAG, "Connect request result=" + result);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
mBluetoothLeService = null;
mBound=false;
}
private void updateConnectionState(final int resourceId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
private void displayData(String data) {//Metodo para obtener los datos
del servicio
if (data != null) {
datafield=data;
Message msg=Message.obtain();
msg.obj=datafield;
msg.setTarget(mUiHandler);
msg.sendToTarget();
Log.d("data",datafield);
}
}
private final ServiceConnection mServiceConnection = new
ServiceConnection() {//Metodo para conectar con el dispositvo BT por medio
del servicio de conexion
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onServiceConnected(ComponentName componentName, IBinder
service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder)
service).getService();
mBound=true;
if (!mBluetoothLeService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
finish();
}
117
// Automatically connects to the device upon successful start-up
initialization.
mBluetoothLeService.connect(mDeviceAddress);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
mBound=false;
}
};
private final BroadcastReceiver mGattUpdateReceiver = new
BroadcastReceiver() {//Metodo para comunicarse con el servicio de conexion
cuando esta conectado y desconectado
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@SuppressLint("RestrictedApi")
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
updateUIConected();
try {
Thread.sleep(650);
} catch (InterruptedException e) {
e.printStackTrace();
}
mBluetoothLeService.readCustomCharacteristic();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
String tiempo = stringToHex("\\wconectado");
byte[] hex=hexStringToByteArray(tiempo+"0D");
mBluetoothLeService.writeCustomCharacteristic(hex);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if(!runtime){
myRunnable2();
runtime=true;
}
} else if
(BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
mBluetoothLeService.disconnect();
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
clearUI();
updateUIDisConected();
118
} else if
(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
// Show all the supported services and characteristics on the
user interface.
} else if
(BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
}
}
};
private void clearUI() {//Limpia el buffer de entrada de datos
txtString= String.valueOf(R.string.no_data);
}
private static IntentFilter makeGattUpdateIntentFilter() {//Filtros para
la recepcion de datos de el servicio con la actividad
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
return intentFilter;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void updateUIDisConected() { // Metodo para
llamar el servicio de conexion si la conexion se llega a perder
Log.d("BT2", String.valueOf(mIsServiceRunning));
btnOn.setVisibility(View.INVISIBLE);
btnDis.setVisibility(View.INVISIBLE);
bt.setColorFilter(Color.parseColor("#FF0000"));
mBluetoothLeService.connect(mDeviceAddress);
prdflag = true;
if (!prdflag2) {
prdflag2 = true;
bth=new Reconnect();
bth.execute();
ConnectSuccess=false;
}
conectado=false;
}
private void updateUIConected() {//Metodo para cuando restablece la
conexion con el dispostivo BT
btnOn.setVisibility(View.VISIBLE);
btnDis.setVisibility(View.VISIBLE);
bt.setColorFilter(Color.parseColor("#00b800"));
if (prdflag) {
ConnectSuccess = true;
bth.cancel(true);
prdflag2=false;
progress.dismiss();
}
119
conectado=true;
}
@SuppressLint("StaticFieldLeak")
private class Reconnect extends AsyncTask<Void, Void, Void>//Mensaje de
espera si la conexion se pierde
{
@Override
protected void onPreExecute() {
progress = ProgressDialog.show(Home.this, "Connecting...",
"Please wait!!!");
}
@Override
protected Void doInBackground(Void... voids) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (!ConnectSuccess) {
msg("Connection Failed. Is it a SPP Bluetooth? Try again.");
} else {
msg("Connected.");
progress.dismiss();
prdflag2=false;
}
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void Disconnect() { //Metodo para
desconectarse del modulo BT u volver a la actividad Device List
if (mBluetoothLeService != null) //If the btSocket is busy
{
unregisterReceiver(mGattUpdateReceiver);
ledcontrol=false;
Intent i = new Intent(Home.this,DeviceList.class);
startActivity(i);
mBluetoothLeService.disconnect(); //close connection
finish();
}
finish(); //return to the first layout
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void turnOnLed() throws UnsupportedEncodingException {
//Metodo para encender la chimenea, enviar tiempo, y avanzar a la siguiente
actividad
if (mBluetoothLeService != null && sen3==0 && sen2ti==0) {
120
ledcontrol=false;
Intent i = new Intent(Home.this, ONCH.class);
if(sMode){
String d = txttiempoch;
Long t =Long.valueOf(d);
Long t1 = t*60;
if(t>=10L){
String encenderch = stringToHex("\\wencenderch");
byte[] hex=hexStringToByteArray(encenderch+"0D");
mBluetoothLeService.writeCustomCharacteristic(hex);
Log.d("Encender","\\wencenderch");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String tt = stringToHex("\\t"+t1);
byte[] hex2=hexStringToByteArray(tt+"0D");
mBluetoothLeService.writeCustomCharacteristic(hex2);
Log.d("d",d.toString());
Log.d("d",t.toString());
Log.d("TIEMPO",t1.toString());
i.putExtra(combustible, String.valueOf(t1));
i.putExtra(modo,sMode);
i.putExtra(ONCH.EXTRAS_DEVICE_ADDRESS,String.valueOf(mDeviceAddress));
i.putExtra(ONCH.EXTRAS_DEVICE_NAME,String.valueOf(mDeviceName));
i.putExtra(ONCH.EXTRAS_ACELEROMETRO,String.valueOf(sen2t));
startActivity(i);
unregisterReceiver(mGattUpdateReceiver);
finish();
}
else{
msg("El tiempo minimo son 10min");
}
}else if(!sMode){
String encenderch = stringToHex("\\wencenderch");
byte[] hex=hexStringToByteArray(encenderch+"0D");
mBluetoothLeService.writeCustomCharacteristic(hex);
Log.d("Encender","\\wencenderch");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Long f = freetime();
i.putExtra(combustible,String.valueOf(f));
i.putExtra(ONCH.EXTRAS_DEVICE_ADDRESS,String.valueOf(mDeviceAddress));
i.putExtra(ONCH.EXTRAS_DEVICE_NAME,String.valueOf(mDeviceName));
i.putExtra(ONCH.EXTRAS_ACELEROMETRO,String.valueOf(sen2t));
String tf = stringToHex("\\t"+f);
121
Log.d("f",f.toString());
byte[] hex2 =hexStringToByteArray(tf+"0D");
mBluetoothLeService.writeCustomCharacteristic(hex2);
startActivity(i);
unregisterReceiver(mGattUpdateReceiver);
finish();
}
} else if(sen3==1 && sen2ti==0){
msg("Por favor espere a que la chimenea se enfrie antes de
encenderla");
}
else if(sen3==0&& sen2ti==1){
msg("Asegurese de limpiar la fuga de combustible antes de
enceder");
sen2ti=0;
sen2t=String.valueOf(0);
wrng.setColorFilter(Color.parseColor("#FFFFFF"));
}
else if(sen3==1&& sen2ti==1){
msg("Espere a que la chimenea se enfrie y luego limpie la fuga de
combustible");
}
else{
msg("Try to connect again");
}
}
private Long freetime(){ //Metodo para establecer el tiempo maximo
de encendido
tfree= (long) sen0;
Long tfree2=tfree*180;
Log.d("tfree",tfree2.toString());
return tfree2;
}
private void msg(String s) { //Metodo para crear Mensajes toast
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
}
public static byte[] hexStringToByteArray(String s) {//Metodo para pasar
un Hexadecimal a un arreglo de bytes
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
public String stringToHex(String input) throws
UnsupportedEncodingException
{
if (input == null) throw new NullPointerException();
return asHex(input.getBytes());
}
122
private String asHex(byte[] buf)//Metodo para pasar un String a un
Hexadecimal
{
char[] chars = new char[2 * buf.length];
for (int i = 0; i < buf.length; ++i)
{
chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
}
return new String(chars);
}
}
13.2.4. ONCH.java
package com.led.ControlR;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.Toast;
import android.app.ProgressDialog;
import java.io.UnsupportedEncodingException;
import java.util.Objects;
import android.os.Handler;
import com.akexorcist.roundcornerprogressbar.IconRoundCornerProgressBar;
import com.led.led.R;
import cn.iwgang.countdownview.CountdownView;
import me.itangqi.waveloadingview.WaveLoadingView;
/**
* Created by CLARA on 19/09/2017.
123
*/
public class ONCH extends AppCompatActivity implements View.OnClickListener{
Button btOFF2,btAdd;
String
sensor0t,sensor1t,sensor2t,combt,txttiempoch,datafield,txtStringLength2,txtSt
ring2;
ImageView bt2;
ProgressDialog progress;
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
public static final String EXTRAS_ACELEROMETRO = "ACELEROMETRO";
private final static String TAG = ONCH.class.getSimpleName();
private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
private String mDeviceName;
private String mDeviceAddress;
private String Over="Over";
private BluetoothLeService mBluetoothLeService;
private boolean mConnected = false;
private StringBuilder recDataString = new StringBuilder();
//
int sen0t,sen1t,sen2t;
long tiempo,time,tfree,tiempo2;
boolean mBound;
String sen2ts;
public Handler mUiHandler = null;
boolean ONCH=true;
boolean modo,sMode;
boolean prdflag=false;
private boolean ConnectSuccess=false;
boolean prdflag2=false;
Reconnect bth = new Reconnect();
private IconRoundCornerProgressBar progressOne2;
private IconRoundCornerProgressBar progressTwo2;
private CountdownView mCvCountdownView;
private CountdownView mCvCountdownView2;
private CountdownView mCvCountdownView4;
private RadioGroup rdGroup2;
private LinearLayout l3;
public void onClick(View v){
int id=v.getId();
if(id== R.id.button10){
decreaseProgress();
}else if (id==R.id.button11){
increaseProgress();
}
}
private void increaseProgress(){//Incrementa el tiempo
progressTwo2.setProgress(progressTwo2.getProgress()+10);
updateTextProgressTwo();
}
private void decreaseProgress(){//Decrece el tiempo
progressTwo2.setProgress(progressTwo2.getProgress()-10);
124
updateTextProgressTwo();
}
private void updateTextProgressTwo(){//Actualiza el tiempo
txttiempoch=(String.valueOf((int) progressTwo2.getProgress()));
String tm = txttiempoch;
time=Long.parseLong(tm);
time=time*60000;
mCvCountdownView2.updateShow(time);
mCvCountdownView2.pause();
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_on_ch);
//
final Intent intent = getIntent();
mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
sen2ts = intent.getStringExtra(EXTRAS_ACELEROMETRO);
sen2t=Integer.valueOf(sen2ts);
Objects.requireNonNull(getSupportActionBar()).setTitle(mDeviceName);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
Intent gattServiceIntent = new Intent(this,
BluetoothLeService.class);
bindService(gattServiceIntent, mServiceConnection,
BIND_AUTO_CREATE);
//
Bundle datos = this.getIntent().getExtras();
combt = datos.getString(Home.combustible);
modo = datos.getBoolean(Home.modo);
btOFF2 = (Button) findViewById(R.id.button8);
btAdd=(Button)findViewById(R.id.button13);
Log.d("Combt", String.valueOf((combt)));
Log.d("Modo",String.valueOf(modo));
final WaveLoadingView mWaveLoadingView = (WaveLoadingView)
findViewById(R.id.waveLoadingView2);
progressOne2 = (IconRoundCornerProgressBar)
findViewById(R.id.progress_One2);
progressOne2.setSecondaryProgressColor(Color.parseColor("#BDDDDC"));
progressOne2.setIconBackgroundColor(Color.parseColor("#3399ff"));
progressOne2.setProgressBackgroundColor(Color.parseColor("#808080"));
progressTwo2 = (IconRoundCornerProgressBar)
findViewById(R.id.progress_Two2);
progressTwo2.setProgressColor(Color.parseColor("#478244"));
progressTwo2.setIconBackgroundColor(Color.parseColor("#478244"));
progressTwo2.setProgressBackgroundColor(Color.parseColor("#808080"));
mCvCountdownView =
(CountdownView)findViewById(R.id.cv_countdownViewTest1);
125
mCvCountdownView2 =
(CountdownView)findViewById(R.id.cv_countdownViewTest3);
mCvCountdownView4 =
(CountdownView)findViewById(R.id.cv_countdownViewTest4);
bt2=(ImageView)findViewById(R.id.imageView2);
tiempo=Long.parseLong(combt);
tiempo2=tiempo/60;
tiempo=tiempo*1000;
btAdd.setVisibility(View.INVISIBLE);
Log.d("tiempo",String.valueOf(tiempo));
findViewById(R.id.button10).setOnClickListener(this);
findViewById(R.id.button11).setOnClickListener(this);
rdGroup2=(RadioGroup)findViewById(R.id.rdgGrupo2);
l3=(LinearLayout)findViewById(R.id.linearLayout3);
if(!modo){
rdGroup2.check(R.id.radioButton3);
l3.setVisibility(View.INVISIBLE);
btAdd.setVisibility(View.INVISIBLE);
mCvCountdownView.setVisibility(View.INVISIBLE);
mCvCountdownView4.setVisibility(View.VISIBLE);
mCvCountdownView4.start(tiempo);
sMode=false;
}
else if(modo){
rdGroup2.check(R.id.radioButton4);
btAdd.setVisibility(View.VISIBLE);
mCvCountdownView.start(tiempo);
progressTwo2.setMax(sen0t*3-10);
progressTwo2.setProgress(tiempo2);
mCvCountdownView2.updateShow(tiempo);
mCvCountdownView2.pause();
mCvCountdownView4.setVisibility(View.INVISIBLE);
sMode=true;
}
rdGroup2.setOnCheckedChangeListener(new
RadioGroup.OnCheckedChangeListener() {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onCheckedChanged(RadioGroup radioGroup, int
checkedId) {
if(checkedId==R.id.radioButton3){
l3.setVisibility(View.INVISIBLE);
btAdd.setVisibility(View.INVISIBLE);
mCvCountdownView.setVisibility(View.INVISIBLE);
mCvCountdownView4.setVisibility(View.VISIBLE);
try {
freetime();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
sMode=false;
}
else if(checkedId==R.id.radioButton4){
l3.setVisibility(View.VISIBLE);
126
btAdd.setVisibility(View.VISIBLE);
mCvCountdownView.setVisibility(View.VISIBLE);
mCvCountdownView4.setVisibility(View.INVISIBLE);
mCvCountdownView2.allShowZero();
time=0L;
mCvCountdownView.updateShow(0L);
mCvCountdownView.pause();
progressTwo2.setMax(sen0t*3-10);
progressTwo2.setProgress(0);
sMode=true;
}
}
});
btOFF2.setOnClickListener(new View.OnClickListener(){
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onClick(View v){
try {
turnOFFCH();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
btAdd.setOnClickListener(new View.OnClickListener() {//Actualiza
el tiempo en la chimenea
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onClick(View view) {
try {
updatetime();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
mUiHandler = new Handler() {
public void handleMessage(Message msg) {//Recibe los datos
del dispositivo BT atravez del servicio
String readMessage = (String) msg.obj;
recDataString.append(readMessage);
int endOfLineIndex = recDataString.indexOf("~");
if (endOfLineIndex > 0) {
String dataInPrint = recDataString.substring(0,
endOfLineIndex);
txtString2 = "Datos recibidos = " + dataInPrint;
int dataLength = dataInPrint.length(); //get
length of data received
txtStringLength2="Tamaño del String = " +
String.valueOf(dataLength);
if (dataInPrint.charAt(0) == '#') //if it
starts with # we know it is what we are looking for
{if(dataLength==13) {
sensor0t = dataInPrint.substring(1, 4);
//get sensor value from string between indices 1-5
sensor1t = dataInPrint.substring(5, 8);
127
sensor2t = dataInPrint.substring(9, 10);
sen0t = Integer.valueOf(sensor0t);
sen1t = Integer.valueOf(sensor1t);
sen2t = Integer.valueOf(sensor2t);
if(sen2t==1){//Si se detecta una vibracion apaga
la chimenea y cambia a la actividad anterior
msg("Se ha detectado una vibracion, la
chimenea se ha apagado por su seguridad");
Intent i = new Intent(ONCH.this, Home.class);
ONCH = false;
try {
String apagarch =
stringToHex("\\wapagarch");
byte[] hex =
hexStringToByteArray(apagarch + "0D");
mBluetoothLeService.writeCustomCharacteristic(hex);
Log.d("SensorAcel","\\wapagarch");
unregisterReceiver(mGattUpdateReceiver);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
i.putExtra(Home.EXTRAS_DEVICE_ADDRESS,
String.valueOf(mDeviceAddress));
i.putExtra(Home.EXTRAS_DEVICE_NAME,
String.valueOf(mDeviceName));
i.putExtra(Home.EXTRAS_ACELEROMETRO,String.valueOf(1));
startActivity(i);
finish();
}
mWaveLoadingView.setCenterTitle(sensor0t + " %");
mWaveLoadingView.setProgressValue(sen0t);
progressOne2.setProgress(sen1t);
if (!sMode) {
progressTwo2.setMax(100);
progressTwo2.setProgress(sen0t);
} else if (sMode) {
progressTwo2.setMax(sen0t * 3 - 10);
}
float progress = progressOne2.getProgress();
if (progress <= 30) {
progressOne2.setProgressColor(Color.parseColor("#CC3131"));
} else if (progress > 30 && progress <= 60) {
progressOne2.setProgressColor(Color.parseColor("#FFA500"));
} else if (progress > 60) {
progressOne2.setProgressColor(Color.parseColor("#3399ff"));
}
}
}else if(dataInPrint.equals(Over)) {//Si el tiempo se
acaba en la chimenea procesa el comando y se devuelve a la actividad anterior
Intent i = new Intent(ONCH.this, Home.class);
128
ONCH = false;
try {
String apagarch = stringToHex("\\wapagarch");
byte[] hex = hexStringToByteArray(apagarch +
"0D");
mBluetoothLeService.writeCustomCharacteristic(hex);
Log.d("TiempoTerminado","\\wapagarch");
unregisterReceiver(mGattUpdateReceiver);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
i.putExtra(Home.EXTRAS_DEVICE_ADDRESS,
String.valueOf(mDeviceAddress));
i.putExtra(Home.EXTRAS_DEVICE_NAME,
String.valueOf(mDeviceName));
i.putExtra(Home.EXTRAS_ACELEROMETRO,String.valueOf(0));
startActivity(i);
finish();
}
recDataString.delete(0, recDataString.length());
//clear all string data
dataInPrint = " ";
}
}
};
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void updatetime() throws UnsupportedEncodingException
{//ACtualiza el tiempo en la chimenea
if(time>=10L){
Long newtime=time;
Long t=newtime/1000;
mCvCountdownView.start(newtime);
String tiempo=stringToHex("\\t"+t);
byte[]hex=hexStringToByteArray(tiempo+"0D");
mBluetoothLeService.writeCustomCharacteristic(hex);
Log.d("T",t.toString());
}
else{
msg("El tiempo minimo son 10min");
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void freetime() throws UnsupportedEncodingException {//Estima el
tiempo restante de acuerdo a la cantidad de combustible
tfree= (long) sen0t;
tfree=tfree*180000;
mCvCountdownView4.start(tfree);
Long tfree2=tfree/1000;
String tiempo=stringToHex("\\t"+tfree2);
byte[]hex=hexStringToByteArray(tiempo+"0D");
129
mBluetoothLeService.writeCustomCharacteristic(hex);
Log.d("tfree2",tfree2.toString());
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){//Si el boton de
retoceso en el hardware del celular se oprime
if(keyCode == KeyEvent.KEYCODE_BACK)
{
try {
turnOFFCH();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return false;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
protected void onResume() {
super.onResume();
registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
if (mBluetoothLeService != null) {
final boolean result =
mBluetoothLeService.connect(mDeviceAddress);
Log.d(TAG, "Connect request result=" + result);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
mBluetoothLeService = null;
mBound=false;
}
private void updateConnectionState(final int resourceId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
private void displayData(String data) {//Toma los datos proveniente del
servicio de conexion
if (data != null) {
datafield=data;
Log.d("data",datafield);
Message msg=Message.obtain();
msg.obj=datafield;
msg.setTarget(mUiHandler);
msg.sendToTarget();
130
}
}
private final ServiceConnection mServiceConnection = new
ServiceConnection() {//Conexion del servicio al dispositivo BT
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onServiceConnected(ComponentName componentName, IBinder
service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder)
service).getService();
mBound=true;
if (!mBluetoothLeService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
finish();
}
// Automatically connects to the device upon successful start-up
initialization.
mBluetoothLeService.connect(mDeviceAddress);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
mBound=false;
}
};
private final BroadcastReceiver mGattUpdateReceiver = new
BroadcastReceiver() {//Metodo para comunicarse con el servicio de conexion
cuando esta conectado y desconectado
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@SuppressLint("RestrictedApi")
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
updateUIConected();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
mBluetoothLeService.readCustomCharacteristic();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
String tiempo = stringToHex("\\wconectado");
131
byte[] hex=hexStringToByteArray(tiempo+"0D");
mBluetoothLeService.writeCustomCharacteristic(hex);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else if
(BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
mBluetoothLeService.disconnect();
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
clearUI();
updateUIDisConected();
} else if
(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
// Show all the supported services and characteristics on the
user interface.
} else if
(BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
}
}
};
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void updateUIDisConected() {// Metodo para llamar el servicio de
conexion si la conexion se llega a perder
btOFF2.setVisibility(View.INVISIBLE);
rdGroup2.setVisibility(View.INVISIBLE);
btAdd.setVisibility(View.INVISIBLE);
bt2.setColorFilter(Color.parseColor("#FF0000"));
mBluetoothLeService.connect(mDeviceAddress);
Log.d("address", mDeviceAddress);
prdflag = true;
if (!prdflag2) {
prdflag2 = true;
bth=new Reconnect();
bth.execute();
ConnectSuccess=false;
}
}
private void updateUIConected() {//Metodo para cuando restablece la
conexion con el dispostivo BT
btOFF2.setVisibility(View.VISIBLE);
rdGroup2.setVisibility(View.VISIBLE);
if (sMode) {
btAdd.setVisibility(View.VISIBLE);
}
bt2.setColorFilter(Color.parseColor("#00b800"));
if (prdflag) {
ConnectSuccess = true;
bth.cancel(true);
prdflag2=false;
progress.dismiss();
132
}
}
private void clearUI() {//Limpia el buffer de entrada de datos
txtString2=String.valueOf(R.string.no_data);
}
private static IntentFilter makeGattUpdateIntentFilter() {//Filtros para
la recepcion de datos de el servicio con la actividad
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
return intentFilter;
}
@SuppressLint("StaticFieldLeak")
private class Reconnect extends AsyncTask<Void, Void, Void>{//Mensaje de
espera si la conexion se pierde
@Override
protected void onPreExecute() {
progress = ProgressDialog.show(ONCH.this, "Connecting...",
"Please wait!!!");
}
@Override
protected Void doInBackground(Void... voids) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (!ConnectSuccess) {
msg("Connection Failed. Is it a SPP Bluetooth? Try again.");
} else {
msg("Connected.");
progress.dismiss();
prdflag2=false;
}
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void turnOFFCH() throws UnsupportedEncodingException {//Metodo
para desconectarse del modulo BT u volver a la actividad Device List
if (mBluetoothLeService != null) {
String apagarch=stringToHex("\\wapagarch");
byte [] hex=hexStringToByteArray(apagarch+"0D");
mBluetoothLeService.writeCustomCharacteristic(hex);
Log.d("Apagar", "\\wapagarch");
ONCH=false;
133
Intent i = new Intent(ONCH.this, Home.class);
i.putExtra(Home.EXTRAS_DEVICE_ADDRESS,String.valueOf(mDeviceAddress));
i.putExtra(Home.EXTRAS_DEVICE_NAME,String.valueOf(mDeviceName));
i.putExtra(Home.EXTRAS_ACELEROMETRO,String.valueOf(0));
startActivity(i);
finish();
}else{
msg("Try to connect again");
}
}
private void msg(String s) {
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
}
public static byte[] hexStringToByteArray(String s) {//Metodo para pasar
un Hexadecimal a un arreglo de bytes
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
public String stringToHex(String input) throws
UnsupportedEncodingException
{
if (input == null) throw new NullPointerException();
return asHex(input.getBytes());
}
private String asHex(byte[] buf)//Metodo para pasar un String a un
Hexadecimal
{
char[] chars = new char[2 * buf.length];
for (int i = 0; i < buf.length; ++i)
{
chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
}
return new String(chars);
}
}
13.3. Manual de operación
ATENCION
Nunca utilice su chimenea si se ha dañado o modificado de alguna manera.
El uso inadecuado o la falta de seguimiento a las precauciones de seguridad pueden provocar lesiones graves o la muerte, así como el daño o la pérdida de la propiedad.
1. Lea toda la información por completo antes de usar su Bio-Chimenea o chimenea de Bioetanol
2. No se deshaga de estas instrucciones manténgalas con su Biochimenea para referencias
Elija un lugar adecuado para su Bio-Chimenea
Ubique la Biochimenea en un lugar fijo y sólido, donde no provoque accidentes o sea pateado o golpeado por alguna persona o animal desprevenido, también alejado de cualquier objeto potencialmente inflamable como objetos móviles (cortinas, tapetes, etc.)
Siempre que la chimenea este encendida mantenga bajo supervisión el comportamiento de la llama si esta no se comporta de una manera natural, apáguela y verifique las corrientes de aire.
Medidas al momento de la instalación
Alrededor del quemador debe existir siempre una distancia mínima de 20 cm antes de cualquier objeto que se pueda quemar.
Hacia arriba debe exstir una distancia minima de 60 cm.
Alrededor de la cámara de combustión /quemador es necesario adoptar las suficientes medidas de protección contra incendios.
Ningun material inflamable debe entrar en contacto directo con las llamas o superficies calientes.
Lea cuidadosamente antes de utilizar el bio-combustible.
1. No permita niños o animales cerca de la Bio-Chimenea. 2. No permita que este encendida sin la supervisión de un adulto. 3. La Biochimenea puede llegar a estar muy caliente durante su uso, no la toque sin
esperar el tiempo necesario para que esta se enfríe. 4. Preste atención cuando la llama este encendida por si su ropa, cabello, manos y
rostro se acercan considerablemente a la chimenea. 5. No almacene combustible adicional en cualquier lugar cerca de la chimenea, el
combustible puede emitir gases y estos pueden ser explosivos. 6. Mantenga bien cerrados los recipientes donde almacena el combustible adicional
y lejos de cualquier fuente potencial de combustión.
Precauciones del Biocombustible
Manténgase alejado de fuentes potenciales de ignición Manténgase fuera del alcance de niños y animales Mantenga el envase bien cerrado No inhalar No ingerir
Instrucciones de encendido y apagado por control a distancia
1. Oprima el interruptor de encendido ubicado en la parte superior de la biochimenea, para dar energía al sistema.
2. Inicie la aplicación en su dispositivo Android, y oprima el botón de “Buscar chimeneas” para establecer una conexión con la biochimenea
3. La biochimenea se mostrará en la lista de dispositivos cuando se muestre nombre “HMsoft”, oprima sobre este nombre para conectarse inalámbricamente con la biochimenea.
Interruptor de encendido
4. Botones y acciones de la aplicación:
5. Botones y elementos de la biochimenea:
Quemador de combustible
Encendedor Eléctrico Puerto de carga Eléctrico
RESET Tapa tanque de
combustible
Botón pulsador
Visualizador LCD
Interruptor ON/OFF
Estado de la conexión
Nivel de combustible
Tiempo a programar
Enciende biochimenea
Tipo de encendido
Nivel de carga batería
Tiempo disponible de combustión
Desconectar conexion bluetooth
6. Abra la tapa de combustible de la biochimenea y vierta el biocombustible para llenar el tanque de combustible
7. Verifique que se está llenando el tanque de combustible mediante el visualizador LCD o en el aplicativo, que supere el 5%, mínimo, para poder encender la biochimenea
8. Compruebe que la biochimenea no este mostrando ninguna alerta tanto en la aplicación Android como en el visualizador LCD ubicado en la parte superior de la biochimenea.
9. Proceda a configurar el tiempo que durara encendida la llama 9.1. Si selecciona “Tiempo Libre” se consumirá todo el combustible disponible en
el tanque de combustible 9.2. Si selecciona “Tiempo específico” tendrá la opción de configurar el tiempo
que usted desee para que la llama dure encendida 10. Oprima el botón de “Encender” y luego verifique que la llama se encienda en el área
del quemador 11. Cuando Se acabe el tiempo programado en la aplicación, espere unos minutos
adicionales para que se termine de quemar el biocombustible restante en el área del quemador.
12. Tenga precaución, cuando la llama se apague, la biochimenea se mantendrá con una alta temperatura, por lo que no será posible recargarla ni encender la llama inmediatamente, hasta que la chimenea se enfrié.
NOTA: Si desea modificar el tiempo de combustión, una vez este encendida la llama, solo hace verificar que este marcada la opción de tiempo especifico y luego podrá modificar el tiempo programado con los botones ubicados en la parte inferior de la aplicación.
Instrucciones de encendido y apagado de forma manual
1. Oprima el interruptor de encendido ubicado en la parte superior para darle energía a la biochimenea.
2. Pulse el botón ubicado en la parte superior de la biochimenea para encender el visualizador LCD
3. Abra la tapa de combustible de la biochimenea y vierta el biocombustible para llenar el tanque de combustible
4. Pulse nuevamente el botón y la biochimenea automáticamente encenderá la llama hasta consumir todo el combustible del tanque de combustible
5. Parametros mostrados en el visualizador LCD:
6. Si desea apagar la llama antes de que se consuma todo el combustible, pulse el botón pulsador nuevamente y la llama se apagara luego de unos segundos, hasta que se consuma el combustible restante en el área del quemador.
7. Tenga precaución, cuando la llama se apague, la biochimenea se mantendrá con una alta temperatura, por lo que no será posible recargar combustible ni encender la llama inmediatamente, hasta que la chimenea se enfrié.
NOTA: Si la biochimenea esta encendida y la llama también, y desea utilizar la aplicación Android, solo hace falta conectarse a la chimenea y el tiempo que tenga programado la biochimenea apareceré automáticamente en la aplicación
Tiempo Restante
Tiempo Trascurrido
Nivel de combustible
Nivel de carga de las baterias 1 y 2
Conectado o desconectado
ALERTAS VISUALES
Este sistema tiene la capacidad de detectar vibraciones y golpes que puedan cambiar accidentalmente su posición y exponer el combustible líquido hacia el exterior de la chimenea mientras está encendida la llama, por lo que el sistema al detectar un evento de este tipo, se apagara automáticamente y enviara una alerta visual tanto en la aplicación como en el visualizador LCD para advertirle que hubo un movimiento brusco sobre la biochimenea.
o Verifique que la flama no se haya salido de la biochimenea y si es el caso, recurra a utilizar un extintor para controlar la propagación del fuego.
Por precaución el sistema impide que se recargue el tanque de combustible o encienda la llama justo después de que se apague la biochimenea o luego de haber funcionado durante varias horas. Mediante una alerta visual en la pantalla LCD y en el aplicativo Android se alerta sobre este evento. Por lo que debe esperar unos minutos a que desaparezca la alerta mientras se enfría la biochimenea para así volver a recargar el biocombustible y/o encender la llama.
CARGA DE LA BATERIA
Cuando la aplicación muestre que la barra de progreso que indica carga de bateria es de color rojo, se recomienda conectar el cargador de corriente en la terminal ubicada en la parte superior de la biochimenea .
Ademas el visualizador LCD también muestra el nivel de carga de las baterías.
Recomendaciones
La biochimenea esta conformada por un tanque de combustible interno que suministra combustible a una recamara de combustión en acero inoxidable en la parte superior de la misma, que garantiza la seguridad de la llama protegiéndolo a usted y a las personas o animales que se encuentran cerca.
Recuerde limpiarlo con un paño húmedo para remover impurezas.
Por ningún motivo ignore la advertencias o alertas que se muestran, tampoco trate de recargar el tanque de combustible si se encuentra encendido o muy caliente, espere hasta que este apagada y no haya ninguna advertencia.
La biochimenea sólo se debe utilizar con Bioetanol. El Bioetanol sólo se debe utilizar dentro del quemador. Tenga en cuenta que el quemador no se debe utilizar sin su respectiva supervisión.
Adecuado intercabio de oxigeno
Una llama consume oxígeno para su combustión, el oxígeno que se consume debe ser reemplazado con el fin de mantener el ambiente saludable para respirar, este normalmente se sustituye automáticamente si existen ventanas o puertas abiertas que permitan la circulación del aire. Recuerde tener en cuenta que del tamaño del espacio depende la cantidad de aire a intercambiar, tenga presente la siguiente tabla
Recommended