sábado, 9 de marzo de 2019

Codificador rotatorio (KY-040 Rotary Encoder Module)

Modelo básico. No utilizo la entrada sw (podría hacer un reset con ella.
Visualizo los 4 pasos y cada vez que finaliza incremento o decremento una unidad el contador. Se puede generar variantes que vayan 2 veces más rápido e incluso 4 veces.

Esquema:
Los leds se llevan a positivo para que en la posición de reposo los LEDs estén apagados.
Esquema realizado con Fritzing. Se necesita la librería del codificador:
https://github.com/hduijn/arduino-dehydrator/blob/master/Fritzing/parts/Rotary%20Encoder%20with%20switch%20(KY-040).fzpz
Fichero de Frtitzing y librería descargada:
https://drive.google.com/open?id=1EdaMBKV06V_dZRHLaRhoIQ14QFzxyQoT
https://drive.google.com/open?id=1G0PAIbRtaSDoQXofP98tQz2rsd6w8KS1

 El diagrama del programa es similar al de los circuitos digitales secuenciales asíncronos.

Código del programa:

************************************************************************************
#define clk 2
#define dt 3
int contador=0;
/* PINES
 *
 * CLK
 * DT
 * SW
 * +
 * GND
 */

/* FUNCIONAMIENTO
 * 
 *  PARTIENDO DE REPOSOSO (CLK, DT): 1,1
 * 
 *  GIRO EN SENTIDO HORARIO (derecha):
 *  1,1
 *  0,1
 *  0,0
 *  1,0
 *  0,0
 * 
 *  GIRO EN SENTIDO ANTIHORARIO (izquierda):
 *  1,1
 *  0,1
 *  0,0
 *  1,0
 *  1,1
 */

//voy a comenzar patiendo de reposo (1,1)
//main (loop) se va a quedar hasta que se produzca la situación (1,1)
//entonces pasará a la función pseudoloop

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(clk, INPUT);
  pinMode(dt, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(digitalRead(clk) && digitalRead(dt)) contar11(0);
}

void contar11(int precontador){
  if (precontador==4){
    Serial.println(++contador);
    precontador=0;
  } else if (precontador==-4){
    Serial.println(--contador);
    precontador=0;
  }
  //no necesito hacer más pruebas porque la otra posibilidad es que se haya movido hacia atrás y valdrá cero
 
  while (digitalRead(clk) && digitalRead(dt));//mientras las dos sigan a 1 no se hace nada
  if(!digitalRead(clk)){
    contar01(++precontador);
  } else {
    contar10(--precontador);
  }
}

void contar01(int precontador){
  while (!digitalRead(clk) && digitalRead(dt));
  if(!digitalRead(dt)){
    contar00(++precontador);
  } else {
    contar11(--precontador);
  }
}

void contar00(int precontador){
  while (!digitalRead(clk) && !digitalRead(dt));
  if(digitalRead(clk)){
    contar10(++precontador);
  } else {
    contar01(--precontador);
  }
}

void contar10(int precontador){
  while (digitalRead(clk) && !digitalRead(dt));
  if(digitalRead(dt)){
    contar11(++precontador);
  } else {
    contar00(--precontador);
  }
}
************************************************************************************