C'è un modo per avere più di 14 pin di output su arduino?


52

È possibile avere più di 14 pin di uscita su Arduino, sto lavorando a un progetto in cui ho bisogno di accendere diversi LED singolarmente. Ho solo un Arduino Uno e non voglio ottenere un Mega.


Nello spirito di espandibilità, I2C è anche un'opzione con Arduino?
Chris O,

@ChrisO Cosa intendi con I2C? Perché da quello che ho capito i registri Shift sarebbero considerati I2C.
JVarhol,

Oh, fammi rispondere alla mia domanda allora ;-) Ecco un articolo di Wikipedia su questo standard di bus. E ho appena trovato un supporto da Wire lib per I2C, in modo da poter collegare una catena I2C al tuo Uno.
Chris O,

@JVarhol Non proprio. I2C, aka TWI è un'interfaccia a 2 fili mentre SPI può essere considerata un'interfaccia a 3 fili.
Klaus-Dieter Warzecha,

1
@JVarhol hai già selezionato una soluzione per il tuo progetto? In caso affermativo, sarebbe utile modificare la tua domanda e accettare la risposta che corrisponde (o è la più vicina) alla tua soluzione.
jfpoilpret,

Risposte:


50

Un modo comune per espandere il set di pin di uscita disponibili su Arduino è utilizzare i registri a scorrimento come l'IC 74HC595 ( collegamento alla scheda tecnica ).

Sono necessari 3 pin per controllare questi chip:

  1. Orologio
  2. chiavistello
  3. Dati

In un programma, si passano i dati un bit alla volta al registro a scorrimento usando il comando shiftOut () , in questo modo:

shiftOut(dataPin, clockPin, data); 

Con quel comando, imposti ciascuna delle 8 uscite sull'IC 595 con gli 8 bit nella datavariabile.

Con un 595, ottieni 5 pin (8 sull'IC, ma ne spendi 3 per parlare con esso). Per ottenere più output, è possibile collegare in serie una serie di 595 insieme, collegando il pin di uscita seriale al pin di dati di quello successivo. È inoltre necessario collegare insieme i pin di clock e di aggancio di tutti i 595 circuiti integrati.

Il circuito risultante (usando un 595) sarebbe simile al seguente:

Circuito che utilizza il registro a scorrimento 595

La figura sopra è stata presa da questa pagina web codeproject.com :

Il perno di chiusura viene utilizzato per mantenere costanti le uscite del 595 mentre si spostano i dati al suo interno, in questo modo:

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, data); 
digitalWrite(latchPin, HIGH);

1
Grazie, ho dimenticato di includere come funziona un registro a scorrimento. Avevo programmato di farlo, ma ho dovuto allontanarmi dal mio computer e quando sono tornato mi era sfuggito di mente. :)
JVarhol,

Nessun problema, ecco perché siamo una comunità. Ci completiamo a vicenda. Ma è bello che tu abbia aggiunto anche alcuni buoni consigli nella tua risposta, specialmente riguardo allo scudo EZ-Expander. Consente a coloro che non sono in grado di realizzare facilmente i propri PCB di espandere il numero di porte disponibili.
Ricardo,

2
Inoltre semplifica la programmazione, non è necessario spostare i dati e inserire il clock, quindi attivare il Latch. Conosco lo scudo da un po 'di tempo e penso che sia perfetto per i principianti. La cosa migliore è che, poiché il codice è opensource, è possibile utilizzare il codice anche se non si utilizza lo scudo effettivo ma si dispone di una propria scheda o si utilizza una breadboard.
JVarhol,

1
Non dimenticare che puoi collegarli in linea (teoricamente) indefinitamente, quindi 2 registri a 8 bit possono diventare uno a 16 bit.
Scott M.,

Grazie! Ecco un link all'archivio per la straordinaria descrizione del codeproject nel caso in cui il link non dovesse mai andare in archivio.fo/1uvPE
akhmed

27

Esistono due modi per ottenere più pin da un arduino.

Il primo modo è usare i pin analogici come pin di uscita digitali, il che è davvero facile da fare. Tutto quello che devi fare è fare riferimento a A0-A5 come pin 14,15,16,17,18,19. Ad esempio per scrivere in alto sul pin A0 basta usare digitalWrite (14, HIGH).

L'altro modo per ottenere più pin da Arduino è utilizzare un registro a scorrimento. Per fare ciò ti consiglio di usare EZ-Expander Shield , che ti consente di usare digitalWrite ([20-35], HIGH) quando importi la libreria EZ-Expander. Questo schermo consente tuttavia solo ai pin di essere utilizzati solo come uscite e utilizza i pin 8,12 e 13 per controllare i registri di spostamento.

La cosa bella è che puoi usare entrambi i due metodi sopra, senza problemi.


3
Secondo il riferimento Arduino, si può effettivamente utilizzare le A0- A5identificatori direttamente invece di usare i numeri 14-19. Ad esempio digitalWrite(A0, HIGH),.
Peter Bloomfield,

3
@ PeterR.Bloomfield Entrambi sono corretti, tuttavia consiglio A0-A5 per semplicità e facilità di lettura. Non è un grosso problema con un LED che lampeggia, ma quando si hanno progetti di grandi dimensioni si sommano piccole abitudini.
Pinguino anonimo,

2
In realtà, mentre entrambi eseguiranno il lavoro su UNO e schede compatibili, digitalWrite(A0)è più corretto rispetto a digitalWrite(14)quando il primo mapperà sempre il pin fisico (analogico) corretto. Su una scheda diversa, pin 14infatti , potrebbe non esserlo A0, ad esempio pin 14il MEGA è Serial3 TXe non influenzerà il pin analogico che stai cercando . cioè, se si usa digitalWritesu un pin analogico, usare il riferimento A0- A5.
Madivad,

18

Se si desidera pilotare i LED, è possibile utilizzare anche un MAX7219 in grado di pilotare 64 LED, senza circuiti aggiuntivi (non è necessario un transistor per amplificare il segnale).

La guida di un MAX7219 richiede solo 3 pin di uscita su Arduino. Inoltre, puoi trovare alcune librerie di Arduino per questo.

Puoi anche incatenarne alcuni se devi alimentare più di 64 LED.

L'ho usato con successo per più display a LED a 7 segmenti.

Unico inconveniente: è costoso (circa $ 10).


Ho dimenticato il MAX7219, grazie per la pubblicazione!
JVarhol,

384 LED ... whoah! Più due pin per inferenza USB. Mi chiedo che tipo di fastidioso gingillo puoi creare (con un alimentatore sufficiente).
Pinguino anonimo,

17

È possibile utilizzare Charlieplexing . Con questa tecnica puoi guidare direttamente i n*(n-1)LED da n pin. Quindi con 3 pin puoi guidare 6 LED, 4 pin - 12 LED, 5 pin - 20 LED e così via.

Esempio:

Sei LED su 3 pin

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

inserisci qui la descrizione dell'immagine

Puoi vedere un tutorial migliore qui .


Una cosa da notare è che questa tecnica ti consente di controllare più led, ma non necessariamente contemporaneamente.
kontur

1
@kontur sì, hai ragione. Ma in termini di persistenza della visione puoi considerare che lo sono. La domanda non ha tali dettagli.
Daniel Grillo,

Il charlieplexing non è l'UNICO modo per multiplexare i LED senza usare i registri a scorrimento.
Linhartr22,

1
@ linhartr22 Non ho MAI detto che è l'unico modo. Il charlieplexing è solo una soluzione comune per questo problema. E la mia risposta è stata la settima. Quindi altre possibilità avevano già mostrato prima.
Daniel Grillo,

@DanielGrillo Avrei dovuto essere più specifico e spiegare come il multiplexing di colonne e righe, che viene generalmente utilizzato sui cubi LED, può essere eseguito senza il registro a scorrimento e senza i limiti del Charlieplexing. Una matrice di colonne in fila 4x4 può controllare singolarmente 16 led con 8 linee I / O. Un cubo 4x4x4 può controllare singolarmente 64 led con 12 linee I / O (possibile anche su uno Uno utilizzando Analog A0-A5 come linee digitali).
Linhartr22,

13

I 2 C (filo)

È possibile utilizzare il protocollo I 2 C (libreria Wire) per connettersi ad altri dispositivi come gli espansori di porte. Ad esempio, MCP23017.

Ho usato uno di quei chip per collegarmi a una scheda LCD. MCP23017 ha 16 porte, che possono essere configurate come ingressi o uscite. Se lo si desidera, come input possono generare interrupt.

Esempio di collegamento di 13 di questi 16 al display LCD:

MCP23017 collegato allo schermo LCD

Ora ci colleghiamo ad Arduino usando solo 2 fili (SDA / SCL) più alimentazione e terra:

MCP23017 collegato ad Arduino


Alcuni produttori di terze parti hanno realizzato schede con 4 x MCP23017, che offrono 64 ingressi / uscite:

Tavola millepiedi


Multiplexer

È possibile utilizzare multiplexer analogici come il 74HC4051 (8 porte) o il 74HC4067 (16 porte) per collegare un pin a una delle porte 8/16 (ma solo una alla volta), in questo modo:

Multiplexer 74HC4051

Questi sono bidirezionali, quindi possono essere utilizzati come espansori di input o output.


SPI con 74HC595

Utilizzando SPI è possibile inviare dati seriali veloci a un registro a scorrimento, come il 74HC595. Questi possono essere concatenati insieme. In questo esempio sto controllando 32 LED con solo 3 pin I / O (MOSI / MISO / SCK) più alimentazione e terra.

74HC595 pilotando 32 LED


Ho scoperto all'interno di un cartello LED commerciale che i 72 LED erano pilotati da chip 74HC595.

Segno LED a scorrimento

Aveva 9 chip che guidavano le colonne (9 x 8 = 72 LED) e un chip che guidava le file, in una configurazione multiplata.


SPI con MAX7219

Se vuoi solo guidare i LED, di solito puoi multiplexarli. Il MAX7219 lo semplifica progettando per pilotare matrici LED, ad esempio display a 7 segmenti:

MAX7219 con display a 7 segmenti

O matrici a 64 LED:

MAX7219 con matrice a 64 LED

In entrambi i casi questi possono essere collegati in cascata insieme, ad esempio:

Catena a margherita MAX7219

Tutti questi esempi usano solo 3 pin dell'Arduino (MOSI / MISO / SCK) più potenza e terra.


SPI con MCP23S17

L'espansore di porte a 16 porte menzionato in precedenza (MCP23017) è disponibile anche in una variante SPI (MCP23S17), che fa praticamente cose identiche. Usa un altro filo, ma sarebbe più veloce.


Altri protocolli

Le strisce LED (come quelle NeoPixel) hanno i loro protocolli. C'è stato un post su Youtube di Josh Levine in cui l'autore ha guidato oltre 1000 pixel con un Duemilanove!


Riferimenti


12

I registri a turni sono stati citati in altre risposte e sono sicuramente una scelta eccellente per molti progetti. Sono economici, semplici, moderatamente veloci e in genere possono essere concatenati per aggiungere più output. Tuttavia, hanno il rovescio della medaglia che di solito hanno bisogno dell'uso esclusivo di diversi pin (tra 2 e 4, a seconda di come li configuri).

Un'alternativa consiste nell'utilizzare espansori di porte più avanzati, come MCP23017 a 16 bit e MCP23S17 . Questi supportano rispettivamente I2C e SPI, il che significa che è possibile posizionarli su un bus con molti altri dispositivi (potenzialmente di diverso tipo). Ogni dispositivo sul bus può essere indirizzato individualmente, il che significa che sono necessari solo 2 o 3 pin per comunicare con tutti. Le velocità di aggiornamento sono in genere estremamente elevate, quindi è improbabile che si verifichi una latenza significativa (ad esempio ritardi di trasmissione) in un progetto Arduino.

A basso livello, l'utilizzo di I2C o SPI è sostanzialmente più complicato di un semplice registro a scorrimento. Tuttavia, esiste un codice di libreria per Arduino che se ne occupa. Vedi questa domanda, ad esempio: Come posso usare i dispositivi I2C con Arduino?


Wow, non ho mai saputo di quelli, grazie, non li guardo!
JVarhol,

Puoi usare I2C per controllare i LED?
Pro Q

1
@ProQ Non è possibile controllare direttamente i LED standard utilizzando I2C. Tuttavia, è possibile ottenere alcuni prodotti LED che dispongono di un driver I2C integrato. Questo di solito è per prodotti con molti LED, come strisce o matrici.
Peter Bloomfield,

8

Oltre alla risposta di Ricardo , ciò che Wikipedia afferma sui registri a turni :

Uno degli usi più comuni di un registro a scorrimento è la conversione tra interfacce seriali e parallele. [...] I registri SIPO sono comunemente collegati all'uscita dei microprocessori quando sono necessari più pin di ingresso / uscita per scopi generici di quelli disponibili. Ciò consente a più dispositivi binari di essere controllati utilizzando solo due o tre pin, ma più lenti degli I / O paralleli.

Nel articolo Ricardo legato è possibile vedere lo schema del registro a scorrimento.

Diagramma del registro a scorrimento

Quello che succede qui è che metti i dati degli 8 pin in una sequenza e per ogni tick di clock il registro a scorrimento si sposterà (sposta i dati binari da ciascun latch a quello successivo) fino a quando "crea un cerchio", ovvero il primo bit arriva all'ultimo perno. I registri a scorrimento hanno anche un input in cui è possibile attivare / disattivare lo spostamento in modo che lo stato possa essere mantenuto dopo che i dati sono stati spostati nella posizione. Per una semplice dimostrazione vedere la seguente animazione.

Spostare l'animazione del registro

Qui la luce rossa è l'ingresso seriale e quelle verdi mostrano lo stato dei fermi in questo registro a scorrimento SIPO semplificato . Dopo che i dati sono stati spostati in posizione, è possibile disattivare lo spostamento e leggere i pin. In questo esempio mi sono spostato 10101011.

Da questi esempi puoi capire che il trasferimento seriale sarà più lento del parallelo, perché devi aspettare che il registro a scorrimento sposta i bit al loro posto. Dovrai attendere la stessa quantità di tick di clock di quanti bit vuoi caricare. Questo è uno dei tanti motivi per cui non puoi incatenarli indefinitamente, perché il caricamento richiederebbe per sempre.


1
+1 per le informazioni aggiuntive E per la bella GIF animata e il suo effetto didattico! Dove hai trovato la GIF? O ce l'hai fatta?
Ricardo,

1
@Ricardo Ho creato il circuito con Digital Works, quindi stampa schermo, modifica, animatore gif.
Totymedli,

6

Come hai già scritto, puoi usare tutti i pin, inclusi TX e RX come output digitale. L'ho fatto qualche tempo fa per un dimostratore e ho registrato un video - 20 LED su 20 pin - di questo progetto piuttosto insensato.

Come descritto da Peter R. Bloomfield qui , devi disconnettere TX e RX per il caricamento. Inoltre, hai esaurito i pin per leggere i sensori per una possibile interattività e devi assicurarti che il limite di corrente totale non sia raggiunto. Non dimenticare che sei limitato a led 5V se li guidi direttamente con il tuo Arduino.

L'uso dei registri a scorrimento in generale e del 595, descritto da Ricardo, è quindi altamente raccomandato.

  • Sono economici!
  • È piuttosto facile metterli in cascata.
  • È possibile ottenere molta velocità quando si utilizza SPI hardware.

Li ho usati poco fa quando ho realizzato la parte di saldatura e programmazione di Kawaii me (il testo del link è in tedesco) dell'artista di upcycling Dominik Jais .

Qui, solo un gruppo di 595 sono stati usati per guidare un display di 8x11 led. Poiché i led erano tagliati da una striscia di led SMD 12V , erano necessari un alimentatore aggiuntivo e alcuni array Darlington UDN2803A , agganciati ai pin di uscita dei registri a scorrimento.

Altri metodi generali includono l'uso degli espansori di porte a 8 bit PCF8574 (A), che sono controllati tramite il bus I2C.

Ad ogni modo, proverei prima i 595 registri a turni.

Se devi controllare un paio di led RGB, tuttavia, potresti voler cercare soluzioni più specializzate. Alcuni LED RGB vengono forniti con il proprio WS2812 . Questi pezzi sottili possono essere collegati in cascata (bus a 1 filo) e indirizzati attraverso la loro posizione nella catena.


3

Se si tratta solo di LED, che dire delle strisce LED WS2812B o dei chip stessi del driver? Puoi controllare un numero praticamente illimitato di LED usando un solo pin!

Sebbene le persone siano abituate a queste in strisce, sono disponibili come LED autonomi (noti come neo pixel su Adafruit). O se stai guidando solo un singolo colore, ogni chip WS2811 potrebbe controllare 3 LED utilizzando ciascuna delle uscite RGB per un singolo LED ciascuna.

Di recente ho appena creato un progetto che utilizza 5 LED di questo tipo: Door1 aperto / chiuso, Door2 aperto / chiuso, motor1 attivo, motor2 attivo e potenza. I LED "attivi" hanno un duplice scopo poiché ho il rosso come input dal motore attivo e il verde è la bandiera attiva all'interno dell'Arduino.

Il punto è che, con 1 pin e la libreria installata, è possibile controllare qualsiasi numero di LED


2

Non rivendico questo metodo per me, ma ho trovato questo trucco sulla pagina MUX-DEMUX: CD4051 Parlor Tricks

Qualunque sia il metodo che scegli di utilizzare per pilotare le uscite o leggere gli ingressi (registri a scorrimento, multiplexor o l'uso diretto diretto dei pin Arduino stessi) puoi raddoppiare il numero di uscite o ingressi mediante un uso intelligente di coppie di circuiti paralleli (per formare un doppio input o output bank ), impiegando diodi in sensi opposti su ciascun ramo parallelo e commutando gli ingressi / uscite su alto e basso.

Per illustrare il metodo per le uscite (i LED in questo caso, notare che i diodi extra non sono richiesti):

Banca LED

Se si considera la coppia di LED in questo esempio un "banco" e si desidera accendere LED_0, è necessario impostare il PIN 17 su ALTO e il PIN 18 su BASSO. (I numeri dei pin sono confusi, ma corrispondono all'esempio successivo così nudo con me). Per accendere LED_1, basta invertire i PIN. La natura del diodo dei LED impedisce alla corrente di fluire nella direzione opposta mantenendo l'altro spento.

Per illustrare il metodo per gli input (CdS in questo caso, notare che sono richiesti i diodi extra):

Banca CdS

Questo diventa un po 'più complicato se vuoi fare una lettura analogica su un sensore di luce CdS. Innanzitutto, è necessario aggiungere un diodo a ciascun sensore per controllare il flusso. In secondo luogo, poiché stai leggendo i valori, devi tirare gli input in alto o in basso per evitare che fluttuino. Essendo una persona pigra, ho intenzione di tirarli su usando le resistenze pull-up interne. Per leggere CdS_0, impostare la modalità PIN 17 su OUTPUT e impostarla su LOW. Questo lo rende il terreno. Quindi si imposta la modalità PIN 18 su INPUT e si imposta su HIGH per attivare la resistenza di pull-up. Ora sei pronto per leggere il PIN 18 (noto anche come pin analogico 4). Per accedere all'altro sensore, basta cambiare modalità e uscite.

Quindi, se si dispone di un multiplexor a 8 porte CD4051, utilizzando 5 pin su Arduino (anziché i soliti 3), è possibile ottenere 16 ingressi o uscite o un mix dei due.

16 uscite / ingressi usando un CD4051

Allo stesso modo, se si dispone di un multiplexor 4067 a 16 porte, è possibile ottenere 32 ingressi o uscite o un mix dei due.

Uno schizzo di esempio sarebbe:

/*
 * 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); 
    }
  } 
}

Come ho detto nella prima riga, la spiegazione completa può essere trovata su MUX-DEMUX: CD4051 Parlor Tricks


1

Per un progetto di classe ho usato un CD4024 e due pin Arduino per guidare un display a 7 segmenti.

Ci sono alcuni avvertimenti su questo approccio. Ad esempio, per scrivere un highvalore sulla prima uscita di un contatore di ripple è necessario solo a resete attivare due volte il pin del clock. Ma se si desidera scrivere higha tutti i pin n richiede portando l'orologio pin 2 n volte, e durante quel tempo tutti gli altri pin sono costantemente commutazione on e off.

Se la tua applicazione è in grado di gestire queste limitazioni e sei a corto di pin, è un'altra opzione.

Risposta bonus: ci sono molti esempi di input multiplexing qui , molti dei quali si applicano anche agli output multiplexing.


L'uso di un contatore a 7 stadi per guidare un display a 7 segmenti sembra un approccio non ottimale, per i motivi che hai indicato tu stesso.
jfpoilpret,

1

Con un po 'di lavoro (installazione di un bootloader diverso) sono disponibili altre sette linee I / O su Uno, sulle intestazioni ICSP1 e JP2. Il bootloader sostitutivo si chiama HoodLoader2 . Ti consente di installare schizzi sia su Atmega328 che su Atmega16U2 su Uno. Trattare con più processori sarebbe la principale complicazione dall'uso di questo metodo.

Su uno Uno, le intestazioni ICSP1 e JP2 si collegano ai pin PB1 ... PB7 dell'Atmega16U2. Inoltre, l'Atmega16U2 ha circa 9 pin I / O senza connessione al circuito. Una persona che lavora al microscopio potrebbe essere in grado di collegare i cavi a un totale di 18 pin I / O sulla 16U2, lasciando altri tre pin I / O collegati alle loro connessioni ordinarie.

HoodLoader2 funziona anche su schede Mega.


0

Ci sono moltissime buone risposte qui, ma se ti costasse del tempo, sarebbe più economico acquistare un Mega.

Il mio valore 3/2-d.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.