4x4x4 Cube mit 74HC595 Array Problem

Guten Abend,

ich programmiere gerade meinen 4x4x4 Cube mithilfe von 74HC595 Schiftregistern…
Soweit funktioniert auch alles und hatte auch keine Probleme mit den Arrays und dem outshiften…

Nun funktiniert eine Array kette nicht und ich finde den Fehler nicht.
Vielleicht fällt ja hier jemandem mein Fehler auf und hilft mir wieder auf die Spur. :slight_smile:

Code:

const byte allePins[] = {2, 3, 4, 5, 6, 7, 8};
int clockPin = 2;
int latchPin = 3;
int dataPin = 4;
const byte alleLayers[] = {5, 6, 7, 8};
int layer1 = 5;
int layer2 = 6;
int layer3 = 7;
int layer4 = 8;

byte dataArray1;
byte dataArray2;

void setup() {
  Serial.begin(57600);
  Serial.println("Start");
  for(int i=0; i<sizeof(allePins); i++) {
    pinMode(allePins[i], OUTPUT);
  }
  for(int i=0; i<sizeof(alleLayers); i++) {
    digitalWrite(alleLayers[i], LOW);
  }

//--------------------------------------------------------ArrayLinksRechts
//~~~~~~~~~~~~1,2,3,4,5,6,7,8~~~Säule
  Array3[0] = 0xF0; //11110000
  Array3[1] = 0x0F; //00001111
  Array3[2] = 0xF0; //00000000
  Array3[3] = 0x0F; //00000000

//~~~~~~~~~~~~~9,10,11,12,13,14,15,16~~~Säule
  Array3_1[0] = 0xF0; //00000000
  Array3_1[1] = 0x0F; //00000000
  Array3_1[2] = 0xF0; //11110000
  Array3_1[3] = 0x0F; //00001111
}

void loop() {
//------------------------------------------------------------funktion5
  platten();
}

//------------------------------------------------------------shiftOut
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  int i=0;
  int pinState;
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {  
      pinState= 0;
    }
    digitalWrite(myDataPin, pinState);
    digitalWrite(myClockPin, 1);
    digitalWrite(myDataPin, 0);
  }
  digitalWrite(myClockPin, 0);
}

void allOff() {
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  digitalWrite(latchPin, 1);
}

void platten() {
  for (int i=0; i < 4; i++) {
    dataArray1 = Array3[i];
    dataArray2 = Array3_1[i];
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, dataArray1);   
    shiftOut(dataPin, clockPin, dataArray2);
    digitalWrite(latchPin, 1);

    for(int j=0; j<16; j++) {
      digitalWrite(layer1, HIGH);
      delay(4);
      digitalWrite(layer1, LOW);
      digitalWrite(layer2, HIGH);
      delay(4);
      digitalWrite(layer2, LOW);
      digitalWrite(layer3, HIGH);
      delay(4);
      digitalWrite(layer3, LOW);
      digitalWrite(layer4, HIGH);
      delay(4);
      digitalWrite(layer4, LOW);
    }
  }
  allOff();
  delay(100);
}

Anordnung der Säulen:

4 8 12 16 | Nano
3 7 11 15 |
2 6 10 14 |
1 5 9 13 |
_________|
2x 74HC595

Bild für Verständnis im Anhang

Das Ziel ist es, dass Vier Säulen in Reihe an sind und von links nach rechts gehen.

EDIT: Aktuell werden (von oben gesehen) Spalte 2(5,6,7,8) und Spalte 4(13,14,15,16) angeschaltet, danach Spalte 1 und 3.
zuletzt nochmal Spalte 2 und 4…
Ich habe absolut kein Plan wie dies zu Stande kommt… Ich habe die Dezimalzahlen überprüft und es müsste so richtig sein :confused:

EDIT2: Array3 und 3_1 laufen quasi parallel.
Das 1. Bit aus Array3 wird hinten in den 2. (linken) 74HC595 geschoben.
Ich habe über den jeweiligen bit geschrieben, welcher Säule dieser entspricht.

Ein Schaltplan wäre sehr hilfreich, um die Lücken in Deiner Beschreibung zu füllen. Auch Kommentare im Code wären hilfreich, auch wenn Dir jetzt alles klar ist. Für andere und auch für Dich in ein paar Wochen ist nicht so richtig klar, was da ablaufen soll - wie soll man dann draufkommen, was nicht so funktioniert wie geplant?

DrDiettrich:
Ein Schaltplan wäre sehr hilfreich, um die Lücken in Deiner Beschreibung zu füllen. Auch Kommentare im Code wären hilfreich, auch wenn Dir jetzt alles klar ist. Für andere und auch für Dich in ein paar Wochen ist nicht so richtig klar, was da ablaufen soll - wie soll man dann draufkommen, was nicht so funktioniert wie geplant?

Mit einem Schaltplan kann ich erst heute Abend dienen.

Eigentlich sollten die Kommentare ausreichen?
Am Anfang gebe ich den Pins andere Bezeichnungen,
Danach im Setup setze ich alle Pins als Output,
Anschließend bekommen die Arrays die 8 bits zugewiesen.
Im loop ist nur ‘platten()’ drin, da ich dafür ein Funktion außerhalb gemacht habe. (diese void Platten findet man weiter unten)

Danach kommt die SchiftOut Funktion und die ‘allOff’ Funktion, wo einfach alle Säulen auf 0 gesetzt werden.

Das sind alle relevanten parts, die nicht funktionieren.
Den Rest meines Codes hab ich nicht hochgeladen, da dieser 4kb+ beträgt

Im Code kommen zwar ab und zu latchPin und dataPin vor, es ist aber unklar wie die mit den Schieberegistern in Verbindung stehen. Im Schaltbild müssen nicht alle 64 LEDs vorkommen, es muß aber klar werden, welche Pins wieviele LEDs treiben sollen, und wo dafür Transistoren eingesetzt werden.

Auch ist es sehr bedenklich, wenn ein Taktimpuls keine definierte (minimale) Länge hat, und der dataPin nicht über den gesamten Taktimpuls gleich bleibt - wieso soll der überhaupt zwischendrin 0 werden? Das Timing ist jedenfalls sehr wacklig.

Hallo,

bevor ich mir einen Sketch überhaupt anschaue kompiliere ich diesen.

Deiner wirft

sketch_jan30a.ino: In function 'void setup()':
sketch_jan30a.ino:18:17: warning: comparison of integer expressions of different signedness: 'int' and 'unsigned int' [-Wsign-compare]
   18 |   for(int i=0; i<sizeof(allePins); i++) {
      |                ~^~~~~~~~~~~~~~~~~

sketch_jan30a.ino:21:17: warning: comparison of integer expressions of different signedness: 'int' and 'unsigned int' [-Wsign-compare]
   21 |   for(int i=0; i<sizeof(alleLayers); i++) {
      |                ~^~~~~~~~~~~~~~~~~~~
sketch_jan30a:27:3: error: 'Array3' was not declared in this scope
   27 |   Array3[0] = 0xF0; //11110000
      |   ^~~~~~
sketch_jan30a:33:3: error: 'Array3_1' was not declared in this scope
   33 |   Array3_1[0] = 0xF0; //00000000
      |   ^~~~~~~~

In function 'void platten()':
sketch_jan30a:75:18: error: 'Array3' was not declared in this scope
   75 |     dataArray1 = Array3[i];
      |                  ^~~~~~
sketch_jan30a:76:18: error: 'Array3_1' was not declared in this scope
   76 |     dataArray2 = Array3_1[i];
      |                  ^~~~~~~~
exit status 1
'Array3' was not declared in this scope

Hinweis!
In der IDE alle Compilerwarnungen einschalten.
Datei > Voreinstellungen >

  • Ausführliche Ausgabe während > beide Haken rein
  • Compilerwarnungen > “ALLE”

Zeilennummern und Codefaltung sind auch hilfreich.

Hallo,

wegen deinen IC Funktionen. Du setzt deine Pins falsch. Erst das Datenbit auflegen, dann einen Takt erzeugen. Wenn alles raus ist müssen die Bits im IC noch übernommen werden, ansonsten liegen die dort ungenutzt rum. Saubere Funktionen schreiben ist wichtig.

Meine Initialisierung sieht so aus.

/* Init 74HC595 */
  pinReset_ON;
  pinReset_OUT;
  pinClock_OUT;
  pinLatch_OUT;
  pinData_OUT;
  pinReset_OFF;  // delete shift register
  pinReset_ON;
  pinLatch_ON;   // take over storage register
  pinLatch_OFF;

und meine shift Funktion sieht so aus, für 2 kaskadierte 595er

/* Bytes rausschieben, LSB first */
void bytesShiftOut( unsigned int data ) 
{    
  // in das Schieberegister eintakten //   
  for(byte i=0; i<16; i++)
  {
    if(data & 0x01) {     // nur unterstes Bit betrachten
      pinData_ON;         // und Datenleitung entsprechend setzen
    }
    else {
      pinData_OFF;
    }
    
    pinClock_ON;          // Takt erzeugen
    data = data >> 1;     // nächstes Bit rechts schieben (gleichzeitig Clocktiming)
    pinClock_OFF;
  }

  // vom Schieberegister ins Ausgaberegister übernehmen //
  pinLatch_ON;
  pinLatch_OFF;
}

Kurze Frage OffTopic Aber für mich zum verständnis. ein Schieberegister nutzt man hier, weil man mit 2 Ausgängen des arduino (als Daten und Clock) nacheinander den Zustand von 8,16,32.... Ausgängen des Schieberegisters durchgeben kann? Sich also eine Menge Ausgänge spart? Der Preis dafür ist dann, dass die Led am ersten Ausgang flackert weil sie die anderen Zustände dirchreicht?

Doc_Arduino:
Hallo,

bevor ich mir einen Sketch überhaupt anschaue kompiliere ich diesen.

Deiner wirft

sketch_jan30a.ino: In function 'void setup()':

sketch_jan30a.ino:18:17: warning: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Wsign-compare]
  18 |  for(int i=0; i<sizeof(allePins); i++) {
      |                ~^~~~~~~~~~~~~~~~~

sketch_jan30a.ino:21:17: warning: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Wsign-compare]
  21 |  for(int i=0; i<sizeof(alleLayers); i++) {
      |                ~^~~~~~~~~~~~~~~~~~~
sketch_jan30a:27:3: error: ‘Array3’ was not declared in this scope
  27 |  Array3[0] = 0xF0; //11110000
      |  ^~~~~~
sketch_jan30a:33:3: error: ‘Array3_1’ was not declared in this scope
  33 |  Array3_1[0] = 0xF0; //00000000
      |  ^~~~~~~~

In function ‘void platten()’:
sketch_jan30a:75:18: error: ‘Array3’ was not declared in this scope
  75 |    dataArray1 = Array3[i];
      |                  ^~~~~~
sketch_jan30a:76:18: error: ‘Array3_1’ was not declared in this scope
  76 |    dataArray2 = Array3_1[i];
      |                  ^~~~~~~~
exit status 1
‘Array3’ was not declared in this scope




Hinweis!
In der IDE alle Compilerwarnungen einschalten.
Datei > Voreinstellungen > 
- Ausführliche Ausgabe während > beide Haken rein
- Compilerwarnungen > "ALLE"

Zeilennummern und Codefaltung sind auch hilfreich.

Ich habe dies ausführliche Ausgabe aktiviert. Nur vergessen das ‘Byte Array3’ und ‘Byte Array3_1’ zu kopieren. Sorry.

Bei mir hat der damit keine Fehler ausgespuckt.

DrDiettrich:
Im Code kommen zwar ab und zu latchPin und dataPin vor, es ist aber unklar wie die mit den Schieberegistern in Verbindung stehen. Im Schaltbild müssen nicht alle 64 LEDs vorkommen, es muß aber klar werden, welche Pins wieviele LEDs treiben sollen, und wo dafür Transistoren eingesetzt werden.

Auch ist es sehr bedenklich, wenn ein Taktimpuls keine definierte (minimale) Länge hat, und der dataPin nicht über den gesamten Taktimpuls gleich bleibt - wieso soll der überhaupt zwischendrin 0 werden? Das Timing ist jedenfalls sehr wacklig.

Ja verstehe, habe eben ja schon geschrieben, dass heute Abend den Schaltplan hier poste.

Die Transistoren sind für die 4 Ebenen gedacht. Sorry, hab vergessen dies zu erwähnen.

raznz_snasna: Der Preis dafür ist dann, dass die Led am ersten Ausgang flackert weil sie die anderen Zustände dirchreicht?

Nein. Die Schieberegister haben Latches. Schau dir das Datenblatt an. Deshalb muss man ja den Latch-Pin an der richtigen Stelle setzen, nachdem man alle Daten reingeschoben hat

raznz_snasna: Kurze Frage OffTopic Aber für mich zum verständnis. ein Schieberegister nutzt man hier, weil man mit 2 Ausgängen des arduino (als Daten und Clock) nacheinander den Zustand von 8,16,32.... Ausgängen des Schieberegisters durchgeben kann? Sich also eine Menge Ausgänge spart? Der Preis dafür ist dann, dass die Led am ersten Ausgang flackert weil sie die anderen Zustände dirchreicht?

Ein shift register benötigt 3 Anschlüsse, einen latch, data und clock pin. Es hat 8 Ausgäng und somit spart man pro 8 leds, 5 arduino Ausgänge.

Ich meine, der clock pin sorgt dafür, dass das shift register angehalten wird bzw ihn arbeiten lässt (Start/stop), der latch pin, ob er neue Bits aufnehmen soll oder nicht und über den data pin werden diese bits übertragen Das shift register kann zwei Zustände erkennen - 0 und 1. Diese Nullen und Einsen Speicher ich in Arrays (jeweils 8 bits = 1 Byte) und gebe diese aus.

In meinem Beispiel, schalte ich zum Beispiel alle Ecksäulen an über diese Arrays (2 shift register, 2 Arrays) Array1 = 1001 0000 Array1_1= 0000 1001 Somit werden der 1., 4., 13. Und 16. Ausgang auf 1(plus) gesetzt Jetzt muss ich die layer nur schnell hinter einander ein und ausschalten. Bp: layer1 an/aus layer2 an/aus layer3 an/aus layer3 an/aus

Zwischen der an/aus Phase muss ein kurzer delay sein, damit die led kurz aufblitzt (in meinem Fall 4ms) So sieht man das flackern der leds nicht, außer man nimmt es mit einer Kamera auf, dann sieht man dies.

Auch kurz genannt multiplexing

Soltanius: Ich meine, der clock pin sorgt dafür, dass das shift register angehalten wird bzw ihn arbeiten lässt (Start/stop), der latch pin, ob er neue Bits aufnehmen soll oder nicht

Nein und nein. Auch du musst dir mal das Datenblatt anschauen.

Bei jedem Puls am Clock-Pin wird der Zustand am Daten-Pin in das Schieberegister geschoben. Aber zwischen dem Schieberegister und den Ausgängen ist ein Zwischenspeicher. Erst mit einem Puls am Latch-Pin wird das Schieberegister in das Latch und damit auf die Ausgänge geschrieben

Serenifly: Nein und nein. Auch du musst dir mal das Datenblatt anschauen.

Bei jedem Puls am Clock-Pin wird der Zustand am Daten-Pin in das Schieberegister geschoben. Aber zwischen dem Schieberegister und den Ausgängen ist ein Zwischenspeicher. Erst mit einem Puls am Latch-Pin wird das Schieberegister in das Latch und damit auf die Ausgänge geschrieben

Genau, so wars. Sorry.. Hatte es nicht mehr ganz im Kopf wie des funktioniert. Hab dazu mal ein geniales Schaubild gefunden, wie ein shift register funktioniert.

So, hier ist der Schaltplan.
Werde erst gegen halb 9 antworten können, habe es nur kurz noch nach hause geschafft.

LG Soltanius

Hallo,

wenn die Widerstände richtig dimensioniert sind geht nichts kaputt. Im dümmsten Fall könnten nur die Leds zu dunkel sein. Hängt vom Led Typ ab. IC Stützkondensatoren solltest du noch spendieren. Lies hier mal https://www.mikrocontroller.net/articles/LED-Matrix

Tja und dann kümmerste dich um dein Programm.

Doc_Arduino: Hallo,

wenn die Widerstände richtig dimensioniert sind geht nichts kaputt. Im dümmsten Fall könnten nur die Leds zu dunkel sein. Hängt vom Led Typ ab. IC Stützkondensatoren solltest du noch spendieren. Lies hier mal https://www.mikrocontroller.net/articles/LED-Matrix

Tja und dann kümmerste dich um dein Programm.

Doc_Arduino: Hallo,

wenn die Widerstände richtig dimensioniert sind geht nichts kaputt. Im dümmsten Fall könnten nur die Leds zu dunkel sein. Hängt vom Led Typ ab. IC Stützkondensatoren solltest du noch spendieren. Lies hier mal https://www.mikrocontroller.net/articles/LED-Matrix

Tja und dann kümmerste dich um dein Programm.

Ich habe dies gerade mal überflogen und nichts über diese genannten IC Stützkondensatoren gefunden. Ich werde später mal versuchen genaueres darüber zu erfahren.. Der Rest war mir vorher schon bewusst, da ich hier schon mal in nem vergangen Post einen aufn Deckel bekommen habe, wegen meiner (für den Arduino tötlichen) Schaltung. Und ja, die Widerstände sind richtig dimensioniert.

Hallo,

wegen der unterschiedlichen LED Helligkeit. Ich frage mich warum noch kein Cube-Bauer über Helligkeitsschwankungen geklagt hat. Oder ob man das durch die Effekte einfach nicht sieht. Jedesfalls habe ich mal nachgedacht. Wenn man jeder LED am Segmentausgang ihren eigenen Widerstand spendiert, dann bekommt jede LED ihren eigenen ungeteilten Strom. Solange der IC den Summenstrom liefern kann. Wäre bei dir mit 4 Zeilen laut Schaltplan, jeder 595er bekommt an jeden Segmentausgang 4 Widerstände die zur jeweiligen LED Anode führen. Kannste machen wenn du schwankendes störendes “flackern” bemerkst.

Stützkondensatoren. Die werden im Grunde vorrausgesetzt. Findest du jedoch im Schaltplan. Im Grunde in jedem ordentlichen Schaltplan der Welt. Der Link war nicht primär wegen den Stützkondensatoren, eher allgemein zur Matrix.

Doc_Arduino: Hallo,

wegen der unterschiedlichen LED Helligkeit. Ich frage mich warum noch kein Cube-Bauer über Helligkeitsschwankungen geklagt hat. Oder ob man das durch die Effekte einfach nicht sieht. Jedesfalls habe ich mal nachgedacht. Wenn man jeder LED am Segmentausgang ihren eigenen Widerstand spendiert, dann bekommt jede LED ihren eigenen ungeteilten Strom. Solange der IC den Summenstrom liefern kann. Wäre bei dir mit 4 Zeilen laut Schaltplan, jeder 595er bekommt an jeden Segmentausgang 4 Widerstände die zur jeweiligen LED Anode führen. Kannste machen wenn du schwankendes störendes "flackern" bemerkst.

Man sieht kein flackern oder irgendwelche Helligkeitsschwankungen. Es wird ja alles nur parallel geschaltet und solange ich für alles genügen Strom liefer, gibt der 74HC595 soviel, wie er kann. Die leds benötigen ja weniger, als er pro output ausgeben kann.. (ist ja immer nur eine LED pro Ausgang, da die Etagen nacheinander geschaltet werden.

Doc_Arduino: Stützkondensatoren. Die werden im Grunde vorrausgesetzt. Findest du jedoch im Schaltplan. Im Grunde in jedem ordentlichen Schaltplan der Welt. Der Link war nicht primär wegen den Stützkondensatoren, eher allgemein zur Matrix.

Achso okay, dann habe ich dies wohl immer überlesen und übersehen oder das Beispiel, welches ich gesehen habe hatte dies nicht drin..

Ich habe dazu bis jetzt nur Texte überflogen (weil ich nur aufm weg zu schule zeit hatte)

Stimmt es, dass ich so einen kerko nur am ersten shift register setze (bei zwei) und dieser 100nF betragen muss? Wenn ja, muss ich gucken, ob ich irgendwo noch welche finde.. Hab direkt nur 22nF Kerkos oder 10uF Folienkondensatoren :/

Die gemultiplexten LED sind nicht so empfindlich auf Spannungsschwankungen, aber alle IC können empfindlich auf Spannungsspitzen reagieren, besonders auf Spannungseinbrüche. Deshalb sollten alle IC ihre Stützkondensatoren an ihre Versorgungsspannung bekommen. Einen kleinen schnellen für kurze Einbrüche (10-100nF) die unerwünschtes Schalten oder Schieben auslösen könnten, und ggf. einen großen (10µF) für die Überbrückung geschalteter höherer Ausgangsströme.

DrDiettrich: Die gemultiplexten LED sind nicht so empfindlich auf Spannungsschwankungen, aber alle IC können empfindlich auf Spannungsspitzen reagieren, besonders auf Spannungseinbrüche. Deshalb sollten alle IC ihre Stützkondensatoren an ihre Versorgungsspannung bekommen. Einen kleinen schnellen für kurze Einbrüche (10-100nF) die unerwünschtes Schalten oder Schieben auslösen könnten, und ggf. einen großen (10µF) für die Überbrückung geschalteter höherer Ausgangsströme.

Also wenn ich es jetzt richtig verstanden habe, dann komme ich mit meinem 22nF Kerko aus, aber kann, wenn ich viele LEDs gleichzeitig einschalte, noch nen 10uF kondensator dazupacken? Und dies an beiden meiner IC?