Ist es möglich, mehr als 14 Ausgangspins auf dem Arduino zu haben, arbeite ich an einem Projekt, in dem ich mehrere LEDs einzeln aufleuchten muss. Ich habe nur einen Arduino Uno und ich möchte keinen Mega bekommen.
Ist es möglich, mehr als 14 Ausgangspins auf dem Arduino zu haben, arbeite ich an einem Projekt, in dem ich mehrere LEDs einzeln aufleuchten muss. Ich habe nur einen Arduino Uno und ich möchte keinen Mega bekommen.
Antworten:
Eine übliche Möglichkeit, den Satz verfügbarer Ausgangspins auf dem Arduino zu erweitern, besteht in der Verwendung von Schieberegistern wie dem 74HC595 IC ( Link zum Datenblatt ).
Sie benötigen 3 Pins, um diese Chips zu steuern:
In einem Programm übergeben Sie an den Daten ein Bit zu einem Zeitpunkt , zu dem Schieberegister mit dem shiftOut () Befehl , etwa so:
shiftOut(dataPin, clockPin, data);
Mit diesem Befehl setzen Sie jeden der 8 Ausgänge des 595 IC mit den 8 Bits in der data
Variablen.
Mit einem 595 erhalten Sie 5 Pins (8 auf dem IC, aber Sie geben 3 aus, um mit ihm zu sprechen). Um mehr Ausgänge zu erhalten, können Sie eine Reihe von 595 in Reihe schalten, indem Sie den Serial-Out-Pin mit dem Daten-Pin des nächsten verbinden. Sie müssen auch die Clock- und Latch-Pins aller 595-ICs miteinander verbinden.
Die resultierende Schaltung (unter Verwendung einer 595) würde folgendermaßen aussehen:
Die obige Abbildung stammt von dieser codeproject.com- Webseite:
Der Latch-Pin wird verwendet, um die 595-Ausgänge ruhig zu halten, während Sie Daten hineinschieben.
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, data);
digitalWrite(latchPin, HIGH);
Es gibt zwei Möglichkeiten, wie Sie mehr Pins aus einem Arduino herausholen können.
Der erste Weg besteht darin, die analogen Pins als digitale Ausgangspins zu verwenden, was sehr einfach ist. Sie müssen sich lediglich auf A0-A5 als Stifte 14,15,16,17,18,19 beziehen. Verwenden Sie zum Beispiel digitalWrite (14, HIGH), um hoch auf Pin A0 zu schreiben.
Die andere Möglichkeit, mehr Pins aus dem Arduino herauszuholen, ist die Verwendung eines Schieberegisters. Zu diesem Zweck empfehle ich die Verwendung des EZ-Expander Shield , mit dem Sie beim Importieren der EZ-Expander Library digitalWrite ([20-35], HIGH) verwenden können. Diese Abschirmung erlaubt jedoch nur die Verwendung der Pins als Ausgänge und verwendet die Pins 8, 12 und 13 zur Steuerung der Schieberegister.
Das Tolle ist, dass Sie beide oben genannten Methoden problemlos zusammen anwenden können.
A0
- A5
-Kennungen direkt verwenden, anstatt die Nummern 14-19 zu verwenden. Zum Beispiel digitalWrite(A0, HIGH)
.
digitalWrite(A0)
ist dies korrekter, als digitalWrite(14)
da erstere immer dem richtigen physischen (analogen) Pin zugeordnet werden. Auf einem anderen Board pin 14
kann das nämlich nicht sein A0
, zB pin 14
auf dem MEGA ist Serial3 TX
und wird den analogen Pin, den du suchst, nicht beeinflussen. Wenn Sie also digitalWrite
einen analogen Pin verwenden, verwenden Sie die A0
- A5
-Referenz.
Wenn Sie LEDs ansteuern möchten, können Sie auch einen MAX7219 verwenden, der 64 LEDs ansteuern kann, ohne dass zusätzliche Schaltkreise erforderlich sind (kein Transistor zur Signalverstärkung erforderlich).
Für den Betrieb eines MAX7219 sind nur 3 Ausgangspins von Arduino erforderlich. Außerdem finden Sie einige Arduino-Bibliotheken dafür.
Sie können auch mehrere von ihnen verketten, wenn Sie mehr als 64 LEDs mit Strom versorgen müssen.
Ich habe es erfolgreich für mehrere 7-Segment-LED-Anzeigen verwendet.
Nachteil: Es ist teuer (ca. 10 Dollar).
Sie können Charlieplexing verwenden . Mit dieser Technik können Sie LEDs direkt n*(n-1)
über n Pins ansteuern. Mit 3 Pins können Sie also 6 LEDs, 4 Pins - 12 LEDs, 5 Pins - 20 LEDs usw. ansteuern.
Beispiel:
Sechs LEDs an 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
Sie können ein besseres Tutorial hier sehen .
Sie können das I 2 C-Protokoll (Wire Library) verwenden, um eine Verbindung zu anderen Geräten wie z. B. Port-Expandern herzustellen. Zum Beispiel das MCP23017.
Ich habe einen dieser Chips verwendet, um eine Verbindung zu einer LCD-Platine herzustellen. Der MCP23017 verfügt über 16 Ports, die als Ein- oder Ausgänge konfiguriert werden können. Als Eingänge können sie bei Bedarf Interrupts auslösen.
Beispiel für den Anschluss von 13 dieser 16 an das LCD:
Jetzt verbinden wir uns mit dem Arduino mit nur 2 Drähten (SDA / SCL) plus Strom und Masse:
Einige Dritthersteller haben Karten mit 4 x MCP23017 hergestellt. Dies ergibt 64 Ein- / Ausgänge:
Sie können analoge Multiplexer wie den 74HC4051 (8 Ports) oder den 74HC4067 (16 Ports) verwenden, um einen Pin mit einem der 8/16 Ports zu verbinden (jedoch jeweils nur einen).
Diese sind bidirektional und können daher als Eingangs- oder Ausgangserweiterung verwendet werden.
Mit SPI können Sie schnelle serielle Daten an ein Schieberegister wie den 74HC595 senden. Diese können verkettet werden. In diesem Beispiel steuere ich 32 LEDs mit nur 3 E / A-Pins (MOSI / MISO / SCK) plus Strom und Masse.
Ich fand in einem kommerziellen LED-Zeichen, dass die 72 LEDs von 74HC595-Chips angetrieben wurden.
Dies hatte 9 Chips, die die Spalten ansteuerten (9 × 8 = 72 LEDs), und einen Chip, der die Zeilen ansteuerte, in einer Multiplex-Konfiguration.
Wenn Sie nur LEDs ansteuern möchten, können Sie diese normalerweise multiplexen. Der MAX7219 vereinfacht dies, indem er für die Ansteuerung von LED-Matrizen ausgelegt ist, beispielsweise für 7-Segment-Anzeigen:
Oder 64-LED-Matrizen:
In beiden Fällen können diese verkettet werden, zum Beispiel:
In all diesen Beispielen werden nur 3 Pins des Arduino (MOSI / MISO / SCK) plus Strom und Masse verwendet.
Der bereits erwähnte 16-Port-Port-Expander (MCP23017) ist auch in einer SPI-Variante (MCP23S17) erhältlich, die nahezu identische Funktionen bietet. Es wird ein Draht mehr verwendet, dies wäre jedoch schneller.
LED-Streifen (wie die NeoPixel-Streifen) haben ihre eigenen Protokolle. Auf Youtube gab es einen Beitrag von Josh Levine, in dem der Autor mit einer Duemilanove über 1000 Pixel gefahren ist!
Schichtregister wurden in anderen Antworten erwähnt und sind definitiv eine ausgezeichnete Wahl für viele Projekte. Sie sind billig, einfach und mäßig schnell und können in der Regel miteinander verkettet werden, um mehr Ausgaben zu erzielen. Sie haben jedoch den Nachteil, dass sie in der Regel ausschließlich mehrere Stifte verwenden müssen (zwischen 2 und 4, je nachdem, wie Sie sie einrichten).
Eine Alternative besteht darin, erweiterte Porterweiterungen zu verwenden, z. B. die 16-Bit-Versionen MCP23017 und MCP23S17 . Diese unterstützen I2C und SPI, was bedeutet, dass Sie sie mit mehreren anderen Geräten (möglicherweise unterschiedlichen Typs) auf einem Bus platzieren können. Jedes Gerät am Bus kann einzeln adressiert werden, dh Sie benötigen nur 2 oder 3 Pins, um mit allen zu sprechen. Die Aktualisierungsgeschwindigkeiten sind in der Regel extrem schnell, sodass in einem Arduino-Projekt mit erheblichen Latenzen (dh Übertragungsverzögerungen) zu rechnen ist.
Auf niedrigem Niveau ist die Verwendung von I2C oder SPI wesentlich komplizierter als ein einfaches Schieberegister. Es gibt jedoch Bibliothekscode für Arduino, der das für Sie erledigt. Siehe diese Frage zum Beispiel: Wie verwende ich I2C-Geräte mit Arduino?
Zusätzlich zu Ricardos Antwort, was Wikipedia in den Schichtregistern angibt :
Eine der häufigsten Anwendungen eines Schieberegisters ist die Konvertierung zwischen seriellen und parallelen Schnittstellen. [...] SIPO-Register werden üblicherweise an den Ausgang von Mikroprozessoren angeschlossen, wenn mehr Universal-Eingangs- / Ausgangspins erforderlich sind, als verfügbar sind. Dies ermöglicht die Steuerung mehrerer Binärgeräte mit nur zwei oder drei Pins, jedoch langsamer als die parallele E / A.
Im verlinkten Artikel von Ricardo sehen Sie das Diagramm des Schieberegisters.
Was hier passiert, ist, dass Sie die Daten der 8 Pins in eine Sequenz setzen und für jedes Takt-Häkchen das Schieberegister verschieben (die Binärdaten von jedem Latch zum nächsten verschieben), bis es "einen Kreis bildet", dh das erste Bit kommt zum letzten Stift an. Schieberegister haben auch einen Eingang, an dem Sie die Verschiebung ein- und ausschalten können, damit der Status beibehalten werden kann, nachdem die Daten an die Position verschoben wurden. Eine einfache Demonstration finden Sie in der folgenden Animation.
Hier ist das rote Licht der serielle Eingang und die grünen zeigen den Zustand der Latches in diesem vereinfachten SIPO-Schieberegister an . Nachdem die Daten zum Ort verschoben wurden, kann die Verschiebung abgeschaltet werden und Sie können die Stifte lesen. In diesem Beispiel bin ich rausgerückt 10101011
.
Anhand dieser Beispiele können Sie erkennen, dass die serielle Übertragung langsamer als die parallele ist, da Sie auf das Schieberegister warten müssen, um die Bits an ihre Stelle zu verschieben. Sie müssen so lange warten, bis die Anzahl der Bits erreicht ist, die Sie laden möchten. Dies ist einer der vielen Gründe, warum Sie sie nicht auf unbestimmte Zeit verketten können, da das Laden ewig dauern würde.
Wie Sie bereits geschrieben haben, können Sie alle Pins, einschließlich TX und RX, als Digitalausgang verwenden. Ich habe das vor einiger Zeit für einen Demonstrator gemacht und ein Video - 20 LEDs auf 20 Pins - von diesem ziemlich unsinnigen Projekt aufgenommen.
Wie von Peter R. Bloomfield hier beschrieben , müssen Sie TX und RX für den Upload trennen. Außerdem haben Sie keine Möglichkeit, Sensoren auf mögliche Interaktivität abzulesen, und müssen sicherstellen, dass die Gesamtstrombegrenzung nicht erreicht wird. Nicht zu vergessen, dass Sie auf 5V-LEDs beschränkt sind, wenn Sie sie direkt mit Ihrem Arduino ansteuern.
Die Verwendung von Schieberegistern im Allgemeinen und des von Ricardo beschriebenen 595 wird daher dringend empfohlen.
Ich habe sie vor einiger Zeit benutzt, als ich den Löt- und Programmierteil von Kawaii me des Upcycling-Künstlers Dominik Jais realisiert habe .
Hier wurden nur 595 verwendet, um ein Display mit 8x11 LEDs zu steuern. Da die LEDs aus einem Streifen von 12-V-SMD-LEDs herausgeschnitten wurden, waren ein zusätzliches Netzteil und einige Darlington-Arrays UDN2803A erforderlich , die an die Ausgangspins der Schieberegister angeschlossen waren.
Andere allgemeine Verfahren würden die Verwendung von PCF8574 (A) -Erweiterungen für 8-Bit-Ports umfassen, die über den I2C-Bus gesteuert werden.
Wie auch immer, ich würde es zuerst mit den 595 Schieberegistern versuchen.
Wenn Sie jedoch mehrere RGB-LEDs steuern müssen, sollten Sie nach spezielleren Lösungen suchen. Einige RGB-LEDs werden mit einer eigenen WS2812 geliefert . Diese feinen Teile sind kaskadierbar (1-Draht-Bus) und werden über ihre Position in der Kette angesprochen.
Wenn es um LEDs geht, was ist mit den WS2812B-LED-Streifen oder nur den Treiberchips selbst? Mit nur einem Pin können Sie praktisch beliebig viele LEDs ansteuern!
Obwohl die Leute an diese Streifen gewöhnt sind, sind sie als eigenständige LEDs (bekannt als Neopixel bei Adafruit) erhältlich. Wenn Sie nur eine Farbe ansteuern, kann jeder WS2811-Chip 3 LEDs steuern, indem jeder der RGB-Ausgänge für jeweils eine LED verwendet wird.
Ich habe vor kurzem ein Projekt erstellt, das 5 solcher LEDs verwendet: Tür1 offen / geschlossen, Tür2 offen / geschlossen, Motor1 aktiv, Motor2 aktiv und Strom. Die "aktiven" LEDs haben einen doppelten Zweck, da ich rot als Eingangssignal für den aktiven Motor und grün als aktive Flagge im Arduino habe.
Mit 1 Pin und der installierten Bibliothek können Sie eine beliebige Anzahl von LEDs steuern
Ich beanspruche diese Methode nicht für mich selbst, aber ich habe diesen tollen Trick auf der Webseite MUX-DEMUX: CD4051 Parlour Tricks gefunden
Unabhängig von der Methode, mit der Sie Ausgänge ansteuern oder Eingänge lesen (Schieberegister, Multiplexer oder die direkte Verwendung der Arduino-Pins selbst), können Sie die Anzahl der Ausgänge oder Eingänge durch geschickte Verwendung von Parallelschaltungspaaren verdoppeln (um ein Dual zu bilden) Ein- oder Ausgabebank ), unter Verwendung von Dioden in Richtungen auf jeder Parallelzweig gegenüberliegen, und die Eingänge / Ausgänge für hohe und niedrige Schalt.
Zur Veranschaulichung der Methode für die Ausgänge (LEDs in diesem Fall, beachten Sie, dass keine zusätzlichen Dioden erforderlich sind):
Wenn Sie das LED-Paar in diesem Beispiel als "Bank" betrachten und LED_0 aufleuchten möchten, müssen Sie PIN 17 auf HIGH und PIN 18 auf LOW setzen. (Die PIN-Nummern sind verwirrend, aber sie stimmen mit dem späteren Beispiel überein. Zum Aufleuchten von LED_1 vertauschen Sie einfach die PINS. Die Diodennatur der LEDs verhindert, dass der Strom in die entgegengesetzte Richtung fließt und die andere ausgeschaltet bleibt.
Zur Veranschaulichung der Methode für Eingänge (in diesem Fall CdSs, beachten Sie, dass zusätzliche Dioden erforderlich sind):
Dies wird etwas komplizierter, wenn Sie einen CdS-Lichtsensor analog auslesen möchten. Zunächst müssen Sie jedem Sensor eine Diode hinzufügen, um den Durchfluss zu steuern. Zweitens müssen Sie, da Sie Werte lesen, die Eingänge hoch oder niedrig ziehen, damit sie nicht schweben. Als faule Person ziehe ich sie mithilfe der internen Pull-up-Widerstände hoch. Zum Lesen von CdS_0 setzen Sie den PIN 17-Modus auf OUTPUT und setzen ihn auf LOW. Das macht es zum Boden. Dann setzen Sie den PIN 18-Modus auf INPUT und setzen ihn auf HIGH, um den Pull-Up-Widerstand zu aktivieren. Jetzt können Sie PIN 18 (auch als Analog-Pin 4 bezeichnet) lesen. Um auf den anderen Sensor zuzugreifen, wechseln Sie einfach die Modi und Ausgänge.
Wenn Sie also einen CD4051-Multiplexer mit 8 Ports verwenden und 5 Pins auf dem Arduino verwenden (anstelle der üblichen 3), können Sie 16 Ein- oder Ausgänge oder eine Mischung aus beiden erhalten.
Wenn Sie einen 4067-Multiplexer mit 16 Anschlüssen haben, können Sie 32 Ein- oder Ausgänge oder eine Mischung aus beiden erhalten.
Eine Beispielskizze wäre:
/*
* 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);
}
}
}
Wie ich in der ersten Zeile sagte, finden Sie die vollständige Erklärung auf MUX-DEMUX: CD4051 Parlor Tricks
Für ein Klassenprojekt verwendete ich einen CD4024 und zwei Arduino-Pins, um eine 7-Segment-Anzeige anzusteuern.
Dieser Ansatz weist einige Einschränkungen auf. Zum Schreiben eines high
Werts auf den ersten Ausgang eines Ripple-Zählers ist beispielsweise nur ein reset
und zweimaliges Umschalten des Clock-Pins erforderlich . Aber wenn Sie schreiben wollen high
auf alle n Pins erfordert Umschalten der Takt Pin 2 n - mal, und während dieser Zeit alle anderen Pins sind ständig Makeln ein- und ausgeschaltet.
Wenn Ihre Anwendung mit diesen Einschränkungen zurechtkommt und es Ihnen an Pins mangelt, ist dies eine weitere Option.
Bonus Antwort: Es gibt viele Beispiele von Multiplexeingänge hier , von denen viele auch Ausgänge Multiplexen gelten.
Mit ein wenig Arbeit (Installation eines anderen Bootloaders) stehen auf einem Uno zusätzliche sieben E / A-Leitungen für die ICSP1- und JP2-Header zur Verfügung. Der Ersatz-Bootloader heißt HoodLoader2 . Damit können Sie Skizzen sowohl auf dem Atmega328 als auch auf dem Atmega16U2 auf einem Uno installieren. Der Umgang mit mehreren Prozessoren wäre die größte Schwierigkeit bei der Verwendung dieser Methode.
Bei einem Uno werden die ICSP1- und JP2-Header mit den Pins PB1 ... PB7 des Atmega16U2 verbunden. Darüber hinaus verfügt der Atmega16U2 über 9 E / A-Pins ohne Verbindung zur Leiterplatte. Eine Person, die unter einem Mikroskop arbeitet, kann möglicherweise Drähte an insgesamt 18 E / A-Pins des 16U2 anschließen, während drei weitere E / A-Pins an ihren normalen Anschlüssen verbleiben.
HoodLoader2 funktioniert auch auf Mega-Boards.