Informe - Escuela de Ingeniería Eléctrica

Anuncio
Universidad de Costa Rica
Facultad de Ingenierı́a
Escuela de Ingenierı́a Eléctrica
Diseño de un sistema de control de acceso
del laboratorio Licit, utilizando hardware
Wi-Fi
Por:
Joel G. Chaves Elizondo
Ciudad Universitaria “Rodrigo Facio”, Costa Rica
16 de diciembre de 2014
Diseño de un sistema de control de acceso
del laboratorio Licit, utilizando hardware
Wi-Fi
Por:
Joel G. Chaves Elizondo
IE-0499 Proyecto eléctrico
Aprobado por el Tribunal:
Ing. Gustavo Nuñez Segura
Profesor guı́a
Ing. Marco Villalta Fallas
Profesor lector
Ing. Julián Gutiérrez Monge
Profesor lector
Resumen
Este trabajo consiste en el diseño e implementación de un sistema de control
de acceso encargado de controlar el acceso en el laboratorio Licit, mediante el
uso de una comunicación Wifi. El sistema fue diseñado para que fuese simple,
económico y fácil de usar. El diseño se desarrolló en etapas para cumplir con
los requerimientos propuestos. Estás etapas son fundamentales en el correcto
funcionamiento del sistema, la etapa de ingreso de datos, de comunicación por
Wifi y la etapa de acople para controlar el sistema. Se usó un microcontrolador,
Spark Core, para manejar el sistema ya que provee un procesador ARM y un
módulo de conexión Wifi.
v
Índice general
Índice de figuras
ix
Índice de cuadros
x
1 Introducción
1.1 Alcance del proyecto . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3 Metodologı́a . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
2
3
4
2 Marco Teórico
2.1 Microcontrolador - Spark Core . . . . . . .
2.2 Control de Acceso . . . . . . . . . . . . . .
2.3 Wifi . . . . . . . . . . . . . . . . . . . . . .
2.4 TCP, Protocolo de Control de Transmisión
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
8
12
13
3 Desarrollo
3.1 Conectando el Spark Core . . . . . . . . . . . . .
3.2 Diseño del control de acceso . . . . . . . . . . . .
3.3 Diseño del teclado numérico. . . . . . . . . . . .
3.4 Diseño de Pantalla LCD . . . . . . . . . . . . . .
3.5 Diseño del Botón para el interior del laboratorio
3.6 Diseño del Relé . . . . . . . . . . . . . . . . . . .
3.7 Programación . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
15
15
18
20
23
27
28
30
4 Pruebas
.
.
.
.
.
.
.
.
35
5 Conclusiones y Recomendaciones
37
5.1 Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.2 Recomendaciones . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Bibliografı́a
39
A Acrónimos
41
B Materiales
43
C Código
45
vii
D Librerı́a liquid-crystal-spi
53
viii
Índice de figuras
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
STM32F103CB - ARM 32-bit Cortex M3.[Spark, 2014] . . . .
TI’s CC3000 module for the WiFi.[Spark, 2014] . . . . . . . . .
Microchip MCP1825S-3302E. [Spark, 2014] . . . . . . . . . . .
Identificación de entradas y salidas del regulador. [Spark, 2014]
Diagrama de entradas y salidas[Spark, 2014]. . . . . . . . . . .
Lectora de huellas dactilares.[Frax, 2013] . . . . . . . . . . . . .
Lectora de tarjetas. [dointech, 2013] . . . . . . . . . . . . . . .
Teclado Numérico. Kaba [2014] . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
5
6
6
7
7
10
11
11
3.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
Aplicación Android del Spark Core, pantalla inicial . . . . . . . . .
Aplicación Android del Spark Core, información de red Wifi . . . .
Aplicación Android del Spark Core, bienvenida . . . . . . . . . . .
Aplicación CuteCom, configurada . . . . . . . . . . . . . . . . . . .
Diagrama general del control de acceso . . . . . . . . . . . . . . . .
Teclado numérico usado en el proyecto. Ebay [2013] . . . . . . . .
Circuito comprobado en TINA . . . . . . . . . . . . . . . . . . . .
Funcionamiento de registro de desplazamiento 74HC595. [Dave Auld,
2011] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tomado del Datasheet del LCD GDM1602K, usado en el proyecto.
Configuración de pantalla LCD controlado en 3 pines por el Spark
Core. [technobly, 2013] . . . . . . . . . . . . . . . . . . . . . . . . .
Configuración de Botón de Emergencia . . . . . . . . . . . . . . . .
SAXXON ZKYM350M, un cerrojo magnético usado. [TVC, 2013] .
Diseño del funcionamiento planteado del relé . . . . . . . . . . . .
Diagrama de bloques general . . . . . . . . . . . . . . . . . . . . .
Diagrama de bloques, etapa inicial . . . . . . . . . . . . . . . . . .
Diagrama de bloques general, recepción de datos . . . . . . . . . .
Diagrama de bloques general, envio de datos . . . . . . . . . . . .
Diagrama de bloques general, respuesta del servidor . . . . . . . .
16
16
17
18
19
20
21
3.9
3.10
3.11
3.12
3.13
3.14
3.15
3.16
3.17
3.18
ix
.
.
.
.
.
.
.
.
23
24
26
27
28
29
30
31
32
33
34
Índice de cuadros
3.1
3.2
Resumen de información obtenida del circuito y del Spark Core . .
Lista de salidas de Interfaz de Control de LCD . . . . . . . . . . .
22
25
B.1 Lista de Materiales Usados en el Proyecto . . . . . . . . . . . . . .
43
x
1
Introducción
La automatización se ha desarrollado durante mucho tiempo, ya que se desea
realizar las diferentes clases de tareas a las que nos enfrentamos a diario de
la forma más rápida y sencilla posible. El automatizar se define como la conversión de una accion corporal en una accion automática; ahora, a partir de
esta definición se justifica el proyecto que se desarrollará, ya que se utilizará
el microcontrolador Spark Core, porque este presenta caracterı́sticas como el
procesador ARM Cortex, compatibilidad con Arduino, un módulo integrado
para conexión Wi-Fi, y un bajo consumo energético. Este microcontrolador,
es una nueva propuesta en el mercado, ya que nació en el año 2013 por medio
de una propuesta en la página https://www.kickstarter.com, por lo que no
es conocido. Con estas, que son sus principales caracterı́sticas, se ajustó para
llevar a cabo un proyecto de domótica, donde toda la conexión del sistema se
puede llevar a cabo inalámbricamente. Este proyecto nace con el fin de administrar, de una forma inteligente y eficiente, la entrada y salida de usuarios del
Laboratorio de Investigación de Circuitos Integrados (LICIT) en el Edificio de
Ingenierı́a Eléctrica de la Universidad de Costa Rica, usando el Spark Core y
este al conectarse por medio del Wi-Fi a un servidor en la red local, verificará
la autenticidad y permitirá el ingreso.
1
2
1.1
1 Introducción
Alcance del proyecto
Este proyecto tiene como fin lograr un acceso de control al Laboratorio de
Investigación de Circuitos Integrados (LICIT) utilizando el Spark Core, el
cierre electro-magnético, un teclado numérico, pantalla LCD, diseñado de tal
forma que el ingreso al laboratorio sea seguro y rápido. Para su implementación
el sistema se programó y se diseñó de la forma más óptima posible. Con el fin
de implementarlo en el laboratorio LICIT, y más adelante, si es posible, sea
replicado en otros laboratorios y aulas.
El micro controlador debe registrar el ingreso de un código por medio de un
teclado numérico, este código se verificará por medio de Wi-Fi, por lo tanto los
datos se envı́an, después deberá recibir una confirmación del acceso, con esta
confirmación el sistema deberá accionar un actuador instalado en la puerta.
1.2. Objetivos
1.2
3
Objetivos
Objetivo general
Diseñar un sistema de control de acceso mediante una autentificación remota
y comunicación Wi-Fi para el laboratorio LICIT que se ubica en el edificio de
Ingenierı́a Eléctrica de la Universidad de Costa Rica.
Objetivos especı́ficos
• Programar un micro controlador con conexión Wi-Fi, para enviar y recibir información de un servidor de la red local.
• Diseñar un sistema de ingreso de datos al micro controlador desde la
interfaz usuario.
• Diseñar un sistema electro-magnético que permita el acople entre un
micro controlador y una cerradura electro-magnética en el acceso del
laboratorio.
4
1 Introducción
1.3
Metodologı́a
El desarrollo del trabajo incluyó los siguientes pasos y procedimientos, listados
en secuencia:
1. Obtención del equipo necesario, como Spark Core, teclado numérico y
pantalla LCD.
2. Investigación sobre los temas a tratar, como control de acceso, servidores,
comunicación Wifi, y microcontroladores.
3. Diseño del prototipo funcional para controlar el cierre electro-magnético.
4. Programación del microcontrolador y puesta en marcha de un servidor
en la red local de internet, para realizar pruebas de comunicación.
5. Realización de pruebas en el sitio con la infrestructura de red, conectando
el sistema al servidor destinado para el proyecto.
2
Marco Teórico
2.1
Microcontrolador - Spark Core
El microcontrolador es un sistema computacional que se compone de una unidad de procesamiento central (CPU), memoria, y periféricos de entrada y
salida. El Spark Core es un microcontrolador que fue diseñado para ser compatible con las librerı́as y los desarrollos que se han efectuado en la plataforma
Arduino. El Spark Core cuenta con un procesador ARM Cortex M3, arquitectura de 32 bits, trabajando a una frecuencia máxima de 72 MHz, cuenta con
128KB de memoria Flash interna, 20KB de memoria RAM y 2MB de memoria
flash externa. Spark [2014]
Figura 2.1: STM32F103CB - ARM 32-bit Cortex M3.[Spark, 2014]
El Micro controlador cuenta con conexión inalámbrica, mediante un chip
CC3000 SimpleLink de Texas Instruments, con un rango que va de 30 metros hasta 90 metros efectivos. El chip CC3000 trabaja con los sistemas de
seguridad inalámbrica WEP, WPA Personal y WPA2 Personal.
Trae instalado un regulador de tensión eléctrica, por lo que se puede alimentar por una fuente de tensión entre 3,6 V a 6.0 V DC. Al tener instalado el
puerto Micro USB 2.0, cuenta con la opción de ser programado y alimentado
por este medio.
5
6
2 Marco Teórico
Figura 2.2: TI’s CC3000 module for the WiFi.[Spark, 2014]
Figura 2.3: Microchip MCP1825S-3302E. [Spark, 2014]
Posee 16 pines que funcionan como entradas y salidas, todo dependerá
de la programación que se cargue en el microcontrolador, 8 son analógicas
y 8 digitales, entre estos pines hay 8 pines con la funcionalidad de generar
un “PWM”(“Pulse Width Modulation”, en español, modulación por ancho de
pulsos) que son 6 pines analógicos A0, A1, A4, A5, A6 A7 y dos pines digitales,
D0 y D1. Todos los pines trabajan a 3,3 V DC, excepto los pines D0, D1, D3,
D4, D6 y D7 que pueden soportar entradas de hasta 5 V DC. El mı́nimo
y máximo de corriente que pueden manejar estos pines es de 8 mA y 20
mA, respectivamente. El microcontrolador posee dos formas de conectarse
2.1. Microcontrolador - Spark Core
7
Figura 2.4: Identificación de entradas y salidas del regulador. [Spark, 2014]
por medio del Serial (UART, Universal Asynchronous Receiver-Transmitter o
en español Transmisor-Receptor Ası́ncrono Universal), usando los pines TX y
RX, y la segunda es por medio del puerto USB.
Figura 2.5: Diagrama de entradas y salidas[Spark, 2014].
8
2 Marco Teórico
2.2
Control de Acceso
El control de acceso se puede definir como una autorización de acceso. Las
reglas de autorización las establecen los responsables de la seguridad del recinto. El objetivo de establecer las reglas para realizar un control de acceso,
es restringir la entrada y proveer un nivel de seguridad a los usuarios y encargados de un área restringida que contenga información o equipo que no pueda
ser accedido por cualquiera, y con esto prevenir entradas no autorizadas. De
lo anterior, los accesos se dan a partir de una categorización de los usuarios,
generando diferentes niveles de autorización, para que esta acción sea segura, se debe establecer una identificación y después una autentificación. Los
usuarios y encargados tienen la responsabilidad de mantener la seguridad e
integridad del control de acceso, entendiendo que deben velar por el correcto
uso y entendiendo los problemas que se generan si comprometen el sistema,
por lo que el sistema debe generar registros y los encargados deben realizar
constantes inspecciones a los mismos. James F. [2004] El control de acceso
cuenta con varios criterios, como:
1. Localización: ubicación del lugar donde se acceda.
2. Identificación: proceso donde se autentifica el acceso.
3. Tiempo: controlar los recursos limitando su uso.
4. Operación: como reaccionar ante malos usos y buenos usos.
5. Privilegios: definir los niveles de acceso que poseen los usuarios.
Usos del control de acceso:
1. Correctivo: solucionar acciones que han estado ocurriendo.
2. Investigación: averiguar que sucedió.
3. Disuadir: evitar que suceda algún acto.
4. Manejo: al indicar las polı́ticas, procedimientos, y responsabilidades de
uso para controlar el sistema.
5. Operacional: ajustar los procedimientos para proteger el sistema.
6. Técnico: automatizar el control y seguridad del sistema.
2.2. Control de Acceso
9
Modelos administrativos de control de acceso
Existen tres modelos para administrar los accesos de control, se encuentran el
centralizado, descentralizado y existe una versión hı́brida. El modelo de administración centralizado está basado en que solamente exista un encargado
de la tarea, o una sola oficina debe de encargarse del acceso de control. La
ventaja que proporciona este modelo administrativo, es que mejora y permite
un control más estricto y da una uniformidad en el acceso. Esto se da ya que
el acceso a realizar cambios o ajustes solo lo pueden realizar un pequeño grupo
de personas. Ası́ que si se necesita un cambio o ajuste, el encargado con acceso
realiza las modificaciones en el lugar donde se realiza los controles de acceso,
pero antes, el administrador del sistema deberá aprobar los cambios o ajustes
a realizar. Otra ventaja es que todas las cuentas pueden ser monitorizadas y
se puede restringir accesos a cuentas que estén incumpliendo alguna regla, o
que ya no deban ingresar. Un inconveniente del modelo administrativo centralizado es que los cambios o ajustes deben ser aprobados y coordinados por
el administrador y los encargados.
En el modelo de administración descentralizado, los accesos son controlados por un documento o archivo, esto permite el acceso solamente a los
responsables del control. Los encargados deben de ser los adecuados de administrar quien necesite el acceso, y que tipo de acceso necesita. La desventaja es
que puede existir una falta de coherencia entre los creadores de permisos y los
administradores, esto con respecto a los procedimientos y los criterios que se
utilizan para dar acceso, además de que no se pueden registrar y monitorizar
todos los accesos. El modelo de administración hı́brido combina aspectos de
ambos modelos en un mismo enfoque. Donde se centraliza la administración,
pero a la vez se reparte la administración a encargados de accesos básicos. La
principal desventaja de un enfoque hı́brido es la discusión sobre lo que debe y
no debe ser centralizado
Mecanismos de Control de Acceso
Durante los años, se han desarrollado sistemas que dan un control sobre los
accesos, y estos sistemas son internos y externos, lo cuál? puede hacer que
varı́en en términos de precisión, costo, y tecnologı́a. La elección de cuales sistemas se deben instalar en los accesos a controlar, varı́a dependiendo de lo que
el administrador requiera, tomando en cuenta el costo, beneficio y lo que se
necesita. Las contraseñas siempre están presentes en la autentificación, el uso
de las mismas puede reducir la seguridad debido a que se presten las contraseñas entre usuarios, pero el uso de contraseñas en los controles de acceso hace
que el sistema sea económico, ya que es un sistema muy simple. La seguridad
dependerá del uso que empleen los usuarios, ya que si las contraseñas son muy
10
2 Marco Teórico
extensas y complicadas, pueden tener problemas para recordarlas, entonces
deberán de escribirlas o las contraseñas serán muy simples. Las contraseñas
deben ser usadas individualmente, además deben de estar siendo renovadas
por decisión del usuario, o por algún sistema que obligue a cambiarlas. La
encriptación es otro mecanismo para mantener un control sobre accesos, al
encriptar alguna información, se debe desencriptar mediante una llave criptográfica. Este método aumenta la eficiencia de la seguridad del sistema. Las
listas de usuarios son otro mecanismo de control de acceso, ya que se le asignan
permisos a estos usuarios dependiendo del uso y nivel de administración que
van a tener. Además, se puede administrar de manera que se realicen grupos
o a nivel individual. James F. [2004]
Sistemas de control de acceso
Existen muchos sistemas para realizar un control de acceso, todo depende del
requerimiento y qué es lo mejor para solucionar la petición. Entre esos sistemas
tenemos:
1. Control Biométrico: utilizado por su alta eficiencia, ya que hacen un
análisis de atributos personales únicos en cada individuo, como lo son
las huellas dactilares, la retina, el iris y la geometrı́a de la mano. Ası́ que
la identificación es única por cada usuario, no es necesario memorizar
claves, además, no es necesario cargar con tarjetas o controles y por
tanto no es posible extraviarla.
Figura 2.6: Lectora de huellas dactilares.[Frax, 2013]
2. Tarjetas de control o proximidad: estas permiten tener toda la información de cada usuario en una base de datos. La mayor ventaja está en
el control de dar autorización a ciertas puertas o zonas, generando una
mayor seguridad y control sobre el acceso de las personas. Toda la transmisión de datos entre la tarjeta y el lector está encriptada utilizando un
algoritmo de seguridad. Al estar encriptada se reduce el riesgo de copiar
las tarjetas sin autorización. Al ser una tarjeta el costo es bajo al tener
2.2. Control de Acceso
11
que reemplazarla, y en caso de que se pierda el permiso de ingreso, se
desactiva en el sistema. Una desventaja frente al control biométrico, es
que la tarjeta puede ser robada y con esto generar un problema en la
seguridad.
Figura 2.7: Lectora de tarjetas. [dointech, 2013]
3. Teclados para digitación de códigos alfanuméricos: son los sistemas más
sencillos, más baratos, y realizan el mismo control de acceso que los
anteriores sistemas, ya que se debe registrar a cada usuario, cada usuario
deberá usar una única contraseña.
Figura 2.8: Teclado Numérico. Kaba [2014]
Estos terminales trabajan de una manera similar, ya que utilizan una base de
datos, propia o externa, que deben consultar para corroborar si se está autorizado o no para ingresar a cierta área, por lo que deben trabajar recopilando los
datos, enviándolos, y esperando una autorización para trabajar en conjunto a
un actuador, como una puerta con magneto.
12
2.3
2 Marco Teórico
Wifi
Es un sistema de conexión inalámbrica, que permite la comunicación de distintos tipos de dispositivos finales dentro de una red que utiliza un mismo
estándar, el IEEE 802.11. Los dispositivos al utilizar un estándar, como el
802.11, para comunicarse con otros dispositivos que utilicen el mismo estándar o nuevas versiones del mismo, como la 802.11 bgn, no se ven afectados
aunque sean dispositivos de otras marcas.
Al poseer la capacidad de comunicarse y conectarse entre ellos, pueden
acceder a redes de computadoras locales o a internet si es necesario. Uno de
los beneficios de permitir una conexión a una red local de computadoras, es
que se puede dar desde distintos puntos sin afectar la infraestructura, ya que
no se necesita llevar cables de red.
La seguridad de una conexión inalámbrica se da mediante el uso de protocolos de cifrado de datos, como el WEP, el WPA, el WPA2, el filtrado de
MAC, entre otros más comunes. IEEE [2013]
2.4. TCP, Protocolo de Control de Transmisión
2.4
13
TCP, Protocolo de Control de Transmisión
TCP por sus siglas en inglé, Transmission Control Protocols, y en español,
Protocolo de Control de Transmisión, se diseñó especı́ficamente para proporcionar un flujo de bytes en una red interna entre dos puntos. La diferencia entre
una red interna y una sola red es que diversas partes podrı́an tener diferentes
topologı́as, anchos de banda, retardos, tamaños de paquete y otros parámetros. TCP se diseñó para que se adapte de manera dinámica a las propiedades
de la interred y evitar fallas.
TCP funciona, primero ambos, el servidor y el cliente, crean sockets. Cada
socket tiene un número que es una dirección, que en si, es la dirección IP
del servidor, y un número de 16 bits, que es local a ese servidor, llamado
puerto. Para obtener el servicio TCP, se debe establecer de manera explı́cita
una conexión entre un socket en la máquina emisora y uno en la máquina
receptora.En el protocolo TCP, las conexiones siguen usando el acuerdo de tres
vı́as. Para establecer una conexión, el servidor está a la espera de una conexión
entrante, y se encuentra ejecutando las acciones de escuchar y aceptar alguna
conexión. Esta debe especificar cierto origen o bien nadie en particular. En
el otro lado el cliente realiza la acción: conectarse, pero debe especificar la
dirección IP y el puerto con el que se debe de conectar, el tamaño máximo de
segmento bytes que está dispuesto a aceptar y opcionalmente algunos datos
de usuario. El cliente al realizar una conexión, se lleva a cabo un proceso
de sincronización y confirmación con el servidor, donde el servidor verifica
si existe algún proceso que estuviera esperando la conexión entrante, con la
dirección IP y el puerto indicado, si no existe el proceso: se envı́a una respuesta
indicando que se rechaza la solicitud. John, Tanenbaum [2004]
3
Desarrollo
3.1
Conectando el Spark Core
Para iniciar a trabajar con el Spark Core, se debe conectar a una red Wifi, la
conexion se puede realizar de dos métodos para conectarlo a una red Wifi, la
primera es usando la aplicación para teléfono inteligente (“Smartphone”) que
use alguno de los siguientes sistemas operativos, Android, versión superior a
4, o IOS para teléfonos Iphone, y la otra forma es por medio de una conexión
por USB.
Para empezar, el Spark Core debe estar alimentado y estar en el modo de
escucha (“LISTENING MODE ”). Una vez alimentado, se debe tocar el botón
“MODE ”por tres segundos, el led multicolor (“RGB LED”) instalado en el
Spark Core, cambia de color a un azul intermitente. Para borrar todas las
contraseñas y conexiones Wifi previas, el botón debe ser sostenido por diez
segundos, en ese momento el led tendrá el color azul intermitente, pero de
forma más rápida, por un momento muy pequeño. Una vez en este modo, el
Spark Core está a la espera de que se le indique la información necesaria para
conectarse a la red Wifi.
Conexión mediante aplicación móvil
El teléfono debe estar en la misma red WIFI, ası́ que una vez instalada la
aplicación es necesario crear una cuenta con contraseña, con esta cuenta se
registrará el Spark Core en caso de ser la primera vez que se conecta.
A continuación la aplicación automáticamente llena el nombre de la red,
por lo que es necesario ingresar la contraseña si es que existe. La anterior
configuración se llevará un corto periodo, menos de un minuto. La secuencia
de colores del led, si la información es correcta y la red está funcionando, es
la siguiente:
1. Azul Intermitente, esperando información de red Wifi.
2. Azul fijo, información obtenida y almacenada.
3. Verde Intermitente, conectando a la red Wifi.
4. Celeste Intermitente, conectando al sistema “Spark Cloud”.
5. Celeste Intermitente muy lento, confirma que está conectado al sistema.
15
16
3 Desarrollo
Figura 3.1: Aplicación Android del Spark Core, pantalla inicial
Figura 3.2: Aplicación Android del Spark Core, información de red Wifi
Después de que el Spark Core este en la última etapa, la aplicación lo agrega a
la lista de dispositivos de la cuenta creada, además se debe de dar un nombre
al dispositivo. Al terminar la configuración, la aplicación presenta una pantalla
de bienvenida con información básica.
3.1. Conectando el Spark Core
17
Figura 3.3: Aplicación Android del Spark Core, bienvenida
Conexión por medio de USB
Debe estar en modo de escucha, instalar una aplicación para comunicación
por medio del Serial USB, como ejemplo se utilizó la aplicación CuteCom en
Ubuntu, pero existen otros programas para los diferentes sistemas operativos,
lo que si es necesario es la siguiente configuración:
1. Baud Rate: 9600
2. Data Bits: 8
3. Parity: None
4. Stop Bits: 1
Una vez conectado el cable USB a la computadora y el programa configurado, se ingresan los comandos “w”, seguido de un espacio, el nombre de la
red Wifi, otro espacio, y la contraseña en caso de que la red tenga una.
Si el Spark Core está siendo usado por primera vez y la conexión es por
medio de la conexión USB, debe ser registrado por otro medio, ya que usando la
aplicación móvil lo hace automáticamente. Se debe instalar la interfaz de lı́nea
de comando de Spark, “spark-cli”, (en inglés “Spark Command Line Interface”),
en el siguiente enlace se encuentra una guı́a bastante completa para realizar la
instalación, https://github.com/spark/spark-cli . Después de instalado
se usa la siguiente instrucción, “spark setup”, y se siguen las instrucciones.
18
3 Desarrollo
Figura 3.4: Aplicación CuteCom, configurada
Al terminar de registrar el Spark Core podemos ingresar al IDE Web,
https://www.spark.io/build/ que proporciona la empresa para poder trabajar. En ella se puede programar, compilar, y buscar librerı́as para desarrollar
proyectos propios.
3.2
Diseño del control de acceso
El sistema se diseñó para ser una terminal que controle un actuador y con ello
mantener un control más estricto; además, se diseñó cumpliendo una serie de
caracterı́sticas, que se aclaran a continuación.
1. Definir un protocolo de comunicación por medio de una conexión de red
inalámbrica.
2. Conectar se con un servidor dedicado y verificar la validez de la solicitud
verificando la dirección MAC, que se encargue de atender sus solicitudes.
3. Establecida una conexión con el servidor, entra en un ciclo de trabajo a
la espera de entradas, el ingreso de información, un numero de usuario,
definido como la cédula de identificación, y una contraseña, definido
como cuatro dı́gitos.
4. Enviar la información al servidor para comprobar, y recibir una autorización.
3.2. Diseño del control de acceso
19
5. Autentificación del servidor, en esta etapa el servidor nos informa si se
está o no autorizado
6. Operar, dependiendo de la información del servidor, abro el cierre magnético, o se ı́ndica en pantalla la solicitud fue rechazada.
La terminal posee una serie de entradas y salidas para cumplir con requerimientos solicitados en el diseño. El microcontrolador Spark Core se encarga de
procesar la información y conectarse a la red local. Para ingresar información
al microcontrolador se instaló un teclado numérico estilo telefónico, además
un botón de emergencia para abrir la puerta.
Figura 3.5: Diagrama general del control de acceso
20
3.3
3 Desarrollo
Diseño del teclado numérico.
El funcionamiento del teclado numérico usado en el proyecto, es de tipo telefónico, ya que inicia la numeración en la parte superior. Eléctricamente se
representa como una matriz de botones, tres columnas y cuatro filas. Existen
dos formas de leer el botón presionado, digital o analógicamente. Digitalmente, se deben conectar las siete terminales del teclado numérico a siete pines
del Spark Core, pero al no contar con una gran cantidad de pines, se decidió
realizar una implementación analógica, de forma que solo se necesite un pin.
Figura 3.6: Teclado numérico usado en el proyecto. Ebay [2013]
Se utilizó un sistema para leer el teclado desde un solo pin, esto se da con
un divisor de tensión, mediante mediciones de tensión eléctrico para obtener
una lectura analógica y ası́ se identificara cada tecla individualmente 1 .
1
http://www.instructables.com/id/Arduino-3-wire-Matrix-Keypad/step2/Wiring-upthe-resistors/
3.3. Diseño del teclado numérico.
El sistema se comprobó en TINA:
Figura 3.7: Circuito comprobado en TINA
21
22
3 Desarrollo
En la tabla 3.1, tenemos el valor real, valor esperado del diseño y simulación, y el valor que lee el Spark Core y que lo escala, de 0 a 4096 valores.
Se utilizó la alimentación del microcontrolador, obtenido desde el pin 3V3, ya
que existen varios pines que no soportan valores mayores al 3,3 V DC.
Por ejemplo, para la tecla del número 1, la tensión leı́da teóricamente debe
de ser,
V3v3 − 180Ω ∗ i − 1kΩ ∗ i − 820Ω ∗ i − 1kΩ ∗ i = 0
(3.1)
V3v3 = (180Ω + 1kΩ + 820Ω + 1kΩ) ∗ i
(3.2)
V3v3 /(3kΩ) = i
(3.3)
V1 = 3, 3V /3000Ω ∗ 2820Ω = 3, 102V
(3.4)
La tensión eléctrica teórica que lee el Spark Core, es de 3,102 V, y como
se observa en la ?? el valor real medido es de 3,01 V, valor un poco inferior.
Tecla
Valor de tensión teórico (V)
1
2
3
4
5
6
7
8
9
0
*
#
3.1
3
2.8
2.53
2.44
1.77
1.333
1
0.6396
0.803
1.1
0.496
Valor de tensión eléctrica
real/medido (V)
3.01
2.89
2.75
2.49
2.32
1.7
1.281
0.971
0.611
0.798
1.06
0.474
Valor leı́do por el Spark Core
3802
3648
3333
3108
2744
2153
1640
1245
800
1003
1356
628
Cuadro 3.1: Resumen de información obtenida del circuito y del Spark Core
3.4. Diseño de Pantalla LCD
3.4
23
Diseño de Pantalla LCD
Como se diseña con el requisito de usar la menor cantidad de pines, la pantalla LCD que se usó también debe de cumplir este requerimiento, ya que la
instalación tı́pica de este tipo de pantallas necesita siete pines entre entradas,
salidas y alimentación. Por lo tanto se buscó una opción que cumpla con este
requerimiento, ası́ que en las librerı́as existentes y soportadas para Spark Core, existe una implementación ya verificada. Esta implementación utiliza un
circuito integrado 74HC595, que se define como un registro de desplazamiento
de 8 bits, con entrada serie, salida serie o paralelo con latch de 3 estados.
Ası́ que con esa definición se puede usar para controlar 8 salidas simultáneas
usando unos pocos pines del microcontrolador, en este caso usando solamente
3 pines. Entonces para su funcionamiento como registro de desplazamiento se
necesitan al menos los 3 pines para una comunicación serial, que son:
1. Datos (DS).
2. Clock (SH CP).
3. Almacenamiento (ST ST).
Figura 3.8: Funcionamiento de registro de desplazamiento 74HC595. [Dave
Auld, 2011]
En la imagen 3.8, podemos observar un poco mejor cómo funciona el
74HC595, por la entrada de datos (DS) se ingresan los datos de forma serial, mediante el reloj (SH CP) los datos se empiezan a mover por los distintos
pines, de una manera interna, en el momento que el pin de almacenamiento,
(ST CP), se activa los pines usados van a reflejar los valores. Por lo que pasamos de una entrada serial a una salida en paralelo. La pantalla LCD que
se usa, cuenta con el controlador Hitachi HD44780 LCD, diseñado especialmente para desplegar caracteres alfanuméricos, que de una manera sencilla se
24
3 Desarrollo
puede acoplar a cualquier micro controlador. El controlador está diseñado e
implementado para facilitar el uso de la pantalla LCD.
Figura 3.9: Tomado del Datasheet del LCD GDM1602K, usado en el proyecto.
La pantalla LCD para uso de microcontroladores, está diseñada para utilizar una interfaz paralela, lo que significa que el microcontrolador debe manipular varios pines de interfaz a la vez para controlar lo que se visualiza en
ella.
La interfaz consta de los pines que están agrupados en la tabla 3.2.
El selector de registro (RS) controla en que parte en la memoria del LCD
se está escribiendo los datos. Este pin puede seleccionar entre dos registros, el
registro de datos o el registro de instrucciones. El registro de datos es donde
se contiene lo que se escribe en la pantalla, mientras que el registro de instrucciones, es donde el controlador de la pantalla LCD consulta para obtener
instrucciones sobre qué hacer a continuación. Los pines del 7 al 14 son de datos
(D0 -D7). Los datos escritos en estos pines (altas o bajas) son los bits que se
están escribiendo a un registro. Para controlar la pantalla LCD, se debe seguir
un proceso de control de la pantalla que consiste a través de los pines D0 al
D7, en colocar los datos que forman la imagen de lo que se desea mostrar en
el registro de datos, y después, poniendo las instrucciones a usar en el registro de instrucciones. Se han desarrollado librerı́as de funciones y definiciones,
además de código para utilizar dispositivos como la pantalla LCD, por lo que
se usan las librerı́as LiquidCrystal y LiquidCrystalSPI, que es una variante
3.4. Diseño de Pantalla LCD
PIN
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SIMBOLO
GND
VCC
VO
RS
R/W
CLK
BIT 0
BIT 1
BIT 2
BIT 3
BIT 4
BIT 5
BIT 6
BIT 7
LED +
LED -
25
DESCRIPCION
Tierra
Fuente de Alimentación eléctrica
Ajuste de contraste
Selector de,registro
Lectura o Escritura
Reloj
Datos 0 - D0
Datos 1 - D1
Datos 2 - D2
Datos 3 - D3
Datos 4 - D4
Datos 5 - D5
Datos 6 - D6
Datos 7 - D7
Luz de Fondo, positivo +
Luz de Fondo, negativo -
Cuadro 3.2: Lista de salidas de Interfaz de Control de LCD
de la primera, ya que simplifican el uso de funciones y no necesita saber las
instrucciones a bajo nivel. La pantalla LCD, al tener instalado el controlador
Hitachi para LCD, obtiene la facilidad para que se pueda controlar en dos
modos, uno en 4 bits y otro en 8 bits. La facilidad recae en que el modo de 4
bits requiere siete pines del microcontrolador entre entradas, salidas, tierra y
alimentación, mientras que en el modo de 8 bits se requieren 11 pines. Ahora,
la implementación de la pantalla LCD con su controlador, además de usar el
circuito integrado 74HC595 como registro de desplazamiento, logra disminuir
la cantidad de pines, pasando de los siete pines a los tres.
En la anterior implementación, podemos observar que usando los pines del
Spark Core D2, D3 y D4, se puede imprimir cualquier mensaje en la pantalla.
La configuración es la siguiente: Los pines del Spark Core al 74HC595,
1. D4 al pin 14 (DS).
2. D3 al pin 11 (SH CP).
3. D2 al pin 12 (ST ST).
Los pines del 74HC595 a la pantalla LCD
1. Pin 1 (Q1) al pin 4 (RS).
26
3 Desarrollo
Figura 3.10: Configuración de pantalla LCD controlado en 3 pines por el Spark
Core. [technobly, 2013]
2. Pin 2 (Q2) al pin 6 (CLK).
3. Pin 3 (Q3) al pin 14 (D7).
4. Pin 4 (Q4) al pin 13 (D6).
5. Pin 5 (Q5) al pin 12 (D5).
6. Pin 6 (Q6) al pin 11 (D4).
En el código, para poder usar la pantalla, debemos agregar la librerı́a
incluyéndola en el código, además, tenemos que definir un tipo LiquidCrystal,
y definir en cuales pines está conectado el registro de desplazamiento 74HC595.
Al configurar los pines y dispositivos del microcontrolador en el programa
debemos inicializar la pantalla, llamando la función “lcd.initSPI()”, ya que está
función indica que se va a trabajar con el estándar de comunicación “SPI”(en
inglés, “Serial Peripheral Interface”) y la librerı́a con esto trabajar en conjunto
con el registro de desplazamiento.
3.5. Diseño del Botón para el interior del laboratorio
3.5
27
Diseño del Botón para el interior del
laboratorio
El diseño de esta etapa del proyecto es necesario para ofrecer una salida a las
personas que ya pasaron previamente por el control de acceso. El botón se
diseña como una interrupción al procesador del microcontrolador, ya que la
interrupción se debe dar en cualquier momento y circunstancia, para ası́ asegurar que en cualquier eventualidad la puerta abrirá sin importar la situación.
Figura 3.11: Configuración de Botón de Emergencia
El circuito de la imagen 3.11 se diseñó para realizar la función de botonera,
cuenta con un botón tipo normalmente abierto, por lo que el pin A7, que está
configurado como entrada en el código del micro controlador, está recibiendo
una cantidad muy pequeña de corriente, ası́ que el pin se encuentra un estado
en alto o un uno lógico. Al cerrar el botón el pin A7 estará conectado directamente a la tierra (GND) por lo que el micro controlador lee un cambio, ya que
el estado pasa de alto a bajo. Se utiliza una resistencia de 10k Ohm para que
no exista un corto circuito al tocar el interruptor. A nivel de código, se utiliza
la función “attachInterrupt()”, esta función se encarga de activar una sub rutina o función cuando ocurre una interrupción externa, en el Spark Core, las
interrupciones se pueden configurar en los pines D0, D1, D2, D3, D4 A0, A1,
A3, A4, A5, A6, y A7. La función “attachInterrupt()recibe tres parámetros,
el primero es el pin donde lee la interrupción, el segundo debe ser la función
que debe ejecutarse, la misma no puede recibir ningún parámetro ni devolver
ningún dato. El tercer parámetro es llamado “Modo”, e indica cuando debe
ser activada la interrupción, donde existen tres modos, el primero es si el pin
cambio de valor sin importar cual, el segundo es solamente cuando pasa de
alto a bajo y el tercero es cuando pasa de bajo a alto.
28
3.6
3 Desarrollo
Diseño del Relé
Usando la información comercial de un cerrojo magnético, se diseñó esta etapa
para que pueda adaptarse a este tipo de cierres que se usan en puertas controladas. Los cerrojos magnéticos son comúnmente controlados por relés, usando
la información del SAXXON ZKYM350M, un cerrojo magnético usado para
control de acceso, se puede simular su funcionamiento para que posteriormente
se use junto al control de acceso que se diseñó.
Figura 3.12: SAXXON ZKYM350M, un cerrojo magnético usado. [TVC, 2013]
En esta etapa lo que se realizó fue verificar el funcionamiento de un relé,
JZC–11F–05VDC–1Z (En la figura 3.13 está representado como RL1), al que
se le conectaron dos LEDS, uno en la salida NC (En inglés “Normally Closed”,
en español, Normalmente Cerrada) y otro en la NO (En inglés “Normally
Open”, en español, Normalmente Abierta) ambos conectados directamente a
tierra, y en el pin COM (En inglés “Common”) conectado a una resistencia de
330 Ohms y la fuente de alimentación. Para activar y desactivar la bobina del
relé, se usa un transistor 2N2222 para utilizarlo como interruptor controlado
por el pin A1, junto a una resistencia de 330 Ohm, que se configura como salida
en la programación del Spark Core. Para adaptarse a un cerrojo magnético,
solamente se debe conectar los pines NC o NO según lo solicite el cerrojo a
usar.
3.6. Diseño del Relé
Figura 3.13: Diseño del funcionamiento planteado del relé
29
30
3 Desarrollo
3.7
Programación
El desarrollo del proyecto se realizo haciendo el diseño fı́sico de una etapa
de la mano de su correspondiente etapa de programación y configuración.
La programación del Spark Core es en base de “Wiring”, que es una forma
de programación de código abierto para microcontroladores. “Wiring”permite
escribir software multiplataforma para controlar los dispositivos conectados a
una amplia gama de placas. Cuando escribimos el código se debe respetar tres
partes básicas en la estructura del programa, como:
• declaración de variables
• setup()
• loop()
La función setup() es la parte donde se inicializa y se realiza la configuración
de los diferentes elementos del sistema, como por ejemplo, la inicialización de
la pantalla LCD, los pines a usar para manejar los leds, el relé y el teclado
numérico. La void setup() sólo se ejecuta en el inicio y no se vuelve a ejecutar.
La función loop() se lleva a cabo en el segundo paso, aquı́ es donde el ciclo
del programa se ejecuta. Por el nombre, sabemos que es un ciclo que estará
trabajando hasta que sea apagado, o se de una interrupción.
El programa está diseñado para que al inicio todas las variables necesarias
sean declaradas e inicializadas, inmediatamente se ingresa a la función setup()
donde se realiza las configuración inicial y después se ejecuta el ciclo de trabajo,
loop(), donde se pueden identificar cuatro etapas, el inicio, ingreso de datos,
envı́o y recepción de datos y por último ejecutar.
Figura 3.14: Diagrama de bloques general
3.7. Programación
31
Inicio
En pantalla se muestra un mensaje de bienvenida y además de las instrucciones
a seguir. El flujo del programa está diseñado para que esté esperando hasta
que el usuario siga las instrucciones, en este caso que deje oprimido la tecla
asterisco (*) hasta que cambie la información en pantalla. En cada ciclo, al
iniciar se verifica que la puerta esté cerrada.
Figura 3.15: Diagrama de bloques, etapa inicial
32
3 Desarrollo
Ingreso de datos
A continuación el programa le indica que debe ingresar el usuario, se solicita
el número de la identificación (número de cédula), deben ser nueve dı́gitos, al
terminar de ingresar la identificación se espera la confirmación del usuario o
se puede borrar para que se corrija algún error. Si se borra, debe empezar de
nuevo. Al terminar de ingresar el usuario y confirmarlo se pasa a ingresar la
contraseña, son cuatro dı́gitos. La identificación y la contraseña están separadas por un punto y coma, para que cuando sea enviada al servidor se pueda
revisar autentificar.
Figura 3.16: Diagrama de bloques general, recepción de datos
3.7. Programación
33
Envı́o de datos
La siguiente etapa se encarga de enviar los datos al servidor, primero se verifica
si el sistema está conectado. Si está conectado se envı́an los datos al servidor
y se avanza a la siguiente etapa. Si se pierde la conexión o no se conectó al
servidor, se verifica si es el usuario es el super usuario si lo es se abre la puerta,
si no queda cerrada y se inicia el ciclo de trabajo. Este usuario es en caso de
emergencia, o para realizar algún tipo de mantenimiento.
Figura 3.17: Diagrama de bloques general, envio de datos
34
3 Desarrollo
Respuesta del servidor
La etapa final del ciclo de trabajo, si el servidor responde afirmativamente,
el micro controlador abre la puerta y deja pasar al usuario. Si la respuesta
es negativa simplemente no se abre y se regresa al inicio del ciclo a la espera
de un nuevo usuario. Puede existir la posibilidad de que el micro controlador
pierda la conexión, el programa verificará si es el super usuario, si no volverá
al inicio.
Figura 3.18: Diagrama de bloques general, respuesta del servidor
4
Pruebas
Durante el proyecto se realizaron distintos tipos de pruebas, verificando varios
tipos de usos al sistema y condiciones que se podrı́an dar durante su funcionamiento.
Prueba de Ingreso de datos
• El sistema recibe datos desde el teclado, en distintas etapas del funcionamiento.
1. Al inicio, si no se oprime la tecla asterisco (*) no continua, no sucede
ningún mal funcionamiento si se oprime otra tecla.
2. Durante el funcionamiento del sistema, mientras no se solicite ingreso de datos y si se oprime alguna tecla no incurrira en ningún
mal funcionamiento o error.
Prueba de Conexión
• El sistema se conecto en distintas redes para probar conectividad y funcionalidad.
1. Las primeras pruebas se realizaron usando el programa Netcat, una
computadora portátil Lenovo G580 y una red local con un Router
D-Link Dir-600. Esta prueba se hizo conectando el sistema a la
computadora y mediante Netcat para ası́ leer todo lo enviado por
el sistema al socket e IP de la computadora. Todo lo enviado se
observo en la consola donde estaba corriendo Netcat. Además se uso
para enviar información al sistema, donde reaccionó como estaba
programado, si se le enviaba una afirmación abrı́a la puerta, si
se le enviaba un negación indicaba en la pantalla que habı́a sido
rechazado, si se le enviaba otra información la ignoraba e indicaba
que existio un error en la comunicación.
2. Las siguientes pruebas se realizaron en la escuela de Ingenierı́a Eléctrica de la Universidad de Costa Rica, usando la infraestructura de
red que está instalado en el edificio. Está vez se comunicó el sistema con una otra computadora portátil, que tenı́a corriendo un
servidor y el programa que se usó para el funcionamiento final del
35
36
4 Pruebas
sistema. Las pruebas obtuvieron resultados positivos, a pesar de
que al principio no se logró establecer una conexión entre ambos.
3. Las últimas pruebas se realizaron con el servidor final, e igual que
en la prueba anterior, se realizó en el laboratorio Licit usando la
infraestructura del edificio. La comunicación se dı́o sin ningún problema. Ya que se hicieron las pruebas previas al montar la prueba
final está se llevo a cabo sin mucho problema.
5 Conclusiones y
Recomendaciones
5.1
Conclusiones
• Al terminar el proyecto se obtuvo un sistema funcional que cumple la
función de control de acceso mediante una autentificación remota que se
dio al conectarse por Wifi con el servidor TCP, instalado en la red local
de computadoras del edificio de Ingenierı́a Eléctrica de la Universidad
de Costa Rica.
• La comunicación se dio de forma bastante simple, al establecer la comunicación con el servidor, se le envı́a un paquete de bytes, que contiene un
número de identificación numérica de nueve dı́gitos de longitud, y una
contraseña numérica, de 4 dı́gitos, separados por medio de un punto y
coma.
• El microcontrolador Spark Core se programa de una forma bastante
simple, y ya que cuenta con la capacidad para conectarse a una red
Wifi, permitió desarrollar el proyecto de una forma fácil y simple. Se
usaron las librerı́as que están a disposición general, por lo que enviar y
recibir información se da mediante rutinas sencillas.
• El diseño del teclado y botón de emergencia usados en el proyecto cumplen las funciones necesarias para que el sistema lea la información que
el usuario necesita ingresar. Se uso la menor cantidad de pines con el fin
de dejar la posibilidad de agregarle más etapas al proyecto.
37
38
5 Conclusiones y Recomendaciones
5.2
Recomendaciones
• Se recomienda conectar una fuente de poder al sistema, por ejemplo una
baterı́a, de 5 V y una corriente de salida de por lo menos 1 A, con el fin
de que funcione de forma aut ?onoma e independiente de una conexión
que pueda fallar.
• Se recomienda usar el sistema en una red confiable, que la seguridad de
la infraestructura de red sea proporcionada por la conexión de red local
donde se conecta el sistema.
• Se recomienda realizar una tarjeta con el circuito impreso, con el fin de
tener un producto terminado y que se pueda usar como un producto
final, y no que este desarrollado en una placa de pruebas.
Bibliografı́a
Spark Docs (2014). Spark. http://docs.spark.io/.
Andrew S., Tanenbaum (2004). Redes de Computadoras.
John, Rittinghouse, PhD, CISM, & James F.Ransome, D. T. (2004). Wireless
Operational Security.
Magneto para Puerta (2014).
technobly http://soporte.tvc.mx/
Ingenieria/YLI/YM350M/mi.html.
Libreria LCD SPI (2014). technobly https://github.com/technobly/
SparkCore-LiquidCrystalSPI.
Arduino Platform - Working with Shift Registers (2011).
Dave
Auld
http://www.codeproject.com/Articles/144606/
Arduino-Platform-Working-with-Shift-Registers.
Teclado
numerico
4x3
(2013).
http://www.ebay.com/itm/
PA-New-1Pc-4X3-Matrix-Array-12-Key-Membrane-Switch-Keypad-Keyboard-SCA-1711-/
291308526289?pt=LH_DefaultDomain_3&hash=item43d3575ad1.
Control de Personal con Lectores Externos (2014).
Kaba.
http:
//www.kaba.es/Soluciones/Cerraduras-electronicas/625702/
lectores-de-tarjetas.html.
Control de Personal con Lectores Externos (2013). dointech. http://www.
dointech.com.co/control-personal.html .
Lector de Huella Digital ZK5000 (2014). Frax. http://www.biometricos.cl.
IEEE 802.11TM WIRELESS LOCAL AREA NETWORKS (2013). IEEE.
http://www.ieee802.org/11/.
Wifi (2014). Wifi Alliance http://www.wi-fi.org/.
39
A
Acrónimos
• SPI: Serial Peripheral Interface.
• LED: Light-Emitting Diode, o en español Diodo Emisor de Luz.
• CPU: Central Processing Unit, o en español Unidad de Procesamiento
Central.
• RAM: Random Access Memory, o en español Memoria de Acceso Aleatorio.
• WEP: Wired Equivalent Privacy o en español Privacidad Equivalente a
Cableado.
• WPA: Wi-Fi Protected Access, o en español Acceso Wi-Fi Protegido.
• USB: Universal Serial Bus, o en español Bus Universal en Serie.
• PWM: Pulse Width Modulation, o en español Modulación por ancho de
pulsos.
• UART: Universal Asynchronous Receiver-Transmitter o en español TransmisorReceptor Ası́ncrono Universal
• MAC: Media Access Control, o en español Control de Acceso al Medio.
• TCP: Transmission Control Protocol, o en español Protocolo de Control
de Transmisión.
• IP: Internet Protocol, o en español Protocolo de Internet.
• IDE: Integrated Development Environment, o en español Entorno de
Desarrollo Integrado.
• LCD: Liquid Crystal Display, o en español Pantalla de cristal lı́quido.
41
B
Materiales
En la siguiente tabla, se encuetra la lista de materiales usados en el proyecto.
Parte
SparkCore
Character LCD
Microchip
Teclado Numerico
LED
LED
LED
Botón
Trimmer
Potenciometro
Resistencia
Resistencia
Resistencia
Resistencia
Resistencia
Resistencia
Resistencia
Capacitor
Relé
Diodo
Transistor
Tipo
Chip Antenna
Basic 16x2
74HC595
Matriz 4 x 3
Rojo
Amarillo
RGB
10 k Ohm
10 k Ohm
330 Ohm
10 k Ohm
1 k Ohm
680 Ohm
1,3 k Ohm
230 Ohm
150 Ohm
1 uF
JZC-11F
1n4148
2N2222AG
Cantidad
1
1
1
1
1
1
1
1
2
1
3
1
2
2
1
1
1
1
1
1
1
Cuadro B.1: Lista de Materiales Usados en el Proyecto
43
C
Código
1 // ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
2 #include ” l i q u i d −c r y s t a l −s p i . h ”
3 // F i r s t , we c o n s t r u c t t h e c l i e n t t h a t w i l l c o n n e c t t o our l o c a l
server .
4 TCPClient c l i e n t ;
5 S t r i n g messageToSend ;
6 char s t r i n g 1 [ 1 ] = ” ” ;
7 byte ∗ msg ;
8 in t l e n g t h ;
9 // IP a d d r e s s o f t h e S e r v e r TCP
10 byte s e r v e r [ ] = { 1 9 2 , 1 6 8 , 1 , 3 } ;
11 // URL o f t h e S e r v e r TCP
12 const char∗ serverURL = ” h t t p s : / /www. a c c e s o l i c i t . e i e . u c r . ac . c r ” ;
13 in t p o r t = 1 0 0 1 0 ;
14 //−−−−−−−−−−−−−−−−−−−−−−−−−−
15 in t keyboardPin = A0 ;
16 // Analog i n p u t p i n t h a t t h e keypad i s a t t a c h e d t o
17 in t P i n R e l a y = A1 ;
18 // D i g i t a l Output p i n f o r t h e r e l a y ’ s c o n t r o l
19 in t Pin ledRIGHT = A6 ;
20 // D i g i t a l / Analog Output p i n f o r LED f o r i n f o r m a t i o n
21 in t Pin ledWRONG = A5 ;
22 // D i g i t a l / Analog Output p i n f o r LED f o r i n f o r m a t i o n
23 in t Pin buttonEXIT = A7 ;
24 // I n p u t Pin t h a t t h e I n t e r r u p t i s a t t a c h e d t o
25
26 in t v a r l o n g I D =9;
27 in t var longPASS =4;
28 S t r i n g SUPERUSERR = ”1 1 3 7 9 0 6 8 6 ; 7 7 9 9 ” ;
29
30 in t v a r k e y p r e s s e d = 1 2 ; // D e f a u l t Value f o r t h e Keypad
31 in t v a r k e y b o a r d V a l u e = 0 ; // v a l u e r e a d from t h e k e y b o a r d
32 in t j , i , k ; // Counters
33 b o o l e a n f l a g u s e r p a s s c o m p l e t e , ok ;
34
35 unsigned long SERVERTimeSecond , SERVERTimeFirst ;
36 //−−−−−−−−−−−−−−−−−−−−−−−−−−−−
37
38 L i q u i d C r y s t a l l c d (D2 , D3 , D4) ;
39
40 // ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
41
42 void s e t u p ( ) {
43
lcd . initSPI () ;
45
46
C Código
44
// i n i t i a l i z e t h e SPI
45
// Must c a l l t h i s b e f o r e b e g i n ( )
46
lcd . begin (16 , 2) ;
47
// s e t up t h e LCD ’ s number o f columns and rows :
48
49
pinMode ( Pin Relay , OUTPUT) ;
50
pinMode ( Pin ledRIGHT , OUTPUT) ;
51
pinMode ( Pin ledWRONG , OUTPUT) ;
52
53
a t t a c h I n t e r r u p t ( Pin buttonEXIT , interr Exit OPEN , CHANGE) ;
54
f o r ( k=0;k <4;k++){
55
delay (500) ;
56
}
57
connectToMyServer ( ) ;
58 }
59
60 void l o o p ( ) {
61
62
interr Exit CLOSE ( ) ;
63
funtion printWelcome () ;
64
f l a g u s e r p a s s c o m p l e t e=f a l s e ;
65
i f ( ( v a r k e y p r e s s e d=f u n t i o n r e a d K e y b o a r d ( ) ) ==10){
66
p r i n t F u n c t i o n ( 1 , 0 , 0 , ” I n g r e s e User ID ” , 0 ) ;
67
j =0;
68
while ( j<=v a r l o n g I D ) { //Read ID Number from user , 9
numbers
69
ok = true ;
70
v a r k e y p r e s s e d=f u n t i o n r e a d K e y b o a r d ( ) ;
71
i f ( ( v a r k e y p r e s s e d <v a r l o n g I D +1) && ( j <v a r l o n g I D ) ) {
72
s p r i n t f ( s t r i n g 1 , ” %d ” , v a r k e y p r e s s e d ) ;
73
// Composes a s t r i n g w i t h t h e same t e x t t h a t would
74
// be p r i n t e d i f f o r m a t was used on p r i n t f
75
// b u t i n s t e a d o f b e i n g p r i n t e d , t h e c o n t e n t
76
// i s s t o r e d as a C s t r i n g i n t h e b u f f e r p o i n t e d by
string1
77
messageToSend+=s t r i n g 1 ;
78
p r i n t F u n c t i o n ( 0 , 0 , 1 , messageToSend , 5 0 ) ;
79
j ++;
80
}
81
i f ( j==v a r l o n g I D ) {
82
// I f t h e ID i s c o m p l e t e , i t i s c o n f i r m e d
83
// by t h e u s e r or i s d e l e t e d t o c o r r e c t
84
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”User ” , 0 ) ;
85
p r i n t F u n c t i o n ( 0 , 5 , 0 , messageToSend , 9 0 0 ) ;
86
lcd . clear () ;
87
while ( ok ) {
88
v a r k e y p r e s s e d=f u n t i o n r e a d K e y b o a r d ( ) ;
89
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”∗ Para Continuar ” , 0 ) ;
90
p r i n t F u n c t i o n ( 0 , 0 , 1 , ”# Para B o r r a r
” ,0) ;
91
i f ( v a r k e y p r e s s e d ==11){
92
messageToSend = ” ” ;
C Código
47
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
p r i n t F u n c t i o n ( 1 , 0 , 0 , ” I n g r e s e User ID ” , 0 )
;
j =0;
ok=f a l s e ;
}
i f ( v a r k e y p r e s s e d ==10){
j ++;
ok=f a l s e ;
}
}
}
}
messageToSend+=” ; ” ; //Add t h e s e p a r a t o r
printFunction (1 , 0 , 0 , ”Ingresar pass ” ,0) ;
i =0;
while ( i <var longPASS ) { //Read Pass Number from user , 4
numbers
v a r k e y p r e s s e d=f u n t i o n r e a d K e y b o a r d ( ) ;
i f ( v a r k e y p r e s s e d <10){
s p r i n t f ( s t r i n g 1 , ” %d ” , v a r k e y p r e s s e d ) ;
messageToSend+=s t r i n g 1 ;
p r i n t F u n c t i o n ( 0 , i , 1 , ”∗ ” , 5 0 ) ;
i ++;
}
}
//END GET USER/PASS
i f ( messageToSend . l e n g t h ( ) ==(var longPASS+v a r l o n g I D +1) ) {
f l a g u s e r p a s s c o m p l e t e=true ;
}
//SEND INFO TO SERVER
i f ( c l i e n t . connected ( ) ) {
i f ( messageToSend != ” ”) {
l e n g t h=messageToSend . l e n g t h ( ) ;
c l i e n t . w r i t e ( ( u i n t 8 t ∗ ) messageToSend . c s t r ( ) , l e n g t h
+1) ;
messageToSend=” ” ;
}
SERVERTimeFirst = m i l l i s ( ) ;
while ( f l a g u s e r p a s s c o m p l e t e ) {
SERVERTimeSecond = m i l l i s ( ) ;
i f ( ( SERVERTimeSecond − SERVERTimeFirst ) > 5 0 0 0 ) {
break ;
f l a g u s e r p a s s c o m p l e t e=f a l s e ;
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”SERVER” , 0 ) ;
p r i n t F u n c t i o n ( 0 , 0 , 1 , ”ERROR” , 9 0 0 ) ;
}
// R e c e i v i n g i n f o r m a t i o n from t h e s e r v e r
i f ( c l i e n t . connected ( ) ) {
// Gets a v a l u e i n d i c a t i n g w h e t h e r t h e u n d e r l y i n g
Socket
48
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
C Código
// f o r a T c p C l i e n t i s c o n n e c t e d t o a remote h o s t . True
or f a l s e .
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”E spe r e . . . ” , 5 0 ) ;
f u n t i o n b l i n k ( Pin ledRIGHT , 2 0 0 ) ;
if ( client . available () ) {
// Gets t h e amount o f d a t a t h a t has been r e c e i v e d from
// t h e n e t w o r k and i s a v a i l a b l e t o be r e a d .
char charANSWER = c l i e n t . r e a d ( ) ;
// Reads t h e n e x t b y t e r e c e i v e d from t h e s e r v e r
// t o which t h e c l i e n t i s c o n n e c t e d , and r e t u r n s t h e v a l u e
i f (charANSWER==’ 1 ’ ) {
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”Aceptado ” , 0 ) ;
funtion openDOOR ( ) ;
f l a g u s e r p a s s c o m p l e t e=f a l s e ;
}
else {
i f (charANSWER==’ 0 ’ ) {
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”Rechazado ” , 9 0 0 ) ;
f l a g u s e r p a s s c o m p l e t e=f a l s e ;
}
else {
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”SERVER” , 0 ) ;
p r i n t F u n c t i o n ( 0 , 0 , 1 , ”ERROR” , 9 0 0 ) ;
f l a g u s e r p a s s c o m p l e t e=f a l s e ;
}
}
}
} // I f S e r v e r i s down , c h e c k t h e Super User
else {
f u n t i o n b l i n k ( Pin ledWRONG , 2 0 0 ) ;
i f ( messageToSend==SUPERUSERR) {
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”Super User ” , 0 ) ;
p r i n t F u n c t i o n ( 0 , 0 , 1 , ”ACEPTADO” , 5 0 0 ) ;
funtion openDOOR ( ) ;
f l a g u s e r p a s s c o m p l e t e=f a l s e ;
messageToSend=” ” ;
}
else {
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”Rechazado ” , 0 ) ;
p r i n t F u n c t i o n ( 0 , 0 , 1 , ”ERROR NO SERVER” , 9 0 0 ) ;
delay (400) ;
f l a g u s e r p a s s c o m p l e t e=f a l s e ;
messageToSend=” ” ;
}
// Reconnect t o t h e s e r v e r
connectToMyServer ( ) ;
f l a g u s e r p a s s c o m p l e t e=f a l s e ;
}
}
}
e l s e { // I f S e r v e r i s down , c h e c k t h e Super User
C Código
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
49
f u n t i o n b l i n k ( Pin ledWRONG , 2 0 0 ) ;
// Reconnect t o t h e s e r v e r
i f ( messageToSend==SUPERUSERR) {
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”Super User ” , 0 ) ;
p r i n t F u n c t i o n ( 0 , 0 , 1 , ”ACEPTADO” , 6 0 0 ) ;
funtion openDOOR ( ) ;
f l a g u s e r p a s s c o m p l e t e=f a l s e ;
messageToSend=” ” ;
}
else {
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”Rechazado ” , 0 ) ;
p r i n t F u n c t i o n ( 0 , 0 , 1 , ”ERROR NO SERVER” , 9 0 0 ) ;
delay (600) ;
f l a g u s e r p a s s c o m p l e t e=f a l s e ;
messageToSend=” ” ;
}
connectToMyServer ( ) ;
f l a g u s e r p a s s c o m p l e t e=f a l s e ;
}
}
}
//END LOOP( )
// ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
// Func tion t o c o n n e c t t o l o c a l s e r v e r TCP,
// u s i n g IP/URL and a number o f p o r t
void connectToMyServer ( /∗ S t r i n g i p ∗/ ) {
i f ( c l i e n t . c o n n e c t ( serverURL , p o r t ) ) {
// Connects t h e c l i e n t t o t h e s p e c i f i e d p o r t on t h e s p e c i f i e d h o s t .
f u n t i o n b l i n k ( Pin ledRIGHT , 9 0 0 )
// I f S e r v e r i s up , D i s c o n n e c t Spark F u n c t i o n s
Spark . d i s c o n n e c t ( ) ;
}
else {
f u n t i o n b l i n k ( Pin ledWRONG , 9 0 0 )
Spark . c o n n e c t ( ) ;
}
delay (50) ;
}
void p r i n t F u n c t i o n ( in t I n t c l e a r , in t IntAxisX , in t IntAxisY ,
S t r i n g message , in t r e t r a s o ) {
235
// c l e a r ,
a x i s X,
a x i s Y,
Message ,
Delay
236
i f ( I n t c l e a r ==1){
237
lcd . clear () ;
238
l c d . p r i n t ( message ) ;
50
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
C Código
delay ( retraso ) ;
}
i f ( I n t c l e a r ==0){
l c d . s e t C u r s o r ( IntAxisX , IntAxisY ) ;
l c d . p r i n t ( message ) ;
delay ( retraso ) ;
}
}
// ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
void f u n t i o n p r i n t W e l c o m e ( ) {
p r i n t F u n c t i o n ( 1 , 0 , 0 , ”P r o y e c t o EIE ” , 0 ) ;
p r i n t F u n c t i o n ( 0 , 0 , 1 , ”C o n t r o l Acceso
” , 900) ;
p r i n t F u n c t i o n ( 0 , 0 , 1 , ”∗ Para Continuar ” , 9 0 0 ) ;
p r i n t F u n c t i o n ( 0 , 0 , 1 , ”C o n t r o l Acceso
” , 900) ;
}
// ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
int funtion readKeyboard ( ) {
i n t temp =12;
i n t v a r k e y b o a r d V a l u e = 0 ; // v a l u e r e a d from t h e k e y b o a r d
//
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
v a r k e y b o a r d V a l u e = analogRead ( keyboardPin ) ; // r e a d t h e
value
delay (200) ;
v a r k e y b o a r d V a l u e = in t ( v a r k e y b o a r d V a l u e ) ;
i f ( var keyboardValue > 500) {
if
( v a r k e y b o a r d V a l u e >=3700) {temp = 1 ; }
i f ( ( v a r k e y b o a r d V a l u e >=3500) && ( v a r k e y b o a r d V a l u e
3 7 0 0 ) ) {temp = 2 ; }
i f ( ( v a r k e y b o a r d V a l u e >=3200) && ( v a r k e y b o a r d V a l u e
3 5 0 0 ) ) {temp = 3 ; }
i f ( ( v a r k e y b o a r d V a l u e >=3000) && ( v a r k e y b o a r d V a l u e
3 2 0 0 ) ) {temp = 4 ; }
i f ( ( v a r k e y b o a r d V a l u e >=2500) && ( v a r k e y b o a r d V a l u e
3 0 0 0 ) ) {temp = 5 ; }
i f ( ( v a r k e y b o a r d V a l u e >=2000) && ( v a r k e y b o a r d V a l u e
2 5 0 0 ) ) {temp = 6 ; }
i f ( ( v a r k e y b o a r d V a l u e >=1500) && ( v a r k e y b o a r d V a l u e
2 0 0 0 ) ) {temp = 7 ; }
i f ( ( v a r k e y b o a r d V a l u e >=1300) && ( v a r k e y b o a r d V a l u e
1 5 0 0 ) ) {temp = 1 0 ; } // A s t e r i s c o ∗
i f ( ( v a r k e y b o a r d V a l u e >=1100) && ( v a r k e y b o a r d V a l u e
1 3 0 0 ) ) {temp = 8 ; }
i f ( ( v a r k e y b o a r d V a l u e >= 9 0 0 ) && ( v a r k e y b o a r d V a l u e
1 1 0 0 ) ) {temp = 0 ; }
pot
<
<
<
<
<
<
<
<
<
C Código
277
i f ( ( v a r k e y b o a r d V a l u e >= 7 0 0 ) && ( v a r k e y b o a r d V a l u e <
9 0 0 ) ) {temp = 9 ; }
i f ( ( v a r k e y b o a r d V a l u e > 5 0 0 ) && ( v a r k e y b o a r d V a l u e <
7 0 0 ) ) {temp = 1 1 ; } // Numeral #
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
}
else {
temp =12;
}
return temp ;
}
// ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
void f u n t i o n b l i n k ( in t l e d , in t r e t r a s o ) {
in t k ;
i f ( r e t r a s o <255) {
f o r ( k=0;k<r e t r a s o ; k++){
analogWrite ( led , k ) ;
delay ( r e t r a s o /5) ;
}
f o r ( k=r e t r a s o ; k==0;k−−){
analogWrite ( led , k ) ;
delay ( r e t r a s o /10) ;
}
analogWrite ( led , 0) ;
}
else {
d i g i t a l W r i t e ( l e d , HIGH) ;
delay ( retraso ) ;
d i g i t a l W r i t e ( l e d , LOW) ;
}
}
// ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
void funtion openDOOR ( ) { //
d i g i t a l W r i t e ( Pin Relay , HIGH) ;
f o r ( k=0;k <10; k++){ //Time 5 s e c
delay (500) ;
}
d i g i t a l W r i t e ( Pin Relay , LOW) ;
}
// ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
void interr Exit OPEN ( ) {
//Open t h e door , from i n s i d e
d i g i t a l W r i t e ( Pin Relay , HIGH) ;
}
// ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
51
52
326
327 void interr Exit CLOSE ( ) {
328
// C l o s e t h e door
329
d i g i t a l W r i t e ( Pin Relay , LOW) ;
330 }
C Código
D
Librerı́a liquid-crystal-spi
liquid-crystal-spi.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#i f n d e f L i q u i d C r y s t a l S P I h
#define L i q u i d C r y s t a l S P I h
/∗
∗ HARDWARE AND SOFTWARE LIQUIDCRYSTAL SPI
∗ 74HC595 LIBRARY FOR SPARK CORE
∗ =======================================================
∗ Author : BDub
∗ Website : h t t p : / / t e c h n o b l y . com
∗
Date : Feb 24 t h 2014
∗ =======================================================
∗ h t t p s : / / g i t h u b . com/ t e c h n o b l y / SparkCore−L i q u i d C r y s t a l S P I
∗/
/∗ ========= INCLUDES ==================== ∗/
#include ” a p p l i c a t i o n . h ”
/∗ ========= Arduino . h =================== ∗/
#define
#define
#define
bit )
b i t S e t ( v a l u e , b i t ) ( ( v a l u e ) |= ( 1UL << ( b i t ) ) )
b i t C l e a r ( v a l u e , b i t ) ( ( v a l u e ) &= ˜ ( 1UL << ( b i t ) ) )
bitWrite ( value , bit , b i t v a l u e ) ( b i t v a l u e ? b i t S e t ( value ,
: b i t C l e a r ( value , b i t ) )
/∗ ========= L i q u i d C r y s t a l S P I . h ========== ∗/
// commands
#define LCD CLEARDISPLAY 0 x01
#define LCD RETURNHOME 0 x02
#define LCD ENTRYMODESET 0 x04
#define LCD DISPLAYCONTROL 0 x08
#define LCD CURSORSHIFT 0 x10
#define LCD FUNCTIONSET 0 x20
#define LCD SETCGRAMADDR 0 x40
#define LCD SETDDRAMADDR 0 x80
// f l a g s f o r d i s p l a y e n t r y mode
#define LCD ENTRYRIGHT 0 x00
#define LCD ENTRYLEFT 0 x02
#define LCD ENTRYSHIFTINCREMENT 0 x01
#define LCD ENTRYSHIFTDECREMENT 0 x00
53
54
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
D Librerı́a liquid-crystal-spi
// f l a g s f o r d i s p l a y on/ o f f c o n t r o l
#define LCD DISPLAYON 0 x04
#define LCD DISPLAYOFF 0 x00
#define LCD CURSORON 0 x02
#define LCD CURSOROFF 0 x00
#define LCD BLINKON 0 x01
#define LCD BLINKOFF 0 x00
// f l a g s f o r d i s p l a y / c u r s o r s h i f t
#define LCD DISPLAYMOVE 0 x08
#define LCD CURSORMOVE 0 x00
#define LCD MOVERIGHT 0 x04
#define LCD MOVELEFT 0 x00
// f l a g s f o r f u n c t i o n s e t
#define LCD 8BITMODE 0 x10
#define LCD 4BITMODE 0 x00
#define LCD 2LINE 0 x08
#define LCD 1LINE 0 x00
#define LCD 5x10DOTS 0 x04
#define LCD 5x8DOTS 0 x00
c l a s s L i q u i d C r y s t a l : public P r i n t {
public :
LiquidCrystal ( u i n t 8 t rs , u i n t 8 t enable ,
u i n t 8 t d0 , u i n t 8 t d1 , u i n t 8 t d2 , u i n t 8 t d3 ,
u i n t 8 t d4 , u i n t 8 t d5 , u i n t 8 t d6 , u i n t 8 t d7 ) ;
L i q u i d C r y s t a l ( u i n t 8 t r s , u i n t 8 t rw , u i n t 8 t e n a b l e ,
u i n t 8 t d0 , u i n t 8 t d1 , u i n t 8 t d2 , u i n t 8 t d3 ,
u i n t 8 t d4 , u i n t 8 t d5 , u i n t 8 t d6 , u i n t 8 t d7 ) ;
L i q u i d C r y s t a l ( u i n t 8 t r s , u i n t 8 t rw , u i n t 8 t e n a b l e ,
u i n t 8 t d0 , u i n t 8 t d1 , u i n t 8 t d2 , u i n t 8 t d3 ) ;
LiquidCrystal ( u i n t 8 t rs , u i n t 8 t enable ,
u i n t 8 t d0 , u i n t 8 t d1 , u i n t 8 t d2 , u i n t 8 t d3 ) ;
L i q u i d C r y s t a l ( u i n t 8 t s s , u i n t 8 t s c l k =255 , u i n t 8 t s d a t =255) ;
// SPI t o S h i f t R e g i s t e r 74HC595 ##########
void i n i t S P I ( void ) ; // SPI ##################################
void i n i t ( u i n t 8 t f o u r b i t m o d e , u i n t 8 t r s , u i n t 8 t rw , u i n t 8 t
enable ,
u i n t 8 t d0 , u i n t 8 t d1 , u i n t 8 t d2 , u i n t 8 t d3 ,
u i n t 8 t d4 , u i n t 8 t d5 , u i n t 8 t d6 , u i n t 8 t d7 , u i n t 8 t
backlight ) ;
void b e g i n ( u i n t 8 t c o l s , u i n t 8 t rows , u i n t 8 t c h a r s i z e =
LCD 5x8DOTS) ;
void c l e a r ( ) ;
void home ( ) ;
D Librerı́a liquid-crystal-spi
55
90
void n o D i s p l a y ( ) ;
91
void d i s p l a y ( ) ;
92
void n o B l i n k ( ) ;
93
void b l i n k ( ) ;
94
void noCursor ( ) ;
95
void c u r s o r ( ) ;
96
void s c r o l l D i s p l a y L e f t ( ) ;
97
void s c r o l l D i s p l a y R i g h t ( ) ;
98
void l e f t T o R i g h t ( ) ;
99
void r i g h t T o L e f t ( ) ;
100
void a u t o s c r o l l ( ) ;
101
void n o A u t o s c r o l l ( ) ;
102
void b a c k l i g h t ( ) ;
103
void n o B a c k l i g h t ( ) ;
104
105
void c r e a t e C h a r ( u i n t 8 t , u i n t 8 t [ ] ) ;
106
void s e t C u r s o r ( u i n t 8 t , u i n t 8 t ) ;
107
virtual s i z e t write ( u i n t 8 t ) ;
108
void command ( u i n t 8 t ) ;
109 private :
110
void send ( u i n t 8 t , u i n t 8 t ) ;
111
void spiSendOut ( ) ;
// SPI
112
void w r i t e 4 b i t s ( u i n t 8 t ) ;
113
void w r i t e 8 b i t s ( u i n t 8 t ) ;
114
void p u l s e E n a b l e ( ) ;
115
void w r i t e S l o w ( u i n t 8 t ) ;
116
void w r i t e F a s t ( u i n t 8 t ) ;
117
118
uint8 t rs pin ;
// LOW: command . HIGH : c h a r a c t e r .
119
uint8 t rw pin ;
// LOW: w r i t e t o LCD. HIGH : r e a d from
LCD.
120
uint8 t enable pin ;
// a c t i v a t e d by a HIGH p u l s e .
121
u i n t 8 t b a c k l i g h t p i n ; // a c t i v a t e d by a HIGH p u l s e ( a d a f r u i t
SPI/I2C LCD Backpack o n l y )
122
uint8 t data pins [ 8 ] ;
123
124
// SPI
125
u i n t 8 t b a c k l i g h t ; // 1 = b a c k l i g h t on , 0 = b a c k l i g h t o f f
126
u i n t 8 t b i t S t r i n g ; // f o r SPI b i t 0=n o t used , b i t 1=RS , b i t 2=RW,
b i t 3=Enable , b i t s 4 −7 = DB4−7
127
bool
u s i n g S p i ; // t o l e t send and w r i t e f u n c t i o n s know we
a r e u s i n g SPI
128
bool
softSpi ;
// t o l e t send and w r i t e f u n c t i o n s know we
a r e u s i n g SPI
129
uint8 t latchPin ;
130
uint8 t sclkPin ;
131
uint8 t sdatPin ;
132
uint8 t clockDivider ;
133
u i n t 8 t dataMode ;
134
u i n t 8 t b i t O r d e r ; // SPI
135
56
D Librerı́a liquid-crystal-spi
136
uint8
137
uint8
138
uint8
139
140
uint8
141
142
uint8
143 } ;
144
145 #endif
t
t
t
displayfunction ;
displaycontrol ;
displaymode ;
t
initialized ;
t
numlines , c u r r l i n e ;
liquid-crystal-spi.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/∗
∗ HARDWARE AND SOFTWARE LIQUIDCRYSTAL SPI
∗ 74HC595 LIBRARY FOR SPARK CORE
∗ ==========================
∗ Author : BDub
∗ W ebsite : h t t p : / / t e c h n o b l y . com
∗
Date : Feb 24 t h 2014
∗ ============================
∗ h t t p s : / / g i t h u b . com/ t e c h n o b l y / SparkCore−L i q u i d C r y s t a l S P I
∗/
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
When t h e d i s p l a y powers up , i t i s c o n f i g u r e d as f o l l o w s :
1. Display clear
2 . F un ction s e t :
DL = 1 ; 8− b i t i n t e r f a c e d a t a
N = 0 ; 1− l i n e d i s p l a y
F = 0 ; 5 x8 d o t c h a r a c t e r f o n t
3 . D i s p l a y on/ o f f c o n t r o l :
D = 0; Display o f f
C = 0 ; Cursor o f f
B = 0; Blinking o f f
4 . Entry mode s e t :
I /D = 1 ; Increment by 1
S = 0 ; No s h i f t
Note , however , t h a t r e s e t t i n g t h e Arduino doesn ’ t r e s e t t h e LCD
, so we
28 // can ’ t assume t h a t i t s i n t h a t s t a t e when a s k e t c h s t a r t s ( and
the
29 // L i q u i d C r y s t a l c o n s t r u c t o r i s c a l l e d ) .
30
31 /∗ ========= INCLUDES ==================== ∗/
32
33 #include ” l i q u i d −c r y s t a l −s p i . h ”
34
35 /∗ ========= L i q u i d C r y s t a l S P I . cpp ======== ∗/
36
D Librerı́a liquid-crystal-spi
57
37 L i q u i d C r y s t a l : : L i q u i d C r y s t a l ( u i n t 8 t r s , u i n t 8 t rw , u i n t 8 t
enable ,
38
u i n t 8 t d0 , u i n t 8 t d1 , u i n t 8 t d2 , u i n t 8 t d3 ,
39
u i n t 8 t d4 , u i n t 8 t d5 , u i n t 8 t d6 , u i n t 8 t d7 )
40 {
41
i n i t ( 0 , r s , rw , e n a b l e , d0 , d1 , d2 , d3 , d4 , d5 , d6 , d7 , 2 5 5 ) ;
42 }
43
44 L i q u i d C r y s t a l : : L i q u i d C r y s t a l ( u i n t 8 t r s , u i n t 8 t e n a b l e ,
45
u i n t 8 t d0 , u i n t 8 t d1 , u i n t 8 t d2 , u i n t 8 t d3 ,
46
u i n t 8 t d4 , u i n t 8 t d5 , u i n t 8 t d6 , u i n t 8 t d7 )
47 {
48
i n i t ( 0 , r s , 2 5 5 , e n a b l e , d0 , d1 , d2 , d3 , d4 , d5 , d6 , d7 , 2 5 5 ) ;
49 }
50
51 L i q u i d C r y s t a l : : L i q u i d C r y s t a l ( u i n t 8 t r s , u i n t 8 t rw , u i n t 8 t
enable ,
52
u i n t 8 t d0 , u i n t 8 t d1 , u i n t 8 t d2 , u i n t 8 t d3 )
53 {
54
i n i t ( 1 , r s , rw , e n a b l e , d0 , d1 , d2 , d3 , 0 , 0 , 0 , 0 , 2 5 5 ) ;
55 }
56
57 L i q u i d C r y s t a l : : L i q u i d C r y s t a l ( u i n t 8 t r s ,
u i n t 8 t enable ,
58
u i n t 8 t d0 , u i n t 8 t d1 , u i n t 8 t d2 , u i n t 8 t d3 )
59 {
60
i n i t ( 1 , r s , 2 5 5 , e n a b l e , d0 , d1 , d2 , d3 , 0 , 0 , 0 , 0 , 2 5 5 ) ;
61 }
62
63 L i q u i d C r y s t a l : : L i q u i d C r y s t a l ( u i n t 8 t s s , u i n t 8 t s c l k , u i n t 8 t
s d a t ) // SPI
64 {
65
latchPin = ss ;
66
s o f t S p i = f a l s e ; // assume we a r e u s i n g hardware SPI
67
i f ( s c l k != 255 && s d a t != 2 5 5 ) {
68
s o f t S p i = true ; // on se c on d t h o u g h t , l e t ’ s u s e s o f t w a r e SPI
69
}
70
sclkPin = sclk ;
71
sdatPin = sdat ;
72
73
/∗
74
initSPI ( ssPin ) ;
75
// s h i f t R e g i s t e r p i n s 1 , 2 , 3 , 4 , 5 , 6 , 7 r e p r e s e n t rs , rw , e n a b l e , d4
−7 i n t h a t o r d e r
76
// b u t we a r e n ot u s i n g RW so RW i t ’ s z e r o or 255
77
i n i t ( 1 , 1 , 255 , 3 , 0 , 0 , 0 , 0 , 4 , 5 , 6 , 7 , 255) ;
78
∗/
79 }
80
81 void L i q u i d C r y s t a l : : i n i t S P I ( void ) // SPI
82 {
83
// i n i t i a l i z e SPI :
58
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
D Librerı́a liquid-crystal-spi
u s i n g S p i = true ;
pinMode ( l a t c h P i n , OUTPUT) ; // s e t u p
and s o f t w a r e SPI
d i g i t a l W r i t e ( l a t c h P i n , HIGH) ;
// I f we ’ r e u s i n g s o f t w a r e SPI , s e t u p t h e c l o c k and d a t a p i n s .
if ( softSpi ) {
pinMode ( s c l k P i n , OUTPUT) ;
pinMode ( s d a t P i n , OUTPUT) ;
d i g i t a l W r i t e ( s c l k P i n , LOW) ;
d i g i t a l W r i t e ( s d a t P i n , LOW) ;
}
e l s e { // E l s e s e t up t h e hardware SPI
SPI . b e g i n ( ) ;
// c l o c k D i v i d e r = SPI CLOCK DIV4 ; // 72MHz / 4 = 18MHz ( works
b u t t a k e s j u s t as l o n g as 9MHz)
c l o c k D i v i d e r = SPI CLOCK DIV8 ; // 72MHz / 8 = 9MHz ( R e a l l y i s
a b o u t t w i c e as f a s t as 4 . 5MHz)
// c l o c k D i v i d e r = SPI CLOCK DIV16 ; // 72MHz / 16 = 4 . 5MHz
SPI . s e t C l o c k D i v i d e r ( c l o c k D i v i d e r ) ;
// FYI : S o f t w a r e SPI i s a b o u t t h e same s p e e d as SPI CLOCK DIV8
! :)
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
l a t c h P i n used i n hardware
// S e t d a t a mode t o SPI MODE0 by d e f a u l t
dataMode = SPI MODE0 ;
SPI . setDataMode ( dataMode ) ;
// S e t b i t O r d e r t o MSBFIRST by d e f a u l t
b i t O r d e r = MSBFIRST ;
SPI . s e t B i t O r d e r ( b i t O r d e r ) ;
}
// A d a f r u i t SPI/I2C LCD Backpack or D i s c r e t e hookup t o 74HC595
// p i n s r e p r e s e n t : f o u r b i t m o d e , rs , rw , e n a b l e , d0 , d1 , d2 , d3 ,
d4 , d5 , d6 , d7 , b a c k l i g h t
i n i t (1 , 1 , 255 , 2 , 0 , 0 , 0 , 0 , 6 , 5 , 4 , 3 , 7) ;
116
117 }
118
119 void L i q u i d C r y s t a l : : i n i t ( u i n t 8 t f o u r b i t m o d e , u i n t 8 t r s , u i n t 8 t
rw , u i n t 8 t e n a b l e ,
120
u i n t 8 t d0 , u i n t 8 t d1 , u i n t 8 t d2 , u i n t 8 t d3 ,
121
u i n t 8 t d4 , u i n t 8 t d5 , u i n t 8 t d6 , u i n t 8 t d7 , u i n t 8 t
backlight )
122 {
123
rs pin = rs ;
124
r w p i n = rw ;
125
enable pin = enable ;
126
backlight pin = backlight ;
127
b a c k l i g h t = 0 ; // o f f by d e f a u l t
D Librerı́a liquid-crystal-spi
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
data
data
data
data
data
data
data
data
pins
pins
pins
pins
pins
pins
pins
pins
[0]
[1]
[2]
[3]
[4]
[5]
[6]
[7]
=
=
=
=
=
=
=
=
59
d0 ;
d1 ;
d2 ;
d3 ;
d4 ;
d5 ;
d6 ;
d7 ;
pinMode ( r s p i n , OUTPUT) ;
// we can s a v e 1 p i n by n o t u s i n g RW. I n d i c a t e by p a s s i n g 255
i n s t e a d o f p i n#
i f ( r w p i n != 2 5 5 ) {
pinMode ( r w p i n , OUTPUT) ;
}
pinMode ( e n a b l e p i n , OUTPUT) ;
// Always 4− b i t mode , don ’ t w a s t e p i n s !
//
// i f ( f o u r b i t m o d e )
d i s p l a y f u n c t i o n = LCD 4BITMODE | LCD 1LINE | LCD 5x8DOTS ;
// e l s e
// d i s p l a y f u n c t i o n = LCD 8BITMODE | LCD 1LINE | LCD 5x8DOTS ;
// b e g i n ( 1 6 , 2) ; // commented out , make s u r e you c a l l t h i s i n
code !
// s i n c e i n i n i t S P I c o n s t r u c t o r we s e t u s i n g S P I t o t r u e and we
run i t f i r s t
// from SPI c o n s t r u c t o r , we do n o t h i n g h e r e o t h e r w i s e we s e t i t
to f a l s e
i f ( u s i n g S p i ) // SPI
{
;
}
else
{
usingSpi = false ;
}
156
157
158
159
160
161
162
163
164 }
165
166 void L i q u i d C r y s t a l : : b e g i n ( u i n t 8 t c o l s , u i n t 8 t l i n e s , u i n t 8 t
dotsize ) {
167
i f ( l i n e s > 1) {
168
d i s p l a y f u n c t i o n |= LCD 2LINE ;
169
}
170
numlines = l i n e s ;
171
currline = 0;
172
173
// f o r some 1 l i n e d i s p l a y s you can s e l e c t a 10 p i x e l h i g h f o n t
60
i f ( ( d o t s i z e != 0 ) && ( l i n e s == 1 ) ) {
d i s p l a y f u n c t i o n |= LCD 5x10DOTS ;
}
174
175
176
177
178
179
// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION !
// a c c o r d i n g t o d a t a s h e e t , we need a t l e a s t 40ms a f t e r power
r i s e s a b o v e 2 . 7V
// b e f o r e s e n d i n g commands . Arduino can t u r n on way b e f e r 4 . 5V
so we ’ l l w a i t 50
delayMicroseconds (50000) ;
// Now we p u l l b o t h RS and R/W low t o b e g i n commands
d i g i t a l W r i t e ( r s p i n , LOW) ;
d i g i t a l W r i t e ( e n a b l e p i n , LOW) ;
i f ( r w p i n != 2 5 5 ) {
d i g i t a l W r i t e ( r w p i n , LOW) ;
}
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
// 4−B i t i n i t i a l i z a t i o n s e q u e n c e from Te c hn o bl y
w r i t e 4 b i t s ( 0 x03 ) ;
// Put b a c k i n t o 8− b i t mode
delayMicroseconds (5000) ;
w r i t e 4 b i t s ( 0 x08 ) ;
delayMicroseconds (5000) ;
// Comment t h i s o u t f o r V1 OLED
// Comment t h i s o u t f o r V1 OLED
w r i t e 4 b i t s ( 0 x02 ) ;
delayMicroseconds (5000) ;
w r i t e 4 b i t s ( 0 x02 ) ;
delayMicroseconds (5000) ;
w r i t e 4 b i t s ( 0 x08 ) ;
delayMicroseconds (5000) ;
// Put i n t o 4− b i t mode
command (LCD DISPLAYCONTROL) ;
delayMicroseconds (5000) ;
command (LCD FUNCTIONSET | d i s p l a y f u n c t i o n ) ;
font size , etc .
delayMicroseconds (5000) ;
clear () ;
command (LCD ENTRYMODESET | LCD ENTRYLEFT) ;
delayMicroseconds (5000) ;
home ( ) ;
delayMicroseconds (5000) ;
command (LCD DISPLAYCONTROL | LCD DISPLAYON) ;
enable cursor & b l i n k
delayMicroseconds (5000) ;
206
207
208
209
210
211
212
213
214
215
216
217
218
219
D Librerı́a liquid-crystal-spi
// Turn O f f
// S e t # l i n e s ,
// C l e a r D i s p l a y
// S e t Entry Mode
// Home Cursor
// Turn On −
}
/∗ ∗∗∗∗∗∗∗∗∗ h i g h l e v e l commands , f o r t h e u s e r ! ∗/
void L i q u i d C r y s t a l : : c l e a r ( )
{
command (LCD CLEARDISPLAY) ; // c l e a r d i s p l a y , s e t c u r s o r
position to zero
D Librerı́a liquid-crystal-spi
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
delayMicroseconds (5000) ;
61
// t h i s command t a k e s a l o n g time !
}
void L i q u i d C r y s t a l : : home ( )
{
command (LCD RETURNHOME) ;
delayMicroseconds (5000) ;
}
// s e t c u r s o r p o s i t i o n t o z e r o
// t h i s command t a k e s a l o n g time !
void L i q u i d C r y s t a l : : s e t C u r s o r ( u i n t 8 t c o l , u i n t 8 t row )
{
in t r o w o f f s e t s [ ] = { 0 x00 , 0 x40 , 0 x14 , 0 x54 } ;
i f ( row > n u m l i n e s ) {
row = n u m l i n e s −1;
// we c o u n t rows s t a r t i n g w/0
}
command (LCD SETDDRAMADDR | ( c o l + r o w o f f s e t s [ row ] ) ) ;
}
// Turn t h e d i s p l a y on/ o f f ( q u i c k l y )
void L i q u i d C r y s t a l : : n o D i s p l a y ( ) {
d i s p l a y c o n t r o l &= ˜LCD DISPLAYON ;
command (LCD DISPLAYCONTROL | d i s p l a y c o n t r o l ) ;
}
void L i q u i d C r y s t a l : : d i s p l a y ( ) {
d i s p l a y c o n t r o l |= LCD DISPLAYON ;
command (LCD DISPLAYCONTROL | d i s p l a y c o n t r o l ) ;
}
// Turns t h e u n d e r l i n e c u r s o r on/ o f f
void L i q u i d C r y s t a l : : noCursor ( ) {
d i s p l a y c o n t r o l &= ˜LCD CURSORON;
command (LCD DISPLAYCONTROL | d i s p l a y c o n t r o l ) ;
}
void L i q u i d C r y s t a l : : c u r s o r ( ) {
d i s p l a y c o n t r o l |= LCD CURSORON;
command (LCD DISPLAYCONTROL | d i s p l a y c o n t r o l ) ;
}
// Turn on and o f f t h e b l i n k i n g c u r s o r
void L i q u i d C r y s t a l : : n o B l i n k ( ) {
d i s p l a y c o n t r o l &= ˜LCD BLINKON ;
command (LCD DISPLAYCONTROL | d i s p l a y c o n t r o l ) ;
}
void L i q u i d C r y s t a l : : b l i n k ( ) {
d i s p l a y c o n t r o l |= LCD BLINKON ;
command (LCD DISPLAYCONTROL | d i s p l a y c o n t r o l ) ;
}
// These commands s c r o l l t h e d i s p l a y w i t h o u t c h a n g i n g t h e RAM
void L i q u i d C r y s t a l : : s c r o l l D i s p l a y L e f t ( void ) {
62
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
D Librerı́a liquid-crystal-spi
command (LCD CURSORSHIFT | LCD DISPLAYMOVE | LCD MOVELEFT) ;
}
void L i q u i d C r y s t a l : : s c r o l l D i s p l a y R i g h t ( void ) {
command (LCD CURSORSHIFT | LCD DISPLAYMOVE | LCD MOVERIGHT) ;
}
// This i s f o r t e x t t h a t f l o w s L e f t t o R i g h t
void L i q u i d C r y s t a l : : l e f t T o R i g h t ( void ) {
d i s p l a y m o d e |= LCD ENTRYLEFT;
command (LCD ENTRYMODESET | d i s p l a y m o d e ) ;
}
// This i s f o r t e x t t h a t f l o w s R i g h t t o L e f t
void L i q u i d C r y s t a l : : r i g h t T o L e f t ( void ) {
d i s p l a y m o d e &= ˜LCD ENTRYLEFT;
command (LCD ENTRYMODESET | d i s p l a y m o d e ) ;
}
// This w i l l ’ r i g h t j u s t i f y ’ t e x t from t h e c u r s o r
void L i q u i d C r y s t a l : : a u t o s c r o l l ( void ) {
d i s p l a y m o d e |= LCD ENTRYSHIFTINCREMENT;
command (LCD ENTRYMODESET | d i s p l a y m o d e ) ;
}
// This w i l l ’ l e f t j u s t i f y ’ t e x t from t h e c u r s o r
void L i q u i d C r y s t a l : : n o A u t o s c r o l l ( void ) {
d i s p l a y m o d e &= ˜LCD ENTRYSHIFTINCREMENT;
command (LCD ENTRYMODESET | d i s p l a y m o d e ) ;
}
// A l l o w s us t o f i l l t h e f i r s t 8 CGRAM l o c a t i o n s
// w i t h custom c h a r a c t e r s
void L i q u i d C r y s t a l : : c r e a t e C h a r ( u i n t 8 t l o c a t i o n , u i n t 8 t charmap
[]) {
l o c a t i o n &= 0 x7 ; // we o n l y have 8 l o c a t i o n s 0−7
command (LCD SETCGRAMADDR | ( l o c a t i o n << 3 ) ) ;
f o r ( in t i =0; i <8; i ++) {
w r i t e ( charmap [ i ] ) ;
}
}
// Turn t h e b a c k l i g h t on/ o f f
// B a c k l i g h t w i l l t u r n on or o f f i m m e d i a t e l y
void L i q u i d C r y s t a l : : b a c k l i g h t ( void ) {
backlight = 1;
// add t h e b a c k l i g h t b i t on a l l t r a n s f e r s
bitWrite ( b i t S t r i n g , b a c k l i g h t p i n , 1) ;
// and send i t o u t
spiSendOut ( ) ;
}
void L i q u i d C r y s t a l : : n o B a c k l i g h t ( void ) {
D Librerı́a liquid-crystal-spi
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
63
backlight = 0;
// add t h e b a c k l i g h t b i t on a l l t r a n s f e r s
bitWrite ( b i t S t r i n g , b a c k l i g h t p i n , 0) ;
// and send i t o u t
spiSendOut ( ) ;
}
/∗ ∗∗∗∗∗∗∗∗∗∗ mid l e v e l commands , f o r s e n d i n g d a t a /cmds ∗/
i n l i n e void L i q u i d C r y s t a l : : command ( u i n t 8 t v a l u e ) {
send ( v a l u e , LOW) ;
}
inline s i z e t LiquidCrystal : : write ( uint8 t value ) {
send ( v a l u e , HIGH) ;
return 1 ; // assume s u c e s s
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗ low l e v e l d a t a p u s h i n g commands ∗∗∗∗∗∗∗∗∗ ∗/
// w r i t e e i t h e r command or data , w i t h a u t o m a t i c 4/8− b i t s e l e c t i o n
void L i q u i d C r y s t a l : : send ( u i n t 8 t v a l u e , u i n t 8 t mode ) {
i f ( u s i n g S p i == f a l s e )
{
d i g i t a l W r i t e ( r s p i n , mode ) ;
// i f t h e r e i s a RW p i n i n d i c a t e d , s e t i t low t o Write
i f ( r w p i n != 2 5 5 ) {
d i g i t a l W r i t e ( r w p i n , LOW) ;
}
i f ( d i s p l a y f u n c t i o n & LCD 8BITMODE) {
w r i t e 8 b i t s ( value ) ;
} else {
w r i t e 4 b i t s ( v a l u e >>4) ;
w r i t e 4 b i t s ( value ) ;
}
}
e l s e //we u s e SPI
{
bitWrite ( bitString ,
spiSendOut ( ) ;
r s p i n , mode ) ; // s e t RS t o mode
// we a r e n o t u s i n g RW w i t h SPI so we a r e n o t even b o t h e r i n g
// or 8BITMODE so we go s t r a i g h t t o w r i t e 4 b i t s
w r i t e 4 b i t s ( v a l u e >>4) ;
w r i t e 4 b i t s ( value ) ;
}
}
void L i q u i d C r y s t a l : : p u l s e E n a b l e ( void ) {
64
D Librerı́a liquid-crystal-spi
372
i f ( u s i n g S p i == f a l s e )
373
{
374
d i g i t a l W r i t e ( e n a b l e p i n , LOW) ;
375
delayMicroseconds (1) ;
376
d i g i t a l W r i t e ( e n a b l e p i n , HIGH) ;
377
delayMicroseconds (1) ;
// e n a b l e p u l s e must be >450ns
378
d i g i t a l W r i t e ( e n a b l e p i n , LOW) ;
379
delayMicroseconds (100) ;
// commands need > 37 us t o s e t t l e
380
}
381
e l s e //we u s e SPI
382
{
383
b i t W r i t e ( b i t S t r i n g , e n a b l e p i n , LOW) ;
384
spiSendOut ( ) ;
385
delayMicroseconds (1) ;
386
b i t W r i t e ( b i t S t r i n g , e n a b l e p i n , HIGH) ;
387
spiSendOut ( ) ;
388
delayMicroseconds (1) ;
// e n a b l e p u l s e must be >450ns
389
b i t W r i t e ( b i t S t r i n g , e n a b l e p i n , LOW) ;
390
spiSendOut ( ) ;
391
delayMicroseconds (40) ;
// commands need > 37 us t o s e t t l e
392
}
393 }
394
395 void L i q u i d C r y s t a l : : w r i t e 4 b i t s ( u i n t 8 t v a l u e ) {
396
i f ( u s i n g S p i == f a l s e )
397
{
398
f o r ( in t i = 0 ; i < 4 ; i ++) {
399
pinMode ( d a t a p i n s [ i ] , OUTPUT) ;
400
d i g i t a l W r i t e ( d a t a p i n s [ i ] , ( v a l u e >> i ) & 0 x01 ) ;
401
}
402
}
403
e l s e //we u s e SPI
404
{
405
f o r ( in t i = 4 ; i < 8 ; i ++) {
406
//we p u t t h e f o u r b i t s i n t o t h e b i t S t r i n g
407
b i t W r i t e ( b i t S t r i n g , d a t a p i n s [ i ] , ( ( v a l u e >> ( i − 4 ) ) & 0
x01 ) ) ;
408
}
409
// add t h e b a c k l i g h t b i t on a l l t r a n s f e r s
410
b i t W r i t e ( b i t S t r i n g , b a c k l i g h t p i n , ( b a c k l i g h t & 0 x01 ) ) ;
411
412
// and send i t o u t
413
spiSendOut ( ) ;
414
}
415
pulseEnable () ;
416 }
417
418 void L i q u i d C r y s t a l : : w r i t e 8 b i t s ( u i n t 8 t v a l u e ) {
419
f o r ( in t i = 0 ; i < 8 ; i ++) {
420
pinMode ( d a t a p i n s [ i ] , OUTPUT) ;
421
d i g i t a l W r i t e ( d a t a p i n s [ i ] , ( v a l u e >> i ) & 0 x01 ) ;
D Librerı́a liquid-crystal-spi
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
65
}
pulseEnable () ;
}
void L i q u i d C r y s t a l : : spiSendOut ( ) // SPI
{
if ( softSpi ) {
writeFast ( bitString ) ;
}
else {
d i g i t a l W r i t e ( l a t c h P i n , LOW) ;
SPI . t r a n s f e r ( b i t S t r i n g ) ;
d i g i t a l W r i t e ( l a t c h P i n , HIGH) ;
}
}
void L i q u i d C r y s t a l : : w r i t e S l o w ( u i n t 8 t v a l u e ) {
d i g i t a l W r i t e ( l a t c h P i n , LOW) ;
s h i f t O u t ( s d a t P i n , s c l k P i n , MSBFIRST, v a l u e ) ;
d i g i t a l W r i t e ( l a t c h P i n , HIGH) ;
}
i n l i n e void L i q u i d C r y s t a l : : w r i t e F a s t ( u i n t 8 t v a l u e ) {
PIN MAP [ l a t c h P i n ] . g p i o p e r i p h e r a l −>BRR = PIN MAP [ l a t c h P i n ] .
g p i o p i n ; // Latch Low
f o r ( u i n t 8 t i = 0 ; i < 8 ; i ++) {
i f ( v a l u e & ( 1 << (7− i ) ) ) { // w a l k s down mask from b i t 7 t o
bit 0
PIN MAP [ s d a t P i n ] . g p i o p e r i p h e r a l −>BSRR = PIN MAP [ s d a t P i n ] .
g p i o p i n ; // Data High
}
else {
PIN MAP [ s d a t P i n ] . g p i o p e r i p h e r a l −>BRR = PIN MAP [ s d a t P i n ] .
g p i o p i n ; // Data Low
}
asm v o l a t i l e ( ”mov r0 , r 0 ” ”\n\ t ” ”nop ” ”\n\ t ” ”nop ” ”\n\ t ” ”
nop ” ”\n\ t ” : : : ”r 0 ” , ”c c ” , ”memory ”) ;
PIN MAP [ s c l k P i n ] . g p i o p e r i p h e r a l −>BSRR = PIN MAP [ s c l k P i n ] .
g p i o p i n ; // C l o c k High ( Data S h i f t e d In )
asm v o l a t i l e ( ”mov r0 , r 0 ” ”\n\ t ” ”nop ” ”\n\ t ” ”nop ” ”\n\ t ” ”
nop ” ”\n\ t ” : : : ”r 0 ” , ”c c ” , ”memory ”) ;
PIN MAP [ s c l k P i n ] . g p i o p e r i p h e r a l −>BRR = PIN MAP [ s c l k P i n ] .
g p i o p i n ; // C l o c k Low
}
asm v o l a t i l e ( ”mov r0 , r 0 ” ”\n\ t ” ”nop ” ”\n\ t ” ”nop ” ”\n\ t ” ”nop ”
”\n\ t ” : : : ”r 0 ” , ”c c ” , ”memory ”) ;
PIN MAP [ l a t c h P i n ] . g p i o p e r i p h e r a l −>BSRR = PIN MAP [ l a t c h P i n ] .
g p i o p i n ; // Latch High ( Data L a t c h e d )
}
Descargar