¿Es posible tener más de 14 pines de salida en el Arduino? Estoy trabajando en un proyecto en el que necesito encender varios LED de forma individual. Solo tengo un Arduino Uno, y no quiero obtener un Mega.
¿Es posible tener más de 14 pines de salida en el Arduino? Estoy trabajando en un proyecto en el que necesito encender varios LED de forma individual. Solo tengo un Arduino Uno, y no quiero obtener un Mega.
Respuestas:
Una forma común de expandir el conjunto de pines de salida disponibles en el Arduino es usar registros de desplazamiento como el 74HC595 IC ( enlace a la hoja de datos ).
Necesita 3 pines para controlar estos chips:
En un programa, pasa los datos un bit a la vez al registro de desplazamiento utilizando el comando shiftOut () , así:
shiftOut(dataPin, clockPin, data);
Con ese comando, establece cada una de las 8 salidas en el 595 IC con los 8 bits en la data
variable.
Con un 595, ganas 5 pines (8 en el IC, pero gastas 3 para hablar con él). Para obtener más salidas, puede conectar en serie una serie de 595, conectando su pin de salida en serie, al pin de datos del siguiente. También debe conectar juntos el reloj y los pines de cierre de todos los 595 IC.
El circuito resultante (usando un 595) se vería así:
La figura anterior se tomó de esta página web codeproject.com :
El pin de enganche se usa para mantener estables las salidas 595 mientras se cambian los datos, así:
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, data);
digitalWrite(latchPin, HIGH);
Hay dos formas de obtener más pines de un arduino.
La primera forma es mediante el uso de los pines analógicos como pines de salida digital, lo cual es realmente fácil de hacer. Todo lo que necesita hacer es referirse a A0-A5 como pines 14,15,16,17,18,19. Por ejemplo, para escribir alto en el pin A0 solo use digitalWrite (14, HIGH).
La otra forma de obtener más pines del Arduino es mediante el uso de un registro de desplazamiento. Para hacer esto, recomiendo usar el EZ-Expander Shield , que le permite usar digitalWrite ([20-35], HIGH) cuando importe la Biblioteca EZ-Expander. Sin embargo, este escudo solo permite que los pines se usen solo como salidas y usa los pines 8,12 y 13 para controlar los registros de desplazamiento.
Lo mejor es que puedes usar los dos métodos anteriores juntos sin ningún problema.
A0
- A5
directamente en lugar de usar los números 14-19. Por ejemplo, digitalWrite(A0, HIGH)
.
digitalWrite(A0)
es más correcto que digitalWrite(14)
ya que el primero siempre se asignará al pin físico (analógico) correcto. En una placa diferente, pin 14
de hecho puede no serlo A0
, por ejemplo, pin 14
en el MEGA es Serial3 TX
y no influirá en el pin analógico que está buscando. es decir, si se usa digitalWrite
en un pin analógico, use la referencia A0
- A5
.
Si desea controlar los LED, también puede usar un MAX7219 que puede controlar 64 LED, sin circuitos adicionales (no es necesario un transistor para amplificar la señal).
Conducir un MAX7219 requiere solo 3 pines de salida en Arduino. Además, puede encontrar algunas bibliotecas Arduino para ello.
También puede encadenar varios de ellos si necesita alimentar más de 64 LED.
Lo he usado con éxito para múltiples pantallas LED de 7 segmentos.
Desventaja: es caro (alrededor de $ 10).
Puedes usar Charlieplexing . Con esta técnica, puede conducir directamente los n*(n-1)
LED desde n pines. Entonces, con 3 pines puede manejar 6 LED, 4 pines - 12 LED, 5 pines - 20 LED y así sucesivamente.
Ejemplo:
Seis LED en 3 pines
PINS LEDS
0 1 2 1 2 3 4 5 6
0 0 0 0 0 0 0 0 0
0 1 Z 1 0 0 0 0 0
1 0 Z 0 1 0 0 0 0
Z 0 1 0 0 1 0 0 0
Z 1 0 0 0 0 1 0 0
0 Z 1 0 0 0 0 1 0
1 Z 0 0 0 0 0 0 1
0 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 0
0 1 1 1 0 0 0 1 0
1 0 0 0 1 0 0 0 1
1 0 1 0 1 1 0 0 0
1 1 0 0 0 0 1 0 1
1 1 1 0 0 0 0 0 0
Puedes ver un mejor tutorial aquí .
Puede usar el protocolo I 2 C (biblioteca Wire) para conectarse a otros dispositivos, como los expansores de puertos. Por ejemplo, el MCP23017.
Usé uno de esos chips para conectarme a una placa LCD. El MCP23017 tiene 16 puertos, que se pueden configurar como entradas o salidas. Como entradas pueden generar interrupciones si lo desean.
Ejemplo de conectar 13 de esos 16 a la pantalla LCD:
Ahora nos conectamos al Arduino usando solo 2 cables (SDA / SCL) más alimentación y tierra:
Algunos fabricantes de terceros han creado placas con 4 x MCP23017, esto le proporciona 64 entradas / salidas:
Puede usar multiplexores analógicos como el 74HC4051 (8 puertos) o el 74HC4067 (16 puertos) para conectar un pin a uno de los puertos 8/16 (pero solo uno en un momento dado), de esta manera:
Estos son bidireccionales, por lo que se pueden usar como expansores de entrada o salida.
Con SPI puede enviar datos seriales rápidos a un registro de desplazamiento, como el 74HC595. Estos pueden ser encadenados juntos. En este ejemplo, estoy controlando 32 LED con solo 3 pines de E / S (MOSI / MISO / SCK) más alimentación y tierra.
Encontré dentro de un letrero LED comercial que los 72 LEDs estaban controlados por chips 74HC595.
Esto tenía 9 chips manejando las columnas (9 x 8 = 72 LEDs) y un chip manejando las filas, en una configuración multiplexada.
Si solo desea controlar los LED, generalmente puede multiplexarlos. El MAX7219 simplifica eso al estar diseñado para controlar matrices LED, por ejemplo, pantallas de 7 segmentos:
O matrices de 64 LED:
En ambos casos, estos se pueden conectar en cadena, por ejemplo:
Todos esos ejemplos solo usan 3 pines del Arduino (MOSI / MISO / SCK) más potencia y tierra.
El expansor de puerto de 16 puertos mencionado anteriormente (MCP23017) también viene en una variante SPI (MCP23S17), que hace cosas prácticamente idénticas. Utiliza un cable más, pero sería más rápido.
Las tiras de LED (como las NeoPixel) tienen sus propios protocolos. ¡Hubo una publicación en Youtube de Josh Levine donde el autor manejó más de 1000 píxeles con un Duemilanove!
Los registros de desplazamiento se han mencionado en otras respuestas, y definitivamente son una excelente opción para muchos proyectos. Son baratos, simples, moderadamente rápidos y, por lo general, se pueden encadenar para agregar más salidas. Sin embargo, tienen el inconveniente de que generalmente necesitan el uso exclusivo de varios pines (entre 2 y 4, dependiendo de cómo los configure).
Una alternativa es utilizar expansores de puertos más avanzados, como el MCP23017 de 16 bits y el MCP23S17 . Estos admiten I2C y SPI respectivamente, lo que significa que puede colocarlos en un bus con varios otros dispositivos (potencialmente de diferentes tipos). Cada dispositivo en el bus se puede direccionar individualmente, lo que significa que solo necesita 2 o 3 pines para hablar con todos ellos. Las velocidades de actualización suelen ser extremadamente rápidas, por lo que es poco probable que experimente una latencia significativa (es decir, retrasos en la transmisión) en un proyecto Arduino.
En un nivel bajo, usar I2C o SPI es sustancialmente más complicado que un simple registro de desplazamiento. Sin embargo, hay un código de biblioteca para que Arduino se encargue de eso por usted. Vea esta pregunta, por ejemplo: ¿Cómo uso los dispositivos I2C con Arduino?
Además de la respuesta de Ricardo , lo que Wikipedia dice en los registros de desplazamiento :
Uno de los usos más comunes de un registro de desplazamiento es convertir entre interfaces seriales y paralelas. [...] Los registros SIPO se conectan comúnmente a la salida de microprocesadores cuando se requieren más pines de Entrada / Salida de Propósito General de los que están disponibles. Esto permite controlar varios dispositivos binarios utilizando solo dos o tres pines, pero más lento que la E / S paralela.
En el artículo que Ricardo vincula puede ver el diagrama del registro de desplazamiento.
Lo que sucede aquí es que coloca los datos de los 8 pines en una secuencia y para cada marca de reloj, el registro de desplazamiento cambiará (moverá los datos binarios de cada pestillo al siguiente) hasta que "haga un círculo", es decir, el primer bit llega al último pin. Los registros de desplazamiento también tienen una entrada donde puede activar / desactivar el desplazamiento para que el estado se pueda mantener después de que los datos se hayan desplazado a la posición. Para una demostración simple, vea la siguiente animación.
Aquí la luz roja es la entrada en serie y las verdes muestran el estado de los pestillos en este registro de desplazamiento SIPO simplificado . Después de que los datos se hayan desplazado a un lugar, se pueden desactivar los cambios y puede leer los pines. En este ejemplo, me mudé 10101011
.
A partir de estos ejemplos, puede darse cuenta de que la transferencia en serie será más lenta que en paralelo, ya que debe esperar a que el registro de desplazamiento desplace los bits a su lugar. Tendrá que esperar la misma cantidad de tics de reloj tantos bits que desee cargar. Esta es una de las muchas razones por las que no se pueden encadenar indefinidamente, porque la carga llevaría una eternidad.
Como ya escribió, puede usar todos los pines, incluidos TX y RX como salida digital. Lo hice hace un tiempo para un demostrador y grabé un video, 20 LEDS en 20 pines , de este proyecto bastante absurdo.
Como lo describe Peter R. Bloomfield aquí , debe desconectar TX y RX para cargar. Además, no tiene pines para leer sensores para una posible interactividad y debe asegurarse de que no se alcance el límite de corriente total. Sin olvidar que está limitado a leds de 5V si los conduce directamente con su Arduino.
Por lo tanto, se recomienda encarecidamente el uso de registros de desplazamiento en general y el 595, descrito por Ricardo .
Los usé hace un tiempo cuando me di cuenta de la parte de soldadura y programación de Kawaii me (el texto del enlace está en alemán) del artista de reciclaje Dominik Jais .
Aquí, solo un grupo de 595 fueron utilizados para manejar una pantalla de 8x11 leds. Dado que los leds se cortaron de una banda de leds SMD de 12V, fue necesaria una fuente de alimentación adicional y algunos arreglos Darlington UDN2803A , conectados a los pines de salida de los registros de desplazamiento.
Otros métodos generales incluirían el uso de expansores de puerto PCF8574 (A) de 8 bits, que se controlan a través del bus I2C.
De todos modos, probaría primero los registros de turno 595.
Sin embargo, si necesita controlar un par de leds RGB, es posible que desee buscar soluciones más especializadas. Algunos leds RGB vienen con su propio WS2812 . Estas piezas finas se pueden conectar en cascada (bus de 1 cable) y se abordan a través de su posición en la cadena.
Si se trata de LED, ¿qué pasa con las tiras de LED WS2812B, o solo los chips del controlador? ¡Puedes controlar un número virtualmente ilimitado de LED con solo un pin!
Aunque las personas están acostumbradas a esto en tiras, están disponibles como LED independientes (conocidos como neo píxeles en Adafruit). O si solo está manejando un solo color, cada chip WS2811 podría controlar 3 LED usando cada una de las salidas RGB para un solo LED cada uno.
Recientemente, acabo de crear un proyecto que utiliza 5 de estos LED: Puerta1 abierta / cerrada, Puerta2 abierta / cerrada, motor1 activo, motor2 activo y encendido. Los LED "activos" tienen un doble propósito, ya que el rojo es la entrada del motor activo y el verde el indicador activo dentro del Arduino.
Punto que, con 1 pin y la biblioteca instalada, puede controlar cualquier número de LED
No reclamo este método por mi cuenta, pero encontré este buen truco en la página web MUX-DEMUX: CD4051 Trucos de salón
Cualquiera que sea el método que elija para manejar salidas o leer entradas (registros de desplazamiento, multiplexores o el uso directo directo de los pines Arduino), puede DOBLAR el número de salidas o entradas mediante un uso inteligente de pares de circuitos paralelos (para formar un doble banco de entrada o salida ), empleando diodos en sentidos opuestos en cada rama paralela, y cambiando las entradas / salidas a alto y bajo.
Para ilustrar el método para las salidas (LED en este caso, tenga en cuenta que no se requieren diodos adicionales):
Si considera que el par de LED en este ejemplo es un "banco" y desea encender LED_0, debe configurar el PIN 17 en ALTO y el PIN 18 en BAJO. (Los números de pin son confusos, pero coinciden con el ejemplo posterior tan desnudo conmigo). Para encender el LED_1, simplemente invierte los PINS. La naturaleza del diodo de los LED evita que la corriente fluya en la dirección opuesta, manteniendo el otro apagado.
Para ilustrar el método para las entradas (CdS en este caso, tenga en cuenta que se requieren diodos adicionales):
Esto se vuelve un poco más complicado si desea hacer una lectura analógica en un sensor de luz CdS. Primero, debe agregar un diodo a cada sensor para controlar el flujo. En segundo lugar, dado que está leyendo valores, debe subir o bajar las entradas para evitar que floten. Siendo una persona perezosa, voy a sacarlos usando las resistencias pull-up internas. Para leer CdS_0, establezca el modo PIN 17 en SALIDA y configúrelo en BAJO. Esto lo convierte en el suelo. Luego configura el modo PIN 18 en INPUT y lo configura en HIGH para activar la resistencia pull-up. Ahora está configurado para leer el PIN 18 (también conocido como pin analógico 4). Para acceder al otro sensor, simplemente cambie los modos y las salidas.
Por lo tanto, si tiene un multiplexor CD4051 de 8 puertos, que utiliza 5 pines en el Arduino (en lugar de los 3 habituales), puede obtener 16 entradas o salidas, o una combinación de los dos.
Del mismo modo, si tiene un multiplexor 4067 de 16 puertos, puede obtener 32 entradas o salidas, o una combinación de las dos.
Un boceto de ejemplo sería:
/*
* Example of getting 16 i/o from 5 pins using a CD4051
*
* Based on tutorial and code by david c. and tomek n.* for k3 / malmö högskola
* http://www.arduino.cc/playground/Learning/4051?action=sourceblock&ref=1
*/
int selPin[] = { 14, 15, 16 }; // select pins on 4051 (analog A0, A1, A2)
int commonPin[] = { 17, 18}; // common in/out pins (analog A3, A4)
int led[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW }; // stores eight LED states
int CdSVal[] = { 0, 0, 0, 0 }; // store last CdS readings
int cnt = 0; // main loop counter
int persistDelay = 100; // LED ontime in microseconds
void setup(){
Serial.begin(9600); // serial comms for troubleshooting (always)
for(int pin = 0; pin < 3; pin++){ // setup select pins
pinMode(selPin[pin], OUTPUT);
}
}
void loop(){
flashLEDs();
if (cnt == 0){
for(int x; x < 8; x++){
led[x] = random(2);
}
}
cnt++;
if (cnt > 100) { cnt = 0; }
}
void flashLEDs() {
for(int pin = 0; pin < 2; pin++) { // set common pins low
pinMode(commonPin[pin], OUTPUT);
digitalWrite(commonPin[pin], LOW);
}
for (int bank = 0; bank < 4; bank++) {
for(int pin = 0; pin < 3; pin++) { // parse out select pin bits
int signal = (bank >> pin) & 1; // shift & bitwise compare
digitalWrite(selPin[pin], signal);
}
if (led[bank * 2]){ // first LED
digitalWrite(commonPin[0], HIGH); // turn common on
delayMicroseconds(persistDelay); // leave led lit
digitalWrite(commonPin[0], LOW); // turn common off
}
if (led[bank * 2 + 1]){ // repeat for second LED
digitalWrite(commonPin[1], HIGH);
delayMicroseconds(persistDelay);
digitalWrite(commonPin[1], LOW);
}
}
}
Como dije en la primera línea, la explicación completa se puede encontrar en MUX-DEMUX: CD4051 Parlor Tricks
Para un proyecto de clase utilicé un CD4024 y dos pines Arduino para manejar una pantalla de 7 segmentos.
Hay algunas advertencias a este enfoque. Por ejemplo, para escribir un high
valor en la primera salida de un contador de ondulación solo se requiere reset
ay alternar el pin del reloj dos veces. Pero si desea escribir high
en todos los n pines, debe activar el pin del reloj 2 n veces, y durante ese tiempo, todos los demás pines se activan y desactivan constantemente.
Si su aplicación puede manejar estas limitaciones y le faltan pines, es otra opción.
Bono de respuesta: hay una gran cantidad de ejemplos de entradas de multiplexación aquí , muchos de los cuales también se aplican a las salidas de multiplexación.
Con un poco de trabajo (instalar un gestor de arranque diferente), hay disponibles siete líneas de E / S adicionales en Uno, en los encabezados ICSP1 y JP2. El gestor de arranque de reemplazo se llama HoodLoader2 . Le permite instalar bocetos tanto en Atmega328 como en Atmega16U2 en Uno. Tratar con múltiples procesadores sería la principal complicación del uso de este método.
En un Uno, los encabezados ICSP1 y JP2 se conectan a los pines PB1 ... PB7 del Atmega16U2. Además, el Atmega16U2 tiene aproximadamente 9 pines de E / S sin conexión a la placa de circuito. Una persona que trabaja bajo un microscopio podría conectar cables a un total de 18 pines de E / S en el 16U2, mientras deja otros tres pines de E / S conectados a sus conexiones normales.
HoodLoader2 también funciona en placas Mega.