Wenn man viele LEDs ansteuern möchte, dann steht man bald einmal vor dem Problem, dass auf einem normalen Arduino eigentlich zu wenige Ausgangspins zur Verfügung stehen.
Der Zustand lässt sich mit einem Schieberegister leicht beheben. Mit dem weit verbreiteten IC vom Typ 74HC595 (hier bei Amazon) beispielsweise erhält man mit lediglich 3 Arduino-Pins 8 weitere Ausgangspins am Shift Register. Wenn diese nicht ausreichen, kann man mehrere Schieberegister aneinanderkoppeln und damit auch 16, 24 oder noch mehr einfach ansteuerbare Ausgänge erhalten.
Genau genommen besteht ein Schieberegister aus zwei Registern. Einmal das Schieberegister, in das der Zustand der einzelnen Ausgangspins seriell, also Bit für Bit, geschoben wird. Und dann das Ausgangsregister, in welches der Zustand des Schieberegisters auf ein Signal vom Arduino hin kopiert wird. Erst dann wird der Zustand der ins Schieberegister geschickten Daten an den Ausgangspins sichtbar.
- 5 Stk./pcs. x 74HC595 mit/with DIP16 Sockel/Socket
- 8-BIT SHIFT REGISTER
- Original Texas Instruments
Die Funktionsweise eines Schieberegisters entspricht einer Eimerkette. Wenn ein am Dateneingang anliegendes Bit in das Schieberegister übernommen wird, rücken alle bereits dort gespeicherten Bits eine Position weiter und machen damit am Eingang eine Speicherstelle frei, welche das neue Bit aufnimmt. Das Signal zur Speicherung einen neuen Bits erhält der IC dabei über einen Flankenwechsel von LOW auf HIGH an einem seiner Pins (SHCP – SHift Clock Pin, die Bezeichnungen variieren aber je nach Hersteller).
Im folgenden Video versuche ich, die Funktionsweise, einen Testaufbau und zwei Beispiel-Sketches zu erklären. Als Basis dafür dient das Projekt „Lauflicht mit dem Arduino“ aus einem der früheren Videos.
Der im Video gezeigte Arduino Sketch 1 liest die Zustände der 8 Speicherstellen im Schieberegister aus einem Array und schreibt diese in das Schieberegister. Um die nötigen Flankenwechsel des Shift Pins und des Store Pins kümmern wir uns dabei selbst.
// Arduino-Pin verbunden mit SH_CP des 74HC595 int shiftPin = 8; // Arduino-Pin verbunden mit ST_CP des 74HC595 int storePin = 9; // Arduino-Pin verbunden mit DS des 74HC595 int dataPin = 10; // Dieses Muster soll ausgegeben werden int muster[8] = {1,1,1,0,0,1,0,1}; void setup() { // Pins 8,9,10 auf Ausgabe pinMode(storePin, OUTPUT); pinMode(shiftPin, OUTPUT); pinMode(dataPin, OUTPUT); // storePin sicherheitshalber auf LOW digitalWrite(storePin, LOW); for (int i=0; i<8; i++) { // Zuerst immer alle 3 Pins auf LOW // Aktion passiert bei Wechsel von LOW auf HIGH digitalWrite(shiftPin, LOW); // Jetzt den Wert der aktuellen Stelle ans Datenpin DS anlegen digitalWrite(dataPin, muster[i]); // Dann ShiftPin SHCP von LOW auf HIGH, damit wird der Wert // am Datenpin ins Register geschoben. digitalWrite(shiftPin, HIGH); } // Wenn alle 8 Stellen im Register sind, jetzt das StorePin STCP // von LOW auf HIGH, damit wird Registerinhalt an Ausgabepins // kopiert und der Zustand an den LEDs sichtbar digitalWrite(storePin, HIGH); } void loop () { // Hier passiert nichts. } |
Im Arduino Sketch 2 wird ein Zähler von 0 bis 255 gezählt und der jeweilige Wert in binärer Darstellung auf den 8 LEDs, die am Shift Register hängen, ausgegeben. Zur Übertragung des 8-bit-Wertes in das Schieberegister verwende ich hier den shiftOut()-Befehl des Arduino. Dieser erledigt die Übertragung der einzelnen Bits ins Schieberegister inklusive der notwendigen Flankenwechsel am Shift Pin.
Die Übertragung des Schieberegister-Inhalts ans Ausgangsregister mit einem Wechsel des STCP (Store Clock Pin) von LOW zu HIGH müssen wir dann noch selbst erledigen.
//Pin verbunden mit SH_CP des 74HC595 int shiftPin = 8; //Pin verbunden mit ST_CP des 74HC595 int storePin = 9; //Pin verbunden mit DS des 74HC595 int dataPin = 10; int counter = 0; // Binärer Counter von 0 bis 255. // 1 = 000000001 // 2 = 000000010 // 3 = 000000011 // 4 = 000000100 // 5 = 000000101 // usw. Die LEDs zeigen alle Werte von 0 bis 255. void setup() { // Pins 8,9,10 auf Ausgabe stellen pinMode(storePin, OUTPUT); pinMode(shiftPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop () { digitalWrite(storePin, LOW); shiftOut(dataPin, shiftPin, MSBFIRST, counter); digitalWrite(storePin, HIGH); delay(500); counter ++; if (counter > 255) { counter = 0; } } |
- Serieller 8-Bit-Eingang.
- Serieller oder paralleler 8-Bit-Ausgang.
- Speicherregister mit 3-State-Ausgängen.
- Schieberegister mit direktem Löschen.
- HINWEIS: Wenn Sie das Gerät über einen längeren Zeitraum absoluten maximalen Nennbedingungen aussetzen, kann dies die Zuverlässigkeit des Geräts beeinträchtigen..
Fragen, Kommentare, Hinweise und Fehler und sonstige Kritik bitte in die Kommentare.
Vielen Dank fürs Lesen!
viel spass macht das programmieren einer led-matrix mit dem schieberegister MAX7219… da gibts bei den üblichen versendern recht günstige module die sich auch koppeln lassen. die library LedControl macht dann das leben leicht. also grad für anfänger/kinder sehr dankbar, weil mit wenig aufwand schöne ergebnisse zu erreichen sind.
Einen Blog-Artikel dazu samt Video gibt es hier: Arduino LED Matrix Display – 8×8 Pixel Zeichenprogramm
Pingback: Planung für 2015 – eure Meinung ist gefragt! | Makerblog.at
hallo adi
ich hab ein kleines Problem mit meinem Arduino wenn ich das shift register dran hab. der resetet sich nach ungefär 20- 30 Sekunden
kannst du mir da weiter helfen ?
Danke schon mal im voraus
Moritz
Hallo Moritz,
erfolgt der Reset generell (unabhängig von einem laufenden Sketch) oder nur bei diesem bestimmten Sketch?
lg, Adi
Ich habe mal eine Frage wie kann ich den bei dem 2 Sketch ein Muster erzeugen ?
Ich verstehe das irgendwie nicht? Oder liegt es daran das ich 2 Shift register habe ?
Hi Adi,
ich bräuchte deine Hilfe. Ich verwende zwei Schieberegister ICs und möchte mit dem shiftOut Befehl 16 LEDs nach einander einschalten. Dazu verwendet ich 16 Bit muster:
muster [0]= 0b0000 0000 0000 0001
muster [1]= 0b0000 0000 0000 0011
………
Bis muster [15] .
Diese möchte ich mit dem shiftOut Befehl wie in deinem Beispiel verarbeiten.
for (int i=0; i<16; i++) {
shiftOut (dataPin, shiftPin, MSBFIRST, muster [i]);
Wie kann ich mit dem shiftOut Befehl 16 Bits durch die zwei ICs schieben ?
Würde mich über deine Hilfe freuen.
Lieben Gruß
Dima Michel
Ok so schwer war das nicht:
…..muster [i] >> 8
…..muster [i] & 255
Fragen, auf die man selbst die Antwort findet, sind ja eh die besten :)
okay ist jetzt zwar mehr als ein Jahr her das du das geschrieben hast, aber ich versuch es mal auf gut glück. kannst du ein wenig weiter erläutern wie du das mit den 16 bit gemacht hast?
ich möchte 10bit zahlen mit Leds darstellen. und stehe da gerade ein wenig auf dem schlauch wie ich das am leichtesten schaffe. bzw ob es da per Shift out befehl gehen könnte, zb die ersten acht auf ein register und die letzten beiden auf ein zweites oder so
Hallo,
Ist es möglich an einem Schiedsrichter 4 als Eingänge und 4 als Ausgänge zu nutzen?
Der Plan ist, 4 Taster mit LED zu beschalten mittels und einem Interrupt anschließend zu fragen welche Taste gedrückt wurde.
Sehr gut erklärt, danke jetzt kann ich mein Projekt ohne LED-Matrix-Gefummel (Bei 20LED = 9Pin des Arduino verloren) umsetzten und habe noch genügend Arduino Aus/Eingänge zur Verfügung. Auch ist das Problem mit dem Multiplexen der LEDs (Hohe Einschaltferequenz – Strombelastung des Arduino zu hoch?) weg.
Nur zwei kleine Frage zum Stromverbrauch/belastung hätte ich noch: wieviel mA pro LED verträgt den das Schieberegister 74LS298 und wielviel verbraucht das Register (möchte ein Uhr bauen, die im Batteriebetrieb möglichst lange läuft)?
MfG
Alfred
There’s one point missing: Set the „MR (SRCLR)“ to HIGH (+5V), and the „OE (LATCH)“ pins to LOW (GND).
Pingback: Arduino Lektion #100: Schieberegister 74HC595N N2B5 - Technik Blog
Pingback: Wort-Uhr mit Arduino und Schieberegistern – georf.de
Pingback: Tic-Tac-Toe mit dem Arduino selber bauen - reichelt.de Magazin
Pingback: Tic-Tac-Toe mit dem Arduino selber bauen - reichelt Magazin
Pingback: Treppen-Lauflicht mit Bewegungserkennung (Arduino) » PFuisi