Conexión de un encoder rotativo al MSP430

El encoder tiene dos pines de salida, A y B. La combinación de datos de estos pines permite conocer la dirección del giro.

El encoder tiene dos pines de salida, A y B. La combinación de datos de estos pines permite conocer la dirección del giro.

Un encoder rotativo es un dispositivo muy versátil para comunicarse con el microcontrolador. A continuación dos maneras de conectarlo, directamente al microcontrolador o utilizando un expansor de IO PCF8574 conectado al bus I2C.

El rotary encoder visto en el osciloscopio.

El encoder rotativo visto con el osciloscopio al girar en sentido horario.  En amarillo el pin A, en azul el B.

El encoder rotativo visto con el osciloscopio al girar en sentido horario. En amarillo el pin A, en azul el B.


El encoder girando en sentido antihorario. En amarillo el pin A, en azul el B.

l encoder girando en sentido antihorario. En amarillo el pin A, en azul el B.

Conexión directa al MSP430.
Dependiendo del modelo el encoder necesita dos o tres pines. La manera más sencilla de utilizarlo es conectándolo directamente a las entradas del microcontrolador.

// pines del rotary P1.1, P1.2, P1.3
#define ROTARY_PIN_BUTTON BIT1
#define ROTARY_PIN_A BIT2
#define ROTARY_PIN_B BIT3


void initIO () {
    // rotary: entradas en P1.1, p1.2 y p1.3
    P1DIR &= ~ROTARY_PIN_BUTTON;
    P1DIR &= ~ROTARY_PIN_A;
    P1DIR &= ~ROTARY_PIN_B;

    // Resistor enabled
    P1REN |= ROTARY_PIN_BUTTON | ROTARY_PIN_A | ROTARY_PIN_B;

    // pull up
    P1OUT |= ROTARY_PIN_BUTTON | ROTARY_PIN_A | ROTARY_PIN_B;

    // iterrupción high to low
    P1IES |= ROTARY_PIN_BUTTON | ROTARY_PIN_A;

    // clear interrupt
    P1IFG &= ~ROTARY_PIN_BUTTON; P1IFG &= ~ROTARY_PIN_A;

  // interrupción activada en el pin del botón y en el pin A
    P1IE |= ROTARY_PIN_BUTTON | ROTARY_PIN_A;	
}


#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
  if ((P1IFG & ROTARY_PIN_BUTTON) == ROTARY_PIN_BUTTON) {
    // Se ha pulsado el rotary
    count = 0;
    P1IFG &= ~ROTARY_PIN_BUTTON;
  }

  if ((P1IFG & ROTARY_PIN_A) == ROTARY_PIN_A) {
    if ((P1IN & ROTARY_PIN_B ) == ROTARY_PIN_B) {
      // giro a derecha
      ++count;
    } else {
      // giro a izquierda
      --count;
    }

    P1IFG &= ~ROTARY_PIN_A;
  }
} // de la fn

Conexión a través de un PCF8574.
Si andamos escasos de pines, utilizar un expansor puede ser una buena idea. El PCF8574 se conecta al bus I2C y proporciona 8 entradas o salidas adicionales. Un pin adicional del MSP430 permite recibir la señal de que se han producido cambios en las entradas del PCF8574.

Conexión:

Encoder PCF8574 MSP430
Pin A P0
Pin B P1
Pin pulsador P2
INT P1.3

Funcionamiento:
Cuando se produce un cambio en el rotary encoder el pin INT del PCF8574 se pone LOW. El MSP430 lo detecta y si corresponde actualiza el estado de un contador. Cada movimiento en el encoder genera cuatro interrupciones (INT). Para identificar el tipo de movimiento hay que evaluar la última interrupción.

Algunas definiciones:

#define PCF_INT_PIN BIT2
#define PULSADO 251
#define LEFT 254
#define RIGHT 253

 

Una función que actualiza un contador:

void updateCounter () {
    if (rotaryEvent == PULSADO) counter = 0;
    if (rotaryEvent == LEFT) --counter;
    if (rotaryEvent == RIGHT) ++counter;
    rotaryEvent = 0;
}

 

Captura de la interrupción:

#pragma vector = PORT1_VECTOR
__interrupt void port1_ISR(void){
	unsigned char currentValue;
	static unsigned char previousValue;

    if ((P1IFG & PCF_INT_PIN) == PCF_INT_PIN) {
		// Lee las entradas del segundo integrado (addr=33)
   		currentValue = pcf8574_readByte(33);

   		// La entrada es 255 cuando han terminado los pulsos
   		// del rotary encoder. El valor anterior de la entrada
   		// permite saber la dirección del giro o si se ha pulsado.
   		if (currentValue == 255) {
   			rotaryEvent = previousValue;
   		}
   		
  		previousValue = currentValue;

  		// Actualiza el contador.
  		updateCounter();

		P1IFG &= ~PCF_INT_PIN;
    }
}