der dritte HC595 verhält sich komisch

hi

ich bastel so ne wort-uhr und habe dazu 3x HC595 in reihe geschaltet um die LEDs ein/aus schalten zu können.

funktioniert soweit ganz gut bis auf den dritten HC595 .. der "folgt" irgendwie dem ersten HC595 aber um 1 schritt versetzt

ich habe um zu debuggen ein script welches einfach alle LEDs der reihe nacht einschalten sollte:

int latchPin = 8; // ST_CP 
int clockPin = 12; // SH_CP
int dataPin = 11; // DS


int i = 0;


void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
// alle aus
  for(i=0; i<17; i++) {
    regOne(i, LOW);    
  }
// sequentiell einschalten
  for(i=0; i<17; i++) {
    regOne(i, HIGH);
    delay(1000);
  }
}


void regOne(int whichPin, int whichState) {
  static int bitsToSend = 0;  
  digitalWrite(latchPin, LOW); 
  bitWrite(bitsToSend, whichPin, whichState);
  byte registerOne = lowByte(bitsToSend);
  byte registerTwo = highByte(bitsToSend);  
  shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, registerOne);   
  digitalWrite(latchPin, HIGH);
}

wie erwähnt, die ersten beiden HC595 machen was sie sollen.. der dritte HC595 geht mit dem ersten sozusagen mit und fängt aber versetzt um 1 an.

(zu erwähnen wäre hier, dass ich nur die Out's 0-2 von dem dritten HC595 benutze .. habe schon versucht die unbenutzen OUTs auf GND zu legen und die verkabelung zig mal durchgecheckt)

HC595-1 HC595-2 HC595-3
0) out0

  1. out1 out0
  2. out2 out1
  3. out3 out2
  4. out4
  5. out5
  6. out6
  7. out7
  8. out0
  9. out1
    10 ....

jemand ne idee was das sein könnte?? bin echt am verzweifeln damit

AdmiralCrunch:
habe schon versucht die unbenutzen OUTs auf GND zu legen

Mit Ausgängen darfst du sowas nie machen!

100nF Abblock Kondensatoren verbaut? Wahrscheinlich nicht

void regOne(int whichPin, int whichState) {
  static int bitsToSend = 0; 
  digitalWrite(latchPin, LOW);
  bitWrite(bitsToSend, whichPin, whichState);
  byte registerOne = lowByte(bitsToSend);
  byte registerTwo = highByte(bitsToSend); 
  shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, registerOne);   
  digitalWrite(latchPin, HIGH);
}

Wenn Du 2 Byte rausschickst so bekommt der dritte 595 die alten Daten des ersten.
Bei drei 595 mußt Du auch 3 Byte rausschicken.
Grüße Uwe

Serenifly:
Mit Ausgängen darfst du sowas nie machen!

100nF Abblock Kondensatoren verbaut? Wahrscheinlich nicht

an welche stelle genau sollte man die verbauen?

uwefed:

void regOne(int whichPin, int whichState) {

static int bitsToSend = 0;
  digitalWrite(latchPin, LOW);
  bitWrite(bitsToSend, whichPin, whichState);
  byte registerOne = lowByte(bitsToSend);
  byte registerTwo = highByte(bitsToSend);
  shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, registerOne); 
  digitalWrite(latchPin, HIGH);
}




Wenn Du 2 Byte rausschickst so bekommt der dritte 595 die alten Daten des ersten.
Bei drei 595 mußt Du auch 3 Byte rausschicken.
Grüße Uwe

hmmmm.. das klingt erstmal logisch :smiley: .. wie würde man das machen in meiner funktion? komme da irgenwie nicht auf den grünen zweig :confused:

Ich habe mal so ins trockene am Notepad geändert also ungetestet.
Hier werden jetzt 3 Bytes erzeugt und die Position "festegelegt" mit Bitwrite und rausgeschoben.
Es ist nicht die schönste aber die für Anfänger verständlichste Variante.

void regOne(int whichPin, int whichState) {
  static byte byte0ToSend = 0;
  static byte byte1ToSend = 0;
  static byte byte2ToSend = 0;
  if (whichPin<=7){
    bitWrite(byte0ToSend, whichPin, whichState);
  }
  if (wichwhichPin>=8&&whichPin<=15){
    bitWrite(byte1ToSend, (whichPin-8), whichState);
   }
  if (wichwhichPin>=16&&whichPin<=23){
    bitWrite(byte2ToSend, (whichPin-16), whichState);
   }
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, byte0ToSend);
  shiftOut(dataPin, clockPin, MSBFIRST, byte1ToSend);   
  shiftOut(dataPin, clockPin, MSBFIRST, byte2ToSend);   
  digitalWrite(latchPin, HIGH);
}

Achtung mit deiner Grundlage bzw Funktion kann man nur 1 Bit pro durchlauf anmachen willst du mehrere Einschalten dann funktioniert das so nicht dann muss du die Byte global deklarieren und dich dann um das ein und Ausschalten kümmern. Hier wird bei jedem Aufruf der Funktion 3 "leere" Bytes erzeugt mit 00000000 Bits. also nach dem Rausshiften sind die Daten "verloren"

Gruß
DerDani

volvodani:
Ich habe mal so ins trockene am Notepad geändert also ungetestet.
Hier werden jetzt 3 Bytes erzeugt und die Position "festegelegt" mit Bitwrite und rausgeschoben.
Es ist nicht die schönste aber die für Anfänger verständlichste Variante.

void regOne(int whichPin, int whichState) {

static byte byte0ToSend = 0;
  static byte byte1ToSend = 0;
  static byte byte2ToSend = 0;
  if (whichPin<=7){
    bitWrite(byte0ToSend, whichPin, whichState);
  }
  if (wichwhichPin>=8&&whichPin<=15){
    bitWrite(byte1ToSend, (whichPin-8), whichState);
  }
  if (wichwhichPin>=16&&whichPin<=23){
    bitWrite(byte2ToSend, (whichPin-16), whichState);
  }
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, byte0ToSend);
  shiftOut(dataPin, clockPin, MSBFIRST, byte1ToSend); 
  shiftOut(dataPin, clockPin, MSBFIRST, byte2ToSend); 
  digitalWrite(latchPin, HIGH);
}

sauber vielen dank.. jetzt versteh ich was du meintest :slight_smile:

volvodani:
Achtung mit deiner Grundlage bzw Funktion kann man nur 1 Bit pro durchlauf anmachen willst du mehrere Einschalten dann funktioniert das so nicht dann muss du die Byte global deklarieren und dich dann um das ein und Ausschalten kümmern. Hier wird bei jedem Aufruf der Funktion 3 "leere" Bytes erzeugt mit 00000000 Bits. also nach dem Rausshiften sind die Daten "verloren"

Gruß
DerDani

das ist korrekt, das hatte ich so beabsichtigt :slight_smile:

vielen dank, werd das direkt mal testen sobald ich feierabend habe.

Hi nochmal :slight_smile:

also der code von volvodani funktioniert .. (sofern man "wichwhichPin" korrigiert) .. vielen dank nochmal :wink:

jetzt ist zwar die reihenfolge durcheinander..

regOne(0,HIGH) ... schaltet Out-0 am dritten HC595 an
regOne(0,HIGH) ... schaltet Out-1 am dritten HC595 an

... aber ich habe es so angepasst dass es für meine bedürfnisse funktioniert :smiley: .. kein plan warum das so ist, aber es funktioniert :slight_smile:

hab noch so einee abschließende grundsätzliche frage.. wenn ich meinen UNO nun an usb anschließe .. mal leuchten alle LEDs auf für paar sekunden während er sich initialisiert.. mal keine .. mal nur ein paar .. warum ist das so und wie kann man sowas verhindern?

Der Zustand der "Speicherzellen" des 595 beim Einschalten ist zufällig und damit auch der Zustand seiner Ausgänge.
Du kannst den !OE Pin mittels 10kOhm Widerstand auf HIGH ziehen und dann im Setup() die 595 mit 0 laden und den !OE dann auf Masse schalten.

Grüße Uwe

AdmiralCrunch:
jetzt ist zwar die reihenfolge durcheinander..

regOne(0,HIGH) ... schaltet Out-0 am dritten HC595 an
regOne(0,HIGH) ... schaltet Out-1 am dritten HC595 an

Ändere die Reihenfolge von

  shiftOut(dataPin, clockPin, MSBFIRST, byte0ToSend);
  shiftOut(dataPin, clockPin, MSBFIRST, byte1ToSend);   
  shiftOut(dataPin, clockPin, MSBFIRST, byte2ToSend);

zu

  shiftOut(dataPin, clockPin, MSBFIRST, byte2ToSend);
  shiftOut(dataPin, clockPin, MSBFIRST, byte1ToSend);   
  shiftOut(dataPin, clockPin, MSBFIRST, byte0ToSend);

Und dann passt es wieder. Denkfehler meinerseits
Gruß
DerDani