CONTROL REMOTO DE UNA BIOCHIMENEA POR MEDIO DE...

146
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

Transcript of CONTROL REMOTO DE UNA BIOCHIMENEA POR MEDIO DE...

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; // Declaraci󮠤e 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() { // Interrupci󮠤ecepci󮠤erie 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 Interrupci󮠤e 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 se󮠤PWM 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

79

Figura 42: Biochimenea semi-ensamblada

Figura 43: Biochimenea completamente ensamblada

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

96

13. ANEXOS

13.1. Circuito electrico

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

Manual de

operación

Biochimenea electrónica

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