É possível ter mais de 14 pinos de saída no Arduino? Estou trabalhando em um projeto no qual preciso acender vários LEDs individualmente. Eu só tenho um Arduino Uno e não quero um Mega.
É possível ter mais de 14 pinos de saída no Arduino? Estou trabalhando em um projeto no qual preciso acender vários LEDs individualmente. Eu só tenho um Arduino Uno e não quero um Mega.
Respostas:
Uma maneira comum de expandir o conjunto de pinos de saída disponíveis no Arduino é usar registros de deslocamento como o IC 74HC595 ( link para a folha de dados ).
Você precisa de 3 pinos para controlar esses chips:
Em um programa, você passa os dados um bit de cada vez para o shift shift usando o comando shiftOut () , da seguinte maneira:
shiftOut(dataPin, clockPin, data);
Com esse comando, você define cada uma das 8 saídas no 595 IC com os 8 bits na data
variável.
Com um 595, você ganha 5 pinos (8 no IC, mas gasta 3 para conversar com ele). Para obter mais saídas, você pode conectar uma série de 595 em série, conectando seu pino de saída serial ao pino de dados do próximo. Você também deve conectar os pinos do relógio e da trava de todos os 595 ICs.
O circuito resultante (usando um 595) ficaria assim:
A figura acima foi retirada desta página da codeproject.com :
O pino de trava é usado para manter as saídas 595 estáveis enquanto você transfere dados para ele, da seguinte forma:
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, data);
digitalWrite(latchPin, HIGH);
Existem duas maneiras de obter mais pinos de um arduino.
A primeira maneira é usar os pinos analógicos como pinos de saída digital, o que é realmente fácil de fazer. Tudo o que você precisa fazer é consultar A0-A5 como pinos 14,15,16,17,18,19. Por exemplo, para gravar alto no pino A0, basta usar digitalWrite (14, HIGH).
A outra maneira de obter mais pinos do Arduino é usando um Shift Register. Para fazer isso, recomendo usar o EZ-Expander Shield , que permite usar o digitalWrite ([20-35], HIGH) ao importar a Biblioteca do EZ-Expander. Essa blindagem, no entanto, permite apenas que os pinos sejam usados apenas como saídas e usa os pinos 8,12 e 13 para controlar os registros de deslocamento.
O melhor é que você pode usar os dois métodos acima juntos, sem problemas.
A0
- A5
identificadores diretamente, em vez de usar os números 14-19. Por exemplo digitalWrite(A0, HIGH)
,.
digitalWrite(A0)
é mais correto do que digitalWrite(14)
porque o primeiro sempre será mapeado para o pino físico (analógico) correto. Em uma placa diferente, pin 14
pode de fato não estar A0
, por exemplo, pin 14
no MEGA é Serial3 TX
e não influenciará o pino analógico que você procura . ou seja, se estiver usando digitalWrite
um pino analógico, use a referência A0
- A5
.
Se você deseja acionar LEDs, também pode usar um MAX7219 que pode acionar 64 LEDs, sem circuitos extras (não é necessário que o transistor amplifique o sinal).
A condução de um MAX7219 requer apenas 3 pinos de saída no Arduino. Além disso, você pode encontrar algumas bibliotecas do Arduino para isso.
Você também pode encadear vários deles, se precisar alimentar mais de 64 LEDs.
Usei-o com sucesso para vários displays de LED de 7 segmentos.
Desvantagem: é caro (cerca de US $ 10).
Você pode usar o Charlieplexing . Com esta técnica, você pode direcionar diretamente os n*(n-1)
LEDs de n pinos. Assim, com 3 pinos, você pode acionar 6 LEDs, 4 pinos - 12 LEDs, 5 pinos - 20 LEDs e assim por diante.
Exemplo:
Seis LEDs em 3 Pins
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
Você pode ver um tutorial melhor aqui .
Você pode usar o protocolo I 2 C (biblioteca de fios) para conectar-se a outros dispositivos, como expansores de porta. Por exemplo, o MCP23017.
Eu usei um desses chips para conectar a uma placa de LCD. O MCP23017 possui 16 portas, que podem ser configuradas como entradas ou saídas. Como entradas, eles podem gerar interrupções, se desejado.
Exemplo de conexão de 13 desses 16 ao LCD:
Agora nos conectamos ao Arduino usando apenas 2 fios (SDA / SCL), além de potência e terra:
Alguns fabricantes terceirizados criaram placas com 4 x MCP23017, o que fornece 64 entradas / saídas:
Você pode usar multiplexadores analógicos como o 74HC4051 (8 portas) ou o 74HC4067 (16 portas) para conectar um pino a uma das portas 8/16 (mas apenas uma por vez), desta forma:
Eles são bidirecionais e podem ser usados como expansores de entrada ou saída.
Usando o SPI, você pode enviar dados seriais rápidos para um registro de turno, como o 74HC595. Estes podem ser encadeados juntos. Neste exemplo, estou controlando 32 LEDs com apenas 3 pinos de E / S (MOSI / MISO / SCK), além de potência e terra.
Encontrei dentro de um sinal comercial de LED que os 72 LEDs eram acionados por chips 74HC595.
Isso tinha 9 chips dirigindo as colunas (9 x 8 = 72 LEDs) e um chip dirigindo as linhas, em uma configuração multiplexada.
Se você quiser apenas conduzir LEDs, geralmente pode multiplexá-los. O MAX7219 simplifica isso ao ser projetado para acionar matrizes de LED, por exemplo, displays de 7 segmentos:
Ou matrizes de 64 LEDs:
Nos dois casos, eles podem ser encadeados juntos, por exemplo:
Todos esses exemplos usam apenas 3 pinos do Arduino (MOSI / MISO / SCK), além de potência e terra.
O expansor de portas de 16 portas mencionado anteriormente (MCP23017) também vem em uma variante SPI (MCP23S17), que faz coisas praticamente idênticas. Ele usa mais um fio, mas seria mais rápido.
As tiras de LED (como as NeoPixel) têm seus próprios protocolos. Houve um post no Youtube de Josh Levine, onde o autor dirigiu mais de 1000 pixels com um Duemilanove!
Os registros de turnos foram mencionados em outras respostas e são definitivamente uma excelente opção para muitos projetos. Eles são baratos, simples, moderadamente rápidos e geralmente podem ser encadeados para adicionar mais saídas. No entanto, eles têm a desvantagem de que geralmente precisam de uso exclusivo de vários pinos (entre 2 e 4, dependendo de como você os configura).
Uma alternativa é usar expansores de porta mais avançados, como o MCP23017 e o MCP23S17 de 16 bits . Eles suportam I2C e SPI, respectivamente, o que significa que você pode colocá-los em um barramento com vários outros dispositivos (potencialmente de tipos diferentes). Cada dispositivo no barramento pode ser endereçado individualmente, o que significa que você só precisa de 2 ou 3 pinos para conversar com todos eles. As velocidades de atualização são geralmente extremamente rápidas, portanto, é improvável que você experimente uma latência significativa (ou seja, atrasos na transmissão) em um projeto do Arduino.
Em um nível baixo, o uso de I2C ou SPI é substancialmente mais complicado do que um simples registro de turno. No entanto, existe um código de biblioteca para o Arduino cuidar disso para você. Veja esta pergunta, por exemplo: Como uso dispositivos I2C com o Arduino?
Além da resposta de Ricardo , o que a Wikipedia afirma no turno registra :
Um dos usos mais comuns de um registrador de deslocamento é converter entre interfaces seriais e paralelas. [...] os registradores SIPO geralmente são anexados à saída dos microprocessadores quando são necessários mais pinos de entrada / saída de uso geral do que os disponíveis. Isso permite que vários dispositivos binários sejam controlados usando apenas dois ou três pinos, mas mais lento que a E / S paralela.
No artigo Ricardo vinculado, você pode ver o diagrama do registro de turnos.
O que acontece aqui é que você coloca os dados dos 8 pinos em uma sequência e, para cada relógio, o registro de deslocamento muda (mova os dados binários de cada trava para a próxima) até que "faça um círculo", ou seja, o primeiro bit chega ao último pino. Os registros de mudança também têm uma entrada na qual é possível ativar / desativar a mudança, para que o status possa ser mantido depois que os dados forem deslocados para a posição. Para uma demonstração simples, veja a seguinte animação.
Aqui, a luz vermelha é a entrada serial e as verdes estão mostrando o estado das travas neste registro de turno SIPO simplificado . Depois que os dados mudam para o local, a mudança pode ser desativada e você pode ler os pinos. Neste exemplo, mudei para fora 10101011
.
A partir desses exemplos, você pode perceber que a transferência serial será mais lenta que a paralela, porque é necessário aguardar que o registrador de deslocamento mude os bits para o seu lugar. Você terá que esperar a mesma quantidade de tiques do relógio quantos bits você deseja carregar. Essa é uma das muitas razões pelas quais você não pode encadear indefinidamente, porque o carregamento levaria uma eternidade.
Como você já escreveu, você pode usar todos os pinos, incluindo TX e RX como saída digital. Eu fiz isso há um tempo atrás para um demonstrador e gravei um vídeo - 20 LEDS em 20 pinos - desse projeto absurdo.
Conforme descrito por Peter R. Bloomfield aqui , é necessário desconectar o TX e o RX para fazer o upload. Além disso, você está sem pinos para ler os sensores para uma possível interatividade e precisa garantir que o limite total de corrente não seja atingido. Para não esquecer que você está limitado a leds de 5V se você os direcionar diretamente com o seu Arduino.
O uso de registros de turno em geral e o 595, descrito por Ricardo, é altamente recomendável.
Eu os usei há um tempo atrás quando percebi a parte de solda e programação do Kawaii me (o texto do link está em alemão) do artista de reciclagem Dominik Jais .
Aqui, apenas um monte de 595 foram usados para exibir um display de 8x11 leds. Como os leds foram cortados a partir de uma faixa de 12V SMD, era necessária uma fonte de alimentação adicional e algumas matrizes UDN2803A Darlington, conectadas aos pinos de saída dos registros de mudança.
Outros métodos gerais incluem o uso de expansores de porta PCF8574 (A) de 8 bits, que são controlados através do barramento I2C.
Enfim, eu daria uma chance aos registradores de turno 595.
Se você precisar controlar alguns leds RGB, no entanto, convém procurar soluções mais especializadas. Alguns leds RGB vêm com seu próprio WS2812 . Essas peças finas podem ser conectadas em cascata (barramento de 1 fio) e são endereçadas através de sua posição na corrente.
Se é tudo sobre LEDs, o que dizer das tiras de LED WS2812B, ou apenas dos próprios chips de driver? Você pode controlar um número praticamente ilimitado de LEDs usando apenas um pino!
Embora as pessoas estejam acostumadas a isso em tiras, elas estão disponíveis como LEDs independentes (conhecidos como pixels neo no Adafruit). Ou, se você estiver dirigindo apenas uma cor, cada chip WS2811 poderá controlar 3 LEDs usando cada uma das saídas RGB para um único LED cada.
Recentemente, criei um projeto que utiliza 5 desses LEDs: Porta1 aberta / fechada, Porta2 aberta / fechada, motor1 ativo, motor2 ativo e potência. Os LEDs "ativos" são de dupla finalidade, pois eu tenho o vermelho sendo a entrada do motor ativo e o verde sendo a bandeira ativa dentro do Arduino.
Sendo que, com 1 pino e a biblioteca instalada, você pode controlar qualquer número de LEDs
Não reivindico esse método sozinho, mas encontrei esse truque na página da web MUX-DEMUX: CD4051 Parlour Tricks
Qualquer que seja o método escolhido para acionar saídas ou ler entradas (registradores de deslocamento, multiplexadores ou o uso direto direto dos próprios pinos do Arduino), você pode DOBRAR o número de saídas ou entradas por meio do uso inteligente de pares de circuitos paralelos (para formar um duplo banco de entrada ou saída ), empregando diodos em sentidos opostos em cada ramo paralelo e alternando as entradas / saídas para alta e baixa.
Para ilustrar o método para saídas (neste caso, LEDs, observe que os diodos extras não são necessários):
Se você considerar o par de LEDs neste exemplo um "banco" e deseja acender o LED_0, precisará definir o PIN 17 como ALTO e o PIN 18 como BAIXO. (Os números dos pinos são confusos, mas coincidem com o exemplo mais recente comigo). Para acender o LED_1, basta reverter os PINS. A natureza do diodo dos LEDs impede que a corrente flua na direção oposta, mantendo o outro desligado.
Para ilustrar o método para entradas (CdSs, neste caso, observe que os diodos extras são necessários):
Isso fica um pouco mais complicado se você deseja fazer uma leitura analógica em um sensor de luz CdS. Primeiro, você precisa adicionar um diodo a cada sensor para controlar o fluxo. Segundo, como você está lendo valores, precisa puxar as entradas para cima ou para baixo para impedir que elas flutuem. Sendo uma pessoa preguiçosa, vou puxá-los para o alto usando os resistores de pull-up internos. Para ler CdS_0, você define o modo PIN 17 como OUTPUT e o valor para LOW. Isso torna o terreno. Em seguida, defina o modo PIN 18 como ENTRADA e ALTO para ativar o resistor de pull-up. Agora você está pronto para ler o PIN 18 (também conhecido como pino analógico 4). Para acessar o outro sensor, basta alternar entre os modos e saídas.
Portanto, se você tiver um multiplexador de 8 portas CD4051, usando 5 pinos no Arduino (em vez dos 3 habituais), poderá obter 16 entradas ou saídas, ou uma mistura dos dois.
Da mesma forma, se você possui um multiplexador 4067 de 16 portas, pode obter 32 entradas ou saídas ou uma mistura dos dois.
Um esboço de exemplo seria:
/*
* 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 eu disse na primeira linha, a explicação completa pode ser encontrada em MUX-DEMUX: CD4051 Parlour Tricks
Para um projeto de classe, usei um CD4024 e dois pinos Arduino para direcionar uma tela de 7 segmentos.
Existem algumas ressalvas nessa abordagem. Por exemplo, para escrever um high
valor na primeira saída de um contador de ondulações, é necessário a reset
e alternar o pino do relógio duas vezes. Mas se você deseja gravar high
em todos os n pinos, é necessário alternar o pino do relógio 2 n vezes e, durante esse período, todos os outros pinos são ativados e desativados constantemente.
Se seu aplicativo pode lidar com essas limitações e você não tem pinos, é outra opção.
Resposta bônus: existem muitos exemplos de entradas de multiplexação aqui , muitos dos quais também se aplicam a saídas de multiplexação.
Com um pouco de trabalho (instalando um gerenciador de inicialização diferente), outras sete linhas de E / S estão disponíveis em um Uno, nos cabeçalhos ICSP1 e JP2. O carregador de inicialização de substituição é chamado HoodLoader2 . Ele permite que você instale esboços no Atmega328 e no Atmega16U2 em um Uno. Lidar com múltiplos processadores seria a principal complicação do uso desse método.
Em um Uno, os cabeçalhos ICSP1 e JP2 se conectam aos pinos PB1 ... PB7 do Atmega16U2. Além disso, o Atmega16U2 possui cerca de 9 pinos de E / S, sem conexão com a placa de circuito. Uma pessoa que trabalha sob um microscópio pode conectar cabos a um total de 18 pinos de E / S na 16U2, deixando três outros pinos de E / S conectados às suas conexões comuns.
HoodLoader2 também funciona em Mega boards.