Tabla de contenido:

Cómo interpretar la dirección de rotación de un interruptor giratorio digital con un PIC: 5 pasos
Cómo interpretar la dirección de rotación de un interruptor giratorio digital con un PIC: 5 pasos

Video: Cómo interpretar la dirección de rotación de un interruptor giratorio digital con un PIC: 5 pasos

Video: Cómo interpretar la dirección de rotación de un interruptor giratorio digital con un PIC: 5 pasos
Video: CÓMO PROGRAMAR UN ENCODER DE CUADRATURA || CÓMO USAR ENCODER ROTATIVO CON CÓDIGO DE PROGRAMACIÓN 2024, Noviembre
Anonim
Cómo interpretar la dirección de rotación de un interruptor giratorio digital con un PIC
Cómo interpretar la dirección de rotación de un interruptor giratorio digital con un PIC

El objetivo de este Instructable es ilustrar cómo conectar un interruptor giratorio digital (codificado en cuadratura) con un microcontrolador. No se preocupe, le explicaré qué significa la codificación en cuadratura para nosotros. Esta interfaz y el software que la acompaña permitirán que el microcontrolador reconozca la dirección de rotación para cada movimiento de un tope a otro. Recientemente utilicé este tipo de interruptor en un proyecto de microcontrolador que requería que se ingresara un punto de ajuste de presión usando una perilla con 16 retenes en lugar de botones arriba / abajo. La idea era permitir al usuario "marcar" la presión deseada. Como resultado, tuvimos que desarrollar una rutina de software para obtener la información de posición del interruptor y deducir la dirección de rotación para incrementar o disminuir el punto de ajuste de presión para el sistema principal. En este Instructable, cubriré la interfaz física para el microcontrolador, la teoría de funcionamiento del interruptor giratorio, la teoría de funcionamiento del software y la rutina de deducción. Finalmente, les mostraré mi aplicación de la rutina de deducción. A medida que avancemos, intentaré mantener las cosas algo genéricas para que la idea se pueda aplicar en tantas plataformas como sea posible, pero también compartiré lo que hice para que puedas ver una aplicación específica.

Paso 1: Partes

Partes
Partes

Para implementar esto, necesitará: Un interruptor giratorio (codificado en cuadratura) Resistencias de extracción Plataforma de microcontrolador adecuada Para mi proyecto, utilicé un codificador óptico Grayhill 61C22-01-04-02. La hoja de datos para el interruptor giratorio requiere resistencias pull up de 8.2k ohmios en las dos líneas de datos que provienen del interruptor. Querrá consultar la hoja de datos del codificador que opta por usar. El interruptor giratorio que utilicé también se puede pedir con un interruptor de botón axial. Es una función útil para confirmar selecciones que se han marcado, etc. pero no discutiré su interfaz aquí. Tengo una "plataforma de microcontroladores adecuada" en la lista porque (creo) esto se puede implementar en más de una plataforma. He visto a mucha gente usar otros microcontroladores para Instructables, así que también quiero mostrar el enfoque general. Escribí todo el código en PIC Basic Pro para usarlo con un Microchip PIC16F877A. Realmente, lo clave que necesita en el microcontrolador es la capacidad de interrumpir cuando hay un cambio lógico en cualquiera de los dos pines. En el PIC16F877A, esto se denomina interrupción de cambio de PORTB. Puede haber otros nombres para él en otros controladores. Esta característica de interrupción del microcontrolador es parte de lo que hace que esta implementación sea tan elegante.

Paso 2: Interfaz de hardware

Interfaz de hardware
Interfaz de hardware

Una solución "simple" sería tener un interruptor "unipolar-16 posiciones" con 16 conexiones al microcontrolador. Luego, cada salida del interruptor se vincularía a un pin en el microcontrolador para que el microcontrolador pueda verificar cada posición del dial. Este es un uso excesivo de pines de E / S. Las cosas empeoran aún más si queremos más de 16 posiciones (retenes) disponibles para nosotros en el interruptor. Cada posición adicional en el interruptor requeriría una entrada adicional al microcontrolador. Esto rápidamente se convierte en un uso muy ineficiente de las entradas en un microcontrolador. Ingrese la belleza del interruptor giratorio. El interruptor giratorio tiene solo dos salidas para el microcontrolador enumerado como A y B en la hoja de datos. Solo hay cuatro niveles lógicos posibles que pueden tomar estas líneas: AB = 00, 01, 10 y 11. Esto reduce en gran medida la cantidad de líneas de entrada que debe usar para conectar el interruptor al microcontrolador. Entonces, hemos reducido el número de líneas de entrada a solo dos. ¿Ahora que? Parece que realmente necesitamos 16 estados diferentes, pero este nuevo interruptor solo tiene cuatro. ¿Nos hemos disparado en el pie? No. Sigue leyendo. Cubriremos un poco de la teoría detrás del funcionamiento del interruptor giratorio para explicarlo.

Paso 3: Teoría de funcionamiento del hardware

Teoría de funcionamiento del hardware
Teoría de funcionamiento del hardware
Teoría de funcionamiento del hardware
Teoría de funcionamiento del hardware
Teoría de funcionamiento del hardware
Teoría de funcionamiento del hardware

La detección de la dirección de rotación es posible utilizando el interruptor "unipolar-16 posiciones" mencionado anteriormente, pero consume muchas entradas en el microcontrolador. El uso del interruptor giratorio reduce la cantidad de entradas al microcontrolador, pero ahora necesitamos interpretar las señales que provienen del interruptor y traducirlas en una dirección de rotación. Mencioné anteriormente que el interruptor estaba codificado en cuadratura. Esta es también una de las claves de elegancia de esta solución. Esto significa que hay un código de 2 bits que proporciona el interruptor que corresponde a la posición del interruptor. Quizás esté pensando: "Si hay una entrada de dos bits al microcontrolador, ¿cómo representamos las 16 posiciones?" Buena pregunta. No los representamos a todos. Solo necesitamos conocer las posiciones relativas de la perilla para poder determinar la dirección de rotación. La posición absoluta del mando es irrelevante. Para la rotación en el sentido de las agujas del reloj, el código que proporciona el interruptor se repite cada cuatro retenciones y está codificado en gris. Codificado en gris significa que solo hay un cambio de bit por cada cambio de posición. En lugar de que la entrada AB cuente para la rotación en el sentido de las agujas del reloj en binario como este: 00, 01, 10, 11, cambia así: 00, 10, 11, 01. Observe que para el último patrón, solo hay una entrada que cambia entre conjuntos. Los valores en sentido antihorario para la entrada AB al microcontrolador se verán así: 00, 01, 11, 10. Esto es simplemente el reverso del patrón en el sentido de las agujas del reloj con AB = 00 enumerado primero. Eche un vistazo a los diagramas para obtener una explicación más visual.

Paso 4: Teoría de funcionamiento del software

Teoría de funcionamiento del software
Teoría de funcionamiento del software

La rutina que deduce la dirección de rotación está impulsada por interrupciones. El microcontrolador que seleccione debe poder interrumpir cada vez que haya un cambio en cualquiera de (al menos) dos pines cuando la interrupción esté habilitada. Esto se denomina interrupción de cambio de PORTB en el PIC16F877A. Cada vez que se gira el interruptor, el microcontrolador se interrumpirá y la ejecución del programa se enviará a la Rutina de servicio de interrupción (ISR). El ISR determinará rápidamente de qué manera se giró el interruptor, establecerá una bandera de manera adecuada y regresará rápidamente al programa principal. Necesitamos que esto suceda rápidamente en caso de que el usuario gire el interruptor muy rápido. Sabemos que el patrón AB codificado en gris se repite cada cuatro posiciones, por lo que si hacemos que la rutina funcione para las transiciones entre esas cuatro posiciones, funcionará para todas las demás. Observe que en un ciclo de cuatro posiciones, hay cuatro bordes. Un flanco ascendente y un flanco descendente para la entrada A y la entrada B. El microprocesador se interrumpirá cada vez que haya un borde, lo que significa que el microcontrolador se interrumpirá cada vez que se gire la perilla. Como resultado, el ISR necesita averiguar en qué dirección se giró la perilla. Para ayudarnos a descubrir cómo hacer esto, recurrimos a la forma de onda para girar en el sentido de las agujas del reloj. Observe que cada vez que A tiene un flanco, su nuevo valor siempre es diferente del de B. Cuando la perilla pasa de la posición 1 a la 2, A pasa de 0 lógico a 1 lógico. B sigue siendo 0 para esta transición y no coincide con el nuevo valor de A. Cuando la perilla pasa de la posición 3 a la 4, A tiene un flanco descendente mientras que B permanece en 1 lógico. Observe nuevamente que B y el nuevo valor de A son diferentes. En este momento, podemos ver que cada vez que A causa la interrupción durante la rotación en el sentido de las agujas del reloj, su nuevo valor es diferente al de B. Revisemos B para ver qué sucede. B tiene un flanco ascendente cuando el interruptor pasa de la posición 2 a la 3. Aquí, el nuevo valor de B es el mismo que A. Mirando el último flanco restante para la rotación en el sentido de las agujas del reloj, B tiene un flanco descendente que se mueve de la posición 4 a la 5. (La posición 5 es la misma que la posición 1.) ¡El nuevo valor de B es el mismo que A aquí también! ¡Ahora podemos hacer algunas deducciones! Si A causa la interrupción y el nuevo valor de A es diferente al de B, la rotación fue en el sentido de las agujas del reloj. Además, si B causa la interrupción y el nuevo valor de B es el mismo que A, entonces la rotación fue en el sentido de las agujas del reloj. Examinemos rápidamente el caso de la rotación en sentido antihorario. Al igual que la rotación en el sentido de las agujas del reloj, la rotación en sentido antihorario provocará cuatro interrupciones en un ciclo: dos para la entrada A y dos para la entrada B. La entrada A tiene un borde ascendente cuando la perilla se mueve de la posición 4 a la 3 y un borde descendente se mueve de la posición 2 a 1 Cuando la perilla se mueve de la posición 4 a la 3, el nuevo valor de A es el mismo que el valor de B. Observe que cuando A se mueve de la posición 2 a 1, su nuevo valor es el mismo que el de B también. Ahora, podemos ver que cuando A causa la interrupción y su nuevo valor coincide con el de B, la rotación fue en sentido antihorario. Rápidamente, veremos la entrada B para verificar todo. B causará una interrupción cuando la perilla se mueva de la posición 5 (que es lo mismo que 1) a la 4 y cuando la perilla se mueva de la posición 3 a la 2. En ambos casos, el nuevo valor de B no coincide con el valor existente de A que es lo opuesto a los casos en los que B causa la interrupción para la rotación en el sentido de las agujas del reloj. Estas son buenas noticias. Todo sale como debería. Para resumir, si A causa la interrupción y su nuevo valor no coincide con el valor de B o si B causa la interrupción y el nuevo valor de B coincide con el valor de A, sabemos que hubo una rotación en el sentido de las agujas del reloj. Podemos verificar los otros casos para la rotación en sentido antihorario en el software o podemos suponer que debido a que no fue una rotación en el sentido de las agujas del reloj, fue en el sentido contrario. Mi rutina simplemente hizo la suposición.

Paso 5: software

Software
Software
Software
Software

No utilicé las interrupciones integradas en PIC Basic Pro. Usé un par de archivos que incluí en mi código de Darrel Taylor para manejar la rutina. ¡Aquí es donde pertenece un gran mérito para Darrel! Los archivos son gratuitos. Simplemente visite su sitio web para obtener más información, otras aplicaciones y descargar los archivos. Puede omitir esta parte si no está utilizando un PIC con interrupciones de Darrel Taylor. Simplemente configure las interrupciones según sea necesario en la plataforma que está utilizando. Para configurar las interrupciones de Darrel Taylor (DT), hay dos cosas que hacer: 1.) Incluya los archivos DT_INTS-14.bas y ReEnterPBP.bas en su code.2.) Copie y pegue esto en su macro code. ASMINT_LIST; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _ISR, PBP, sí endm INT_CREATEENDASMI Inserte pestañas y espacios como el gráfico al final del Instructable para que pueda ver las cosas un poco más fácilmente en su código. Deberá modificarlo ligeramente para que se ajuste a sus necesidades. En Etiqueta, reemplace ISR con el nombre de la subrutina que es su ISR. ¡No olvide el subrayado! ¡Lo necesita! Para que las interrupciones funcionen, hay dos cosas más que hacer: 1.) Escribir el ISR. Escribirá esto como si fuera a escribir una subrutina PBP, excepto que necesitará insertar @ INT_RETURN al final de la subrutina en lugar de RETURN. Esto reconocerá la interrupción y devolverá la ejecución del programa a donde se detuvo en el bucle principal. Dentro del ISR, debe borrar la bandera de interrupción para que su programa no quede atrapado en una interrupción recursiva. Simplemente leyendo PORTB es todo lo que se necesita hacer para borrar el indicador de interrupción en el PIC16F877A. Cada microcontrolador diferente tiene una forma diferente de borrar los indicadores de interrupción. Verifique la hoja de datos de su microcontrolador.2.) Cuando llegue al punto en su código en el que desea habilitar la interrupción, use esta línea de código: @ INT_ENABLE RBC_INT Cuando desee deshabilitar la interrupción simplemente use: @ INT_DISABLE RBC_INT Hay mucho de cosas incluidas en lo que acabo de cubrir, así que lo resumiré rápidamente. Hasta ahora, su programa debería verse así:; Cualquier configuración o código necesario INCLUYE "DT_INTS-14.bas" INCLUYE "ReEnterPBP.bas" macro ASMINT_LIST; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _myISR, PBP, sí endm INT_CREATEENDASM; Cualquier otra configuración necesaria o código @ INT_ENABLE RBC_INT; Código que necesita saber en qué dirección está girando la perilla @ INT_DISABLE RBC_INT; Otro códigoEND; Fin del programa myISR:; código ISR aquí @ INT_RETURN (Tabla de configuración del controlador de interrupciones) Creo que aquí es donde cualquiera que no esté usando interrupciones PIC o DT puede unirse nuevamente. Ahora, necesitamos escribir el ISR para que el microcontrolador sepa en qué dirección está girando la perilla. Recuerde de la sección de teoría del software que podemos deducir el sentido de rotación si conocemos la entrada que causó la interrupción, su nuevo valor y el valor de la otra entrada. Aquí está el pseudocódigo: Lea PORTB en una variable scratch para borrar el indicador de interrupción Verifique si A causó la interrupción. Si es verdadero, compare A y B. Compruebe si es diferente, si es diferente, fue en sentido horario. De lo contrario, fue en sentido antihorario EndifCheck si B causó la interrupción. Si es verdadero, compare A y B Compruebe si es diferente, si es el mismo, fue rotación en el sentido de las agujas del reloj. De lo contrario, fue en el sentido contrario a las agujas del reloj. Descubrir el nuevo valor de la entrada modificada y la otra entrada (sin cambios) es fácil porque podemos leerlos dentro del ISR. Necesitamos saber cuál era el estado de cada uno antes de que la ejecución se envíe al ISR. Esto sucede en la rutina principal. La rutina principal espera a que una variable de byte que llamamos CWflag se establezca en 1 o se borre en 0 por el ISR. Después de cada cambio reconocido de la perilla o si no hay actividad de la perilla, la variable se establece en 5 para indicar un estado inactivo. Si la bandera se establece o se borra, la rutina principal incrementa o disminuye inmediatamente la presión del punto de ajuste de manera apropiada según la rotación y luego establece la variable CWflag nuevamente en 5 porque la perilla ahora está inactiva nuevamente. Como la rutina principal es verificar el indicador CW, también documenta el estado de los valores del interruptor giratorio A y B. Esto es realmente simple y se ve así: oldA = AoldB = B Realmente no hay nada súper elegante aquí. Solo incluya esas dos líneas al comienzo del ciclo que verifica la rotación de CWflag. Solo estamos actualizando los valores lógicos de las entradas del botón giratorio dentro del ciclo de incremento / decremento en la rutina principal para que podamos ver qué entrada causó la interrupción cuando se ejecuta el ISR. Aquí está el código ISR: ABchange: scratch = PORTB 'Leer PORTB para borrar el indicador de interrupción' Si A causa la interrupción, verifique B para la dirección de rotación SI oldA! = A THEN 'Si A y B son diferentes, fue rotación en sentido horario SI A! = B THEN GOTO CW 'De lo contrario, fue rotación en sentido antihorario ELSE GOTO CCW ENDIF ENDIF' Si B causa la interrupción, verifique el sentido de rotación de A IF oldB! = B THEN 'Si A y B son iguales, fue rotación en sentido horario IF A == B THEN GOTO CW 'De lo contrario, fue rotación en sentido antihorario ELSE GOTO CCW ENDIF ENDIFCW: CWflag = 1 @ INT_RETURNCCW: CWflag = 0 @ INT_RETURN He incluido el código ISR en un archivo AB_ISR.bas porque el Las pestañas en el código no se muestran como deberían. Ahora, debido a que el ISR tiene los valores antiguos para las entradas A y B, puede determinar qué entrada causó la interrupción, compararla con la otra entrada (sin cambios) y determinar la dirección de rotación. Todo lo que tiene que hacer la rutina principal es verificar el CWflag para ver en qué dirección ha girado la perilla (si lo ha hecho) e incrementar o disminuir un contador, un punto de ajuste o lo que quieras o necesites. Espero que esto ayude y no ha sido demasiado. confuso. Este tipo de interfaz es especialmente útil si su sistema ya está usando interrupciones, ya que esta es solo una interrupción más para agregar. ¡Disfrutar!

Recomendado: