Forum: Mikrocontroller und Digitale Elektronik 74hc259 macht komische Faxen


von General E. (generalerror)


Lesenswert?

Hi,

ich habe ein kurioses Problem mit dem 74hc259 8bit-adressierbaren 
speicher.

ich möchte ihn nutzen um einge LEDs unabhängig voneinander zu steuern. 
Er funktioniert soweit ganz gut.. nur verhällt er sich komisch, wenn ich 
einen Status in einem Latch gespeichert zurücklasse und mich einem 
anderen latch zuwende um dessen Status zu ändern..

sorry, ich weiss nichtmal wie ich das beschreiben soll. habe das mal 
gefilmt:

https://www.youtube.com/watch?v=GQRN1lZeSI0

kann mit jemand sagen, was ich falsch mache ?? (ja ich weiss, so ohne 
code und kram ist das schon eine zumutung.. aber vielleicht kennt jemand 
dieses verhalten?)

von Thomas E. (thomase)


Lesenswert?

General E. schrieb:
> kann mit jemand sagen, was ich falsch mache ??

Keine Stützkondensatoren.

von Joe F. (easylife)


Lesenswert?

General E. schrieb:
> ja ich weiss, so ohne
> code und kram ist das schon eine zumutung..

So ist es.
Too many "oops'es" in the video as well.

: Bearbeitet durch User
von General E. (generalerror)


Lesenswert?

Thomas E. schrieb:
> General E. schrieb:
>> kann mit jemand sagen, was ich falsch mache ??
>
> Keine Stützkondensatoren.

Hey,

kannst du das bitte etwas näher erläutern? .. sorry, bin noch blutiger 
anfänger :/ .. wie krieg ich raus, welche kondensatoren ich brauche? und 
wo schalte ich sie zu? .. am daten-kanal ?? oO

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

Das Video ist ja auf "Ausländisch" gesprochen.

An jedes IC gehört ein 100nF Keramikkondensator. Der Aufbau ist 
ausgedehnt aufgebaut und durch die hohen Stromstärken zu den LEDs rechts 
kann an den wackeligen Steckkontakten unerwünschter Spannungsabfall 
entstehen. Wie niederohmig die Eingänge beschaltet sind, enthält uns der 
Reporter vor Ort leider vor. Im Fehlerfall sollen vermutlich mehrere 
Schaltvorgänge gleichzeitig ablaufen.

Konnte schon jemand anhand des Videos ein Schaltbild erstellen?


Mit freundlichem Gruß

: Bearbeitet durch User
von General E. (generalerror)


Lesenswert?

Joe F. schrieb:
> General E. schrieb:
>> ja ich weiss, so ohne
>> code und kram ist das schon eine zumutung..
>
> So ist es.
> Too many "oops'es" in the video as well.

naaaagut.. ich versuchs mal aufs das relevanteste zu beschränken, da es 
echt viel ist:

alo ich hab meine klasse "light" welche ich dazu nutzen möchte, den 
zustand der LEDs zu kontrollieren:

light.h
1
 
2
#ifndef light_h
3
#define light_h
4
#include "Arduino.h"
5
6
class light {
7
    
8
  public:  
9
    
10
    light(int ledMuxPin1,
11
          int ledMuxPin2,
12
          int ledMuxPin3,          
13
          int _muxRedPin,
14
          int _muxGreenPin,
15
          int _muxBluePin,
16
          int _ledResetPin); 
17
      
18
    void setColor(int red, int green, int blue);
19
    void resetAll();
20
    
21
    int _ledMuxPin1;
22
    int _ledMuxPin2;
23
    int _ledMuxPin3; 
24
    
25
    int _muxRedPin;
26
    int _muxGreenPin;
27
    int _muxBluePin;
28
    
29
    int _muxBit1;
30
    int _muxBit2;
31
    int _muxBit3;
32
    
33
    void switchMux(int i);
34
    
35
    
36
    // COLORS
37
    int colors[6][3] = {        
38
        {255,255,255},
39
        {255,0,128},
40
        {0,255,0},
41
        {0,0,255},
42
        {255,60,0},
43
        {255,0,128}
44
    };
45
    int orange[3] = {255,60,0};
46
    int lila[3] = {255,0,128};
47
    int red[3] = {255,0,128};
48
    int green[3] = {0,255,0};
49
    int blue[3] = {0,0,255};
50
    int white[3] = {255,255,255};
51
    
52
  private:   
53
    
54
};
55
56
#endif

ledMuxPin1 bis ledMuxPin3 sind die steuer-pins am 74hc259 ..
muxRedPin ist der datenkanal (geen und blue eigentlich auch, denn der 
plan war es 3x 74hc259 in reihe zu schalten, aber das haben ich erstmal 
- um den fehler einzugränzen - nicht verbunden.. also ist nur muxRedPin 
relevant)

light.cpp
1
#include "Arduino.h"
2
#include "light.h"
3
4
light::light(int ledMuxPin1, int ledMuxPin2, int ledMuxPin3, int muxRedPin, int muxGreenPin, int muxBluePin) {
5
    
6
    // INITIALIZE MUX-CONTROL
7
    _ledMuxPin1 = ledMuxPin1;
8
    _ledMuxPin2 = ledMuxPin2;
9
    _ledMuxPin3 = ledMuxPin3;    
10
    pinMode(_ledMuxPin1, OUTPUT);
11
    pinMode(_ledMuxPin2, OUTPUT);
12
    pinMode(_ledMuxPin3, OUTPUT);
13
    
14
  
15
    
16
    // INITIALIZE MUX COLOR-CONTROL
17
    _muxRedPin = muxRedPin;
18
    _muxGreenPin = muxGreenPin;
19
    _muxBluePin = muxBluePin;
20
    pinMode(_muxRedPin, OUTPUT);
21
    pinMode(_muxGreenPin, OUTPUT);
22
    pinMode(_muxBluePin, OUTPUT);
23
}
24
25
26
 void light::setColor(int red, int green, int blue) {
27
    #ifdef COMMON_ANODE
28
        red = 255 - red;
29
        green = 255 - green;
30
        blue = 255 - blue;
31
    #endif  
32
    
33
    analogWrite(_muxRedPin, red);
34
    analogWrite(_muxGreenPin, green);
35
    analogWrite(_muxBluePin, blue);    
36
 }
37
38
39
40
41
void light::switchMux(int i) {        
42
    _muxBit1 = bitRead(i,0);
43
    _muxBit2 = bitRead(i,1);
44
    _muxBit3 = bitRead(i,2);    
45
    digitalWrite(_ledMuxPin1, _muxBit1);
46
    digitalWrite(_ledMuxPin2, _muxBit2);
47
    digitalWrite(_ledMuxPin3, _muxBit3);
48
}

switchMux() schaltet auf das latch i .. setColor() schickt den/die 
wert/e durch den/die daten-bus/e

in meinem hauptprogramm mache ich dann sowas:
1
light.switchMux(i); 
2
light.setColor(btnTrackSelect[i]._rgb[0],btnTrackSelect[i]._rgb[1],btnTrackSelect[i]._rgb[2]);

habe da fehlverhalten jetzt ein bisschen uner die lupe genommen.. es 
passier immer das muster:

- latch 1 auf 255 --> LED 1 leuchtet
- latch 2 auf 255 --> LED 2 leuchtet
- latch 3 auf 255 --> LED 3 leuchtet
- latch 4 auf 255 --> LED 4 leuchtet

- latch 3 auf 0 --> LED 2 ist aus
- latch 2 auf 0 --> LED 2 und LED 4 gehen aus!! why? oO

das selbe wenn die die latches 5-8 ändere

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

General E. schrieb:
> naaaagut.. ich versuchs mal aufs das relevanteste zu beschränken

Dann tu das auch und bring deine Hardware in Ordnung.

General E. schrieb:
> kannst du das bitte etwas näher erläutern? .. sorry, bin noch blutiger
> anfänger

Dann hast du noch eine Menge zu lernen.
Als erstes kommen 100nF-Keramikkondensatoren an jeden Spannungseingang 
jedes ICs. Auch wenn irgendwelche Bastler denken, daß man das nicht 
machen müsste.

: Bearbeitet durch User
von Joe F. (easylife)


Lesenswert?

Wie ist denn eigentlich MR und LE des Latches beschaltet? Offen?

von General E. (generalerror)


Angehängte Dateien:

Lesenswert?

Joe F. schrieb:
> Wie ist denn eigentlich MR und LE des Latches beschaltet? Offen?

Hi, also MR ist auf HIGH und LE ist auf GND

von Erich (Gast)


Lesenswert?

>Hi, also MR ist auf HIGH und LE ist auf GND

Das Teil braucht auf "D" (den Dateneingang) und "LE" (Latch enable) 
ansteuerbar bom uC.
a) "LE" auf highpegel initialisieren.
b) für jeden Q: Erst D sowie A1, A2, A3 Werte anlegen.
c) "LE" auf low setzen, dann zurück auf high
d) Loop b)

Wie soll es sonst "speichern"?

Gruss

von Joe F. (easylife)


Lesenswert?

Erich schrieb:
> Wie soll es sonst "speichern"?

speichern tut es, aber es werden gleich mehrere Adressen decodiert und 
damit auch gleich mehrere Latches geändert.

General E. schrieb:
> - latch 3 auf 0 --> LED 2 ist aus
> - latch 2 auf 0 --> LED 2 und LED 4 gehen aus!! why? oO

Beginne deine Zählung mal besser mit 0, dann wird das Problem 
offensichtlicher
Es passiert also folgendes:

- adresse 2 auf 0 --> LED 2 ist aus
- adresse 1 auf 0 --> LED 1 und LED 3 gehen aus!! why? oO

switchMux() macht folgendes
1
    digitalWrite(_ledMuxPin1, _muxBit1);
2
    digitalWrite(_ledMuxPin2, _muxBit2);
3
    digitalWrite(_ledMuxPin3, _muxBit3);

Es wird also erst Bit 0 der Adresse geändert, dann Bit 1 und dann Bit 2.

Wenn du jetzt von Adresse 2 = (binär 010) auf Adresse 1 (001) 
"umschaltest", liegen der Reihe nach folgende Adressen am Latch an:

010 (=2)
011 (=3)
001 (=1)

Das erklärt, warum auch LED 3 aus geht.

Du musst also LE auf high setzen (und nicht fest auf LOW legen), solange 
du die Adresse änderst, und erst nachdem die Adresse korrekt anliegt 
wieder auf LOW setzen.

Inwiefern die Verwendung eines Latches hier überhaupt Sinn macht, sei 
mal noch eine ganz andere Sache.
PWM kann man damit jedenfalls nicht so ohne weiteres realisieren.

Guck dir mal die übliche Methode mit 74xx595 Schieberegistern an.

: Bearbeitet durch User
von General E. (generalerror)


Lesenswert?

Joe F. schrieb:
> Das erklärt, warum auch LED 3 aus geht.
Hey!! SUPER :)) vielen lieben dank für die Erklärung :)
Das hat mir echt weitergeholfen, auch in Bezug auf andere Module.


Joe F. schrieb:
> Inwiefern die Verwendung eines Latches hier überhaupt Sinn macht, sei
> mal noch eine ganz andere Sache.
> PWM kann man damit jedenfalls nicht so ohne weiteres realisieren.
>
> Guck dir mal die übliche Methode mit 74xx595 Schieberegistern an.

also daraus werde ich irgendwie nicht schlau :/
.. PWM bräuchte ich definitiv, aber ich check das nicht mit dem 
Schieberegister. Ich meine, da "schiebt" man doch einen wert rein, d.h. 
je nachdem ob ich den vorne oder hinten reinschiebe, irgendwo fällt 
einer raus und irgendwo verschiebt sich doch auch der rest (?)

von Erich (Gast)


Lesenswert?

Joe F. schrieb:
> PWM kann man damit jedenfalls nicht so ohne weiteres realisieren.

zum HC259:
Warum sollte das nicht gehen?
Selbstverständlich geht das, da bei korrekter Ansteuerung jederzeit 
jeder einzelne Ausgang adressiert und gesetzt oder gelöscht werden kann.
PWM ist nichts anderes als zyklischen ein-aus.

zum Vorschlag Schieberegister mit HC595:
Eine andere Methode, die auch funktioniert.
Das ist ein doppelt gebuffertes Schieberegister.
Man schiebt also immer 8 neue Bits rein, während die alten Zustände noch 
unverändert an den Ausgangspins anstehen.
Dann erfolgt ein Übernahme-Puls, und alle Ausgänge wechseln gleichzeitig 
auf die vorher reingeschobenen neuen Werte.
Für PWM Ausgabe (einzelner Pins) sollte man sich den Ausgabezustand 
intern im uC merken bzw. eine Kopie halten.
Ist nur ein Ausgangspin zu ändern, muss man trotzdem alle 8 Bits 
rausschieben. D.h. in der internen Kopie erstellt man erst den neuen 
Zustand, beispielsweise mit UND bzw. ODER Maskierungen.
Vorteil des Schieberegisters ist, daß man solche kaskadieren kann, z.B. 
3 Stück für 24 Ausgangspins. Dann muss man immer 24 Bits (3 Byte) 
rausschieben.
Das Schieben kann bei geeignetem uC und Einstellung die "SPI" 
Schnittstelle stark vereinfachen und beschleunigen.

Wenn es nur um 8 Bit Erweiterung geht, mag das HC259 jedoch einfacher 
sein. Erweiterung auch hier möglich, ein uC Pin mehr zu einem zweiten 
HC259 "LE", restliche Eingangspins parallel.

Gruss

von General E. (generalerror)


Lesenswert?

Erich schrieb:

> Man schiebt also immer 8 neue Bits rein, während die alten Zustände noch
> unverändert an den Ausgangspins anstehen.
> Dann erfolgt ein Übernahme-Puls, und alle Ausgänge wechseln gleichzeitig
> auf die vorher reingeschobenen neuen Werte.
aaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhh... jetzt kapiere ich es :D 
.. lieben dank !! :)

von General E. (generalerror)


Lesenswert?

Hey leute.. eine frage bevor ich mich noch in was verrenne, was garnicht 
geht. Kann ich mit dem 74hc595 analoge Werte durchschicken??

.. ich will ja einem hc595 nur die R-Kathoden, mit einem anderen nur die 
G-, und mit einem dritten nur die B-Kathoden steuern. Um eine Farbe zu 
kombinieren kann ich nicht einfach den Output am hc595 auf HIGH setzen 
sondern müsste den ja z.B. auf 120 setzen können.

Geht das? oO

von Joe F. (easylife)


Lesenswert?

General E. schrieb:
> Hey leute.. eine frage bevor ich mich noch in was verrenne, was garnicht
> geht. Kann ich mit dem 74hc595 analoge Werte durchschicken??
>
> .. ich will ja einem hc595 nur die R-Kathoden, mit einem anderen nur die
> G-, und mit einem dritten nur die B-Kathoden steuern. Um eine Farbe zu
> kombinieren kann ich nicht einfach den Output am hc595 auf HIGH setzen
> sondern müsste den ja z.B. auf 120 setzen können.
>
> Geht das? oO

Nein, natürlich nicht. Wir reden hier von Digitaltechnik.
Dir ist das Prinzip von PWM offensichtlich überhaupt nicht klar.

Wenn du in deinem Arduino Programm analogWrite() aufrufst, heisst das 
nicht, dass an dem Pin ein Analogwert ausgegeben wird (das ist die 
Schei**e an dieser API). Es wird eine PWM ausgegeben, d.h. der Pin ist 
eine Weile auf 3.3V (high) und eine Weile auf 0V (low). analogWrite() 
stellt das zeitliche Verhältnis von high und low ein.
Deswegen kannst du ein solches PWM Signal weder als Eingangssignal für 
ein Latch noch für ein Schieberegister benutzen, wenn es nicht "full on" 
oder "full off" (also dauerhaft high oder low) ist.

Um eine PWM mit dem Latch oder dem Schieberegister zu erzeugen, musst du 
die Ausgänge periodisch auf 1 oder 0 setzen, das Tastverhältnis bestimmt 
dann die Helligkeit der LEDs.
Beispiel: du möchtest eine PWM mit 100 Hz erzeugen und willst 256 
Helligkeitsstufen haben.
Für die Helligkeitsstufe 50 schickst du dann 50x eine 1 und 206x eine 0, 
dann wieder 50x eine 1, 206x eine 0 usw.
Da das Schieberegister 8 Ausgänge hat, kann man damit auch gleich 8 LEDs 
individuell dimmen.
Dazu musst du das gesamte Schieberegister 100 x 256 = 25600 mal pro 
Sekunde updaten. Die hierfür nötige Bit-Clock liegt dann bei 25600 Hz x 
8 = 204.8 KHz.

Das ganze entsprechend performant zu Programmieren ist schon eher was 
für Experten.
Aber zum Glück gibt es ja Libraries:
https://github.com/elcojacobs/ShiftPWM

Vielleicht solltest du dich für den Anfang mal damit begnügen, ein paar 
LEDs am Schieberegister einfach nur ein- oder auszuschalten.
Dabei lernt man schon eine ganze Menge.

: Bearbeitet durch User
von General E. (generalerror)


Lesenswert?

Super! danke für die erklärung! :)

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.