Go Down

Topic: Vier 7 Segment Anzeigen mit 74HC595 (Read 11105 times) previous topic - next topic

n1co_7

Feb 20, 2015, 12:29 pm Last Edit: Feb 20, 2015, 12:29 pm by n1co_7
Hallo zusammen,

ich versuche gerade vier 7 Segmentanzeigen mit Hilfe von vier 74HC 595 Schieberegistern anzusteuern, um möglichst wenig Pins zu verbrauchen. Dazu habe ich im Internet eine Anleitung gefunden siehe hier.

Leider leuchten bei mir nur Segment c und d von den ersten beiden Anzeigen. Verwendet habe ich 7 Segment Anzeigen mit gemeinsamer Kathode, da ich bis gerade eben davon ausgegangen bin, dass jeweils beide Anschlüsse der 7 Segment anzeigen auf GND liegen. Nun sehe ich aber, dass einer auf 5V und einer auf GND liegt.

Mir stellt sich jetzt die Frage, welche 7 Segment Anzeigen ich hierfür verwenden muss, gemeinsame Anode oder Kathode?
Auch der Widerstand von 1,5 kOhm (ich habe 1 kOhm verwendet) kommt mir etwas viel vor, da ich sonst immer nur ca. 220 Ohm verwende.

Vielen Dank schonmal im voraus,
Nico

uwefed

#1
Feb 20, 2015, 12:41 pm Last Edit: Feb 20, 2015, 12:42 pm by uwefed
Der Sketch steuert nur 2 Segmente an da die Zahl 1 dargestellt wird.
Code: [Select]
shiftOut(dataPin1, clockPin, MSBFIRST, number[1]);
Daß nur 2 der 4 Stellen funktionieren könnte ein Schaltungsfehler sein.

Der Schaltplan ist sehr unüberssichtlich. Da laut Sketch die Segmente nicht ge-multiplext werden, muß jedes Segment einen Vorwiderstand bekommen und nicht nur die gemeinsame Katode.

Bei 4 Anzeigen würd ich einen MAX7219 wählen.

Grüße Uwe

Schachmann

#2
Feb 20, 2015, 01:00 pm Last Edit: Feb 20, 2015, 01:16 pm by Schachmann Reason: Hatte was vergessen :)
Hallo Nico,

die Pins 3 und 8 der LED-Module sind intern verbunden. Wenn man sich die erste Breadboard-Grafik in Deinem Link anschaut, sieht man, dass sie oben über den Widerstand an +5V und unten über den Widerstand an GND angeschlossen sind. Das kann so überhaupt nicht funktionieren. Wenn ich mich nicht vollständig irre, ist einfach die Schaltung komplett falsch.

Wie das auf das Wesentliche reduziert aussieht, habe ich Dir als Bild angehängt. Macht keinen Sinn, aber die Widerstände warm und die Batterie leer :-)

Die LED-Module gibt es entweder mit gemeinsamer Anode oder gemeinsamer Kathode. Aber nicht auf der einen Seite Anode und auf der anderen Seite Kathode.

Ich habe so eine Schaltung mal mit einem SAA1064 aufgebaut, der aber leider nicht mehr erhältlich ist. Falls Dich die Vorgehensweise von damals trotzdem interessiert, hier der Link: Mit SAA1064

Falls Du wirklich die Shift-Register verwenden willst, wäre hier eine Erklärung, wie die anzuschließen und anzusteuern sind: 74HC595

Aber ich würde etwas "Moderneres" empfehlen, z.B. den MCP23017 (entweder zwei oder die Displays multiplexen): MCP23017

Gruß,
Ralf

sschultewolter

Würde dir auch zum Max7219 raten. Schau am besten in Bucht nach Matrixmodulen um. Dort gibt es die als Komplettset zum selber löten. Matrix weglegen und nur den Max7219 nutzen, dann ist der auch günstig.

Das Tutorial ist eines von vielen, die zeigt wie es nicht geht. Bei dem 74HC595 spielt es keine Rolle, ob du 7-Segment Anzeigen mit gemeinsamer Kathode oder gemeinsamer Anode verwendest.

Code: [Select]

HC595 -  I>|  - GND  // Leuchtet wenn HC595 Pin HIGH
HC595 -  |<I  - VCC  // Leuchtet wenn HC595 Pin LOW


Bedenke aber, wenn du das so machst (ohne Multiplexing), dass ud Widerstände entsprechend anpasst. Hier kannst du nicht für jede Led 20mA rechen, dass schafft der HC595 gerade so, ist aber ausserhalb der Spezifikation.
Orginal Atmel AVRISP mkII zu verkaufen. Anfrage per PN ;)

maddi

Es gibt in der Bucht auch den MAX7219 mit 2x 4fach 7-Segment-Anzeigen, entweder als Fertigmodul (ca 80x16mm) oder zum Zusammenlöten, damit wären ev. auch eigene (ähnliche) 7-Segment-Anzeigen recht aufwandarm zu betreiben.

Serenifly

Man kann bei sowas auch nur ein Schieberegister nehmen und die Anzeigen mit Transistoren multiplexen. Das ist weit weniger Hardware Aufwand. Da braucht man die Segmentvorwiderstände auch nur einmal und nicht für jede Anzeige (aber immer noch für die einzelnen Segmente!)
 
Um mehr Strom zu haben empfiehlt sich auch ein UDN2981 als Treiber (PNP da gemeinsame Kathode). Den kann man direkt 1:1 zwischen Schieberegister und LEDs hängen.

So:
http://i.stack.imgur.com/KeSUJ.gif
Und bei "Port 2" hängt man Schieberegister + UDN hin

n1co_7

#6
Feb 21, 2015, 03:29 pm Last Edit: Feb 21, 2015, 03:30 pm by n1co_7
Vielen Dank für die zahlreichen Antworten  :)

Also ich werde das jetzt zunächst einmal mit den Schieberegistern versuchen, weil ich da alles da habe an Hardware und ich mich da schon recht gut eingearbeitet habe (ist mein erstes Projekt).

Entstehen soll am Ende eine Spielstandsanzeige für meinen Fußballverein.

Wie genau sind denn die Sekunden wenn ich diese ganz normal mit ShiftOut am 74HC595 ansteuere und anschließend delay(1000) für eine Sekunde mache?

Das einfachste wäre z.B. für mich, die 7 Segmentanzeigen einzeln anzusteuern und dann für:
- 1 Sekunde: delay(1000)
- 10 Sekunden: delay (10000)
- 1 Minute: delay(60000)
- 10 Minuten: delay(600000)

Alternatov würde ich mit Schleifen arbeiten und dann nur mit Sekunden (delay(1000)) arbeiten.

Edit: Habe nun den Arduino Mega, weshalb ich mir nicht mehr so viele Sorgen um die Anzahl der Pins mache.

Danke nochmals!

Serenifly

Die Schiebregister sind in Reihe geschaltet! Das heißt du musst immer die Daten für alle Segmente hintereinander rausschieben.

Also jede Sekunden die Zeit in ihre Ziffern teilen und dann alle hintereinander ausgeben.

sschultewolter

Vielen Dank für die zahlreichen Antworten  :)

Also ich werde das jetzt zunächst einmal mit den Schieberegistern versuchen, weil ich da alles da habe an Hardware und ich mich da schon recht gut eingearbeitet habe (ist mein erstes Projekt).

Entstehen soll am Ende eine Spielstandsanzeige für meinen Fußballverein.

Wie genau sind denn die Sekunden wenn ich diese ganz normal mit ShiftOut am 74HC595 ansteuere und anschließend delay(1000) für eine Sekunde mache?
1000ms + benötigte Zeit für das rausschicken der Daten

Das einfachste wäre z.B. für mich, die 7 Segmentanzeigen einzeln anzusteuern und dann für:
- 1 Sekunde: delay(1000)
- 10 Sekunden: delay (10000)
- 1 Minute: delay(60000)
- 10 Minuten: delay(600000)

Alternatov würde ich mit Schleifen arbeiten und dann nur mit Sekunden (delay(1000)) arbeiten.

Edit: Habe nun den Arduino Mega, weshalb ich mir nicht mehr so viele Sorgen um die Anzahl der Pins mache.

Danke nochmals!
Den Vorschlag direkt vergessen! Schau dir BlinkWithoutDelay an.
Orginal Atmel AVRISP mkII zu verkaufen. Anfrage per PN ;)

Serenifly

Und zur Hardware nochmal um das deutlich zu machen:

Du brauchst für jedes Segment einer Anzeige einen LED-Vorwiderstand! Also 7 oder 8 pro Segment (je nachdem ob du den Punkt anschließt). Ein Widerstand pro Segment am gemeinsamen Anschluss geht nicht!

nix_mehr_frei

Entstehen soll am Ende eine Spielstandsanzeige für meinen Fußballverein.
Dann guck dir mal mein Projekt hier an: http://forum.arduino.cc/index.php?topic=207948.0
Ist ebenfalls mit Schieberegistern realisiert und die Ziffern sind in der Größe frei skalierbar und für eine Spielstandsanzeige von der Größe und Helligkeit her absolut perfekt  :D

Gruß Gerald



rot ist blau und Plus ist Minus

n1co_7

Dann guck dir mal mein Projekt hier an: http://forum.arduino.cc/index.php?topic=207948.0
Ist ebenfalls mit Schieberegistern realisiert und die Ziffern sind in der Größe frei skalierbar und für eine Spielstandsanzeige von der Größe und Helligkeit her absolut perfekt  :D

Gruß Gerald
Wow, schaut echt super aus! So in der Art habe ich das auch vor, habe aber noch fragen zu den LED strips.
Du schreibst ja, dass die sehr hell sind, aber im Zimmer ist ja ne andere Umgebung als draußen, wenn die Sonne scheint. Wieviel Lumen haben die LEDs denn und kann man die auch bei "Tageslicht" sehen?

Den Vorschlag direkt vergessen! Schau dir BlinkWithoutDelay an.
Danke, habs durch ausprobieren nun auch realisiert, dass es so doch nicht geht. Werd mich jetzt an deinem Vorschlag versuchen :)

n1co_7

Hab jetzt mal versucht diese Schaltung aufzubauen:


Der dazugehörige Code:
Code: [Select]
#define LATCH 4
#define CLK 3
#define DATA 2

//Binary numbers from 0 to 9
byte digitOne[10]= {B0000001, B1001111, B0010010, B0000110, B1001100, B0100100, B0100000, B0001111, B000000, B0001100};
byte digitTwo[10]= {B0000001, B1001111, B0010010, B0000110, B1001100, B0100100, B0100000, B0001111, B000000, B0001100};

int i;
int j;

void setup(){
 
  pinMode(LATCH, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
 
}

void loop(){
 
  for(int i=0; i<10; i++){
    for(int j=0; j<10; j++){
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[i]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[j]); // digitOne
      digitalWrite(LATCH, HIGH);
      delay(500);
    }
  }
}


Alles von dieser Quelle

Leider leuchten bei mir alle Segmente, anstatt dass es von 0 bis 99 zählt. Woran könnte der Fehler liegen?

n1co_7

Okay, ich habe mich nochmal versucht  :D Funktioniert aber immer noch nicht richtig.
Habe jetzt für jedes Digit 7 LED Lämpchen angeschlossen und habe diese über die 74HC595 Schieberegister angesteuert. Leider funktionieren aber nur die ersten beiden Digits richtig. Wird daran liegen, dass ich ein Beispiel für 2 Digits genommen habe und versucht habe, diesen umzuschreiben, funktioniert aber wie gesagt nicht (es funktioniert nur die ersten beiden Digits).

Code: [Select]

//**************************************************************//
//  Name    : shiftOutCode, Predefined Dual Array Style         //
//  Author  : Carlyn Maw, Tom Igoe                              //
//  Date    : 25 Oct, 2006                                      //
//  Version : 1.0                                               //
//  Notes   : Code for using a 74HC595 Shift Register           //
//          : to count from 0 to 255                            //
//****************************************************************

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

//holders for infromation you're going to pass to shifting function
byte dataBLUE;
byte dataGREEN;
byte dataRED;
byte dataWHITE;
byte dataArrayBLUE[10];
byte dataArrayGREEN[10];
byte dataArrayRED[10];
byte dataArrayWHITE[10];

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  Serial.begin(9600);

  dataArrayBLUE[0] = B1111110; //0
  dataArrayBLUE[1] = B0110000; //1
  dataArrayBLUE[2] = B1101101; //2
  dataArrayBLUE[3] = B1111001; //3
  dataArrayBLUE[4] = B0110011; //4
  dataArrayBLUE[5] = B1011011; //5
  dataArrayBLUE[6] = B1011111; //6
  dataArrayBLUE[7] = B1110000; //7
  dataArrayBLUE[8] = B1111111; //8
  dataArrayBLUE[9] = B1111011; //9

  dataArrayGREEN[0] = B1111110; //0
  dataArrayGREEN[1] = B0110000; //1
  dataArrayGREEN[2] = B1101101; //2
  dataArrayGREEN[3] = B1111001; //3
  dataArrayGREEN[4] = B0110011; //4
  dataArrayGREEN[5] = B1011011; //5
  dataArrayGREEN[6] = B1011111; //6
  dataArrayGREEN[7] = B1110000; //7
  dataArrayGREEN[8] = B1111111; //8
  dataArrayGREEN[9] = B1111011; //9
 
  dataArrayRED[0] = B1111110; //0
  dataArrayRED[1] = B0110000; //1
  dataArrayRED[2] = B1101101; //2
  dataArrayRED[3] = B1111001; //3
  dataArrayRED[4] = B0110011; //4
  dataArrayRED[5] = B1011011; //5
  dataArrayRED[6] = B1011111; //6
  dataArrayRED[7] = B1110000; //7
  dataArrayRED[8] = B1111111; //8
  dataArrayRED[9] = B1111011; //9
 
  dataArrayWHITE[0] = B1111110; //0
  dataArrayWHITE[1] = B0110000; //1
  dataArrayWHITE[2] = B1101101; //2
  dataArrayWHITE[3] = B1111001; //3
  dataArrayWHITE[4] = B0110011; //4
  dataArrayWHITE[5] = B1011011; //5
  dataArrayWHITE[6] = B1011111; //6
  dataArrayWHITE[7] = B1110000; //7
  dataArrayWHITE[8] = B1111111; //8
  dataArrayWHITE[9] = B1111011; //9

  //function that blinks all the LEDs
  //gets passed the number of blinks and the pause time
  blinkAll_4Bytes(2,500);
}

void loop() {


  for (int j = 0; j < 6; j++) {
    for (int k = 0; k < 10; k++) {
      for (int l = 0; l < 6; l++) {
        for (int m = 0; m < 10; m++) {
    //load the light sequence you want from array
    dataBLUE = dataArrayBLUE[m];
    dataGREEN = dataArrayGREEN[l];
    dataRED = dataArrayRED[k];
    dataWHITE = dataArrayWHITE[j];
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    //move 'em out
    shiftOut(dataPin, clockPin, dataGREEN);   
    shiftOut(dataPin, clockPin, dataBLUE);
    shiftOut(dataPin, clockPin, dataRED);
    shiftOut(dataPin, clockPin, dataWHITE);
    //return the latch pin high to signal chip that it
    //no longer needs to listen for information
    digitalWrite(latchPin, 1);
    delay(1000);
  }}}}
}



// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out MSB first,
  //on the rising edge of the clock,
  //clock idles low

  //internal function setup
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  //for each bit in the byte myDataOut�
  //NOTICE THAT WE ARE COUNTING DOWN in our for loop
  //This means that %00000001 or "1" will go through such
  //that it will be pin Q0 that lights.
  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);

    //if the value passed to myDataOut and a bitmask result
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {
      pinState= 0;
    }

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin 
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
  }

  //stop shifting
  digitalWrite(myClockPin, 0);
}


//blinks the whole register based on the number of times you want to
//blink "n" and the pause between them "d"
//starts with a moment of darkness to make sure the first blink
//has its full visual effect.
void blinkAll_4Bytes(int n, int d) {
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  digitalWrite(latchPin, 1);
  delay(200);
  for (int x = 0; x < n; x++) {
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, 255);
    shiftOut(dataPin, clockPin, 255);
    shiftOut(dataPin, clockPin, 255);
    shiftOut(dataPin, clockPin, 255);
    digitalWrite(latchPin, 1);
    delay(d);
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, 0);
    shiftOut(dataPin, clockPin, 0);
    shiftOut(dataPin, clockPin, 0);
    shiftOut(dataPin, clockPin, 0);
    digitalWrite(latchPin, 1);
    delay(d);
  }
}     

nix_mehr_frei

Guck dir mal den Aufbau von Paul auf dieser Seite an. Er dokumentiert Hard- & Sofware
http://www.sqlskills.com/blogs/paulselec/post/arduino-cascading-shift-registers-to-drive-7-segment-displays.aspx
Er hat nur die Widerstände für die Segmente nicht eingezeichnet.
MR der Schieberegister habe ich von allen Registern verbunden und resette alle gleichzeitig beim Einschalten über ein RC-Glied, wie beim Reset vom ATMEGA. Nur umgekehrt, das der Widerstand auf Masse geht und der Kondensator (100n) auf +.
Hast du über jedem 595 einen 100n Kondensator? Die sind wichtig und sollen kürzestmöglich die Betriebsspannung abblocken. Ich lege die Scheibe diagonal aufs IC und löte die Anschlüsse direkt an die Pins an.
Für die 4 Schieberegister ist nochmals ein gemeinsamer Elko von 47µF eine gute Wahl.
So wie beschrieben habe ich meine 6 stellige Uhr aufgebaut. Von 4 auf 6 skalieren war kein Problem. Ich habe Pauls Code ebenfalls als Basis genommen. Meinen abgewandelten Code habe ich ebenfalls hochgeladen. Hat bei mir auf Anhieb funktioniert. Andere Sonderzeichen kannst du nach Pausl Schema ebenfalls als Arry selbst definieren.
rot ist blau und Plus ist Minus

Go Up