Utilización de Shift-In


Cuando teníamos que enviar datos a led y/o displays desde Arduino y para disminuir la cantidad de pines a utilizar, hablamos de utilizar un Shift Register (74HC595), ahora bien, cuando necesitamos realizar el proceso inverso, o sea enviar pulsaciones de interruptores, botones, etc., desde el simulador para no ocupar un pin por cada posición lo ideal es utilizar un Shift In, donde recibimos la señal en paralelo, y el integrado la transforma y envía en serie hacia la placa Arduino.
Para este caso el que yo utilizo es el integrado CD4021B, este integrado se puede conectar en serie con otros, y recibiendo 8 señales por integrado, luego solo utilizar 3 pines de nuestra placa Arduino.
A continuación, diagrama propio de conexión que utilizo para armar la plaqueta, en este caso utilizando 3 integrados CD4021B con lo cual puedo leer 24 entradas.



Para más detalles les paso el link de la página de Arduino donde hay ejemplo de diagramas, conexión y ejemplos de código fuente.



A Continuación, parte del código real utilizado en la placa Arduino para el manejo de los interruptores del MIP.
Declaración de variables:

/***********************************************************************************/
/****        DECLARACION DE VARIABLES - MATRIZ DE RECEPCION A PLACA (MIP)       ****/
/***********************************************************************************/
const int PINDataIN_MIP     = 23; /Pin connected to ST_CP of D 
const int PINLatchIN_MIP    = 25;
const int PINClockIN_MIP    = 27;
byte SwitchVar1_MIP        = 72;
byte SwitchVar2_MIP        = 159;

Ciclo que realiza la llamada a la función para determinar el estado de los interruptores a través del Shift-In (en este caso utilizado 2 Integrados) los cuales se cargan en las variables SwitchVar1_MIP y SwitchVar2_MIP.

/***********************************************************************************/
/****        LECTURA - CARGAR CHIP A VARIABLE CHIP                              ****/
/***********************************************************************************/
void P_MIP_CararChipaVariable(){
    digitalWrite(PINLatchIN_MIP,1);
    delayMicroseconds(10); /*Pasar a 20 si no se reciben bien los datos */
    digitalWrite(PINLatchIN_MIP,0);
    SwitchVar2_MIP = shiftIn(PINDataIN_MIP, PINClockIN_MIP);
    SwitchVar1_MIP = shiftIn(PINDataIN_MIP, PINClockIN_MIP);
}

Función shiftIn encargada de procesar la petición y devolver el estado de cada interruptor.

/************************************************************************************
/****        FUNCION: LECTURA DE CHIP IN                                         ****
/************************************************************************************
byte shiftIn(int myDataPin, int myClockPin) {
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
  for (i=7; i>=0; i--) {
      digitalWrite(myClockPin, 0);
      delayMicroseconds(2);
      temp = digitalRead(myDataPin);
      if (temp) {
          pinState = 1;
          myDataIn = myDataIn | (1 << i);
      } else {
          pinState = 0;
      }
      digitalWrite(myClockPin, 1);
  }
  return myDataIn;
}

Por último, el proceso que se encarga de asignar el valor de cada interruptor obtenido sobre las variables de Chips a las variables de cada elemento.

/***********************************************************************************/
/****        LECTURA - ASIGNACION A VARIABLES                                   ****/
/***********************************************************************************/
void P_MIP_CargaraVariable() {
    /************************************************/
    /****        PANEL SUPERIOR IZQUIERDO        ****/
    /************************************************/
    /* SE CARGAN VALORES ANTERIORES SOLO PARA PULSADORES */
    PulsadorCPBelowGSInhibitAnterior_MIP = PulsadorCPBelowGSInhibit_MIP;
    PulsadorCPAPResetAnterior_MIP        = PulsadorCPAPReset_MIP;
    PulsadorCPATResetAnterior_MIP        = PulsadorCPATReset_MIP;
    PulsadorCPFMCResetAnterior_MIP       = PulsadorCPFMCReset_MIP;
    /* Las llaves toman valores varios */
    LlaveCPMainDU_1_MIP   = bitRead(SwitchVar2_MIP,4); 
    LlaveCPMainDU_2_MIP   = bitRead(SwitchVar2_MIP,5); 
    LlaveCPMainDU_3_MIP   = bitRead(SwitchVar2_MIP,6); 
    LlaveCPMainDU_4_MIP   = bitRead(SwitchVar2_MIP,7); 
    LlaveCPMainDU_5_MIP   = bitRead(SwitchVar2_MIP,3); 
    LlaveCPLowerDU_1_MIP  = bitRead(SwitchVar2_MIP,2); 
    LlaveCPLowerDU_2_MIP  = bitRead(SwitchVar2_MIP,0); 
    LlaveCPLowerDU_3_MIP  = bitRead(SwitchVar2_MIP,1); 
    /*Enviar(">llave1=", LlaveCPMainDU_1_MIP); */
    if (LlaveCPMainDU_1_MIP == 1) {LlaveCPMainDU_MIP = 0;}
    if (LlaveCPMainDU_2_MIP == 1) {LlaveCPMainDU_MIP = 1;}
    if (LlaveCPMainDU_3_MIP == 1) {LlaveCPMainDU_MIP = 2;}
    if (LlaveCPMainDU_4_MIP == 1) {LlaveCPMainDU_MIP = 3;}
    if (LlaveCPMainDU_5_MIP == 1) {LlaveCPMainDU_MIP = 4;}
    if (LlaveCPLowerDU_1_MIP == 1) {LlaveCPLowerDU_MIP = 0;}
    if (LlaveCPLowerDU_2_MIP == 1) {LlaveCPLowerDU_MIP = 1;}
    if (LlaveCPLowerDU_3_MIP == 1) {LlaveCPLowerDU_MIP = 2;}

    PulsadorCPBelowGSInhibit_MIP    = bitRead(SwitchVar1_MIP,7); 
    PulsadorCPAPReset_MIP           = bitRead(SwitchVar1_MIP,4);  
    PulsadorCPATReset_MIP           = bitRead(SwitchVar1_MIP,5); 
    PulsadorCPFMCReset_MIP          = bitRead(SwitchVar1_MIP,6); 
    InterruptorCPDisTest_1_MIP      = bitRead(SwitchVar1_MIP,3); 
    InterruptorCPDisTest_2_MIP      = bitRead(SwitchVar1_MIP,2); 
    InterruptorCPMasterLights_1_MIP = bitRead(SwitchVar1_MIP,0); 
    InterruptorCPMasterLights_2_MIP = bitRead(SwitchVar1_MIP,1); 
   
    if (InterruptorCPDisTest_1_MIP == 1) {InterruptorCPDisTest_MIP = 0;}
    if (InterruptorCPDisTest_2_MIP == 1) {InterruptorCPDisTest_MIP = 2;}
    if ((InterruptorCPDisTest_1_MIP == 0) && (InterruptorCPDisTest_2_MIP == 0)) {InterruptorCPDisTest_MIP = 1;}

    if (InterruptorCPMasterLights_1_MIP == 1) {InterruptorCPMasterLights_MIP = 0;}
    if (InterruptorCPMasterLights_2_MIP == 1) {InterruptorCPMasterLights_MIP = 2;}
    if ((InterruptorCPMasterLights_1_MIP == 0) && (InterruptorCPMasterLights_2_MIP == 0)) {InterruptorCPMasterLights_MIP = 1;}

}



Utilización de Shift Register

A la hora de enviar los datos desde nuestra placa Arduino hacia varios LEDs o Displays de 7 digitos. Necesitamos multpliples pines los cuales nunca serían suficiente.
Para tal caso la mejor opcion es la utilización del integrado 74HC595 (Shift Register).
Con este integrado podemos enviar información en serie, y el integrado tranmitirá los datos a los distintos pines (hasta 8 pines por integrado) utilizando solo 3 pines para enviar los datos.
Debajo un ejemplo de la utlización de los integrados tanto para el uso de Leds como para el uso de los displays.
Estos integrados a su vez pueden conectarse en serie, y asi reducir mas el consumo de pines necesarios.