MONITOR SONDA LAMBDA
La sonda Lambda mide el oxigeno de los gases de combustión con referencia al oxígeno atmosférico, gracias a esto la unidad de control puede regular con mayor presición la cantidad de aire y combustible hasta en una relación 14,7 a 1 (a esto se la denomina, "Relacion Estequiometrica"), contribuyendo con su medición a una mejor utilización del combustible y a una combustión menos contaminante al medio ambiente gracias al control de los gases de escape que realiza.
La sonda esta situada en el tubo de escape del auto; Se busca en su colocación la mejor posición para su funcionamiento cualquiera sea el regímen del motor. La temperatura óptima de funcionamiento de la sonda es alrededor de los 300° o más.
Un parte de la sonda Lambda siempre esta en contacto con el aire de la atmósfera (exterior al tubo de escape), mientras que otra parte de ella lo estará con los gases de escape producidos por la combustión.
Su funcionamiento se basa en dos electrodos de platino, uno en la parte en contacto con el aire y otro en contacto con los gases, separados entre sí por un electrolito de cerámica. Los iones de oxígeno son recolectados por los electrodos (recuerde que cada uno de los electrodos estarán en diferentes lugares, uno al aire atomosférico y otro a los gases de escape), creándose así una diferencia de tensión entre ambos (o una diferencia nula) consistente en una tensión de 0 a 1 volt.
Ante una diferencia de oxígeno entre ambas secciones la sonda produce una tensión eléctrica envíándola a la unidad de control (ECU), para que ésta regule la cantidad de combustible a pulverizar (a este proceso, se lo llama tiempo de inyeccion).
Para mas info sobre Sonda Lambda (click acá)
Recuerde que una sonda lambda en mal estado le pude ocasionar un consumo excesivo de combustible, por lo que es ideal tener la seguridad que la sonda tiene un funcionamiento correcto.
A continuacion, presento un sencillo programa para poder monitorear nuestars sondas lambdas por intermedio de un voltimetro que incluye un LCD que ademas de mostrar una barra grafica, nos indica con un mensaje si la mezcla de combustible es "Rica"-"Pobre"-"Muy Pobre"-"Muy Rica"...
;**************
EJEM_VOLT:
LCDOUT $FE, 1
lcdout " EJEMPLO BASICO "
LCDOUT $fe,$C0,"VOLTIMETRO LAMBDA"
pause 1500
LCDOut $fe, $48, $00, $00, $00, $00, $00, $00, $1F, $1F 'Figura 1.
LCDOut $fe, $50, $00, $00, $00, $00, $1F, $1F, $1F, $1F 'Figura 2.
LCDOut $fe, $58, $00, $00, $1F, $1F, $1F, $1F, $1F, $1F 'Figura 3.
LCDOut $fe, $60, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F 'Figura 4.
EJEM_VOLT1:
if botonMODO = 0 then PUBLI
ADCIN 1, Res1
Volts3 = Res1 * Conv1
Volts4 = Res1 * Conv2
Volts4 = Volts4 / 100
Volts3 = Volts3 + Volts4
if volts3 > 800 then nivel5E
if volts3 > 600 then nivel4E
if volts3 > 400 then nivel3E
if volts3 > 200 then nivel2E
if volts3 < 200 then nivel1E
goto EJEM_VOLT1
nivel1E:
pause 100
LCDOUT $FE, 1
LCDOUT $fe, $C0,"VE= ",DEC4 Volts3 , "mV"
LCDOut $fe,2,"Mezcla muy POBRE"
LCDOut $fe,$CB, 1
goto EJEM_VOLT1
nivel2E:
pause 100
LCDOUT $FE, 1
LCDOUT $fe, $C0,"VE= ",DEC4 Volts3 , "mV"
LCDOut $fe,2,"Mezcla POBRE"
LCDOut $fe,$CB, 1
LCDOut $fe,$CC, 2
goto EJEM_VOLT1
nivel3E:
pause 100
LCDOUT $FE, 1
LCDOUT $fe, $C0,"VE= ",DEC4 Volts3 , "mV"
LCDOut $fe,2,"Mezcla BUENA"
LCDOut $fe,$CB, 1
LCDOut $fe,$CC, 2
LCDOut $fe,$CD, 3
goto EJEM_VOLT1
nivel4E:
pause 100
LCDOUT $FE, 1
LCDOUT $fe, $C0,"VE= ",DEC4 Volts3 , "mV"
LCDOut $fe,2,"Mezcla RICA"
LCDOut $fe,$CB, 1
LCDOut $fe,$CC, 2
LCDOut $fe,$CD, 3
LCDOut $fe,$CE, 4
goto EJEM_VOLT1
nivel5E:
pause 100
LCDOUT $FE, 1
LCDOUT $fe, $C0,"VE= ",DEC4 Volts3 , "mV"
LCDOut $fe,2,"Mezcla muy RICA"
LCDOut $fe,$CB, 1
LCDOut $fe,$CC, 2
LCDOut $fe,$CD, 3
LCDOut $fe,$CE, 4
LCDOut $fe,$CF, 4
goto EJEM_VOLT1
;*****************
(vista del proyecto en mi placa entrenadora, simulado con un potenciometro)
Si me dan un tiempo, voy a volver a este mismo tema, y les voy a mostrar mi segunda BETA de este proyecto, que en si, se basa en una interface de potenciacion.
Basicamente lo que estoy haciendo, es leer el valor de la sonda lambda, y luego, con un PWM, genero en la salida del microcontrolador una señal del mismo valor que el de entrada... Luego, el usuario, a gusto puede setear si quiere incremetar o decrementar por % el valor de salida, obteniendo por resultado un poco mas de engorde de la mezcla de combustible...
Son varias las variables que estan en juego para obtener un 0.3% adicional de potencia en nuestro vehiculo, pero trabajando el avance desde el sensor de temperatura, el map y el engorde de la mezcla, logre realizar un cambio notable en mi suzuki fun 1.0...
MATRIZ DE LED
En este pequeño ejemplo, pretendo mostrar como podemos controlar los led bit a bit con una sencilla tabla...
'****************************************************************
'* Name : MATRIZ8x8.BAS *
'* Author : [Martin A. Torres Fortelli] *
'* Notice : Copyright (c) 2009 [prof.martintorres@educ.ar] *
'* : All Rights Reserved *
'* Date : 08/11/2009 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
TRISB=%11111111
TRISC=%00000000
TRISD=%00000000
dAUX VAR BYTE
LETRA VAR BYTE
P1 VAR BYTE
i VAR BYTE
i1 VAR BYTE
D0 VAR BYTE ;A
D1 VAR BYTE
D2 VAR BYTE
D3 VAR BYTE
D4 VAR BYTE
D5 VAR BYTE
D6 VAR BYTE
D7 VAR BYTE
D8 VAR BYTE ;B
D9 VAR BYTE
D10 VAR BYTE
D11 VAR BYTE
D12 VAR BYTE
D13 VAR BYTE
D14 VAR BYTE
D15 VAR BYTE
D16 VAR BYTE
D17 VAR BYTE ;C
D18 VAR BYTE
D19 VAR BYTE
D20 VAR BYTE
D21 VAR BYTE
D22 VAR BYTE
D23 VAR BYTE
D24 VAR BYTE
D25 VAR BYTE ;D
D26 VAR BYTE
D27 VAR BYTE
D28 VAR BYTE
D29 VAR BYTE
D30 VAR BYTE
D31 VAR BYTE
D32 VAR BYTE
D33 VAR BYTE ;E
D34 VAR BYTE
D35 VAR BYTE
D36 VAR BYTE
D37 VAR BYTE
D38 VAR BYTE
D39 VAR BYTE
D40 VAR BYTE
D41 VAR BYTE ;F
D42 VAR BYTE
D43 VAR BYTE
D44 VAR BYTE
D45 VAR BYTE
D46 VAR BYTE
D47 VAR BYTE
D48 VAR BYTE
D49 VAR BYTE ;G
D50 VAR BYTE
D51 VAR BYTE
D52 VAR BYTE
D53 VAR BYTE
D54 VAR BYTE
D55 VAR BYTE
D56 VAR BYTE
D57 VAR BYTE ;H
D58 VAR BYTE
D59 VAR BYTE
D60 VAR BYTE
D61 VAR BYTE
D62 VAR BYTE
D63 VAR BYTE
D64 VAR BYTE
D65 VAR BYTE
D66 VAR BYTE ;I
D67 VAR BYTE
D68 VAR BYTE
D69 VAR BYTE
D70 VAR BYTE
D71 VAR BYTE
D72 VAR BYTE
D73 VAR BYTE
D74 VAR BYTE
D75 VAR BYTE ;J
D76 VAR BYTE
D77 VAR BYTE
D78 VAR BYTE
D79 VAR BYTE
D80 VAR BYTE
D81 VAR BYTE
D82 VAR BYTE ;K
D83 VAR BYTE
D84 VAR BYTE
D85 VAR BYTE
D86 VAR BYTE
D87 VAR BYTE
D88 VAR BYTE
D89 VAR BYTE
D90 VAR BYTE ;L
D91 VAR BYTE
D92 VAR BYTE
D93 VAR BYTE
D94 VAR BYTE
D95 VAR BYTE
D96 VAR BYTE
D97 VAR BYTE
D98 VAR BYTE ;M
D99 VAR BYTE
D100 VAR BYTE
D101 VAR BYTE
D102 VAR BYTE
D103 VAR BYTE
D104 VAR BYTE
D105 VAR BYTE
D106 VAR BYTE ;N
D107 VAR BYTE
D108 VAR BYTE
D109 VAR BYTE
D110 VAR BYTE
D111 VAR BYTE
D112 VAR BYTE
D113 VAR BYTE
D114 VAR BYTE ;O
D115 VAR BYTE
D116 VAR BYTE
D117 VAR BYTE
D118 VAR BYTE
D119 VAR BYTE
D120 VAR BYTE
D121 VAR BYTE
D122 VAR BYTE ;P
D123 VAR BYTE
D124 VAR BYTE
D125 VAR BYTE
D126 VAR BYTE
D127 VAR BYTE
D128 VAR BYTE
D129 VAR BYTE
D130 VAR BYTE ;Q
D131 VAR BYTE
D132 VAR BYTE
D133 VAR BYTE
D134 VAR BYTE
D135 VAR BYTE
D136 VAR BYTE
D137 VAR BYTE
D138 VAR BYTE ;R
D139 VAR BYTE
D140 VAR BYTE
D141 VAR BYTE
D142 VAR BYTE
D143 VAR BYTE
D144 VAR BYTE
D145 VAR BYTE
D146 VAR BYTE ;S
D147 VAR BYTE
D148 VAR BYTE
D149 VAR BYTE
D150 VAR BYTE
D151 VAR BYTE
D152 VAR BYTE
D153 VAR BYTE
D154 VAR BYTE ;T
D155 VAR BYTE
D156 VAR BYTE
D157 VAR BYTE
D158 VAR BYTE
D159 VAR BYTE
D160 VAR BYTE
D161 VAR BYTE
D162 VAR BYTE ;U
D163 VAR BYTE
D164 VAR BYTE
D165 VAR BYTE
D166 VAR BYTE
D167 VAR BYTE
D168 VAR BYTE
D169 VAR BYTE
D170 VAR BYTE ;V
D171 VAR BYTE
D172 VAR BYTE
D173 VAR BYTE
D174 VAR BYTE
D175 VAR BYTE
D176 VAR BYTE
D177 VAR BYTE
D178 VAR BYTE ;W
D179 VAR BYTE
D180 VAR BYTE
D181 VAR BYTE
D182 VAR BYTE
D183 VAR BYTE
D184 VAR BYTE
D185 VAR BYTE
D186 VAR BYTE ;X
D187 VAR BYTE
D188 VAR BYTE
D189 VAR BYTE
D190 VAR BYTE
D191 VAR BYTE
D192 VAR BYTE
D193 VAR BYTE
D194 VAR BYTE ;Y
D195 VAR BYTE
D196 VAR BYTE
D197 VAR BYTE
D198 VAR BYTE
D199 VAR BYTE
D200 VAR BYTE
D201 VAR BYTE
D202 VAR BYTE ;Z
D203 VAR BYTE
D204 VAR BYTE
D205 VAR BYTE
D206 VAR BYTE
D207 VAR BYTE
D208 VAR BYTE
D209 VAR BYTE
P1=11
i=0
i1=22
dAUX = 0
;TABLAS (esto seria ideal en una eeprom externa)
D0 =%00000000 ;A
D1 =%01111110
D2 =%01000010
D3 =%01000010
D4 =%01111110
D5 =%01000010
D6 =%01000010
D7 =%00000000
D8 =%00000000 ;B
D9 =%01111100
D10 =%01000010
D11 =%01000010
D12 =%01111100
D13 =%01000010
D14 =%01000010
D15 =%01111100
D16 =%00000000
D17 =%00000000 ;C
D18 =%00111110
D19 =%01000000
D20 =%01000000
D21 =%01000000
D22 =%01000000
D23 =%00111110
D24 =%00000000
D25 =%00000000 ;D
D26 =%01111100
D27 =%01000010
D28 =%01000010
D29 =%01000010
D30 =%01000010
D31 =%01111100
D32 =%00000000
D33 =%00000000 ;E
D34 =%01111110
D35 =%01000000
D36 =%01000000
D37 =%01110000
D38 =%01000000
D39 =%01111110
D40 =%00000000
D41 =%00000000 ;F
D42 =%01111110
D43 =%01000000
D44 =%01000000
D45 =%01110000
D46 =%01000000
D47 =%01000000
D48 =%00000000
D49 =%00000000 ;G
D50 =%00111110
D51 =%01000000
D52 =%01000000
D53 =%01001110
D54 =%01000010
D55 =%00111110
D56 =%00000000
D57 =%00000000 ;H
D58 =%01000010
D59 =%01000010
D60 =%01000010
D61 =%01111110
D62 =%01000010
D63 =%01000010
D64 =%01000010
D65 =%00000000
D66 =%00000000 ;I
D67 =%00010000
D68 =%00010000
D69 =%00010000
D70 =%00010000
D71 =%00010000
D72 =%00010000
D73 =%00010000
D74 =%00000000
D75 =%01111110 ;J
D76 =%00000100
D77 =%00000100
D78 =%00000100
D79 =%01000100
D80 =%00111000
D81 =%00000000
D82 =%00000000 ;K
D83 =%01000100
D84 =%01001000
D85 =%01110000
D86 =%01001000
D87 =%01000100
D88 =%01000010
D89 =%00000000
D90 =%00000000 ;L
D91 =%01000000
D92 =%01000000
D93 =%01000000
D94 =%01000000
D95 =%01000000
D96 =%01111110
D97 =%00000000
D98 =%00000000 ;M
D99 =%01000010
D100 =%01100110
D101 =%01011010
D102 =%01000010
D103 =%01000010
D104 =%01000010
D105 =%00000000
D106 =%00000000 ;N
D107 =%01000010
D108 =%01100010
D109 =%01010010
D110 =%01001010
D111 =%01000110
D112 =%01000010
D113 =%00000000
D114 =%00000000 ;O
D115 =%00111100
D116 =%01000010
D117 =%01000010
D118 =%01000010
D119 =%01000010
D120 =%00111100
D121 =%00000000
D122 =%00000000 ;P
D123 =%01111100
D124 =%01000010
D125 =%01000010
D126 =%01111100
D127 =%01000000
D128 =%01000000
D129 =%00000000
D130 =%00000000 ;Q
D131 =%00000000
D132 =%00000000
D133 =%00000000
D134 =%00000000
D135 =%00000000
D136 =%00000000
D137 =%00000000
D138 =%00000000 ;R
D139 =%00000000
D140 =%00000000
D141 =%00000000
D142 =%00000000
D143 =%00000000
D144 =%00000000
D145 =%00000000
D146 =%00000000 ;S
D147 =%00000000
D148 =%00000000
D149 =%00000000
D150 =%00000000
D151 =%00000000
D152 =%00000000
D153 =%00000000
D154 =%00000000 ;T
D155 =%00000000
D156 =%00000000
D157 =%00000000
D158 =%00000000
D159 =%00000000
D160 =%00000000
D161 =%00000000
D162 =%00000000 ;U
D163 =%00000000
D164 =%00000000
D165 =%00000000
D166 =%00000000
D167 =%00000000
D168 =%00000000
D169 =%00000000
D170 =%00000000 ;V
D171 =%00000000
D172 =%00000000
D173 =%00000000
D174 =%00000000
D175 =%00000000
D176 =%00000000
D177 =%00000000
D178 =%00000000 ;W
D179 =%00000000
D180 =%00000000
D181 =%00000000
D182 =%00000000
D183 =%00000000
D184 =%00000000
D185 =%00000000
D186 =%00000000 ;X
D187 =%00000000
D188 =%00000000
D189 =%00000000
D190 =%00000000
D191 =%00000000
D192 =%00000000
D193 =%00000000
D194 =%00000000 ;Y
D195 =%00000000
D196 =%00000000
D197 =%00000000
D198 =%00000000
D199 =%00000000
D200 =%00000000
D201 =%00000000
D202 =%00000000 ;Z
D203 =%01111110
D204 =%00000100
D205 =%00001000
D206 =%00010000
D207 =%00100000
D208 =%01111110
D209 =%00000000
;******************************************
INICIO:
i=i+1
IF i=i1 Then PALABRA
PORTD=%11111110
PORTC=d1
Pause P1
PORTD=%11111101
PORTC=d2
Pause P1
PORTD=%11111011
PORTC=d3
Pause P1
PORTD=%11110111
PORTC=d4
Pause P1
PORTD=%11101111
PORTC=d5
Pause P1
PORTD=%11011111
PORTC=d6
Pause P1
PORTD=%10111111
PORTC=d7
Pause P1
PORTD=%01111111
PORTC=d8
Pause P1
PALABRA:
i=0
;LETRA_a:
dAUX=D0
d0=d1
d1=d2
d2=d3
d3=d4
d4=d5
d5=d6
d6=d7
d7=d8
d8=D9
;LETRA_b:
d9=d10
d10=d11
d11=d12
d12=d13
d13=d14
d14=d15
d15=d16
d16=d17
D17=D18
;LETRA_c:
d18=d19
d19=d20
d20=d21
d21=d22
d22=d23
d23=d24
d24=d25
D25=D26
;LETRA_d:
d26=d27
d27=d28
d28=d29
d29=d30
d30=d31
d31=d32
d32=d33
;LETRA_e:
d33=d34
d34=d35
d35=d36
d36=d37
d37=d38
d38=d39
d39=d40
d40=d41
;LETRA_f:
d41=d42
d42=d43
d43=d44
d44=d45
d45=d46
d46=d47
d47=d48
d48=d49
;LETRA_g:
d49=d50
d50=d51
d51=d52
d52=d53
d53=d54
d54=d55
d55=d56
d56=d57
; Y ASI SIGUE SUCESIVAMENTE....
goto INICIO
END
Cuando inicien el programa, notaran que la matriz arrancara presentando las distintas letras que hay en la tabla, pero con la novedad, de que se ve con el efecto visual de desplazamiento...
Para hacerlo un poco mas claro y que arranquen con pruebas mas pequeñas, voy a explicar el paso a paso de como controlar una matriz de led... El siguiente articulo originalmente lo escribi para picaxe, pero como estos son programados en un basic, no creo que tengan problema alguno en modificarlo para llevarlo a sus necesidades; O sea, la base de este articulo, es valida para cualqier programacion en basic...arranquemos:
Como controlar una pantalla del tipo matriz de LED
En otro articulo, ya hemos estado viendo un poco de lo que refiere el control matricial; Concretamente, aprendimos como controlar un teclado matricial, y tomando como base aquel proyecto, seguiremos abordando el tema de control de matrices, pero con un proyecto aun mas ambicioso… “La creación de una simple pantalla matricial a Leds”.
Si bien, se podría implementar un puerto para cada LED, esto nos llevaría a requerir de un microcontrolador con varios puertos y a su vez, estaríamos desperdiciando un microcontrolador, ya que la cantidad de puertos empleados para controlar el hardware de la pantalla, serian muchos y no aprovecharíamos su máximo rendimiento para emplearlo en mas de una cosa; Es por ello, que en este articulo, aprenderemos otro método mas de control matricial, que se lo denomina “control por multiplexacion”.
Una matriz es una tabla rectangular de números ordenados por filas y columnas. Para nuestro caso, tenemos una matriz con lógica binaria; Es decir, los valores de la matriz, pueden varían entre 1 y 0 lógico (encendido, 0 apagado).
Si nos vamos a la estructura interna de las pantallas a led, sencillamente lo que podemos encontrar en la gran mayoría de estos hardware, es un arreglo de LED conectados en filas y columnas (ver imagen inferior); que por esta misma razón, se los llama y o denomina, Pantallas Matriciales.
ANÁLISIS DE CIRCUITO
El control multiplexado de una matriz de 49 LEDs (o sea, una matriz como la de nuestro ejemplo, pero puede ser de mas o menos leds), es muy sencilla y sólo requiere un truco; La implementación del método de “persistencia de la visión”, que en si, es un sencillo efecto visual, donde son tan rápidas las conmutaciones de los Leds, que el ojo no percibe estos cambios y podemos ver figuras, números, letras, etc, en la pantalla.
O sea, lo que hacemos, es encender y apagar repetidas veces cada led afectado a la figura a una velocidad importante, y el ojo no notara el parpadeo de los led, todo lo contrario; Solo vera la figura formada por los led que se encendieron.
Notaran que mencione que nuestra matriz esta compuesta por 49 led… Bien, como el
picaxe18x tan solo posee 8 salidas digitales, nos estarían faltando, supuestamente, 6 u 7 salidas mas para poder crear nuestra matriz de 49 leds ; Para que esto ultimo no sea un impedimento en la creación de nuestro proyecto, observemos el siguiente diagrama de circuito, para ver como resolvimos nuestro pequeño dilema.
Como verán, para obtener estas salidas que nos estaban faltando, recurrimos a un circuito integrado que trabajara como auxiliar en nuestro proyecto. Este CI, es un contador Johnson (CD4017); Y básicamente, tiene la función de activar sus salidas en forma lineal, a cada pulso de reloj que tenga en su entrada. O sea, cuando recibe el 1er pulso de reloj este circuito integrado, activa la salida1, al siguiente pulso de reloj, desactiva la salida1 y activa la salida2, y así sucesivamente hasta que sea reseteado. Digamos que es ideal para nuestra aplicación, ya que nosotros solo deseamos que active una fila por vez.
Como la corriente del CD4017 es muy baja (1mA) y nosotros requerimos de una corriente de 60mA por columna; En serie a las salidas de nuestro contador Johnson, hemos implementado un circuito integrado mas a nuestro diseño, que es un Array de transistores (algo así como implementar dos transistores en configuración darlington para cada salida, pero mas reducido en un solo IC).
La implementación del ULN2803, es para obtener más corriente a través de los LEDs (este nos entrega 500mA), y si bien podría implementar un par de transistores NPN, resolví implementar este IC por una cuestión cómoda a la hora de diseñar nuestro PCB (ocupa mucho menos espacio).
INTRODUCCIÓN A LA PROGRAMACION
La rutina de control, es relativamente simple y fácil de seguir.
Primero que nada, debemos definir nuestros caracteres y o imágenes a imprimir en la pantalla de leds.
Para ello, dibujaremos una cuadricula que sea similar a nuestra matriz, y dentro de cada circulo, le asignaremos un valor absoluto hasta formar nuestra imagen...
Luego, tomaremos el valor de cada fila, y esos valores, serán los bits de cada puerto a la hora de controlar nuestro picaxe.
Por ejemplo, si tenemos la siguiente situación (dibujaremos la letra “X”):
Una vez que ya tenemos lista la tabla con los valores que adoptara cada salida, para formar la figura; Tomaremos estos valores y los introduciremos en nuestro programa del picaxe, de la siguiente manera…
Como podemos deducir en el programa, para habilitar cada fila, primero vamos al
subprograma “clock4017” (recordar que en cada pulso de reloj, este CI, desplaza sus salidas linealmente, o sea, va encendiendo y apagando sus salidas en un orden especifico).
Una vez que habilitamos la fila, volvemos al programa principal, y daremos la orden de que led deben encenderse y cuales no , osea, habilitaremos las columnas que deseemos (esto lo hacemos sencillamente con la función “let pins” mas el valor obtenido en la tabla que creamos anteriormente).
El resto del programa, básicamente es lo mismo. Volvemos a repetir los pasos para mandar el pulso de clock en el CD4017, y luego daremos la orden de que columnas queremos encender… Veamos este mismo ejemplo, un poco mas grafico:
Y así sucesivamente hasta formar la imagen…
La idea, es entrar en un bucle de parpadeos continuo, que contengan pequeños retardos para que se pueda crear el efecto visual.
El retardo mínimo que podemos emplear en la señal clock del CD4017, es de 20mS y para poder obtener el efecto visual sin notar las conmutaciones de los Leds, deberemos jugar con los valores de b2; cuando mas rápido sea el ciclo mejor.
Recuerden siempre que, las salidas de nuestro picaxe, dicen que led se enciende o no, en cada columna; y el CD4017, es el encargado de habilitar cada fila. Con estos dos importantes datos, de seguro muchos proyectos podrán comenzar a crear.
Para cerrar el tema de matriz, acá dejo un ejemplo casi completo de una matriz de led (mas de 300), que es gobernada por un microcontrolador... Digo casi, por que no esta simulada toda la etapa de potencia, pero se entiende perfectamente el circuito...
Lo que la hace distinta a los demas proyectos de matriz que pueden encontrar en google, es que la mia es serial y por intermedio de un software u otro microcontrolador con teclado (mas adelante veremos un ejemplo de teclado ps2 con pic que se amolda justo a este proyecto), podemos escribir en ella... Ahí les arme un archivo comprimido con la simulacion en proteus, el hex y una nota para que sepan como simularlo con el Hyper terminal...
CONTROL DE LED CON POKE
Bueno, acá tenemos el tipico "Hello Word" de los PIC´s... encender un led ; pero en esta ocasion, vamos hacerlo un poco mas interesante... vamos hacer una seudo-animacion con el comando POKE y vamos a encender y pagar los led escalonadamente...
TRISA=$FF
TRISB=0
BUTONsubir VAR BYTE
BUTONbajar VAR BYTE
b1 VAR BYTE
SYMBOL LED=$6
BUTONsubir=0
BUTONbajar=0
b1=0
PORTB=0
inicio:
BUTTON PORTA.0,0,254,254,BUTONsubir,1,subeLED
BUTTON PORTA.3,0,254,254,BUTONbajar,1,bajaLED
GOTO inicio
subeLED:
b1=b1+1
POKE LED,b1
GOTO inicio
bajaLED:
b1=b1-1
POKE LED,b1
GOTO inicio
END
CONTADOR 0-99
sencillo programa para armar un contador de 0 a 99 con display 7 segmentos
TRISA=0
TRISB=0
CONTA VAR BYTE
UNIDAD VAR BYTE
DECENA VAR BYTE
UNIDAD=0
INCREMENTAR:
PORTA=1
FOR CONTA= 1 TO 10
LOOKUP CONTA,[8,0,1,2,3,4,5,6,7,8,9],UNIDAD
PORTB=UNIDAD
PAUSE 150
NEXT
GOSUB DECENAS
DECENAS:
PORTB=DECENA
PORTA=2
IF DECENA=10 THEN INCREMENTAR
DECENA=DECENA+1
PAUSE 100
GOSUB INCREMENTAR
otro sencillo programa para armar un contador, pero en esta ocasion de 0 a 99... si observan, es muy facil de modificarlo con un par de lineas mas para ampliarlo a mas digitos...
Código:
TRISB=0
w1 VAR WORD
w2 VAR WORD
w3 VAR WORD
w4 VAR WORD
PORTB=0
w1=0
inicio:
w1=w1+1
PAUSE 1
IF w1=999 THEN w1=0
w2=w1 DIG 0
w3=w1 DIG 1
w4=w1 DIG 2
PORTB=240 | w2
LOW PORTB.6
PAUSE 1
HIGH PORTB.6
PAUSE 1
PORTB=240 | w3
LOW PORTB.5
PAUSE 1
HIGH PORTB.5
PAUSE 2
PORTB=240 | w4
LOW PORTB.4
PAUSE 1
HIGH PORTB.4
PAUSE 1
GOTO inicio
END
PWM EN 2DO PLANO
Basicamente, con este ejemplo, se muestra como generar un pwm por hardware, el cual trabaja en 2do plano sin importar el resto del programa... Mas adelante, les voy a mostrar un proyecto mas interesante, donde apartir de una lectura por el puerto analogico, podemos variar el PWM por hardware, y ese mismo dato del puerto analogico, lo podremos usar para el resto del programa...
Código:
@ device xt_osc
define osc 4
CMCON = 7
VRCON = 0
TRISB = %11110000
PR2 = 25
CCPR1L = 13
CCP1CON = %00001100
T2CON = %00000100
LOOP:
high PortB.0
pause 50
low PortB.0
pause 50
high PortB.1
pause 50
low PortB.1
pause 50
high PortB.2
pause 50
low PortB.2
pause 50
goto LOOP
No es perfecto, pero puede ser una solucion a la hora de crear un potenciometro digital... acá va el 1er diseño, despues subo otro que funciona con un sencillo PWM y filtro a la salida de tan solo 1 puerto
Código:
@ Device PIC16F628A
@ Device Intrc_Osc
define Osc 4
CmCon=7
TrisA=%01100000
TrisB=%00000000
A var word
porta=0
portb=0
a=0
Gosub salida
inicio:
if PortA.6=0 then a=a+1:Gosub salida
if PortA.5=0 then
if porta>=1 then a=a-1
gosub salida
endif
Goto inicio
salida:
porta=0
select case a
case 0
TrisA=%01100000
TrisB=%00000000
case 1
TrisA=%01100000
TrisB=%00000001
case 2
TrisA=%01101111
TrisB=%00000001
case 3
TrisA=%01110001
TrisB=%00000001
case 4
TrisA=%01110111
TrisB=%00000001
case 5
TrisA=%01111000
TrisB=%00000001
case 6
TrisA=%01111011
TrisB=%00000001
case 7
TrisA=%01111100
TrisB=%00000001
case 8
TrisA=%01111101
TrisB=%00000001
case 9
TrisA=%01111110
TrisB=%00000001
case 10
TrisA=%01111111
TrisB=%00000001
end select
pause 200
Return
TECLADO HEX
Sencillo ejemplo de un teclado hex con un display 7 segmentos, donde se visualiza la tecla que oprimimos...
Código:
@ device xt_osc
define osc 4
fila VAR BYTE
columna VAR BYTE
tecla VAR BYTE
TRISA=0
LOOP1:
PORTB=0
TRISB=%11110000
IF ((PORTB>>4)!=%1111) THEN LOOP1
LOOP2:
FOR FILA=0 TO 3
PORTB=0
TRISB=(DCD FILA)^%11111111
COLUMNA=PORTB>>4
IF COLUMNA!=%1111 then numtecla
NEXT FILA
GOTO LOOP2
NUMTECLA:
TECLA=(FILA*4)+(NCD(COLUMNA^%1111))
PORTA=TECLA
GOTO LOOP1
END
Bueno, aca les comparto un excelente ejemplo aportado por el amigazo MECADATROS, que es similar al ejemplo anterior, pero con la diferencia que se visualiza en un display LCD...
Código:
'****************************************************************
'* Name : UNTITLED.BAS *
'* Author : mecatrodatos *
'* Notice : Copyright (c) 2009 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 8/17/2009 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
; programa de visualizacion de teclado
' 1 2 3 A
' 4 5 6 B
' 7 8 9 C
' * 0 # D
' con pic 16f877A y lcd 2x16 en donde muestra la tecla presionada en la pantalla
' del LCD utilizando operandos matematicos del PBP.
'Definir libreria
Define LOADER_USED 1
'definir oscilador externo
@ device xt_osc
define osc 4
' Define LCD connections
Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTD
Define LCD_RSBIT 3
Define LCD_EREG PORTD
Define LCD_EBIT 2
' Definicion de variables
col Var Byte ' columnas
fila Var Byte ' filas
B Var Byte ' numero
A Var Byte ' tecla a visualizar
OPTION_REG.7 = 0 ' Activa resistencias internas PORTB
ADCON1 = 7 ' PORTA y PORTE digital
Low PORTD.1 ' LCD R/W low (escritura)
Pause 100 ' tiempo para inicializar el LCD
Lcdout $fe, 1, "PRESIONE TECLA" ' mensaje
inicio:
Gosub leer
Lookup A, ["0123456789*#ABCD"],B
Lcdout $fe,1,B ' mostrar tecla primida
Goto inicio
' Subrutina para leer tecla pulsada
leer:
Pause 50 ' esperer 50ms
leer0:
PORTB = 0 ' puerto B como salida
TRISB = $f0
If ((PORTB >> 4) != $f) Then leer0
Pause 50
leer1:
For col = 0 To 3
PORTB = 0
TRISB = (dcd col) ^ $ff
fila = PORTB >> 4 'leer filas
If fila != $f Then tecla
Next col
Goto leer1
tecla:
B = (col * 4) + (ncd (fila ^ $f)) - 1
' transformacion de tecla activada
' 10 = *
' 11 = #
' 12 = A
' 13 = B
' 14 = C
' 15 = D
Lookup B, [1,2,3,12,4,5,6,13,7,8,9,14,10,0,11,15],A
Return ' retornar
End
LECTURA SIMULTANEA 3 LM35
Bueno, aca les dejo un ejemplo basico de como leer tres puertos analogicos a la vez y visualizar el dato en un display LCD....
Código:
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3
DEFINE LCD_RWREG PORTB
DEFINE LCD_RWBIT 2
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 1
DEFINE LCD_LINES 4
DEFINE LCD_BITS 4
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50
A_canal VAR WORD
B_canal VAR WORD
C_canal VAR WORD
ADCON1=%10000010
TRISA=255
TRISB=0
PORTB=0
LOW PORTB.2
PAUSE 500
inicio:
LCDOUT $FE,$83,"MartinTorres"
ADCIN 0,A_canal
A_canal=(A_canal*/500)>>2
A_canal=A_canal*32
A_canal=A_canal/10
LCDOUT $FE,$C0,"A_canal = ",DEC (A_canal/100),".", DEC2 A_canal,"VOLT"
ADCIN 1,B_canal
B_canal=(B_canal*/625)>>2
B_canal=B_canal*32
B_canal=B_canal/10
LCDOUT $FE,$94,"B_canal = ",DEC (B_canal/100),".", DEC2 B_canal,"VOLT"
ADCIN 2,C_canal
C_canal=(C_canal*/500)>>2
C_canal=C_canal*32
C_canal=C_canal/10
LCDOUT $FE,$D4,"C_canal = ",DEC (C_canal/100),".", DEC2 C_canal,"VOLT"
PAUSE 100
PAUSE 100
PAUSE 100
GOTO inicio
MULTIPLE LECTURA ANALOGICA
Bueno, aca les dejo otro ejemplo de multiple lectura de puertos analogicos, pero en este caso, los 8 puertos analogicos y visualizar el dato en un display LCD....
Código:
TRISA=%101111
TRISE=255
TRISB=0
OPTION_REG.7=0
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 2
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50
AN0 VAR WORD
AN1 VAR WORD
AN2 VAR WORD
AN3 VAR WORD
AN4 VAR WORD
AN5 VAR WORD
AN6 VAR WORD
AN7 VAR WORD
ADCON1=%10100000
LCDOUT $FE,1
LCDOUT $FE,$82,"www.ucontrol.com"
LCDOUT $FE,$C0,"www.yoreparo.com"
LCDOUT $FE,$96,"Martin Torres"
LCDOUT $FE,$D4,"Lectura 8 ADC"
PAUSE 5000
inicio:
ADCIN 0,AN0
LCDOUT $FE,1,"AN0:",DEC AN0
ADCIN 1,AN1
LCDOUT $FE,$8B,"AN1:",DEC AN1
ADCIN 2,AN2
LCDOUT $FE,$C0,"AN2:",DEC AN2
ADCIN 3,AN3
LCDOUT $FE,$CB,"AN3:",DEC AN3
ADCIN 4,AN4
LCDOUT $FE,$94,"AN4:",DEC AN4
ADCIN 5,AN5
LCDOUT $FE,$9F,"AN5:",DEC AN5
ADCIN 6,AN6
LCDOUT $FE,$D4,"AN6:",DEC AN6
ADCIN 7,AN7
LCDOUT $FE,$DF,"AN7:",DEC AN7
PAUSE 500
GOTO inicio
END
DESPLAZADORES DE REGISTRO:
Una manera sencilla de controlar un shift register (registros de desplazamiento) tipo 74HC595
Click acá para ver la hoja de datos)
Código:
TRISA=25
TRISB=0
PORTA=0
PORTB=0
SYMBOL CLK=PORTA.0
SYMBOL DTA=PORTA.1
SYMBOL TRANSFERENCIA=PORTA.3
DATO VAR WORD
PORTA=0
DATO=1
inicio:
IF DATO=256 THEN DATO=1
SHIFTOUT DTA,CLK,1,[DATO]
HIGH TRANSFERENCIA
PAUSE 5
LOW TRANSFERENCIA
BILGI=DATO*2
PAUSE 500
GOTO inicio
END
Una manera sencilla de controlar un shift register (registros de desplazamiento) tipo 74LS164
Click acá para ver la hoja de datos)
Código:
TRISA=0
TRISB=0
CLEARR VAR PORTA.0 'CLEAR
CLOCK VAR PORTA.2 'CLOCK
DATO_0 VAR PORTA.3 'DATA
DATO_1 VAR BYTE
DATO_2 VAR BYTE
CLOCK=1
DATO_1=%00001111
DATO_2=%11110000
INICIO:
TEST1:
shiftout DATO_0,CLOCK,MSBFIRST,[DATO_1]
PAUSE 500
TEST2:
shiftout DATO_0,CLOCK,MSBFIRST,[DATO_2]
PAUSE 500
GOTO INICIO
END
a ver si sirve a modo de ejemplo sencillo de un 74165:
Click acá para ver la hoja de datos
Código:
TRISA=%00000001
TRISB=0
PORTA=0
PORTB=0
DATO VAR BYTE
DATO =0
INICIO:
LOW PORTA.2 : PAUSEUS 1 : HIGH PORTA.2
SHIFTIN PORTA.0,PORTA.1,0,[DATO]
PORTB= DATO
PAUSE 300
GOTO INICIO
END
Sencillo ejemplo de como controlar un StepMotor con un L298
Código:
@ device pic16f877A,xt_osc
define OSC 4
Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTD
Define LCD_RSBIT 2
Define LCD_EREG PORTD
Define LCD_EBIT 3
Define ADC_BITS 10
Define ADC_CLOCK 3
Define ADC_SAMPLEUS 50
TrisB=255
TrisC=0
Portc=%110000
SensA var word
SensB var word
AStep Var word
ADCON1 = %10000010
astep=0
Pause 500
Inicio:
if portb.0=1 then
if portb.1=0 then astep=Astep+1
if portb.1=1 then
if astep<>0 then astep=Astep-1
endif
if portb.2=0 then gosub mueveh
if portb.2=1 then gosub muevef
if portb.3=0 then Lcdout $fe,1,"Value A:", DEC astep
endif
if portb.3=1 then gosub adc
Goto inicio
End
MueveF:
if astep>=5 then astep=1
if astep<=0 then astep=4
if astep=1 then portc=58
if astep=2 then portc=54
if astep=3 then portc=53
if astep=4 then portc=57
pause 10
return
MueveH:
if astep>=9 then astep=1
if astep<=0 then astep=8
if astep=1 then portc=17
if astep=2 then portc=57
if astep=3 then portc=40
if astep=4 then portc=58
if astep=5 then portc=18
if astep=6 then portc=54
if astep=7 then portc=46
if astep=8 then portc=53
pause 10
return
ADC:
ADCIN 0, SensA
ADCIN 1, SensB
Lcdout $fe,1,"Value A:", DEC sensa," B:",Dec sensb
Return
Bueno, un ejemplo muy basico de como controlar un servo:
Código:
cmcon=7
x var byte
trisb=%00000110
portb=0
x=150
inicio:
pulsout portb.0,x
gosub timer
goto inicio
timer:
if portb.1=1 then gosub mas
if portb.2=1 then gosub menos
return
mas:
pause 10
x=x+1
if x>200 then x=200
return
menos:
pause 10
x=x-1
if x<100 then x=100
return
end
Y acá les dejo otro ejemplo del amigo MECATRODATOS
Código:
;Programa en donde se mueve un servo motor de tres lineas con el pic 16f877A,
;se utiliza LCD 2X16 que muestra la posicion de giro dada por tres botones
;conectados al puerto B, los cuales dan las posiciones: giro derecha ,centro y
;giro izquierda referenciado de 0 a 1000, donde posicion de centro es 500.
; deficion de Oscilador Externo
@ device xt_osc ; oscilador externo XT
define osc 4 ; especifica que se va a utilizar uno de 4 Mhz
' Libreria para la operacion del programa
Define LOADER_USED 1
; Definicion de conecciones del LCD
Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTA
Define LCD_RSBIT 0
Define LCD_EREG PORTA
Define LCD_EBIT 1
pos var word ' Posicion del servo
servo1 var PORTC.1 'pin donde se conecta el servo
ADCON1 = 7 ' PORTA y PORTE digitales
Low PORTA.2 ' LCD R/W low = escritura
Pause 100 ' retardo para inicializar el LCD
OPTION_REG = $7f
Low servo1 ;portc.1 como salida para controlar el servo
Gosub center 'ir a centro
LOOP:
PORTB = 0 ' PORTB lineas a cero logico para leer botones
TRISB = $fe
'Rutinas para el chequeo de botones y posiciones del servo
If PORTB.4 = 0 Then
Gosub left
Endif
If PORTB.5 = 0 Then
Gosub center
Endif
If PORTB.6 = 0 Then
Gosub right
Endif
;Rutina para mostrar mensaje y valor decimal de la posicion del servo
Lcdout $fe,1
Lcdout $fe,2,"Position = ", #pos
servo1 = 1 ' iniciar pulso hacia el servo
Pauseus 1000 + pos
servo1 = 0 ' termine pulso
Pause 16 ' retardo
Goto LOOP ' Crea un bucle cerrado
' giro hacia la izquierda
left: If pos < 1000 Then
pos = pos + 1
Endif
Return
' giro hacia la derecha
right: If pos != 0 Then
pos = pos - 1
Endif
Return
' posicion de centro
center: pos = 500
Return
End
Bueno, este proyecto puede ser una sencilla adaptacion a nuestras fuentes de laboratorio que no tienen monitor de tension y corriente...
Código:
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3
define lcd_RWREG PORTB
define LC_RWBIT 2
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50
@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_off
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, XT_OSC
ADCON1=%10001110
TRISA=%00010011
TRISB=0
TRISC=0
VOLT VAR WORD
LECTURA VAR WORD
HVD var word
AMPER var word
MV VAR BYTE
MA VAR BYTE
PORTB=0
PORTA=0
VOLT=0
PAUSE 100
LCDOUT $FE,1
INICIO:
ADCIN 0,LECTURA
CICLO:
IF ADCON0.2=1 THEN CICLO
PAUSE 5
GOSUB CALCULO_V
ADCIN 1,LECTURA
PAUSE 5
GOSUB CALCULO_A
GOSUB PANTALLA
PAUSE 1500
GOTO INICIO
PANTALLA:
' LCDOUT$FE,2,"LECTURA=",#LECTURA
LCDOUT $FE,$02,"VOLT =",DEC VOLT,",",DEC1 MV
LCDOUT $FE,$C0,"AMPER=",DEC2 AMPER,",",DEC2 MA
' LCDOUT $FE,$C0,"AMPER=",DEC HVD
RETURN
CALCULO_V:
HVD=((LECTURA+1)*/875)/10
VOLT=HVD/10
MV=(HVD)//10
RETURN
CALCULO_A:
HVD=(LECTURA+1)*/250
AMPER=HVD/100
MA=HVD//100
RETURN
Aclaro algo bastante importante..."No se parece en nada al mostro que armo el amigo Sergio (Felix)"
COMUNICACION SERIAL
Este es un sencillo ejemplo de como enviar la informacion adquirida desde los puertos de un microcontrolador, hasta el otro microcontrolador y luego imprimir la accion en el display...
Microcontrolador emisor:
Código:
INCLUDE "modedefs.bas"
define OSC 4
BOTON_A VAR PORTA.0
BOTON_B VAR PORTA.1
BOTON_C VAR PORTA.2
BOTON_L VAR PORTA.3
SALIDA VAR PORTB.0
TRISA=1
TRISB=0
PORTA=0
PORTB=0
TRANSMITIR:
IF BOTON_A=1 THEN ENVIA_LETRA_A
IF BOTON_B=1 THEN ENVIA_LETRA_B
IF BOTON_C=1 THEN ENVIA_LETRA_C
IF BOTON_L=1 THEN LIMPIAR_PANTALLA
GOTO TRANSMITIR
ENVIA_LETRA_A:
SEROUT SALIDA,N2400,["A"]
PAUSE 500
GOTO TRANSMITIR
ENVIA_LETRA_B:
SEROUT SALIDA,N2400,["B"]
PAUSE 500
GOTO TRANSMITIR
ENVIA_LETRA_C:
SEROUT SALIDA,N2400,["C"]
PAUSE 500
GOTO TRANSMITIR
LIMPIAR_PANTALLA:
SEROUT SALIDA,N2400,["0"]
PAUSE 500
GOTO TRANSMITIR
END
Microcontrolador receptor:
Código:
include "modedefs.bas"
define OSC 4
TRISB=0
TRISA=1
PORTA=0
DEFINE LCD_LINES 2
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 3
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 2
ENTRADA VAR PORTA.0
DATOS VAR BYTE
LCDOUT $FE,1
pause 500
RECIBIR:
LCDOUT $FE,2,"RECIBIENDO DATO:"
SERIN ENTRADA,N2400,DATOS
IF DATOS="A" THEN LCDOUT $FE,$C3,"A"
if datos="B" THEN LCDOUT $FE,$C3,"B"
IF DATOS="C" THEN LCDOUT $FE,$C3,"C"
if DATOS="0" THEN LIMPIAR_LCD
GOTO RECIBIR
LIMPIAR_LCD:
LCDOUT $FE,1
PAUSE 500
GOTO RECIBIR
END
Bueno, seguimos con el segundo ejemplo basico de comunicaciones seriales Pic a Pic, pero con la diferencia del ejemplo anterior, que en esta oportunidad, en el PIC transmisor, colocaremos un teclado (keypad)
Microcontrolador emisor:
Código:
TRISA=0
TRISB=%00001110
CMCON=7
OPTION_REG.7=0
SYMBOL SALIDA=PORTA.0
NUM VAR WORD
B1 VAR BYTE
SYMBOL P_A=PORTB.4
SYMBOL P_B=PORTB.5
SYMBOL P_C=PORTB.6
SYMBOL P_D=PORTB.7
SYMBOL P_1=PORTB.1
SYMBOL P_2=PORTB.2
SYMBOL P_3=PORTB.3
NUM=0
B1=0
PAUSE 500
INICIO:
PORTB=254
P_A=0
IF P_1=0 THEN
B1=10
GOSUB ENVIAR
WHILE P_1=0
WEND
ENDIF
IF P_2=0 THEN
B1=20
GOSUB ENVIAR
WHILE P_2=0
WEND
ENDIF
IF P_3=0 THEN
B1=30
GOSUB ENVIAR
WHILE P_3=0
WEND
HIGH P_A
ENDIF
P_B=0
IF P_1=0 THEN
B1=40
GOSUB ENVIAR
WHILE P_1=0
WEND
ENDIF
IF P_2=0 THEN
B1=50
GOSUB ENVIAR
WHILE P_2=0
WEND
ENDIF
IF P_3=0 THEN
B1=60
GOSUB ENVIAR
WHILE P_3=0
WEND
ENDIF
HIGH P_B
P_C=0
IF P_1=0 THEN
B1=70
GOSUB ENVIAR
WHILE P_1=0
WEND
ENDIF
IF P_2=0 THEN
B1=80
GOSUB ENVIAR
WHILE P_2=0
WEND
ENDIF
IF P_3=0 THEN
B1=90
GOSUB ENVIAR
WHILE P_3=0
WEND
ENDIF
HIGH P_C
P_D=0
IF P_1=0 THEN
B1=100
GOSUB ENVIAR
WHILE P_1=0
WEND
ENDIF
IF P_2=0 THEN
B1=110
GOSUB ENVIAR
WHILE P_2=0
WEND
ENDIF
IF P_3=0 THEN
B1=120
WHILE P_3=0
WEND
GOSUB ENVIAR
ENDIF
HIGH P_D
PAUSE 100
GOTO INICIO
ENVIAR:
SEROUT2 SALIDA,396,["U","C","O","N","T","R","O","L",B1]
SEROUT2 SALIDA,396,["U","C","O","N","T","R","O","L",B1]
SEROUT2 SALIDA,396,["U","C","O","N","T","R","O","L",B1]
SEROUT2 SALIDA,396,["U","C","O","N","T","R","O","L",B1]
RETURN
END
Microcontrolador receptor:
Código:
TRISA=%00001
TRISB=0
PORTA=0
PORTB=0
OPTION_REG.7=0
CMCON=7
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 2
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4
b1 VAR BYTE
INTRO VAR PORTA.0
CLEAR
Bueno, arrancamos con el 3er ejemplo de comunicacion, pero en este caso, les muestro que "tan"
engorroso pueden llegar a ser las comunicaciones Rf empleando los modulos economicos RF de 433Mhz
Microcontrolador emisor:
Código:
@ DEVICE PIC16F628A
@ DEVICE INTRC_OSC
@ DEVICE WDT_OFF
@ DEVICE PWRT_OFF
@ DEVICE MCLR_OFF
@ DEVICE BOD_OFF
@ DEVICE LVP_OFF
@ DEVICE CPD_OFF
@ DEVICE PROTECT_OFF
DEFINE OSC 4
TRISB=%01
serout portb.1,4,[$10]
INICIO:
IF PORTB.0 THEN
pause 500
SEROUT PORTB.1,4,["A",84]
ENDIF
gOTO INICIO
Microcontrolador receptor:
Código:
@ DEVICE PIC16F628A
@ DEVICE INTRC_OSC
@ DEVICE WDT_OFF
@ DEVICE PWRT_OFF
@ DEVICE MCLR_OFF
@ DEVICE BOD_OFF
@ DEVICE LVP_OFF
@ DEVICE CPD_OFF
@ DEVICE PROTECT_OFF
DEFINE OSC 4
TRISB=%10
B0 var byte
INICIO:
SERin PORTB.1,4,["A"],B0
if b0=84 then high PortB.0:pause 1000:low PortB.0
gOTO INICIO
Comunicacion serial "PIC - Modem GSM ENFORA".
Dentro de la gran variedad de modem GSM / GPRS que hay en el mercado, el modem enfora a mi parecer es uno de los modem mas completo y rusticos que hay dando vuelta.
El equipo cuenta con un puerto de entradas y salidas configurables para empleo multiproposito:
2 puertos de entrada convertidores analogicos digital (ADC)
1 puerto de salida convertidor digital analogico (DAC)
4 puertos digitales configurables como I/O
Tambien esta la opcion de poder configurar los tres primeros mencionados como entradas o salidas digitales
Me olvidaba mencionar que el mismo equipo, cuenta tambien con un puerto de sonido incorporado, donde nosotros podemos introducir un microfono y auricular para establecer comunicacion como con cualquier otro celular...
Los comandos AT son genericos, asi que no varia mucho el control de este modem, con cualquier otro, esceptuando el control de los puertos y o, por ahi, la configuracion para internet es un poco engorrosa y distinta a otros modem, pero con unsa horas de pruebas falla / error, se aca adelante estos temas.
Les muestro un sencillo ejemplo de comunicacion con este modem (solo envio de SMS)
Código:
Inicio:
gosub ELIMINAR
serout PORTC.6,N9600,["AT+CMGR=1",10,13]
pause 100
loop:
if PORTB.0=0 then mensaje1:
pause 50
goto loop
mensaje1:
gosub ENVIO_1
serout PORTC.6,N9600,["ALARMA Z1",26,10,13]
GOTO INICIO
ENVIO_1:
pause 2000
SEROUT PORTC.6,N9600,["at+cmgf=1",10,13]
pause 1000
SEROUT PORTC.6,N9600,["at+cmgs=",34,"+54297XXXXXXX",34,10,13]
pause 5000
return
ELIMINAR:
PAUSE 100
SEROUT PORTC.6,N9600,["at+cmgd=1",10,13]
pause 1000
return
Vallamos a un ejemlpo mas interesante... una alarma con teclado, display lcd y comunicacion gsm:
Código:
include "modedefs.bas"
define OSC 4
ADCON1 = %00001111 ;el puerto A.0 es conversor los demás Digitales
TRISA = %00001111
TRISB = %00011111
TRISC = %10000000
TRISD = %00000011
TRISE = %00000000
;*************** DISPLAY LCD ****************
DEFINE LCD_DREG PORTD
DEFINE LCD_BITS 4 ;DB4-PORTD.4
DEFINE LCD_DBIT 4 ;DB7-PORTD.7
DEFINE LCD_RSREG PORTD
DEFINE LCD_RSBIT 2 ;RS-PORTD.2
DEFINE LCD_EREG PORTD
DEFINE LCD_EBIT 3 ;E-PORTD.3
DEFINE LCD_LINES 2 ;LCD DE 2 LINEAS
POS1 var Byte
POS2 var Byte
POS3 var Byte
POS4 var Byte
POS1 = $C0 ' Ver figura 6.13
POS2 = $C1 '
POS3 = $C2 '
POS4 = $C3
LCDOUT $FE,$40,$00,$00,$10,$0F,$0F,$0D,$18,$10 ' Palabra 0 de la CGRAM
LCDOUT $FE,$48,$04,$0E,$1F,$1C,$1C,$1C,$06,$05 ' Palabra 1 de la CGRAM
LCDOUT $FE,$50,$00,$00,$10,$0F,$0F,$0D,$04,$06 ' Palabra 2 de la CGRAM
LCDOUT $FE,$58,$04,$0E,$1F,$1C,$1C,$1C,$08,$18 ' Palabra 3 de la CGRAM
LCDOUT $FE,$60,$04,$0E,$1F,$07,$07,$07,$02,$03 ' Palabra 4 de la CGRAM
LCDOUT $FE,$68,$00,$00,$01,$1E,$1E,$16,$04,$0C ' Palabra 5 de la CGRAM
LCDOUT $FE,$70,$04,$0E,$1F,$07,$07,$07,$0C,$14 ' Palabra 6 de la CGRAM
LCDOUT $FE,$78,$00,$00,$01,$1E,$1E,$16,$03,$01 ' Palabra 7 de la CGRAM
;**************** TECLADO ******************
UNO VAR PORTB.1 ;nombres para los pines de las columnas
DOS VAR PORTB.2
TRES VAR PORTB.3
CUATRO VAR PORTB.4
A VAR PORTB.5 ;nombres para los pines de las filas
B VAR PORTB.6
C VAR PORTB.7
D VAR PORTC.0
;*************** SALIDAS ********************
LEDROJO VAR PORTE.0
LEDVERDE VAR PORTE.1
SIRENA VAR PORTE.2
SONIDO VAR PORTA.5
;*************** VARIABLES ******************
BANDERA VAR BYTE
BANDERA1 VAR BYTE
BANDERA2 VAR BYTE
NUMERO VAR BYTE ;variable número para almacenar la tecla pulsada
R VAR BYTE ;variable r para hacer repeticiones
SET1 VAR BYTE
SET2 VAR BYTE
SET3 VAR BYTE
SET4 VAR BYTE
dato VAR WORD ;crear variable dato para guardar
seguridad_ON var byte
On Interrupt GoTo ZONA ' Define el vector de interrupción.
INTCON = %10010000 ' Activa el inspector de interrupciones y
' habilita la interrupción RB0/INT.
LCDOUT $FE,1
LCDOUT "INICIO SISTEMA"
LCDOUT $FE,$C2,"DE SEGURIDAD"
PAUSE 1000
GOSUB perroGUARDIAN
LCDOUT $FE,1
BANDERA = 0
INICIANDO:
FOR R=1 TO 2
HIGH LEDROJO:HIGH LEDVERDE:HIGH SONIDO
PAUSE 200
LOW LEDROJO:LOW LEDVERDE:LOW SONIDO
PAUSE 100
NEXT
LCDOUT $FE,$C0, 0
;******************GUARDAR LA CLAVE EN LA MEMORIA EEPROM************************
EEPROM 0,[1,2,3,4]
;*******************************************************************************
ARRANQUE:
PAUSE 500
LCDOUT $FE,1
LCDOUT "(*)S/N (#)Config"
LCDOUT $FE,$C0,"(0) PRUEBA GSM"
BANDERA = 0
;*******************************************************************************
LOW A
IF UNO=0 THEN NUMERO=1:RETURN
IF DOS=0 THEN NUMERO=2:RETURN
IF TRES=0 THEN NUMERO=3:RETURN
HIGH A
;*******************************************************************************
LOW B
IF UNO=0 THEN NUMERO=4:RETURN
IF DOS=0 THEN NUMERO=5:RETURN
IF TRES=0 THEN NUMERO=6:RETURN
HIGH B
;*******************************************************************************
LOW C
IF UNO=0 THEN NUMERO=7:RETURN
IF DOS=0 THEN NUMERO=8:RETURN
IF TRES=0 THEN NUMERO=9:RETURN
HIGH C
;*******************************************************************************
LOW D
IF UNO=0 THEN mensajeACTIVADO
IF DOS=0 THEN MODEM
IF TRES=0 THEN GRABAUNO
HIGH D
PAUSE 25
GOTO ARRANQUE
mensajeACTIVADO:
GOSUB perroGUARDIAN
LCDOUT $FE,1
LCDOUT $FE,2," SISTEMA ALARMA "
LCDOUT $FE,$C0," ACTIVADA "
PAUSE 2000
LCDOUT $FE,1
BANDERA = 1
GOTO RESETEO
RESETEO:
;LOW PUERTA
LCDOUT $FE,1
FOR R=1 TO 2
HIGH LEDROJO:HIGH SONIDO
PAUSE 200
LOW LEDROJO:LOW SONIDO
PAUSE 100
IF D=0 AND UNO=0 THEN RESETEO
NEXT
READ 0,SET1
READ 1,SET2
READ 2,SET3
READ 3,SET4
GOSUB TECLAUNO
GRABAUNO:
lcDout $FE,1
LCDOUT $FE,3,"INGRESE SU CLAVE":LCDOUT $FE,$C3,"ANTERIOR"
PAUSE 1000
GOSUB TCLAUNO
RETURN
TCLAUNO:
LCDOUT $FE,1
LCDOUT $FE,2,"CLAVE ANTERIOR:"
GOSUB BARRIDO
GOSUB PTECLA
IF NUMERO=SET1 THEN GOSUB TCLADOS
GOTO FALSO
TCLADOS:
GOSUB BARRIDO
GOSUB PTECLA
IF NUMERO=SET2 THEN GOSUB TCLATRES
GOTO FALSO1
TCLATRES:
GOSUB BARRIDO
GOSUB PTECLA
IF NUMERO=SET3 THEN GOSUB TCLACUATRO
GOTO FALSO2
TCLACUATRO:
GOSUB BARRIDO
GOSUB PTECLA
IF NUMERO=SET4 THEN GOSUB GRABA_1
GOTO FALSO3
GRABA_1:
LCDOUT $FE,1
LCDOUT $FE,2,"INGRESE SU NUEVA":LCDOUT $FE,$C3,"CLAVE:"
LCDOUT $FE,$C5
GOSUB PTECLA:HIGH LEDROJO
GOSUB BARRIDO:GOSUB PTECLA
HIGH LEDROJO
WRITE 0,NUMERO
GRABADOS:
GOSUB BARRIDO:GOSUB PTECLA
GOSUB PTECLA:HIGH LEDROJO
HIGH LEDROJO
WRITE 1,NUMERO
GRABATRES:
GOSUB BARRIDO:GOSUB PTECLA
GOSUB PTECLA:HIGH LEDROJO
HIGH LEDROJO
WRITE 2,NUMERO
GRABACUATRO:
GOSUB BARRIDO:GOSUB PTECLA
GOSUB PTECLA:HIGH LEDROJO
HIGH LEDROJO
WRITE 3,NUMERO
LOW D
IF D=0 AND UNO=0 THEN RESETEO
HIGH D
PAUSE 500
LCDOUT $FE,1
LCDOUT $FE,2,"NUEVA CLAVE HA"
LCDOUT $FE,$C0,"SIDO CONFIGURADA"
PAUSE 2000
GOTO ARRANQUE
BARRIDO:
;*******************************************************************************
LOW A
IF UNO=0 THEN NUMERO=1:RETURN
IF DOS=0 THEN NUMERO=2:RETURN
IF TRES=0 THEN NUMERO=3:RETURN
HIGH A
;*******************************************************************************
LOW B
IF UNO=0 THEN NUMERO=4:RETURN
IF DOS=0 THEN NUMERO=5:RETURN
IF TRES=0 THEN NUMERO=6:RETURN
HIGH B
;*******************************************************************************
LOW C
IF UNO=0 THEN NUMERO=7:RETURN
IF DOS=0 THEN NUMERO=8:RETURN
IF TRES=0 THEN NUMERO=9:RETURN
HIGH C
;*******************************************************************************
LOW D
IF UNO=0 THEN GOSUB BORRAR
IF DOS=0 THEN NUMERO=0:RETURN
IF TRES=0 THEN GOSUB GRABAUNO
HIGH D
PAUSE 25
GOTO BARRIDO
;*******************************************************************************
PTECLA:
HIGH LEDROJO:HIGH SONIDO
PAUSE 100
LOW LEDROJO:LOW SONIDO
ESPACIO:
IF UNO=0 THEN ESPACIO
IF DOS=0 THEN ESPACIO
IF TRES=0 THEN ESPACIO
PAUSE 25
RETURN
TECLAUNO:
LCDOUT $FE,2,"INTRODUCIR CLAVE"
GOSUB BARRIDO
LCDOUT $FE,$C5, "*"
GOSUB PTECLA
IF NUMERO=SET1 THEN TECLADOS
GOTO FALSO
TECLADOS:
GOSUB BARRIDO
LCDOUT "*"
GOSUB PTECLA
IF NUMERO=SET2 THEN TECLATRES
GOTO FALSO1
TECLATRES:
GOSUB BARRIDO
LCDOUT "*"
GOSUB PTECLA
IF NUMERO=SET3 THEN TECLACUATRO
GOTO FALSO2
TECLACUATRO:
GOSUB BARRIDO
LCDOUT "*"
GOSUB PTECLA
IF NUMERO=SET4 THEN ABRIR
GOTO FALSO3
ABRIR:
LCDOUT $FE,1
LCDOUT $FE,2," CLAVE CORRECTA"
;HIGH PUERTA
FOR R=1 TO 4
HIGH LEDVERDE:HIGH SONIDO
PAUSE 200
LOW LEDVERDE:LOW SONIDO
NEXT
PAUSE 500
LOW D
IF D=0 AND UNO=0 THEN BORRAR
HIGH D
PAUSE 25
GOTO mensajeDESACTIVADO
FALSO:
GOSUB BARRIDO:GOSUB PTECLA:LCDOUT $FE,$C5, "*"
FALSO1:
GOSUB BARRIDO:GOSUB PTECLA:LCDOUT "*"
FALSO2:
GOSUB BARRIDO:GOSUB PTECLA:LCDOUT "*"
FALSO3:
LCDOUT $FE,1
FOR R=1 TO 10
HIGH LEDROJO:HIGH SONIDO
PAUSE 200
LOW LEDROJO:LOW SONIDO
NEXT
IF D=0 AND UNO=0 THEN BORRAR
ALERTA:
LCDOUT $FE,2,"CLAVE INCORRECTA"
HIGH LEDROJO:HIGH SONIDO
PAUSE 200
LOW LEDROJO:LOW SONIDO
LOW D
IF D=0 AND UNO=0 THEN BORRAR
HIGH D
GOTO ALERTA
BORRAR:
LCDOUT $FE,1
GOSUB RESETEO
RETURN
mensajeDESACTIVADO:
PAUSE 1500
LOW SIRENA
BANDERA = 0
LCDOUT $FE,1
LCDOUT $FE,2," SISTEMA ALARMA "
LCDOUT $FE,$C0," DESACTIVADA "
PAUSE 2000
GOTO ARRANQUE
MODEM:
LCDOUT $FE,1
LCDOUT $FE,2,"PRUEBA MODEM GSM"
LCDOUT $FE,$C0," ACTIVADA "
PRUEBA1:
PAUSE 1000
LCDOUT $FE,1
LCDOUT $FE,2,"AT+CMGR=1"
serout PORTC.6,T9600,["AT+CMGR=1",10,13]
serin PORTC.7,T9600,900,PRUEBA2,["+"]
SERIN PORTC.7,T9600,DATO
LCDOUT $FE,$C0,DEC DATO
PRUEBA2:
PAUSE 1000
LCDOUT $FE,1
LCDOUT $FE,2,"AT+CMGD=1"
SEROUT PORTC.6,T9600,["AT+CMGD=1",10,13]
serin PORTC.7,T9600,900,PRUEBA3,["+"]
SERIN PORTC.7,T9600,DATO
LCDOUT $FE,$C0,DEC DATO
PRUEBA3:
pause 1000
LCDOUT $FE,1
LCDOUT $FE,2,"AT+CMGD=2"
SEROUT PORTC.6,T9600,["AT+CMGD=2",10,13]
serin PORTC.7,T9600,900,PRUEBA4,["+"]
SERIN PORTC.7,T9600,DATO
LCDOUT $FE,$C0,DEC DATO
PRUEBA4:
pause 1000
LCDOUT $FE,1
LCDOUT $FE,2,"AT+CMGF=1"
SEROUT PORTC.6,T9600,["AT+CMGF=1",10,13]
serin PORTC.7,T9600,900,PRUEBA5,["+"]
SERIN PORTC.7,T9600,DATO
LCDOUT $FE,$C0,DEC DATO
PRUEBA5:
pause 1000
LCDOUT $FE,1
LCDOUT $FE,2,"2976256173"
SEROUT PORTC.6,T9600,["AT+CMGS=",34,"2976256173",34,10,13]
serin PORTC.7,T9600,900,PRUEBA6,["+"]
SERIN PORTC.7,T9600,DATO
LCDOUT $FE,$C0,DEC DATO
PRUEBA6:
pause 1000
LCDOUT $FE,1
LCDOUT $FE,2,"SMS: PRUEBA TEL"
SEROUT PORTC.6,T9600,["PRUEBA TEL",26,10,13]
serin PORTC.7,T9600,900,PRUEBA7,["+"]
SERIN PORTC.7,T9600,DATO
LCDOUT $FE,$C0,DEC DATO
PRUEBA7:
PAUSE 1500
LCDOUT $FE,1
LCDOUT $FE,2,"PRUEBA TERMINADA"
LCDOUT $FE,$C0," REINICIANDO "
PAUSE 2000
GOTO ARRANQUE
perroGUARDIAN:
LCDOUT $fe, 1 ' Limpia la pantalla LCD
LCDOUT $FE,POS1, 0 ' Muestra Palabra 0 en la LCD
LCDOUT $FE,POS2, 1 ' Muestra Palabra 1 en la LCD
Pause 300
LCDOUT $fe, 1 ' Limpia la pantalla LCD
LCDOUT $FE,POS3, 2 ' Muestra Palabra 2 en la LCD
LCDOUT $FE,POS4, 3 ' Muestra Palabra 3 en la LCD
Pause 300
' Aumentamos la posición de cada símbolo en la pantalla para dar el efecto
' de movimiento:
POS1 = POS1 + 3
POS2 = POS2 + 3
POS3 = POS3 + 3
POS4 = POS4 + 3
If POS4 > $CF Then RETRO ' Pregunta si llega al tope derecho de la LCD
' si POS4 = $CF salta a la etiqueta "RETRO"
goto perroguardian ' Salta a la etiqueta "inicio"
' Antes de retroceder nos aseguramos de que las figuras E,F,G y H tengan una
' posición inicial en la pantalla LCD:
RETRO:
POS1 = $CF
POS2 = $CE
POS3 = $CD
POS4 = $CC
RETROCEDE:
LCDOUT $fe, 1 ' Limpia la pantalla LCD
LCDOUT $FE,POS1, 7 ' Muestra Palabra 7 en la LCD
LCDOUT $FE,POS2, 6 ' Muestra Palabra 6 en la LCD
Pause 300
LCDOUT $fe, 1 ' Limpia la pantalla LCD
LCDOUT $FE,POS3, 5 ' Muestra Palabra 5 en la LCD
LCDOUT $FE,POS4, 4 ' Muestra Palabra 4 en la LCD
Pause 300
' Disminuimos la posición de cada símbolo en la pantalla para dar el efecto
' de movimiento en sentido contrario:
POS1 = POS1 - 3
POS2 = POS2 - 3
POS3 = POS3 - 3
POS4 = POS4 - 3
If POS4 < $C0 Then REINICIA ' Pregunta si llega al tope Izquierdo de la LCD
GoTo RETROCEDE
' Nos aseguramos de que las figuras A,B,C y D tengan una posición inicial en la
' pantalla LCD:
REINICIA:
POS1 = $C0
POS2 = $C1
POS3 = $C2
POS4 = $C3
return ' Se repite el proceso saltando a la etiqueta "inicio"
DISABLE
ZONA:
IF BANDERA = 1 THEN
HIGH SIRENA
BANDERA1 = BANDERA1 + 1
ELSE
LOW SIRENA
ENDIF
BANDERA1 = BANDERA1 + 1
IF BANDERA1 > 6 THEN BANDERA1 = 0
IF BANDERA = 1 AND BANDERA1 < 3 THEN
PAUSE 100
serout PORTC.6,T9600,["AT+CMGR=1",10,13]
PAUSE 500
SEROUT PORTC.6,T9600,["AT+CMGD=1",10,13]
pause 500
SEROUT PORTC.6,T9600,["AT+CMGD=2",10,13]
pause 500
SEROUT PORTC.6,T9600,["AT+CMGF=1",10,13]
pause 1000
SEROUT PORTC.6,T9600,["AT+CMGS=",34,"2976256173",34,10,13]
pause 1000
SEROUT PORTC.6,T9600,["DISPARO ALARMA",26,10,13]
PAUSE 100
ENDIF
INTCON = %10010000 ' Habilita las interrupciones (GIE=1)
' Habilita la interrupción RB0/INT (INTE=1)
' Inicializa la interrupción (INTF=0)
Resume ' GIE = 1 y retorna al punto donde había quedado
' antes de la interrupción.
Enable ' Habilita el inspector de interrupciones.
END
Nota: Tengo que solucionar un par de errores... El primero que tengo, es que no puedo visualizar en el display las respuestas que le hago al modem por que el delay que hay entre pregunta y respuesta es casi instantaneo y no da tiempo al micro a que lo lea, guarde e imprima... No encuentro en el manual donde se puede variar esto...La otra cosa ue tengo que hacer, es cambiar la instruccion SERIN para que pueda saltar correr el programa sin quedar en una linea esperando que entre los datos...
La opcion mas rapida que tengo y segura, es implementar otro microcontrolador solo para el manejo de la comunicacion con el modem y el 16F877, imlpementarlo para la alarma en si.
Asi como esta, funciona, pero tengo que mejorarla; Espero que les sea de utilidad