Buenas, esta entrada es un poco por recordar. Se trata de un pequeño programa que únicamente nos muestra una pelota y un muñeco que va delante de ella.
La simulación corre a cargo de un PIC 16f876A a 4MHZ
Es una transición sencilla de dos imágenes cargadas en la CGRAM de la pantalla LCD, en la entrada "Caracteres especiales LCD" explico como se añaden estos dibujos.
Una vez que los tenemos grabados, solo hay que borrar la posición anterior y volver a escribirlos en la siguiente posición .
Este tipo de animación se podría poner, por ejemplo, cuando no presionemos ninguna tecla durante X segundos y que volviera a la pantalla del programa una vez que presionemos alguna tecla
Seguramente seria más corto haberlo escrito moviéndome por los cursores de la pantalla con un FOR...NEXT... pero creo que así se ve mejor como va pasando de una posición a otra, aunque puede que lo incluya más tarde como otro ejemplo
Adjunto el archivo en PBP y la simulación en Proteus para quien quiera ver como funciona
**Recuerda que si quieres reproducir este ejemplo en un PIC tienes que añadir el cristal de 4MHZ y los condensadores. No los puse en la simulación por que Proteus me deja correr el programa solo configurando el micro, pero solo en la simulación
La nueva versión del CDLA ya está disponible para descargar. También sera la última versión en tener potenciómetro, a partir de ahora sera un encoder rotatorio el encargado de esa función, pero eso será, espero, en próximas versiones.
para está versión, la número 2, incluye las siguientes características:
Posibilidad de memorizar :
El número de circuitos desde el 1 hasta el 8
Velocidad máxima
Velocidad mínima .
Carga de la locomotora.
Intensidad de luz con el mando a 0 .
Numero de desvíos
Luces!!! Ahora puedes estar parado con las luces encendidas!!! Si estas en la pantalla principal y pulsas "4", aparecerá un mensaje en la pantalla "Luces ON" indicando que has encendido las luces; Despues de eso el icono de la luces pasara a la posición de encendido;Si pulsas "4" de nuevo aparecerá el mensaje "Luces OFF" y el icono pasara a la posición de apagado.
Además en la pantalla de configuración he añadido una opción para resetear los valores originales.
También le he puesto un escape de la pantalla "igualar" para poder salir de él sin igualar la velocidad solo pulsando "#".
En la pantalla principal también he modificado un poco para que muestre la dirección de las locomoras y el último desvío y su posición.
Gestor de bucles (aun en construcción) para poder asociar los desvíos de 8 buclesretorno a los 8 circuitos. De esta manera los desvíos se abrirán o cerraran según la dirección de la locomotora.
Evidentemente yo ya la tengo instalada en la central y la verdad es que funciona bastante bien y no me ha dado problemas. Espero que alguien se anime a verla funcionar aunque sea en Proteus.
Con la ampliación de la maqueta, me he metido de lleno a mejorar el tema de la electrónica y aprovechar al máximo los micro controladores, y se me ocurrió, que podría hacer algo parecido al sistema DCC pero en analógico. Para mi esto significa tener una central (Master) y los demás dispositivos auxiliares (Slaves).
De esta manera espero poder tener un control mucho más personalizado para cada circuito.
Nunca había caído en la cuenta de poder usar arrays para mejorar el código y estoy bastante contento ya que con ellos he podido resumir el código y hacerlo más compacto y espero que eficiente.
La velocidad esta controlada por el potenciómetro, que es común para todas las locomotora. Bueno no es lo más correcto llamarlas locomotoras, en realidad se refiere a cada circuito, ya que al ser analógico no alimento las locomotoras como en el sistema DCC, si no las vías.
Para entrar en el modo manual se pulsa 1, ya que en el montaje final la pantalla ira sobre el teclado. El modo PC aun no esta terminado así que ahora mismo no funciona.
Para seleccionar el circuito pulsaremos 1, 2 o 3 . Una vez dentro, aparecerá el número de circuito, la velocidad, y la dirección en la que va la locomotora situada en ese circuito. Para salir de ese circuito y volver al menú principal hay que pulsar "#"
Para la maqueta he decidido cambiar el sistema que utilizo en la comunicación entre PIC‘s.
Antes lo hacia directamente PIC a PIC, pero se me quedaba corto para poder añadir más microcontroladores.
Primero mire si se podía con un MAX232, pero tiene el problema de no ser multipunto, es decir que no se pueden conectar más de 2 microcontroladores así que no servía para mi propósito de poder crear módulo independientes.
Investigando un poco encontré el MAX485, que se adapta mejor al tipo de configuración que se utilizará finalmente.
Después de ver algunos ejemplos de libros y la web, he hecho este pequeño programa de comunicaciones con MAX485. El programa es un bucle que comunica un pic con el otro haciendo que se enciendan la luz verde cuando recibe el dato.
Si bien este programa es para 2 micros, la idea seria ir añadiendo más, (el MAX485 admite hasta 32 dispositivos). El mayor problema que estoy teniendo hasta ahora es el tema de la sincronización, ya que para que funcione, cuando enviamos un dato, tenemos que poner el control bajo, es decir, el pin que hayamos seleccionado tiene que estar en LOW para poder recibir y el HIGH para poder transmitir.
Código para microcontrolador principal:
'PRINCIPAL
define LOADER_USED 1
DEFINE OSC 4
include "modedefs.bas" 'Activa el modo de comunicación
ADCON1=6
rojo var portb.1
verde var portb.0
control var portc.0
entrada var portc.6
salida var portc.7
dato var byte
repet var byte
'para saber que el pic esta encendido
high rojo : high verde
pause 1000
low rojo : low verde
Estado:
low control
serin entrada,T2400,dato
if dato = "E" then
high verde
pause 250
low verde
pause 250
goto enviando
endif
goto estado
enviando:
for repet = 1 to 10
high control
serout salida,T2400, ["D"]
next
high rojo
pause 250
low rojo
goto estado
end
Código para microcontrolador secundario:
define LOADER_USED 1
DEFINE OSC 4
include "modedefs.bas" 'Activa el modo de comunicación
ADCON1=6
rojo var portb.1
verde var portb.0
control var portc.0
entrada var portc.7
salida var portc.6
cnt var bit
dato var byte
repet var byte
'para saber que el pic esta encendido
high rojo : high verde
pause 1000
low rojo : low verde
Enviando:
for repet = 1 to 10
high control
serout salida,t2400, ["E"]
next
high rojo
pause 250
low rojo
Estado:
low control
serin entrada,T2400,dato
if dato = "D" then
high verde
pause 250
low verde
pause 250
goto Enviando
endif
goto Estado
end
Por otro lado también estoy barajando la posibilidad de utilizar HSERIN y HSEROUT, pero eso sera dentro de un tiempo ya que ahora estoy un poco liado con la navidad y el trabajo.
También me gustaría poder hacer un ejemplo con más microcontroladores, pero como he comentado tendrá que ser un poco más adelante.
Bien ya solo me queda un poco para terminar todo el conjunto de desvíos y controles para los 3 circuitos de la maqueta.
Ya solo faltaría el modulo de detección para, por ejemplo, paradas en caso de choque inminente, detención frente a el desvió, para ceder el paso a otra locomotora etc.
Supongo que este sera un poco más complicado que estos 2 últimos ya que sera el encargado de interconectar todo.
Bien hoy solo pongo una foto para que se vea como quedan todo el conjunto de circuitos. Espero organizarlo todo un poco mejor ya que hoy solo he tenido tiempo para unas pocas pruebas y todavía hay cosas que se pueden mejorar.
Por fin ya esta casi casi terminado, le he añadido un LCD 16x2 al conjunto del micro que controla los desvíos y el teclado.
Ahora puedo ver en la pantalla que desvíos (Dx) y que cruces (Cx), o significa circuito en su posición predeterminada y 1 si esta activado, el otro conjunto es para las velocidades de los 3 circuitos, en la imagen corresponden a el grupo de la derecha.
Las velocidades que son controladas por el otro microcontrolador aparecen reflejadas en LCD y las envío mediante la instrucción SEROUT a una velocidad de 9600.
Todo funciona correctamente, pero se puede mejorar, por ejemplo, haciendo que el LCD me indique la dirección en la que va cada circuito.
Buscando como controlar las locomotoras de la maqueta encontré como configurar la instrucción HPWM que tiene internamente el 16F876A.
¿Qué es HPWM?
HPWM es una instrucción que hacia tiempo que quería probar pero siempre me había dado fallos, eso unido a mi poca paciencia y tiempo...
Al final junto con un ejemplo que encontré en Todo PIC y revisando la ayuda de Microcode Studio, hice este pequeño programa para controlar la intensidad de 2 leds con los conversores analógicos.
Una de las ventajas que tiene es que se ejecuta en segundo plano así que puedes hacer otras cosas mientras que se ejecuta hpwm.
Una de las desventajas es que utiliza pines específicos del PIC llamados CCP, en el caso del 16F876A son 2 y están situados en los pines 12 y 13 (CCP2 y CCP1 respectivamente).
Para activar el HPWM en PBP se utilizan los siguientes DEFINE'S en la configuración inicial del programa:
DEFINE CCP1_REG PORTC ' Hpwm 1 pin port DEFINE CCP1_BIT 2 ' Hpwm 1 pin bit DEFINE CCP2_REG PORTC ' Hpwm 2 pin port DEFINE CCP2_BIT 1 ' Hpwm 2 pin bit
Con esto se habilita el HPWM, y la instrucción es así:
HPWM Channel, Dutycycle, Frequency
Channel: Es el canal del CCP que estemos usando, 1 para CCP1 y 2 para CCP2
Dutycycle: pondremos la variable o el número que queramos para los ciclos que especifica el encendido / apagado en relación a la Frecuencia (Frequency). Con una variable Byte, 0 es totalmente apagado, 127 es la mitad de la onda y 255 seria la onda completa, en el caso del led, este brillara a su máxima potencia.
Frequency: estoy utilizando el valor de 255 aunque no lo tengo muy claro asi que lo mejor es que lo consulteis en el datasheet del mismo 16F876A
Ejemplo para el uso de HPWM
' Control HPWM con la lectura ADC del microcontrolador 16F876A
' Lee los potenciómetros y ajusta la intensidad de los leds conectados
' a los puertos CCP1 y CCP2
define LOADER_USED 1 ' Para usar el bootloader del 16F876A
DEFINE OSC 4 ' Define la velocidad de reloj del microcontrolador
define ADC_BITS 10 ' Conversión A/D a 10 bits
Define ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo
DEFINE CCP1_REG PORTC ' Hpwm 1 pin port
DEFINE CCP1_BIT 2 ' Hpwm 1 pin bit
DEFINE CCP2_REG PORTC ' Hpwm 2 pin port
DEFINE CCP2_BIT 1 ' Hpwm 2 pin bit
' Variables para el dato
Dato1 var word
Dato2 var word
Dato3 var word
dato1 = 0
dato2 = 0
dato3 = 0
TRISA = %11111111
TRISC = %00000000
portc = %00000000
ADCON1 =%10000000
Pause 1000
Inicio:
adcin 0, dato1
dato1 = (dato1 / 4)
hpwm 1, dato1, 250
adcin 1, dato2
dato2 = ( dato2 / 4)
hpwm 2, dato2, 250
goto inicio
end
Imagen del montaje en Proteus:
Otros artículos sobre PWM en microcontroladores que te pueden interesar:
Una de las diferencias es que se muestra el resultado en una pantalla LCD 16x2 conectada en el puerto C del 16F876A.
En un futuro también se mostrara la velocidad en una escala de 0 a 85, la verdad es que ya le he estado tocando aquí y allí y más o menos ya lo tengo controlado, aunque sigue en periodo de pruebas.
Como comenté anteriormente el programa es muy parecida a la entrada Teclado y portA. Con el LCD tuve un pequeño problema relacionado con el bootloader.
El Screamer1.4 / 1.6 tiene un problema al cargar el bootloader en el principio de la memoria del PIC y cuando lo intentaba cargar me daba un fallo relacionado con GOTO, como si intentara escribir en la zona donde esta el bootloader.
Lo solucione buscando otro bootloader llamado Tiny PIC bootloader. Resulta que este bootloader se programa en la parte final de la memoria y ya no da el error. Bueno lo mismo estoy equivocado, pero lo que si es cierto es que funciono... ¡¡Y a la primera!!
Primero de todo comentar que el bootloader con el microcontrolador 16F876A es lo más cómodo que he utilizado desde que empecé con los microcontroladores. Realmente animo a todos los que crean que tiene mucho lio, que se pongan, es realmente fácil y sobre todo muy cómodo.
Dicho esto, este es el primer programa que he realizado en PBP para el PIC 16F876A, aparte del mítico Blink (parpadeo) para comprobar que todo esta correcto con la programación.
Es un programa para utilizar un potenciómetro con el conversor analógico que integra el PIC internamente.
Primero lee el potenciómetro en una de las entradas analógicas del microcontrolador, en este caso AN0 y con ello controlamos la intensidad del un led mediante la función PWM (Pulse Width Modulation).
DEFINE LOADER_USED 1 ' Para usar el bootloader
DEFINE OSC 20 ' Defino la velocidad del cristal
DEFINE ADC_BITS 10 ' Conversión A/D a 10 bits
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 10
Led1 VAR portc.1 ' El puerto C1 pasa a llamarse Led1
Dato VAR WORD ' Variable para el dato
TRISA = %11111111 ' Puerto A todo como entradas
ADCON1 = %10000010
PAUSE 1000
Inicio:
ADCIN 0, Dato ' Lee el puerto AN0 y lo guarda en la variable Dato.
Dato = Dato /4 ' Al tener la conversión en 10bits la variable es de 0 a 1023 dividimos
' entre 4 para tener una variable de 0 a 255.
PWM Led1, dato, 30 'PWM lee la variable almacenada en Dato y la transmite atraves de Led1.
GOTO Inicio
END
Una imagen de las conexiones:
Otros artículos sobre PWM en microcontroladores que te pueden interesar:
Muy buenas a todos y todoas fanáticos de Visual Basic
Este es el código para el coche RC con Visual Basic.
Código PBP para coche RC con con microcontrolador PIC 16F628a con el que controlamos los dos motores, uno para la tracción y otro para la dirección de un pequeño coche RC modificado:
Para el control de los motores se han reciclado los transistores que ya estaban en la placa de control del coche RC original construyendo con ellos un rudimentario puente H.
' Coche RC
@ DEVICE PIC16F628A, BOD_OFF
@ DEVICE pic16F628A, WDT_OFF
@ DEVICE pic16F628A, PWRT_OFF
@ DEVICE pic16F628A, PROTECT_OFF
@ DEVICE pic16F628A, MCLR_OFF
@ DEVICE PIC16F628A, XT_OSC
@ DEVICE PIC16F628A, LVP_OFF
include "modedefs.bas"
Define OSC 4
CMCON = 7
Serial var byte
datos var portb.1
TRISB = 000010
PORTB = 000000
Inicio:
serin datos,T1200,serial
if serial="A" then Avance
if serial="B" then Atras
if serial="C" then Derch
if serial="D" then izqui
if serial="P" then parar
if serial="E" then Atder
if serial="F" Then Ader
if serial="G" then Aizq
if serial="H" then ATizq
goto inicio
Avance:
portb = %01000000
goto inicio
Atras:
portb = %10000000
goto inicio
Derch:
portb = %01000000
goto inicio
Izqui:
portb = %10000000
goto inicio
ATder:
portb = %10100000
goto inicio
Ader:
portb = %10010000
goto inicio
ATizq:
portb = %01100000
goto inicio
Aizq:
portb = %01010000
goto inicio
Parar:
portb = %00000000
goto inicio
END
Este código es un ejemplo clásico de control de coches RC con microcontroladores PIC.
Como es bastante sencillo lo hace ideal para principiantes como yo, mientras que su estructura permite expandirlo con algunas funciones avanzadas como control inalámbrico o retroalimentación con sensores. ¡Perfecto para proyectos educativos y hobbies de electrónica!
Otros artículos sobre Visual Basic 6.0 que te pueden interesar:
Este es parte del circuito para controlar los desvíos de mi maqueta, pero sirve también como un buen ejemplo para ver como conectar un teclado a un 16F628A y como utilizar las salidas del puerto A, en este caso para encender un led, pero también podemos conectarle relés o lo que se os ocurra.
También es un buen ejemplo para ver como encender y apagar un led con un solo pulsador mediante IF THEN y ELSE
Este Chip seria el esclavo para mi maqueta y con el solo controlaría el teclado y las 7 salidas para activar o desactivar los desvíos. Solo utiliza los 7 primeros dígito del teclado, los demás los utilizare para la rotonda, la estación y el desenganchador mediante Serout.
Este es el esquema:
Y este es el programa en PBP:
@ DEVICE PIC16F628A, WDT_OFF
@ DEVICE PIC16F628A, PWRT_ON
@ DEVICE PIC16F628A, BOD_ON
@ DEVICE PIC16F628A, PROTECT_OFF
@ DEVICE PIC16F628A, CPD_OFF
@ DEVICE PIC16F628A, MCLR_OFF
@ DEVICE PIC16F628A, INTRC_OSC_NOCLKOUT
@ DEVICE PIC16F628A, LVP_OFF
include "modedefs.bas"
CMCON=7 ' Todo digital
' Salida de datos serout
salida var portb.0
'Teclado
La var portb.1
Lb var portb.2
Lc var portb.3
Ld var porta.4
Funo var portb.5
Fdos var portb.6
Ftres var portb.7
'Salidas
Duno Var porta.0
Ddos Var porta.1
Dtres var porta.2
Dcuatro var porta.3
Dcinco var portb.4
Dseis var porta.6
Dsiete var porta.7
Trisa=000000
Porta=000000
'Bits de control
Buno var bit
Bdos var bit
Btres var bit
Bcuatro var bit
Bcinco var bit
Bseis var bit
Bsiete var bit
menu:
pause 100
serout salida,T9600,[Buno,Bdos,Btres,Bcuatro,Bcinco,Bseis,Bsiete]
; Etiqueta para el teclado
teclado:
low La : high lb
high lc : high ld
if funo = 0 then uno
if fdos = 0 then Dos
if ftres = 0 then tres
high La : low lb
high lc : high ld
if Funo = 0 then cuatro
if Fdos = 0 then cinco
if Ftres = 0 then seis
HIGH La : HIGH Lb
LOW Lc : HIGH Ld
if funo = 0 then siete
pause 10
goto teclado
Uno:
if Buno = 0 then
high Duno
Buno = 1
pause 100
else
low dDun
Buno = 0
pause 100
endif
Goto menu
Dos:
if bdos = 0 then
high ddos
bdos = 1
pause 100
else
low ddos
bdos = 0
pause 100
endif
Goto menu
Tres:
if Btres = 0 then
high Dtres
Btres = 1
pause 100
else
low Dtres
Btres = 0
pause 100
endif
Goto menu
cuatro:
if Bcuatro = 0 then
high Dcuatro
Bcuatro = 1
pause 100
Else
low Dcuatro
Bcuatro = 0
pause 100
endif
Goto menu
cinco:
if Bcinco = 0 then
high Dcinco
Bcinco = 1
pause 100
Else
low Dcinco
Bcinco = 0
pause 100
endif
Goto menu
seis:
if Bseis = 0 then
high Dseis
Bseis = 1
pause 100
Else
low Dseis
Bseis = 0
pause 100
endif
Goto menu
siete:
if Bsiete = 0 then
high Dsiete
Bsiete = 1
pause 100
Else
low Dsiete
Bsiete = 0
pause 100
endif
Goto menu
END
Esto es lo ultimo que me ha dado por hacer, un coche seguidor de linea. Es decir un coche al que le pones una linea negra sobre un fondo blanco y va siguiendo la linea.
La verdad es algo sencillo de hacer y algo más complicado si lo quieres hacer bien, me explico:
Empezando por la base, no es una muy buena base para este tipo de practica, es algo más difícil de controlar. La base ideal seria dos ruedas cada uno con un motor y una rueda loca como rueda de apoyo.
Esta es la parte inferior donde están puestos los tres CNY70. Esta es la primera prueba que hice poniéndolos a mucha distancia y montándolos un poco de "aquella manera" sobre el mismo chasis...
No funciono... bueno lo que es el circuito si funcionaba bien el problema era que al estar fijos no podía regular los sensores y hacia lo que quería.
Aquí ya están mejor, la colocación es MUY IMPORTANTE, si no no detectara la linea, hay que alinearlo bien sobre todo en altura. Hay por ahí algún esquema donde ponen los CNY70 con unos potenciómetros, no los he llegado ha probar, pero supongo que con esto podremos hacer un reglaje más "fino".
Si podemos quitarle vibraciones mejor también.
Esta es la parte inferior, donde se ven los sensores CNY70, como se ve están encendidos, esto solo puede verse con el móvil y no se si con las cámaras de fotos también pasara (Esto también es útil para saber si el mando de la tele tiene pilas jejeje)
La idea ya la tenia en mente aunque la verdad lo he hecho un poco por hacer. Parte de la información la he sacado de la web de Glafebre que hizo el Hyperion donde tendréis más información y el programa original, el mio tiene algunas variaciones, pero fue el que me inspiro.
Código en PBP:
@ DEVICE PIC16F628A, WDT_OFF ' Watchdog Timer desconectado
@ DEVICE PIC16F628A, PWRT_OFF ' Power-On Timer conectado
@ DEVICE PIC16F628A, BOD_OFF ' Brown-Out Detect conectado
@ DEVICE PIC16F628A, MCLR_OFF ' Master Clear Externo desconectado
@ DEVICE PIC16F628A, LVP_OFF ' Low-Voltage Programming desconectado
@ DEVICE PIC16F628A, CPD_OFF ' Data Memory Code Protect desconectado
DEFINE OSC 4
'-----CONFIGURACION DE LOS PUERTOS--------
PORTB=%11110000
TRISB=%11110000
'------------PROGRAMA PRINCIPAL------------
pause 3000
loop:
IF (PORTB.5=0) AND (portb.6=1) AND (portb.7=1) THEN GOSUB AVANCE
IF (PORTB.7=0) AND (portb.5=1) AND (portb.6=1) THEN GOSUB IZQUIERDA
IF (PORTB.6=0) AND (portb.5=1) AND (portb.7=1) THEN GOSUB DERECHA
IF (PORTB.5=0) AND (portb.6=0) AND (portb.7=0) THEN GOSUB PARO
IF (PORTB.5=1) AND (portb.6=1) AND (portb.7=1) THEN GOSUB PARO
GOTO loop
END
'--------------SUBRRUTINAS-----------------
AVANCE:
PORTB.0 = 1
PORTB.1 = 0
PORTB.2 = 0
PORTB.3 = 0
return
ATRAS:
PORTB.0 = 0
PORTB.1 = 0
PORTB.2 = 0
PORTB.3 = 0
RETURN
DERECHA:
PORTB.0 = 1
PORTB.1 = 0
PORTB.2 = 1
PORTB.3 = 0
RETURN
IZQUIERDA:
PORTB.0 = 1
PORTB.1 = 0
PORTB.2 = 0:
PORTB.3 = 1
RETURN
PARO:
PORTB.0 = 0
PORTB.1 = 0
PORTB.2 = 0
PORTB.3 = 0
RETURN
Muy buenas a todos y todas los fanáticos de los microcontroladores
Aquí les dejo un video de una cerradura electrónica hecha con el microcontrolador PIC 16f628a. Más tarde pondré el esquema y el código en Pic Basic Pro (pbp).
Este es el esquema en Proteus:
Como no tenía reles a mano he puesto un led en su lugar, pero a efectos es lo mismo poniendo un transistor podremos controlar cargas mayores.
Después de una pequeña revisión, me he dado cuenta que si se pone RS en el A4 no funciona la simulación, pero solo en la simulación. De todas maneras he cambiado la foto del esquema y el código. Aunque el problema estaba solo ahí. También os dejo los archivos en Proteus y los de PBP en la sección de descargas de este blog.
Y este es el código para la programación en PBP:
; Cerradura Electrónica con teclado 3x4,Lcd 16x2,
; y clave de 4 dígitos que queda grabada aun cuando el Pic
; deje de tener corriente.
; utiliza el microcontrolador 16f628a prescidiendo del cristal de cuarzo
; externo y usando el reloj interno
@ DEVICE PIC16F628A, WDT_OFF
@ DEVICE PIC16F628A, PWRT_ON
@ DEVICE PIC16F628A, BOD_ON
@ DEVICE PIC16F628A, PROTECT_OFF
@ DEVICE PIC16F628A, CPD_OFF
@ DEVICE PIC16F628A, MCLR_OFF
@ DEVICE PIC16F628A, INTRC_OSC_NOCLKOUT
@ DEVICE PIC16F628A, LVP_OFF
DEFINE LCD_DREG PORTA ; Puerto de datos LCD
DEFINE LCD_DBIT 0 ; datos LCD comenzando en BIT 0 o 4 "estos deven estar consecutivos"
DEFINE LCD_EREG PORTB ; cambiamos Enable del portb.3
DEFINE LCD_EBIT 7 ; al portb.7
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 7
; Definicion de variables
a var word
tecla var word
n1 var byte
n2 var byte
n3 var byte
n4 var byte
eprom1 var byte
; Definiendo puertos
LA var portb.0 ; Linea A
LB var portb.1 ; Linea B
LC var portb.2 ; Linea C
LD var portb.3 ; Linea D
Funo var portb.4 ; Columna 1
Fdos var portb.5 ; Columna 2
Ftres var portb.6 ; Columna 3
rele var porta.6 ; Rele
n1 = "1" ; asigno valor a las variables
n2 = "1" ; el valor es equivalente en ascII
n3 = "1" ; esta sera la combinación predefinida
n4 = "1" ; recuerda cambiarla!!
eprom1 = "0"
PAUSE 100 ; Inicio del programa
read 0, eprom1
if eprom1 = 255 then gravar_clave
goto bienvenida
gravar_clave:
WRITe 0, n1
WRITe 1, n2
WRITe 2, n3
WRITe 3, n4
LCDOUT $FE,1, $FE, 2 , " CLAVE GRABADA "
PAUSE 1500
GOTO bienvenida
Bienvenida:
pause 500 ; Mensaje de Bienvenida
LCDOUT $FE,1, $FE, 2, " Infotronikblog"
LCDOUT $FE, $C0, " Presenta: "
inicio:
pause 500
LOW LA
LOW LB
HIGH LC
LOW lD ; Activamos la linea del asterisco
IF fUNO = 0 then goto clave
pause 500 ; LEE EL TECLADO A VER SI ES "*" SI NO ES CONTINUA MOSTRANDO MENSAJE
goto inicio
; Función para leer el teclado
teclado:
low la
if funo = 0 then uno
if fdos = 0 then dos
if ftres = 0 then tres
high la
low lb
if funo = 0 then cuatro
if fdos = 0 then cinco
if ftres = 0 then seis
high lb
low lc
if funo = 0 then siete
if fdos = 0 then ocho
if ftres = 0 then nueve
high lc
low ld
if funo = 0 then asterisco
if fdos = 0 then cero
if ftres = 0 then numeral
high ld
pause 10
goto teclado
asterisco:
tecla ="*"
return
siete:
tecla = "7"
return
cuatro:
tecla = "4"
return
uno:
tecla = "1"
return
dos:
tecla = "2"
return
cinco:
tecla = "5"
return
ocho:
tecla = "8"
return
cero:
tecla = "0"
return
tres:
tecla = "3"
return
seis:
tecla = "6"
return
nueve:
tecla = "9"
return
numeral:
tecla = "#"
return
clave:
LCDOUT $FE,1, $FE,2, "Escribe la Clave"
pause 1000
gosub teclado
SWAP tecla, n1
LCDOUT $FE, $C5, "*"
pause 500
gosub teclado
SWAP tecla, n2
LCDOUT $FE, $C6, "*"
pause 500
gosub teclado
SWAP tecla, n3
LCDOUT $FE, $C7, "*"
pause 500
gosub teclado
SWAP tecla, n4
LCDOUT $FE, $C8, "*"
pause 500
READ 0,EPROM1
IF eprom1 = n1 then miro_dos
Error:
LCDOUT $FE, 1, $FE, 2, "Clave Incorrecta"
pause 500
goto bienvenida
miro_dos:
READ 1, eprom1
IF eprom1 = n2 then miro_tres
goto error
miro_tres:
READ 2, eprom1
IF eprom1 = n3 then miro_cuatro
goto error
miro_cuatro:
READ 3, eprom1
IF eprom1 = n4 then goto menu
goto error
menu:
LCDOUT $FE, 1, " Elige una "
LCDOUT $FE, $C0, " Opcion: "
pause 1500
LCDOUT $FE, 1, "1 Abrir Puerta"
pause 300
LCDOUT $FE, $C0, "2 Cambiar Clave"
gosub teclado
if tecla = "1" THEN goto abrir
if tecla = "2" then goto nueva_clave
if tecla != "1" and tecla!= "2" then LCDOUT $FE,1, $FE,2, "TECLA INCORRECTA" ; Si pulsamos una
LCDOUT $FE, 1, $FE, 2, "TECLA INCORRECTA " ;que no es ni 1 ni 2 muestra tecla incorrecta
pause 700
goto menu
abrir:
high rele
LCDOUT $FE, 1, $FE, 2, " Bienvenido "
pause 3000
low rele
goto bienvenida
nueva_clave:
LCDOUT $FE,1, $FE,2, "Escribe tu nueva"
LCDOUT $FE, $C0, "Clave:"
pause 500
gosub teclado
SWAP tecla, n1
LCDOUT $FE, $C8, "*"
pause 500
gosub teclado
SWAP tecla, n2
LCDOUT $FE, $C9, "*"
pause 500
gosub teclado
SWAP tecla, n3
LCDOUT $FE, $C9+1, "*"
pause 500
gosub teclado
SWAP tecla, n4
LCDOUT $FE, $C9+2, "*"
pause 500
goto gravar_clave
*NOTA: En la simulación la clave esta cambiada a 2580 *
Otron enlaces sobre información o proyectos con microcontroladores:
Este es el circuito de mi alarma con el pic 16F84A , y aunque en principio es bastante simple espero ir añadiendo y mejorando poco a poco.
(Pulsar foto para agrandar)
El funcionamiento es simple, cuando enciendes, se pone en marcha el led verde (On) indicando que el PIC está en funcionamiento y entra un contador de 10 segundos antes de que la alarma quede totalmente armada durante los cuales el led rojo parpadeara hasta quedarse encendido.
Ya tenemos la alarma armada, ahora con los 2 pulsadores simulando las puertas del coche, en el pulsador 1 he incluido un retardo de 20 segundos para que de tiempo a apagar la central antes de que comience a sonar la sirena, si no se desconecta en esos 20 segundos entrara el relé haciendo sonar el claxon a intervalos de 2 segundos si y 2 no.
Si se entra por la puerta del(pulsador 2) la alarma se dispara automáticamente. La alarma estará sonando durante 1 minuto y si no se desconecta volverá a armarse automáticamente.
El programa esta hecho en PBP y no es para nada complicado. Saludos!!!
PD. en la imagen no lo he puesto pero el rele es alimentado por un 7812 conectado al ULN2003
Bueno aquí les dejo el programa escrito en microcode, compilado con PBP246 y grabado con TE-20 y el programa ic-prog 1.06b. Con Cristal de 4Mhz.
ledon var portb.0 ; Nombre al puerto B0
ledarm var portb.1 ; Nombre al puerto B1
p1 var portb.2 ; Nombre al puerto B2
p2 var portb.3 ; Nombre al puerto B3
rele var porta.0 ; Nombre al puerto A0
x var byte ; Nombre a la variable X
trisb=001100
Porta=0
Portb=0
Pmarcha: ; Puesta en marcha
high ledon
for x=0 TO 20 ; Repite cinco veces
high ledarm ; Enciende led
pause 500 ; Espera 500ms
low ledarm ; Apaga led utilice comando low que cumple la misma
; funcion que toggle que cambia la configuracion
; de un bit es decir si esta en ALTO LO PASA A BAJO
; y viceversa
pause 500
NEXT ; Siguiente hasta que se repite 5 veces
goto Siguiente
Siguiente:
pause 500
high ledarm
if p1=0 then alarma1 ; Si pulsador1 a 0, va a alarma1
if p2=0 then alarma2 ; Si pulsador2 a 0, va a alarma2
goto siguiente
alarma1: ; Esta parte da el retardo para apagar la
for x = 0 to 40 ; alarma, en este caso son 20seg, en el
high ledon ; caso en el que no se apague pasaria
high ledarm ; a la siguiente etiqueta alarma2
pause 250
low ledon
low ledarm
pause 250
next
goto alarma2
alarma2: ; Si no hemos apagado la alarma durante
for x = 0 to 15 ; la etiqueta alarma1, o se a activado
high ledarm ; El segundo pulsador (p2) se activa el
high ledon ; Rele conectado a una vocina o a un
high rele ; Indicador luminoso a intervaluos de
pause 2000 ; 2seg encendiendose tambien todos
low ledarm ; led's del circuito, para saber el
low ledon ; Tiempo que va a estar sonando calculamos
low rele ; (pause + pause)* X / 1000
pause 2000 ; Donde X es igual al número de repeticiones
next ; FOR.. TO..
goto pmarcha
END ; Fin del programa