{"id":1284,"date":"2020-02-02T01:18:59","date_gmt":"2020-02-02T01:18:59","guid":{"rendered":"http:\/\/robots-argentina.com.ar\/didactica\/?p=1284"},"modified":"2020-11-02T00:56:18","modified_gmt":"2020-11-02T00:56:18","slug":"ampliar-la-cantidad-de-entradas-de-arduino","status":"publish","type":"post","link":"https:\/\/robots-argentina.com.ar\/didactica\/ampliar-la-cantidad-de-entradas-de-arduino\/","title":{"rendered":"Ampliar la cantidad de entradas de Arduino"},"content":{"rendered":"

Para expandir la capacidad de entradas digitales se utilizan registros de desplazamiento (Shift Register<\/strong> en ingl\u00e9s) con entradas en paralelo y salida serie.<\/p>\n

\"\"<\/a><\/p>\n

Para este ejemplo, utilizamos tres pines digitales de la placa Arduino en conjunto con el circuito integrado 74HC165<\/strong> (puede ser, tambi\u00e9n, 74LS165<\/strong>), que nos aportar\u00e1 8 entradas.<\/p>\n

Diagrama de pines:<\/strong><\/p>\n

\"\"<\/a><\/p>\n

Se pueden conectar varios de estos chips en cadena, lo que le nos aporta 16, 24, 32 o m\u00e1s entradas, sin usar ning\u00fan pin digital adicional de Arduino, simplemente conectando la salida QH<\/strong> de un registro a la entrada de datos serie SER<\/strong> del otro.<\/p>\n

\"\"<\/a><\/p>\n

En el diagrama que sigue se ve c\u00f3mo es la conexi\u00f3n completa de dos 74HC165. Los conjuntos de llaves de corredera, llamados DIP Switch<\/strong> en ingl\u00e9s, representan a las diversas entradas que se podr\u00edan ingresar. Si son llaves que se cierran (pulsadores, microswitches, rel\u00e9s, salidas de colector abierto), corresponde el circuito tal como se lo ve, con un resistor de polarizaci\u00f3n (pull-up<\/strong>) conectado a +5V. Si se trata de salidas digitales de otros chips y placas con salidas compatible con l\u00f3gica TTL, no es necesario colocar el resistor.<\/p>\n

Con l\u00ednea de puntos se indica la conexi\u00f3n para continuar la cadena indefinidamente. La se\u00f1al CLK<\/strong> (pata 2<\/strong>) va unida entre chips, e igual la se\u00f1al SH\/LD<\/strong> (pata 1<\/strong>), con la \u00fanica salvedad de que hay que leer la hoja de datos del microcontrolador (seg\u00fan cu\u00e1l sea) para saber cu\u00e1ntas entradas de este tipo de chip TTL HC se le pueden conectar a una salida digital de Arduino.<\/p>\n

\"\"<\/a><\/p>\n

La tabla que sigue, y el diagrama interno del chip, los agrego para ofrecer m\u00e1s informaci\u00f3n y mejor comprensi\u00f3n del funcionamiento. Se pueden encontrar m\u00e1s detalles en su hoja de datos<\/a><\/strong>.<\/p>\n

\"\"<\/a><\/p>\n

Diagrama de tiempo<\/strong><\/p>\n

La se\u00f1al SH\/LD<\/strong> se mantiene en ALTO<\/strong> durante las operaciones de desplazamiento. Un pulso a BAJO<\/strong> en este pin ingresa nuevos datos desde las entradas al registro de desplazamiento. Cuando el pulso vuelve a ALTO<\/strong>, queda todo dispuesto para aplicar pulsos de CLK<\/strong> y desplazar uno a uno los bits del registro hacia la salida serie QH<\/strong>. Si hemos usado un solo chip 74HC165<\/strong>, con 8 pulsos se habr\u00e1n le\u00eddo todas las entradas a trav\u00e9s de QH<\/strong> (luego de haberlo conectado a una entrada digital del Arduino). Cada chip adicional requiere 8 pulsos m\u00e1s. En los programas se puede entender claramente c\u00f3mo se ingresan los datos a variables dentro de nuestro microcontrolador.<\/p>\n

\"\"<\/a><\/p>\n

Leer una de las entradas del 74HC165 – Dise\u00f1o del programa:<\/strong><\/p>\n

\u25a0 Se aplica un pulso de alto a bajo y luego de regreso a alto en SH\/LD<\/strong>, y as\u00ed las entradas ingresan al registro de desplazamiento (condici\u00f3n \u201cLOAD<\/strong>\u201d, o de carga).<\/p>\n

\"\"<\/a><\/p>\n

\u25a0 Aplicar a la salida CLK<\/strong> la cantidad de pulsos necesarios, desplazando los datos, para que el bit que deseamos leer quede ubicado en la l\u00ednea de salida QH<\/strong>.<\/p>\n

\"\"<\/a><\/p>\n

\u25a0 Leer el valor del pin digital de entrada del Arduino.<\/p>\n

Primer programa de prueba<\/strong><\/p>\n

Este programa lee de a un pin e indica su estado en el LED<\/strong> incluido en el Arduino UNO, pin 13<\/strong> = LED_BUILTIN<\/strong>. Para determinar qu\u00e9 entrada queremos leer para conocer su estado, se lo indicamos tipeando los n\u00fameros 1<\/strong> a 8<\/strong> desde el teclado de la computadora a la que est\u00e9 conectado el Arduino por USB<\/strong>.<\/p>\n

Incluso, usando comparaciones con IF<\/strong> se podr\u00eda elegir como comando cualquier caracter. Puede ser \u201ca\u201d, \u201cb\u201d, \u201cc\u201d, o \u201cA\u201d, \u201cB\u201d, \u201cC\u201d, o lo que usted elija. Si la entrada proviene de sensores de puertas o ventanas abiertas, o de luces encendidas, se puede usar, por ejemplo, \u201cC\u201d para cocina, \u201cB\u201d para ba\u00f1o, \u201cP\u201d para pasillo, \u201cp\u201d para patio, \u201cE\u201d para entrada, \u201cH\u201d para una habitaci\u00f3n y \u201ch\u201d para otra habitaci\u00f3n. Y as\u00ed. Adem\u00e1s, estas letras de comando se pueden enviar a trav\u00e9s de un m\u00f3dulo Bluetooth HC-06<\/strong> o HC-05<\/strong> y controlar desde el tel\u00e9fono celular, recibiendo la respuesta por el mismo medio.<\/p>\n

En este programa \u2014para simplificar\u2014 se eligi\u00f3 tipear un n\u00famero desde el teclado para leer cada entrada. Lo m\u00e1s interesante es la funci\u00f3n que lee las entradas y las desplaza hacia la salida. Se le env\u00eda como par\u00e1metro un valor num\u00e9rico y entero de 1 a 8, y devuelve un 1 o un 0 seg\u00fan el estado de la entrada. No es dif\u00edcil ampliar el c\u00f3digo hasta la cantidad de entradas que desee.<\/p>\n

Agregando esta funci\u00f3n a su programa, puede usarla del modo que usted quiera.<\/p>\n

Utilizamos este circuito, que es el mismo que servir\u00e1 para todos los programas excepto el de manejo por SPI<\/strong>, que requiere conectar dos se\u00f1ales del circuito a las entradas MOSI<\/strong> y SCLK<\/strong> de esta interfaz, como luego veremos.<\/p>\n

Disculpen si tiene un aspecto un poco antiest\u00e9tico, pero ocurre que es dif\u00edcil cablear un conjunto de llavecitas DIP al chip 74HC165 con el programa de dibujo sin hacer cruces de cables, y que sea todo visible. Ya ver\u00e1n en la foto que el circuito real, en la protoboard, qued\u00f3 m\u00e1s prolijo.<\/p>\n

\"\"<\/a><\/p>\n

\"\"<\/a><\/p>\n

Programa para leer de a una entrada<\/strong><\/p>\n

\/* Este programa no requiere el uso de bibliotecas *\/\r\n\r\nint pinCargarDatos  = 8;  \/\/ Pin SH\/LD: desplazar-cargar en paralelo del 165\r\nint pinDato         = 11;  \/\/ Pin QH: salida serie del 165\r\nint pinClock        = 12;  \/\/ Pin CLK: clock del 165\r\n\r\n\/\/ esta funcion devuelve 1 o 0 segun el estado del pin\r\nint leeBit(int pinLeer){\r\n    int valorBit;\r\n    \/\/ Pulso de carga paralela, guarda estado de las entradas\r\n    digitalWrite(pinCargarDatos, LOW);\r\n    digitalWrite(pinCargarDatos, HIGH);  \/\/ pulso carga datos\r\n\r\n    \/\/ Lee el valor de bits de la salida QH del 74HC165\r\n     for(int i = 0; i < pinLeer; i++) \r\n     {\r\n        valorBit = digitalRead(pinDato); \/\/ leer el pin deseado\r\n        digitalWrite(pinClock, HIGH);\r\n        digitalWrite(pinClock, LOW); \/\/ pulso desplaza datos\r\n     }\r\n    return(valorBit);\r\n}\r\n\r\nvoid setup()\r\n{\r\n   Serial.begin(9600);\r\n\r\n    \/\/ Inicializar los pines digitales\r\n    pinMode(LED_BUILTIN, OUTPUT);\r\n    pinMode(pinCargarDatos, OUTPUT);\r\n    pinMode(pinClock, OUTPUT);\r\n    pinMode(pinDato, INPUT);\r\n    digitalWrite(pinClock, LOW);\r\n    digitalWrite(LED_BUILTIN, LOW);\r\n}\r\n\r\nvoid loop()\r\n{\r\n  int numeroPin;\r\n  char datoSerie;\r\n  if (Serial.available() > 0) \/\/ espero el caracter tipeado\r\n  {\r\n    datoSerie = Serial.read();  \/\/ lo leo\r\n    numeroPin = 8-(datoSerie-48)+1; \/\/ char ASCII en numero\r\n    if (leeBit(numeroPin) == 1) { digitalWrite(LED_BUILTIN,HIGH); } \r\n      else { digitalWrite(LED_BUILTIN,LOW); }\r\n  }\r\n}\r\n<\/pre>\n

 <\/p>\n


\n

 
\nSegundo ejemplo: ingresar todas las entradas a variables<\/strong><\/p>\n

El siguiente programa permite listar en el Monitor Serie el estado de los pines de entrada del circuito del ejemplo, o de una cadena de chips para ampliar 16, 24, 32 o m\u00e1s entradas. Tampoco necesita biblioteca. El listado se actualiza cada vez que cambia una entrada. Los comentarios explican en detalle su funcionamiento.<\/p>\n

\/* SN74HC165N_shift_reg\r\n * Traducido y modificado de https:\/\/playground.arduino.cc\/\r\n * Programa para ingresar valores de 8 bits desde un 74HC165\r\n * (registro de desplazamiento entrada paralela\/salida serie.\r\n * Este programa demuestra la lectura de 8 estados digitales\r\n * de un registro de desplazamiento 74HC165 usando solamente\r\n * 3 pines digitales del Arduino.\r\n * Se pueden conectar en cadena mas chips uniendo la salida serie\r\n * (pin QH) de un registro de desplazamiento a la entrada serie\r\n * (pin SER) del siguiente.\r\n * Por supuesto usted puede conectar en cadena tantos chips como\r\n * quiera y seguir usando solo 3 pines de Arduino (aunque hay que\r\n * ingresarlos en diferente variables unsigned long).\r\n*\/\r\n\r\n\/\/ Definir la cantidad de chips que estan conectados en cadena.\r\n#define CANTIDAD_CHIP   1\r\n\r\n\/\/ Ancho de los datos (cuantas lineas de entrada).\r\n#define ANCHO_DATOS  CANTIDAD_CHIP * 8\r\n\r\n\/\/ Ancho del pulso para cargar el registro de desplazamiento\r\n#define ANCHO_PULSO  5\r\n\r\n\/\/ Espera opcional entre lecturas del registro de desplazamiento\r\n#define ESPERA_DEL_CICLO 1\r\n\r\n\/\/ Debera cambiar \"int\" a \"long\" si la cantidad\r\n\/\/ CANTIDAD_CHIP es mayor que 2\r\n#define TIPO_VAL_BYTES unsigned int\r\n\r\nint pinCargarDatos  = 8;  \/\/ Pin SH\/LD: desplazar-cargar en paralelo del 165\r\nint pinDato         = 11; \/\/ Pin QH: salida serie del 165\r\nint pinClock        = 12; \/\/ Pin CLK: clock del 165\r\n\r\nTIPO_VAL_BYTES valoresPin;\r\nTIPO_VAL_BYTES viejosValoresPin;\r\n\r\n\/\/ Esta funcion es una rutina de \"desplazamiento hacia adentro\" que\r\n\/\/ lee datos en serie desde el registro de desplazamiento de los chips\r\n\/\/ y arma el estado de los pines en un unsigned integer (o long integer)\r\nTIPO_VAL_BYTES lee_registros_desplaz()\r\n{\r\n    long valorBit;\r\n    TIPO_VAL_BYTES valorBytes = 0;\r\n\r\n    \/\/ Pulso de carga paralela para guardar el estado de las entradas\r\n    digitalWrite(pinCargarDatos, LOW);  \/\/ pulso carga datos a BAJO\r\n    delayMicroseconds(ANCHO_PULSO);     \/\/ duracion pulso\r\n    digitalWrite(pinCargarDatos, HIGH); \/\/ pulso carga datos a ALTO\r\n\r\n    \/\/ Lazo que lee el valor de cada bit de la salida serie del 74HC165\r\n     for(int i = 0; i < ANCHO_DATOS; i++)\r\n    {\r\n        valorBit = digitalRead(pinDato);\r\n\r\n        \/\/ poner el bit correspondiente en valorBytes\r\n        valorBytes |= (valorBit << ((ANCHO_DATOS-1) - i));\r\n\r\n        \/\/ Pulso de Clock (el flanco de subida desplaza el siguiente bit).\r\n        digitalWrite(pinClock, HIGH);\r\n        delayMicroseconds(ANCHO_PULSO);\r\n        digitalWrite(pinClock, LOW);\r\n    }\r\n    return(valorBytes);\r\n}\r\n\r\n\/\/ Mostrar la lista de datos con su estado\r\nvoid mostrar_valores_pines()\r\n{\r\n    Serial.print(\"Estado pines:\\r\\n\");\r\n\r\n    for(int i = 0; i < ANCHO_DATOS; i++)\r\n    {\r\n        Serial.print(\"  Pin-\");\r\n        Serial.print(i);\r\n        Serial.print(\": \");\r\n\r\n        if((valoresPin >> i) & 1)\r\n            Serial.print(\"ALTO\");\r\n        else\r\n            Serial.print(\"BAJO\");\r\n\r\n        Serial.print(\"\\r\\n\");\r\n    }\r\n    Serial.print(\"\\r\\n\");\r\n}\r\n\r\nvoid setup()\r\n{\r\n    Serial.begin(9600);\r\n\r\n    \/\/ Inicializar los pines digitales\r\n    pinMode(pinCargarDatos, OUTPUT);\r\n    pinMode(pinClock, OUTPUT);\r\n    pinMode(pinDato, INPUT);\r\n\r\n    digitalWrite(pinClock, LOW); \/\/ inicializa CLK en BAJO\r\n    digitalWrite(pinCargarDatos, LOW); \/\/ inicializa carga datos a BAJO\r\n\r\n    \/\/ Leer y mostrar los estados de los pines la 1ra vez\r\n    valoresPin = lee_registros_desplaz();\r\n    mostrar_valores_pines();\r\n    viejosValoresPin = valoresPin;\r\n}\r\n\r\nvoid loop()\r\n{\r\n    \/\/ Lee el estado de todos los bytes\r\n    valoresPin = lee_registros_desplaz();\r\n\r\n    \/\/ Si hay un cambio de estado, muestra los que cambiaron\r\n    if(valoresPin != viejosValoresPin)\r\n    {\r\n        Serial.print(\"*Detectado cambio de valor de Pin*\\r\\n\");\r\n        mostrar_valores_pines();\r\n        viejosValoresPin = valoresPin;\r\n    }\r\n\r\n    delay(ESPERA_DEL_CICLO);\r\n}\r\n<\/pre>\n

El Monitor Serie mostrar\u00e1 este mensaje, y se renovar\u00e1 cada vez que se cambie el valor de una entrada.<\/p>\n

\"\"<\/a><\/p>\n

\"\"<\/a>
\n <\/p>\n


\n

 
\nBiblioteca ShiftIn<\/strong><\/p>\n

Esta es una biblioteca que permite leer 8 o m\u00e1s entradas. Y tambi\u00e9n, si bien la biblioteca tiene una funci\u00f3n que define 4 pines, se pueden usar s\u00f3lo 3 pines al Arduino. Adem\u00e1s, se puede conectar en cadena varios registros de desplazamiento utilizando la misma cantidad de pines digitales, o sea 3. El cableado es con la misma configuraci\u00f3n que en el diagrama de protoboard mostrado arriba.<\/p>\n

Instalaci\u00f3n f\u00e1cil (importar zip)<\/strong><\/p>\n

La forma m\u00e1s f\u00e1cil de instalar esta biblioteca es descargar la \u00faltima versi\u00f3n y luego importarla. No tiene que descomprimirlo. Simplemente abra su IDE de Arduino y navegue a Programa > Incluir Librer\u00eda > A\u00f1adir Biblioteca .ZIP… y luego seleccione el archivo zip, que puede bajar desde aqu\u00ed<\/a><\/strong>.<\/p>\n

Instalaci\u00f3n manual<\/strong><\/p>\n

Por supuesto tambi\u00e9n se puede instalar esta biblioteca manualmente. Para hacerlo, descargue la versi\u00f3n m\u00e1s reciente y descompr\u00edmala. Luego tiene que copiar la carpeta ShiftIn (NO la carpeta ShiftIn-x.y.z) y colocarla en la carpeta de la biblioteca Arduino:<\/p>\n

Windows:<\/strong> Documentos\\Arduino\\libraries\\
\nMac and Linux:<\/strong> Documents\/Arduino\/libraries\/<\/p>\n

Despu\u00e9s de esto solo hay que reiniciar el IDE<\/strong> de Arduino.<\/p>\n

Uso de ShiftIn<\/strong><\/p>\n

Si ha instalado esta biblioteca, puede incluirla navegando a Programa > Incluir Librer\u00eda > ShiftIn. Esto agregar\u00e1 la l\u00ednea #include <ShiftIn.h> a su programa (por supuesto, tambi\u00e9n puede escribir esta l\u00ednea manualmente).<\/p>\n

Ahora se puede usar esta biblioteca:<\/p>\n

\/*\r\n  Este programa es ejemplo de la libreria ShiftIn.h\r\n  que se encuentra aqui https:\/\/github.com\/InfectedBytes\/ArduinoShiftIn\r\n*\/\r\n#include <ShiftIn.h>\r\n\/\/ Inicia una instancia de ShiftIn un 1 chip.\r\n\/\/ El numero define la cantidad de chips 74HC165 conectados en serie\r\n\/\/ Si usted arma un circuit con 2 chips debe escribir: ShiftIn<2> shift;\r\n\r\nShiftIn<1> shift;\r\n\r\nvoid setup() {\r\n\/\/ iniciar serie. El programa muestra en Monitor Serie\r\n  Serial.begin(9600);\r\n  \r\n\/\/ declar pines: \r\n\/\/ pLoadPin (SH\/LD = 8), clockEnablePin (CLK INB = 9), \r\n\/\/ dataPin (SER = 11), clockPin (CLK = 12)\r\n\/\/ si bien la librer\u00eda usa 4 pines solo usamos 3\r\n\/\/ no hace falta usar CLK INB en el circuito, va a GND\r\n  shift.begin(8, 9, 11, 12);\r\n}\r\n\r\nvoid displayValues() {\r\n  for(int i = 0; i < shift.getDataWidth(); i++)\r\n    Serial.print( shift.state(i) ); \/\/ obtiene el estado de la entrada i\r\n  Serial.println();\r\n}\r\n\r\nvoid loop() {\r\n\/\/ lee los valores. Retorna VERDADERO\r\n\/\/ si alguna entrada ha cambiado y\r\n\/\/ muestra los valores en Monitor Serie\r\n  if(shift.update()) \r\n    displayValues();\r\n  delay(1);\r\n}\r\n<\/pre>\n

Los datos en el Monitor Serie se ver\u00e1n as\u00ed:<\/p>\n

\"\"<\/a><\/p>\n

Si usted necesita usar dos shift registers, s\u00f3lo tiene que cambiar la declaraci\u00f3n de ShiftIn<1> shift;<\/strong> a ShiftIn<2> shift;<\/strong>, y as\u00ed sucesivamente. <\/p>\n

El diagrama para 2 chips – 16 entradas es este:<\/p>\n

\"\"<\/a><\/p>\n

Detalle de las funciones de la biblioteca ShiftIn<\/strong><\/p>\n

Dependiendo de la cantidad de chips, esta biblioteca utilizar\u00e1 diferentes tipos de datos. Si solo est\u00e1 utilizando un chip, el tipo ShiftType<\/strong> ser\u00e1 un unsigned byte<\/strong> (uint8_t<\/strong>). Para dos chips ser\u00e1 un unsigned int<\/strong> (uint16_t<\/strong>). Para tres o cuatro chips ser\u00e1 un unsigned long<\/strong> (uint32_t<\/strong>) y para 5<\/strong> a 8<\/strong> chips ser\u00e1 un unsigned long long<\/strong> (uint64_t<\/strong>). La biblioteca todav\u00eda no maneja m\u00e1s de ocho chips.<\/p>\n

Esta funci\u00f3n debe ser llamada en la funci\u00f3n de configuraci\u00f3n. Se utiliza para indicar a la biblioteca los pines que debe usar.<\/p>\n

void begin(int ploadPin, int clockEnablePin, int dataPin, int clockPin)<\/strong><\/p>\n

GetPulseWidth()<\/strong> define el retardo para el pin de clock en microsegundos. Este valor est\u00e1 fijado en 5 us y en general no habr\u00e1 necesidad de cambiarlo, aunque teniendo en cuenta el tiempo de programa transcurrido entre la ejecuci\u00f3n de el inicio del pulso y de su final, puede ser tan peque\u00f1o como 1 us, incluso 0.<\/p>\n

uint8_t getPulseWidth()
\nvoid setPulseWidth(uint8_t value)<\/strong><\/p>\n

Retorna la cantidad de entradas (bits en el estado)
\nuint16_t getDataWidth()<\/strong><\/p>\n

Retornan VERDADERO si ha cambiado alguna entrada durante la \u00faltima lectura.
\nboolean hasChanged()<\/strong>
\nboolean hasChanged(int i)<\/strong> \/\/ lo mismo de arriba, pero solo para la entrada i<\/p>\n

Retornan el estado completo del actual y el \u00faltimo grupo de bits
\nShiftType getCurrent()
\nShiftType getLast()<\/strong><\/p>\n

Retornan el estado de una sola entrada en el grupo actual de bits y el \u00faltimo grupo de bits
\nboolean state(int i)
\nboolean last(int i)<\/strong><\/p>\n

Indica cuando una entrada ha cambiado. En el ejemplo de los esquemas, se ha presionado o se ha soltado un pulsador
\nboolean pressed(int id)<\/strong> \/\/ no estaba presionado en la \u00faltima lectura, pero ahora s\u00ed
\nboolean released(int id)<\/strong> \/\/ estaba presionado en la \u00faltima lectura, pero ahora fue liberado<\/p>\n

Esta funci\u00f3n (la funci\u00f3n para actualizar) debe ser llamada una vez por cada grupo de bits. Leer\u00e1 todos los valores de los shift registers y retornar\u00e1 el nuevo estado.
\nShiftType read()<\/strong><\/p>\n

Esta funci\u00f3n es b\u00e1sicamente la misma que la funci\u00f3n read<\/strong>, pero retorna VERDADERO si ha cambiado de estado alguna entrada, y FALSO en el caso contrario
\nboolean update()<\/strong>
\n <\/p>\n


\n

 
\nIngresando datos por SPI<\/strong><\/p>\n

Conectando el 74HC165<\/strong> a la interfaz SPI<\/strong> se puede leer r\u00e1pidamente 8 entradas digitales, ingresando los 8 bits en una sola instrucci\u00f3n de SPI<\/strong>. Se los puede encadenar para leer 16, 24, 32 o m\u00e1s entradas a la vez.<\/p>\n

Podr\u00eda usarse, por ejemplo, para examinar la configuraci\u00f3n de un interruptor DIP de 8 interruptores (donde se fijar\u00eda la configuraci\u00f3n del dispositivo).<\/p>\n

En el 74HC165<\/strong> se tiene que pulsar el pin de \u00abcargar\u00bb (pin 1 del chip) para que el registro ingrese las entradas externas en sus registros internos.<\/p>\n

La habilitaci\u00f3n del chip, en esta prueba, es fija. El pin de activaci\u00f3n de chip (\/CLK INH<\/strong>) est\u00e1 a tierra, ya que el chip tambi\u00e9n puede funcionar estando siempre habilitado. Tenga en cuenta que la l\u00ednea MISO<\/strong> siempre est\u00e1 activa, por lo que no es posible compartir este chip con otros dispositivos SPI<\/strong> utilizando el hardware SPI. Se puede solucionar agregando un circuito selector, pero no lo describir\u00e9 en este art\u00edculo ya que si necesita usar otro dispositivo SPI, puede utilizar los otros ejemplos de programa, sin necesidad de SPI<\/strong>.<\/p>\n

C\u00f3digo de programa<\/strong><\/p>\n

Es f\u00e1cil de leer desde el registro. La biblioteca SPI<\/strong> se ocupar\u00e1 de todo. <\/p>\n

Los pasos importantes son (dentro de la funci\u00f3n de bucle):<\/p>\n

1. Aplique un pulse al pin de carga paralela para cargar el registro desde las entradas.
\n2. Haga una transferencia SPI para leer el registro del chip.<\/p>\n

Si desea leer m\u00e1s de 8 interruptores, simplemente use m\u00e1s registros, conecte en paralelo los pines 1, 2 y 15 de los chips, y la salida de cada chip \u00abanterior\u00bb en la secuencia (QH<\/strong>) a la entrada del siguiente (SER<\/strong>).<\/p>\n

Para leer cuatro bancos de interruptores, se cambia la secci\u00f3n de lectura del programa:<\/p>\n

digitalWrite(LATCH, LOW);
\ndigitalWrite(LATCH, HIGH);
\nbancoEntradas1 = SPI.transfer(0);
\nbancoEntradas2 = SPI.transfer(0);
\nbancoEntradas3 = SPI.transfer(0);
\nbancoEntradas4 = SPI.transfer(0);<\/strong><\/p>\n

NOTA:<\/strong> OBSERVE QUE HAY QUE CAMBIAR<\/strong>, EN EL DIAGRAMA DEL PROTOBOARD DE ARRIBA, LOS PINES QUE IBAN A SALIDA DIGITAL 11 Y SALIDA DIGITAL 12<\/strong> DEL ARDUINO. LA CONEXI\u00d3N QUE ESTABA EN 12<\/strong> SE DEBE PASAR A 13<\/strong>, Y LA QUE ESTABA EN 11<\/strong> SE DEBE PASAR A 12<\/strong>.<\/p><\/blockquote>\n

\/* Programa Demo para leer desde 74HC165\r\n   Autor: Nick Gammon\r\n   Fecha: 23 Marzo 2013\r\n\r\n   Conexiones para Uno y similares:\r\n   Chip pin 1 (SH\/LD)  conectado a LATCH (8) queda igual\r\n   Chip pin 2 (CLK)   conectado a SCK (13) antes en 12\r\n   Chip pin 9 (QH)   conectado a MISO (12) antes en 11\r\n\r\n   Conexiones para Mega2560:\r\n   Chip pin 1 (SH\/LD)  conectado a LATCH (8)\r\n   Chip pin 2 (CLK)   conectado a (52)\r\n   Chip pin 9 (QH)   conectado a (50)\r\n*\/\r\n\r\n#include <SPI.h>\r\n\r\nconst byte LATCH = 8;\r\n\r\nvoid setup()\r\n{\r\n  SPI.begin();\r\n  Serial.begin(9600);\r\n  Serial.println (\"Comienza la prueba de entradas\");\r\n  pinMode(LATCH, OUTPUT);\r\n  digitalWrite(LATCH, HIGH);\r\n}\r\n\r\nbyte bancoEntradas1;\r\n\/\/ agregar declaracion: byte bancoEntradas2;\r\n\/\/ agregar declaracion: byte bancoEntradas3;\r\n\/\/ agregar declaracion: byte bancoEntradas4;\r\nbyte bancoEntradas1Viejo; \/\/ estado previo\r\n\r\nvoid loop()\r\n{\r\n  digitalWrite (LATCH, LOW);\r\n  digitalWrite (LATCH, HIGH); \/\/ pulso en carga paralela\r\n  bancoEntradas1 = SPI.transfer(0);\r\n  \/\/  donde se debe agregar: bancoEntradas2 = SPI.transfer(0);\r\n  \/\/  donde se debe agregar: bancoEntradas3 = SPI.transfer(0);\r\n  \/\/  donde se debe agregar: bancoEntradas4 = SPI.transfer(0);\r\n  \r\n  byte mascara = 1;\r\n  for (int i = 1; i <= 8; i++) {\r\n    if ((bancoEntradas1 & mascara) != (bancoEntradas1Viejo & mascara))\r\n      {\r\n      Serial.print (\"Llave \");\r\n      Serial.print (i);\r\n      Serial.print (\" ahora \");\r\n      Serial.println ((bancoEntradas1 & mascara) ? \"cerrada\" : \"abierta\");\r\n      }  \/\/ fin de \"el bit ha cambiado\"\r\n    mascara <<= 1;  \r\n    }  \/\/ final para cada bit\r\n  \r\n  bancoEntradas1Viejo = bancoEntradas1;\r\n  delay (10);\r\n}\r\n<\/pre>\n

Resultados en Monitor Serie<\/strong>. Muestra una indicaci\u00f3n del estado al inicio, y luego lista cada cambio que se produce en las entradas:<\/p>\n

\"\"<\/a>
\n <\/p>\n


\n

 
\nOtras opciones<\/strong><\/p>\n

Por \u00faltimo, existen dos librer\u00edas relacionadas, llamadas bitBangedSPI<\/a><\/strong> y bitBangedSPIfast<\/a><\/strong>, que permiten operar las m\u00faltiples entradas desde 74HC165<\/strong> con un SPI<\/strong> implementado por software, y dejar libre el m\u00f3dulo SPI<\/strong> de hardware para otros dispositivos. Entiendo que es lo que hicimos con los programas de ejemplo anteriores, pero les dejo la inquietud de investigarlos y probarlos.<\/p>\n