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.

Schieberegister 74HC595 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.

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;
 }
}

Fragen, Kommentare, Hinweise und Fehler und sonstige Kritik bitte in die Kommentare.

Vielen Dank fürs Lesen!

13 thoughts on “Das Schieberegister 74HC595 am Arduino

  • 19. Januar 2015 um 12:31
    Permalink

    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.

    Antworten
  • Pingback: Planung für 2015 – eure Meinung ist gefragt! | Makerblog.at

  • 26. April 2016 um 18:37
    Permalink

    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

    Antworten
    • 27. April 2016 um 10:06
      Permalink

      Hallo Moritz,
      erfolgt der Reset generell (unabhängig von einem laufenden Sketch) oder nur bei diesem bestimmten Sketch?
      lg, Adi

      Antworten
  • 3. Oktober 2016 um 10:55
    Permalink

    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 ?

    Antworten
  • 28. November 2016 um 22:29
    Permalink

    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

    Antworten
    • 29. November 2016 um 10:20
      Permalink

      Ok so schwer war das nicht:
      …..muster [i] >> 8
      …..muster [i] & 255

      Antworten
      • 29. November 2016 um 11:35
        Permalink

        Fragen, auf die man selbst die Antwort findet, sind ja eh die besten :)

        Antworten
      • 24. Februar 2018 um 22:19
        Permalink

        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

        Antworten
  • 3. Dezember 2016 um 3:14
    Permalink

    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.

    Antworten
  • 6. Februar 2017 um 18:58
    Permalink

    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

    Antworten
  • 31. Oktober 2019 um 15:43
    Permalink

    There’s one point missing: Set the „MR (SRCLR)“ to HIGH (+5V), and the „OE (LATCH)“ pins to LOW (GND).

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload the CAPTCHA.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.