29 jul 2010

Conteos, los rebotes y el mundo real.

Saludos.

Si me hicieron caso y no desarmaron su protoboard de la entrada anterior, genial. Si no aguantaron los 6 meses que me avente de vacaciones.... Pos perdon otra vez, habra que armarlo de nuevo.

Suponiendo que ya estamos listos, vamos a consegir un boton pulsador normalmente abierto. Existen muchos modelos y tamaños, cualquiera nos sirve mientras puedan conectarle las patitas al protoboard.


Ahora vamos a colocarlo en el Protoboard y conectar una patita a tierra y la otra al pin 2 que es el bit0 del puerto D. (se leera como PIND.0 y se escribira como PORTD.0).

Quedando mas o menos asi:



Notese que puse mas gruesos los cables del boton, pero es solo para facilitar su identificación, puede usarse cualqier cablecito mientras no este encuerado.

Ahora bien abrimos el codevision como de costumbre, pero esta vez vamos a definir los puertos C y B como Salidas (out) y al puerto D como entrada (in) con resistencias pull-up.

Asi mero:

Eso de las resistencias Pull-up solo significa que el atmega8 va a conectarse por dentro de forma que las entradas sean consideradas positivas hasta que algun dispositivo las ponga a tierra. Esto es muy util por que de otro modo tendriamos que poner las resistencias nosotros por fuera. En este caso la entrada se leera como un 1 hasta que se presione el boton, en cullo momento se leera como un 0.


Dicho esto vamos a crear el programa

Agregamos la libreria del retraso de tiempo con #include<delay.h>
en la parte de las variables globales vamos a integrar:


int l; // (l sera el numero a contar)
char seg []={63,6,91,79,102,109,125,7,127,103};
// (seg son los valores para expresar cada numero)


Como ven es la misma mecanica del post anterior, con la excepción de la configuración de entrada del puerto D.

El programa varia un poco:


while (1)
{
if(l==100)l=0; //si el valor de l llega a 100, lo regresa a 0.
if(PIND.0==0)l++; // si el PIND8 se encuentra en nivel bajo(tierra) incrementa el valor de l.
PORTC=2; //Pone el PORTC.0 en bajo y el PORTC.1 en alto encendiendo asi el display unidades.
PORTB=seg[l%10]; //presenta el numero en el display. (leer post anterior para explicación)
delay_ms(5); //espera 5 milisegundos
PORTC=1; //Pone el PORTC.0 en alto y el PORTC.1 en bajo encendiendo asi el display decenas.
PORTB=seg[l/10]; //presenta el numero en el display.(leer post anterior para explicación)
delay_ms(5); //espera 5 milisegundos
PORTB=0; // Pone el puerto B en 0 apagando ambos displays (por un tiempo efimero)
};
}


Hasta aqui vamos a compilar y montar del modo tradicional.

Ahora podemos pulsar el boton y ver como el aparatito cuenta.

Intentalo antes de seguir leyendo.



Asi es. Cuenta tan rapido que nos parece que esta generando numeros al azar.

Esto ha sido por que la instrucción if(PIND.0==0)l++; solo detecta si el boton esta pulsado. De este modo como el ciclo se repite cada 10milisegundos aproximadamente, no nos da tiempo a soltar el boton.

Asi que cambiamos el programa un poquitin.


if(PIND.0==0){ // en caso de que el PIND.0 este en nivel bajo:
l++; // incrementa el valor de l y...
while(PIND.0==0){} //mientras esta en nivel bajo "hace nada"
} // fin de la condición

Asi que el programa queda asi:


while (1)
{
if(l==100)l=0; //si el valor de l llega a 100, lo regresa a 0.
if(PIND.0==0){ // en caso de que el PIND.0 este en nivel bajo:
l++; // incrementa el valor de l y...
while(PIND.0==0){} //mientras esta en nivel bajo "hace nada"
} // fin de la condición
PORTC=2; //Pone el PORTC.0 en bajo y el PORTC.1 en alto encendiendo asi el display unidades.
PORTB=seg[l%10]; //presenta el numero en el display. (leer post anterior para explicación)
delay_ms(5); //espera 5 milisegundos
PORTC=1; //Pone el PORTC.0 en alto y el PORTC.1 en bajo encendiendo asi el display decenas.
PORTB=seg[l/10]; //presenta el numero en el display.(leer post anterior para explicación)
delay_ms(5); //espera 5 milisegundos
PORTB=0; // Pone el puerto B en 0 apagando ambos displays (por eso el tiempo efimero)
};
}


Probemoslo ahora y veremos una gran mejoria.

Si aun notamos que cuenta de mas, es por que los botones son perfectos, y al momento de hacer contacto hacen "falsos contactos" rapidisimos, que para nosotros son imperceptibles, pero que un microcontrolador serio como nuestro querido atmega si toma en cuenta. Esos falsos contactos son conocidos como "rebotes" o "bounces" y existen dispositivos que se encargan de anularlos llamados "debouncer". En nuestro caso para solucionarlo, simplemente vamos pedir a nuestro chip que espere 40 milisegundos. La instrucción es delay_ms(40); pero les dejo de tarea donde deben agregarla. Despues de while(PIND.0==0){}

No hay comentarios:

Publicar un comentario