Forum: Mikrocontroller und Digitale Elektronik Schieberegister Letzter Pin immer 1


von Dennis H. (dennis_h71)


Lesenswert?

Heyho,

bin neu im Forum und hätte dirket eine Frage.
Ich bin ein Anfänger in der MC Welt und habe mich die letzten 2 Wochen 
intensiv in die Materie reingelesen.
Bis jetzt hat auch alles wunderbar geklappt.

Jedoch bin ich nun an einem Punkt angekommen, wo ich einfach einen 
Fehler nicht finde und nach 4h rumprobieren und googlen mir einfach 
nichts mehr einfällt.

Ich habe einen 8-Bit Schieberegister 74HC595 an meinen Arduino 
angeschlossen.
Die Schaltung sollte auf jeden Fall stimmen. (Habe es schon locker 10 
mal kontrolliert)

Wie ein Schieberegister Funktioniert habe ich auch verstanden und es 
funktioniert ja auch zu 95%.


Nun zu meinem Code:
1
    int test[8] = {0,0,0,0,1,1,1,1};
2
    digitalWrite(PIN_IC_STORE, 0);
3
    
4
    
5
    for (int i = 0; i < 8; i++)
6
        {
7
            digitalWrite(PIN_IC_SHIFT, LOW);
8
9
            digitalWrite(3, test[i]);
10
11
            digitalWrite(PIN_IC_SHIFT, HIGH);
12
        }
13
    
14
    digitalWrite(PIN_IC_STORE, 1);

Es funktioniert alles wunderbar bis auf eines:

Die letzte LED (der 8te Pin) leuchtet auch.
Ich kann mir es einfach nicht erklären.
Es ist wie als würde der Array wie folgt aussehen: {1,0,0,0,1,1,1,1}.

Das selbe Problem besteht auch, wenn ich es mit der ShiftOut Methode 
probiere.

Hat jemand ne Idee woran das liegen könnte?

lg Dennis

: Bearbeitet durch User
von Dennis H. (dennis_h71)


Lesenswert?

So hab jetzt durch einen Zufall etwas herausgefunden.

wenn ich zuerst in den Schieberegister bzw. dann auch in den 
Speicherregister nur Nullen eintrage ({0,0,0,0,0,0,0,0}) und dann meinen 
Code ausführe, dann funktioniert alles wunderbar.. Aber woran liegt das? 
:)

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Dennis H. schrieb:
> Nun zu meinem Code:    int test[8] = {0,0,0,0,1,1,1,1};
Das ist 32-facher Overkill...

> Die Schaltung sollte auf jeden Fall stimmen.
Welche Schaltung denn?

Dennis H. schrieb:
> ({0,0,0,0,0,0,0,0}) und dann meinen Code ausführe, dann funktioniert
> alles wunderbar.. Aber woran liegt das? :)
Dann probier mal, vorher die Nullen auszugeben, und danach 
{1,1,1,1,0,0,0,0}. Was passiert dann mit dem fraglichen Bit?

: Bearbeitet durch Moderator
von Dennis H. (dennis_h71)


Lesenswert?

Danke für deine Antwort Lothar.

Habe eine Frage.. Was ist ein 32-facher Overkill.. Habe ich noch nie 
gehört.

Mit Schaltung meine ich den Anschluss vom Schieberegister.

Lothar Miller schrieb:
> Dann probier mal, vorher die Nullen auszugeben, und danach
> {1,1,1,1,0,0,0,0}. Was passiert dann mit dem fraglichen Bit?

So funktioniert alles wunderbar.

Es funktioniert auch wenn ich die Nullen Anfangs nur ins Schieberegister 
speicher und nicht ins Speicherregister kopiere.


Außerdem habe ich noch was ganz anderes probiert:

Ich habe als Array welches übergeben wird folgendes ausprobiert:

int test[9] = {0, 0,0,0,0,1,1,1,1};

Damit wird anscheinend der Byte der noch auf 1 steht "rausgeschoben". 
Auf jeden Fall funktioniert es so.

Mich würde aber trotzdem einmal interessieren wieso das ganze so läuft. 
Hatte halt davor nich nie etwas in dem Bereich zu tun :)

von Route_66 H. (route_66)


Lesenswert?

Dennis H. schrieb:
> Habe eine Frage.. Was ist ein 32-facher Overkill.. Habe ich noch nie
> gehört.

Das ist, wenn man 8 Bit in 128 (!) Bit speichert, wobei 32 wohl mit 
einem Augenzwinkern übertrieben ist.

: Bearbeitet durch User
von Cyblord -. (cyblord)


Lesenswert?

Dennis H. schrieb:
> Habe eine Frage.. Was ist ein 32-facher Overkill.. Habe ich noch nie
> gehört.

> Mit Schaltung meine ich den Anschluss vom Schieberegister.

Du bist nicht hellste Kerze im Leuchter oder?

von Max H. (hartl192)


Lesenswert?

Dennis H. schrieb:
> Mit Schaltung meine ich den Anschluss vom Schieberegister.
So ein Schieberegister hat 16 Pins und der Arduino noch mehr, es gibt 
unzählige Möglichkeiten die beiden zu verbinden. Poste mal als 
SCHALTPLAN welche du gewählt hast...

von Ingo (Gast)


Lesenswert?

Route 66 schrieb:
> Das ist, wenn man 8 Bit in 128 (!) Bit speichert, wobei 32 wohl mit
> einem Augenzwinkern übertrieben ist.
Ich kenne Leute, die speichern einen DCF-Output in einem uint16_t[60] 
;).
Und? Es funktioniert auch, wenn auch nicht elegant.

von Route_66 H. (route_66)


Lesenswert?

@ingo:
Es sollte eine Erklärung für den TO sein, damit er ohne Google oder Wiki 
erfährt, was Overkill ist.

von Dennis H. (dennis_h71)


Lesenswert?

Cyblord ---- schrieb:
> Du bist nicht hellste Kerze im Leuchter oder?

Dein ernst?
Nur weil ich von dem ganzen Zeug keine Ahnung habe einen gleich als dumm 
abstempeln?
Naja im Internet ne große klappe und im RL immer in der letzten Reihe.


Zurück zum Thema:

Danke für die Antworten. Habe jetzt verstanden was ein Overload ist.

Habe jetzt eine Lösung gefunden, sodass alles funktioniert.

von Poster (Gast)


Lesenswert?

Dennis H. schrieb:
> Habe jetzt eine Lösung gefunden, sodass alles funktioniert.
Es wäre nicht schlecht wenn du diese auch postest, falls jemand mit 
einem ähnlichen Problem in Zukunft den Thread findet.

von Dennis H. (dennis_h71)


Lesenswert?

Wie oben bereits erwähnt habe ich den 8 Bytes die ich dem 
Schieberegister sende eine weiter 0 vorangeschoben. (Diese fällt 
sozusagen wieder hinten raus).
Wieso es so funktioniert weiß ich nicht^^

von Cyblord -. (cyblord)


Lesenswert?

Dennis H. schrieb:
> Dein ernst?
> Nur weil ich von dem ganzen Zeug keine Ahnung habe einen gleich als dumm
> abstempeln?

Nein, sondern weil du beide antworten bzw. nachfragen noch nicht mal 
verstanden hast.

Den Schaltplan hast du immer noch nicht gezeigt. Hast du inzwischen 
wenigstens gerallt dass du danach gefragt wurdest?

Irgendwas scheint ja wohl immernoch nicht korrekt zu laufen, aber 
hauptsache irgendwas hingemurkst dass es mal kurz tut.

Da darf man dann doch schon mal kritisch nachfragen oder?

von Peter D. (peda)


Lesenswert?

Dennis H. schrieb:
> Wieso es so funktioniert weiß ich nicht^^

Dann hast Du den Fehler auch nicht gefunden, sondern nur überdeckt.
Er wird Dir bei nächster unpassender Gelegenheit wieder ins Gesicht 
springen.

Abgesehen von der 16-fachen RAM-Verschwendung sieht der Code o.k. aus.

von Dennis H. (dennis_h71)


Angehängte Dateien:

Lesenswert?

Hier die Schaltung.. Ist die STandartschaltung aus dem Tutorial direkt 
von der Arduino Homepage. Einziger unterschied ist, dass der 
data/clock/latch Pin auf anderen Pins am Arduino selber liegen.
Hab den Schaltplan vorhin nur nicht geposted, weil ich den Fehler da zu 
99% ausschließen kann.

Ich versteh immer noch nicht was dein Problem ist. Ich kann doch nix 
dafür wenn ich nicht verstehe was ein Overkill ist. (Ich weiß es ja 
jetzt).

Peter Dannegger schrieb:
> Abgesehen von der 16-fachen RAM-Verschwendung sieht der Code o.k. aus.

Hab ich jetzt ja geändert :)

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Dennis H. schrieb:
> Hab den Schaltplan vorhin nur nicht geposted, weil ich den Fehler da zu
> 99% ausschließen kann.
Wir aber nicht, es gab schon fälle wo lange nach einem Softwarefehler 
gesucht wurde und schlussendlich ein Hardware Fehler die Ursache war.

Ich würde den Kondensator besser zwischen Pin 16 und Pin 8 als zwischen 
Pin 12 und Masse.

: Bearbeitet durch User
von Holger L. (max5v)


Lesenswert?

Peter Dannegger schrieb:
> Abgesehen von der 16-fachen RAM-Verschwendung sieht der Code o.k. aus.

Für mich ehrlich gesagt nicht.
Die For - Schleife zählt einen zu weit, zumindest in dem Codebeispiel 
das oben gesendet wurde ?!
( 0 .. 8 = neun Elemente )

von Cyblord -. (cyblord)


Lesenswert?

Holger L. schrieb:
> Peter Dannegger schrieb:
>> Abgesehen von der 16-fachen RAM-Verschwendung sieht der Code o.k. aus.
>
> Für mich ehrlich gesagt nicht.
> Die For - Schleife zählt einen zu weit, zumindest in dem Codebeispiel
> das oben gesendet wurde ?!
> ( 0 .. 8 = neun Elemente )

i<8 als for-Bedingung zählt aber nur bis 7

von Karl H. (kbuchegg)


Lesenswert?

Das einzige was ich tun würde (jetzt mal abgesehen von dem Array 
Wahnsinn bzw. dem Datentypunsinn), das ist die Pulserzeugung nicht so 
über den Code zu verstreuen. Ein Puls, das ist immer von einer 
Ausgangslage (low oder High), geht die Leitung in den anderne Zustand 
und dann wieder zurück.

Die Ausgangslage beim 595 nehm ich normalerweise als Low an (der 595 
reagiert an und für sich nur auf die Flanke) (und genau das stellst du 
auch einmal in setup() ein)
1
#define PIN_IC_DATA  3
2
3
...
4
5
    for (int i = 0; i < 8; i++)
6
    {
7
      digitalWrite(PIN_IC_DATA, test[i]);
8
9
      digitalWrite(PIN_IC_SHIFT, HIGH);
10
      digitalWrite(PIN_IC_SHIFT, LOW);
11
    }
12
    
13
    digitalWrite(PIN_IC_STORE, HIGH);
14
    digitalWrite(PIN_IC_STORE, LOW);
15
16
....

Wenns weiterhin Probleme gibt, dann würde ich halt mal ein paar LED an 
die 3 Leitungen zum 595 hängen und zwischen die einzelnen Aktion mal ein 
paar delay einfügen, so dass ich optisch verfolgen kann, in welcher 
Reihenfolge welche Leitung was macht.

Aber so ist das unbefriedigend. Einfach eine 0 nachschieben, weil man 
nicht versteht, woher der Versatz kommt, ist keine Lösung.

von Holger L. (max5v)


Lesenswert?

Cyblord ---- schrieb:
> i<8 als for-Bedingung zählt aber nur bis 7

Und was ist mit der 0 ?

Lektüre zum lesen :
http://www.c-howto.de/tutorial-schleifen-for.html
http://www.c-howto.de/tutorial-arrays-felder.html

von Cyblord -. (cyblord)


Lesenswert?

Holger L. schrieb:
> Cyblord ---- schrieb:
>> i<8 als for-Bedingung zählt aber nur bis 7
>
> Und was ist mit der 0 ?

Ich schrieb NICHT, die schleife laufe 7 mal. Sondern i wird nicht größer 
als 7. Lies deine Lektüre mal selber.

von Holger L. (max5v)


Lesenswert?

Ja genau darum geht es ja auch.
Der Index in Array's beginnt bei 0 nicht bei 1.

Soll heißen es muß von 0..7 und nicht von 0..8 oder 1..8 gezählt werden 
wenn das Array nur 8 Elemente beinhaltet. Das sollte auch den Fehler 
beseitigen.

von Max H. (hartl192)


Lesenswert?

Holger L. schrieb:
> Soll heißen es muß von 0..7
Und genau das macht
Dennis H. schrieb:
1
for (int i = 0; i < 8; i++)
auch.

Wenn du es nicht glauben willst kannst du gerne mal das auf deinem PC 
laufen lassen:
1
int main(int argc, char** argv)
2
{
3
  int i;
4
  for(i = 0; i < 8; i++)
5
    printf("%d\n", i);
6
  return 0;
7
}

: Bearbeitet durch User
von Christian K. (the_kirsch)


Lesenswert?

Holger L. schrieb:
> Peter Dannegger schrieb:
>> Abgesehen von der 16-fachen RAM-Verschwendung sieht der Code o.k. aus.
>
> Für mich ehrlich gesagt nicht.
> Die For - Schleife zählt einen zu weit, zumindest in dem Codebeispiel
> das oben gesendet wurde ?!
> ( 0 .. 8 = neun Elemente )

Holger L. schrieb:
> Ja genau darum geht es ja auch.
> Der Index in Array's beginnt bei 0 nicht bei 1.
>
> Soll heißen es muß von 0..7 und nicht von 0..8 oder 1..8 gezählt werden
> wenn das Array nur 8 Elemente beinhaltet. Das sollte auch den Fehler
> beseitigen.

Die Schleife geht von 0 bis 7, das sind 8 Durchläufe.

"i < 8" ist das gleiche wie "i <= 7"

Nach dem 8. Durchlauf ist i = 8, und die Bedingung ist dann FALSE und 
die Schleife springt raus.

von Cyblord -. (cyblord)


Lesenswert?

Der Holger sollte das jetzt mal so langsam glauben.

von Holger L. (max5v)


Lesenswert?

Oh man entschuldigt, ich stand gerade ein wenig auf dem Schlauch.

von Noch einer (Gast)


Lesenswert?

>Hab den Schaltplan vorhin nur nicht geposted, weil ich den Fehler da zu
>99% ausschließen kann.

Bei langen Kabeln auf dem Steckbrett kann man gar nichts ausschließen. 
Ein HC ist so schnell, dass ihn 20cm Kabel durcheinander bringen können. 
Möglicherweise sind es nur Effekte durch Kabel und Kapazität des 
Steckbrettes.

von Dennis H. (dennis_h71)


Lesenswert?

Noch einer schrieb:
> Bei langen Kabeln auf dem Steckbrett kann man gar nichts ausschließen.
> Ein HC ist so schnell, dass ihn 20cm Kabel durcheinander bringen können.
> Möglicherweise sind es nur Effekte durch Kabel und Kapazität des
> Steckbrettes.

Das hab ich auch schon berücksichtigt.. In meinem Test sind die Kabel 
Maximal 10cm lang.. hab das für den Anfang sehr kompakt gemacht.
Soll ja später eh alles verlötet werden.

Achja. Gibt es irgendetwas wichtiges zu beachten wenn ich einen IC 
verlöten will?

Karl Heinz schrieb:
> Das einzige was ich tun würde (jetzt mal abgesehen von dem Array
> Wahnsinn bzw. dem Datentypunsinn), das ist die Pulserzeugung nicht so
> über den Code zu verstreuen. Ein Puls, das ist immer von einer
> Ausgangslage (low oder High), geht die Leitung in den anderne Zustand
> und dann wieder zurück.
>
> Die Ausgangslage beim 595 nehm ich normalerweise als Low an (der 595
> reagiert an und für sich nur auf die Flanke) (und genau das stellst du
> auch einmal in setup() ein)

Danke dafür. Werde ich eben ausprobieren und dann das Ergebnis posten.

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Dennis H. schrieb:
> Achja. Gibt es irgendetwas wichtiges zu beachten wenn ich einen IC
> verlöten will?

https://www.mikrocontroller.net/articles/Kondensator#Entkoppelkondensator

von Dennis H. (dennis_h71)


Lesenswert?

Danke. Sehr hilfreicher Post.

Habs nun mit dem Arduino eigenen shiftOut Befehl umgesetzt, da ich so am 
einfachsten mehrere Schieberegister hintereinander ansprechen kann.
1
digitalWrite(LATCHPIN, LOW);
2
  shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, ledData[8]); //2. Register
3
  shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, ledData[4]);  //erster Register
4
  digitalWrite(LATCHPIN, HIGH);

Also so funktioniert alles einwandfrei.
Aber das wäre ja anfangs zu einfach gewesen :) scherz

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.