Forum: Mikrocontroller und Digitale Elektronik 7-Segment Anzeige 3-3tellig


von artur (Gast)


Lesenswert?

Hallo,

kennt jemand eine 3-stellige 7-Segment Anzeige, Ziffernhöhe 14mm, 
Rot/Orange, die zu empfehlen ist?

ich habe eine gefunden, das Problem ist, die benachbarte, nicht 
angesteuerte Segmente leuchten leicht mit.

Gruß Artur

von Karl H. (kbuchegg)


Lesenswert?

Zeig mal dein Programm.

Ich denke eher du hast einen Programmfehler gemacht und Ghosting 
produziert.

von Martin V. (oldmax)


Lesenswert?

Hi
Dann machst du etwas falsch. Daher meine Frage: steuerst du sie mit 
einem eigenen Programm an ? Dann ist die Multiplexroutine vielleicht 
falsch aufgebaut. Folgende Vorgehensweise hat sich bewährt:
Gemeinsamen ausschalten
Neues Bitmuster an die Segmente legen
nächste Stelle selektieren gemeinsamen einschalten.
1 mSek. warten, dann wieder von vorn
Wichtig ist das Abschalten vor der Beschaltung der Segmente.
Gruß oldmax

von m.n. (Gast)


Lesenswert?

Statische Ansteuerung wäre auch eine Möglichkeit.
Beitrag "7-Segm.-LED-Anzeige, 6-stellig, statische Ansteuerung mit (74HC)4094"

von artur (Gast)


Lesenswert?

Martin,

ich bin mir nicht mehr sicher, wie ich die beschreibe. In jedem fall 
wird zeitlich gemultiplext.

Das projekt ist seit einem halben Jahr in Wartestellung. Den Code habe 
ich gerade nicht da.

Vielen Dank schon mal, ich werde heute Abend mal nachschauen!

von artur (Gast)


Lesenswert?

Gibt es vielleicht auch Blschöne Blenden für 3-stellige Anzeigen?
Klar, eins nach dem Anderen, aber muss schnell gehen))

bei Reichelt und Conrad nichts gefunden.

von Karl H. (kbuchegg)


Lesenswert?

Martin Vogel schrieb:
> Hi
> Dann machst du etwas falsch. Daher meine Frage: steuerst du sie mit
> einem eigenen Programm an ? Dann ist die Multiplexroutine vielleicht
> falsch aufgebaut. Folgende Vorgehensweise hat sich bewährt:
> Gemeinsamen ausschalten

@artur

und drauf achten, dass auch wirklich ausgeschaltet wird und nicht 
irrtümlich eingeschaltet. Denn dieser Fehler würde isch genau so 
bemerkbar machen, wie du es beschrieben hast. Alle eigentlich nicht 
leuchtenden Segmente glimmen ganz leicht vor sich hin.

von artur (Gast)


Lesenswert?

Ich werde das mit dem Programm in jedem Fall mal checken.

Aber an sich glaube ich dass es eher "Lichtverschmutzung" ist, also 
wirklich das Licht der benachbarten Segmente rüberschwappt.

von Karl H. (kbuchegg)


Lesenswert?

Eher unwahrscheinlich. Etwas lichtdicht zu bekommen, wie zb den 
Zwischenraum zwischen 2 LED, ist recht einfach. 7-Segment Anzeigen sind 
zu lange am Markt, als das da ein Hersteller schlampen würde.

Wegen Blenden.
Es gibt solche BLenden
http://www.conrad.com/ce/de/product/185370/Frontrahmen-fuer-Digital-Anzeigen-Mentor-26568422-Schwarz-RotL-x-B-28-mm-x-64-mm-Ausschnitt-innen-515-x-15-mm?ref=searchDetail

mit etwas Geschick kann man aber auch aus eingefärbtem Filterscheiben 
was bauen.
http://www.conrad.com/ce/de/product/185230/Farbfilterscheibe-fuer-Frontrahmen-Best-Nr-18-55-15-Strapubox-FS41-Rot-Farbe-Rot-transparent?ref=list

von artur (Gast)


Lesenswert?

Danke Karl Heinz, über die bin ich auch schon gestolpert.
Die sind wie es scheint für 4-stellige Anzeigen - eine Stelle zu breit.

von artur (Gast)


Lesenswert?


von Dietrich L. (dietrichl)


Lesenswert?

artur schrieb:
> Aber an sich glaube ich dass es eher "Lichtverschmutzung" ist, also
> wirklich das Licht der benachbarten Segmente rüberschwappt.

Das kannst Du ja damit testen, indem Du Segmente fest über Widerstände 
direkt einschaltest. Ist der Kontrast dann besser, liegt es am Timing 
des Multiplexers.

Gruß Dietrich

von artur (Gast)


Angehängte Dateien:

Lesenswert?

Hallo nochmal,

anbei mal ein Bild.
Das Leuchten kommt denke ich vom reflektierenden Hintergrund zustande.

hier für alle Fälle mein Code (ich hoffe es liegt an ihm)):
1
  d++;
2
  if(d == 30)
3
  {
4
    if(is_state_km)  //Geschwindigkeitsanzeige oder km-Stand
5
    {
6
      if(main_state == state_Gesamt_km2)
7
      {
8
        if(is_zero && (zahl < 100))
9
          PORTD &= ~(1<<PNP_100);         //PD2 aus --- Hunderterstelle
10
        else
11
          PORTD |= (1<<PNP_100);
12
      }
13
      else
14
      {
15
        if(zahl < 100)
16
          PORTD &= ~(1<<PNP_100);
17
        else
18
          PORTD |= (1<<PNP_100);
19
      }
20
    }
21
    else
22
      PORTD |= (1<<PNP_100);         //PD2 an --- Hunderterstelle
23
24
    PORTB  = Zahl[Hunderter];
25
26
    if(Zahlenart == DEZIMAL2)
27
      PORTB &= ~(1<<DP);    //DP ON
28
    else
29
      PORTB |= (1<<DP);    //DP OFF
30
31
    PORTD &= ~(1<<PNP_1);
32
    PORTD &= ~(1<<PNP_10);
33
34
  }
35
  if(d == 60)
36
  {
37
    if(is_state_km)  //Geschwindigkeitsanzeige oder km-Stand
38
    {
39
      if(zahl < 10)
40
        PORTD &= ~(1<<PNP_10);
41
      else
42
        PORTD |= (1<<PNP_10);
43
    }
44
    else
45
      PORTD |= (1<<PNP_10);         //PD1 an --- Zehnerstelle
46
47
48
    PORTB  = Zahl[Zehner];
49
50
    if(Zahlenart == DEZIMAL1)
51
      PORTB &= ~(1<<DP);    //DP ON
52
    else
53
      PORTB |= (1<<DP);    //DP OFF
54
55
56
    PORTD &= ~(1<<PNP_1);
57
    PORTD &= ~(1<<PNP_100);
58
59
  }
60
  if(d == 90)
61
  {
62
    if(main_state == state_Gesamt_km1 && is_zero)
63
      PORTD &= ~(1<<PNP_1);         //PD0 aus --- Einerstelle
64
    else
65
      PORTD |= (1<<PNP_1);      //PD0 an --- Einerstelle
66
67
68
    PORTB  = Zahl[Einer];
69
70
    PORTB |= (1<<DP);    //DP OFF
71
72
    PORTD &= ~(1<<PNP_10);
73
    PORTD &= ~(1<<PNP_100);
74
75
    d = 0;
76
  }

von Karl H. (kbuchegg)


Lesenswert?

Ich bin mir recht sicher, dass es an deinem Code liegt. Du provozierst 
ghosting. Deine Reihenfolge beim Umschalten der Stellen stimmt nicht.

Aber lass mich das erst mal auseinander sortieren. Dieser ganze 
Multiplex muss anders gemacht werden. Das wichtigste ist erst mal die 
Trennung der Multiplex-Anzeigensteuerung von dem was anzuzeigen ist. 
Diese ganze Steuerung mit dem d ist nicht vernünftig gelöst.

Gib mir mal ein bischen mehr von deinem COde

Zahl?
Einer?
Zehner?
Hunderter?

Am PORTD sind offenbar die Stellentreiber. Mit einer 0 am Pin schaltet 
man die betreffende Stelle aus?
am PORTB sind offenbar die Segmenttreiber. Würde eine Ausgabe von 0x00 
alle Stellen abschalten oder anschalten? Ich denke mal anschalten, wenn 
ich nach der Behandlung des Dezimalpunktes gehe.

Was hast du noch in deinem Code?
Werden Timer benutzt?

: Bearbeitet durch User
von artur (Gast)


Angehängte Dateien:

Lesenswert?

An PORTD sind Transistoren...mach ich mal ein Bild))

Zahl und der Rest:
1
//Hier kann man den Code an seine Siebensegment Anzeige anpassen
2
const unsigned char Zahl[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
3
uint8_t Hunderter = 0;
4
uint8_t Zehner    = 0;
5
uint8_t Einer     = 0;
6
7
void Ziffern_calc(float Wert, uint8_t Zahlenart)
8
{
9
  if(Zahlenart == DEZIMAL1)    //Eine Stelle nach dem Komma
10
  {
11
    Hunderter   = Wert/10;
12
    Zehner      = (Wert - Hunderter*10);
13
    Einer       = (Wert - Hunderter*10 - Zehner)*10;
14
  }
15
  else if(Zahlenart == DEZIMAL2)  //Zwei Stellen nach dem Komma
16
  {
17
    Hunderter = Wert;
18
    Zehner    = (Wert - Hunderter)*10;
19
    Einer     = (Wert - Hunderter)*100 - Zehner*10;
20
  }
21
  else              //Ganze Zahlen
22
  {
23
    Hunderter = Wert/100;
24
    Zehner    = (Wert - Hunderter*100)/10;
25
    Einer     = Wert - Hunderter*100 - Zehner*10;
26
  }
27
}

von artur (Gast)


Lesenswert?

Ja, Timer werden benutzt, mit den anderen Vermutungen hast Du recht

von MaWin (Gast)


Lesenswert?

> Eher unwahrscheinlich. Etwas lichtdicht zu bekommen, wie zb den
> Zwischenraum zwischen 2 LED, ist recht einfach.

Theoretisch schon, aber viele 7-Segment-LED-Anzeigenhersteller
schaffen es trotzdem, das zu vergeigen.
Nur mal als Beispiel diese dämlichen Lichtschächte von Mentor
http://www.mentor-bauelemente.de/de/aktuelles/produktneuheiten/mentor-meldet-7-segmentanzeigen-mit-stufenlos-variablen-hoehen-zum-patent/
die sind aus WEISSEM Kunststoff, durchscheinend schon bei
moderatem Licht.

von artur (Gast)


Lesenswert?

auf dem Foto mit den Anzeigen, sieht man, dass sie bis auf die Platte 
leuchtet - und wenn Licht wo raus geht, kann es reflektierenderweise 
auch in die anderen Segmente dachte ich.

Für Verbesserungen am Programmierstil bin ich aber immer offen

von Conny G. (conny_g)


Lesenswert?

... artur hat anscheinend vor Verzweiflung schon in die 
Lochrasterplatine gebissen. :-)

von guter Rat (Gast)


Lesenswert?

Ich würde die Helligkeit der Anzeigen reduzieren. Bei 47 Ohm pro Segment 
ergeben sich mehr als 50mA. Auch wenn jede Stelle nur 1/3 der Zeit 
leuchtet ist das bei den heutigen hocheffizienten LED Displays ziemlich 
grenzwertig. 100 Ohm würden es auch tun evtl sogar 220 Ohm.

von Karl H. (kbuchegg)


Lesenswert?

Man sieht aber auch, dass die einzelnen Segmente, zb in der 
Hunderterstelle nicht gleichmässig leuchten. Ein Teil kommt 
wahrscheinlich von der Platine über die Reflexion. EIn Teil ist aber 
definitiv durch das Multiplexen entstanden, denn du schaltest die Stelle 
ab und die nächste ein, während noch die alte Belegung am Port B 
anliegt. D.h. die Zehnerstelle zeigt ganz kurz noch das Bild der 
Hunderterstelle an, ehe dann die Segmentbelegung der Zehnerstelle 
ausgegeben wird.

Die Sache mit der Rückreflexion kannst du ja testen. Schieb ein scharzes 
Stück Papier (oder Karton) zwischen Anzeige und Platine rein. LED werden 
nicht heiss, damit kann da nix passieren und abbrennen. Aber das 
schwarze Papier verschluckt die Rückreflexion.

von artur (Gast)


Lesenswert?

Conny G. schrieb:
> ... artur hat anscheinend vor Verzweiflung schon in die
> Lochrasterplatine gebissen. :-)

so ist das)) habs zuerst aufm Board aufgebaut. Dann reverse engeneert 
und sogar in Eagle reingeklopft

@guter Rat:
das Ding soll auch bei Tageslicht lesbar sein. Hab alle 
Helligkeitsstufen durch)

unter die Anzeige auch mal Schwarzband druntergeschoben.
Als nächstes werd ich wohl die Rückseite betonieren...

von Karl H. (kbuchegg)


Lesenswert?

artur schrieb:

> @guter Rat:
> das Ding soll auch bei Tageslicht lesbar sein. Hab alle
> Helligkeitsstufen durch)

Wobei:
man soll es nicht für möglich halten, um wieviel besser 7-Segment 
Anzeigen ablesbar werden, wenn dann erst mal eine entsprechende 
Filterfolie vor der Anzeige sitzt.


So. Jetzt mach ich dir erst mal ein Testprogramm mit einem sauberen 
Multiplex zurecht. Mal sehen um wieviel dann das Fremdleuchten zurück 
geht.

: Bearbeitet durch User
von artur (Gast)


Angehängte Dateien:

Lesenswert?

Werde auch mal den Test von Dietrich L. machen.


Was ist denn richtige Reihenfolge KH?

Hab mal ne zweite Anzeige aufgetrieben und die Rücksite abgeknipst.

von artur (Gast)


Lesenswert?

Filterfolie wird morgen gekauft...

von Karl H. (kbuchegg)


Lesenswert?

artur schrieb:
> Werde auch mal den Test von Dietrich L. machen.
>
>
> Was ist denn richtige Reihenfolge KH?

Erst die gerade leuchtende stelle komplett abstellen. In deinem Fall 
müsste es reichen an PORTB eine 0xFF zuzuweisen.

DANN die nächste Stelle mit den Pins am Port D zu aktivieren.
DANN am PORTB das Muster für diese Stelle ausgeben.


Aber der Auftakt beim Umschalten in die nächste Stelle besteht darin, 
dass die Anzeige (wenn auch nur für ein paar Nanosekunden) komplett 
dunkel gemacht wird. Wenn die nächste Stelle dann aktiviert wird, dann 
muss dort auch schon das korrekte Muster für diese Stelle aktiv sein.


In einem Timer Interrupt würde das zb so aussehen
1
// enthält die an einer Stelle auszugebenden 7_Segment Muster. Und zwar
2
// schon so aufbereitet, dass sie nur noch ausgegeben werden müssen
3
volatile uint8_t Pattern[3];
4
uint8_t patternMultiplex;
5
6
uint8_t digitCode[] = { 1 << PNP_100, 1 << PNP_10, 1 << PNP_1 };
7
8
// multiplexen im Timer-Interrupt
9
ISR( TIMER0_OVF_vect )
10
{
11
  // alles aus
12
  PORTD &= ~( ( 1 << PNP_100 ) | ( 1 << PNP_10 ) | ( 1 << PNP_1 ) );
13
14
  // welches ist die nächste auszugebende Stelle?
15
  patternMultiplex++;
16
  if( patternMultiplex == 3 )
17
    patternMultiplex = 0;
18
19
  // dann die Segmenttreiber entsprechend einstellen. Noch kann nichts
20
  // leuchten, weil ja noch kein Stellentreiber aktiv ist. Die sind ja
21
  // noch abgestellt
22
  PORTB = Pattern[ patternMultiplex ];
23
24
  // aber jetzt: die Segmentleitungen für die nächste Stelle sind alle korrekt
25
  // die Stelle auch tatsächlich aktivieren.
26
  PORTD |= digitCode[ patternMultiplex ];
27
28
  // die nächste Stelle leuchtet jetzt. Bye, bye bis zum nächsten Interrupt
29
}

in der Timer ISR werden reihum alle Stellen eine nach der anderen 
ausgegeben. Die Sequenz beginnt damit, dass die bestehende Anzeige 
abgeschaltet wird. Dann wird das Muster für die nächste anzuzeigende 
Stelle eingestellt und diese Stelle aktiviert.
Damit ist der Interrupt fertig bearbeitet. Bis zum nächsten Aufruf der 
ISR leuchtet jetzt diese Stelle.

Dazu braucht es natürlich einen Timer.
Das ist nicht besonders zeitkritisch. Solange die Frequenz nur hoch 
genug ist, dass nichts flimmert.
1
...
2
  TIMSK |= (1<<TOIE0);
3
  TCCR0 = (1<<CS01);    // Vorteiler 8, jetzt zählt der Timer bereits
4
...
5
6
  OutputNumber( 0 );
7
...
8
9
  // jetzt gilts. AB jetzt ist die 7_Segment aktiv und zeigt etwas an.
10
  sei();
11
12
  while( 1 )
13
    ...

Beachte: die ISR macht nicht mehr lange rum mit irgendwelchen Codes für 
Zahlen oder dergleichen. Die ISR gibt einfach nur die Muster an die 
7-Segment aus, die ihr irgendwer im Array 'Pattern' hinterlassen hat.

Natürlich ist 'irgendwer' nicht einfach irgendwer. Sondern eine Funktion 
die eine Zahl entsprechend aufbereitet. Und noch was. Es ist sinnvoll 11 
'Ziffern' zu benutzen. 10 Ziffern für die normalen Zahlen 0 bis 9. DIe 
11-te hingegen ist eine Ziffer, die nichts anzeigt. Genau sie wird 
benutzt um führende 0-en zu unterdrücken. Das ist etwas, worum sich die 
ISR nicht selbst kümmert. Und auch nicht kümmern soll. Auch das macht 
die Funktion, die eine Zahl (welche auch immer das ist) aufbereitet. 
Genauso wie diese Funktion den Dezimalpunkt in das Ausgabemuster 
einbaut.
1
void OutputNumber( uint16_t number )
2
{
3
  uint8_t Einer, Zehner, Hunderter;
4
5
  Hunderter = number % 100;
6
  number = number / 10;
7
8
  Zehner = number % 10;
9
  Einer = number / 10;
10
11
  Pattern[2] = Zahl[number];
12
13
  if( Zehner != 0 && Hunderter != 0 )
14
    Pattern[1] = Zahl[Zehner];
15
  else
16
    Pattern[1] = Zahl[10];    // führende 0 ausblenden mit einem Spezialzeichen
17
18
  if( Hunderter != 0 )
19
    Pattern[0] = Zahl[Hunderter];
20
  else
21
    Pattern[0] = Zahl[10];    // führende 0 ausblenden mit einem Spezialzeichen
22
}

Der springende Punkt ist, dass der Timer die Multiplexausgabe alleine 
macht. Der schaufelt nur die Muster raus, sonst nichts.
Wenn immer es gilt eine Zahl auszugeben, wo auch immer die herkommt oder 
wie auch immer die entsteht, dann wird die Funktion OutputNumber 
aufgerufen, die die entsprechenden auszugebenden Muster bestimmt und für 
die ISR hinterlegt.

Der Bereitstellungscode kmmert sich nicht darum, wie technisch genau das 
funktioniert, dass die Anzeigen beschickt werden. Und der eigentliche 
Multiplex-Code kümmert sich nicht darum, was die Muster bedeuten, die er 
an die Anzeigen ausgibt. Wenn ihm beim Startup irgendein Code zb 3 
Stück'-' anzeigen lässt, dann ist das dem Multiplexcode auch wurscht. 
Der schaufelt nur noch Muster an die Anzeigen.

: Bearbeitet durch User
von artur (Gast)


Lesenswert?

Vielen Dank für die ausfühliche Antwort Karl Heinz!

Ich werde mir morgen die Mühe machen Deinen UND meinen Code durchzusehen 
und anzupassen.

Ein wichtiger Punkt ist, dass ich die Timer ISR nivht ausschliesslich 
für die Ausgabe der Anzeige benutze. In erster Linie für eine 
Blinkfunktion. Aus Mangel an Timern und Auflösung habe ich die Ausgabe 
auch in diese Routine gepackt.
Punkt ist aber, dass ich die Stellen trotzdem in einem Festen Zyklus und 
in einer festen Reihenfolge ausgebe (eben durch die Variable 
d=30,60,90).

Ich schick mal die ganze ISR und werde mich Deinem Code morgen zuwenden. 
Dein Beispiel st wirklich interessant!
1
ISR(TIMER2_OVF_vect)  //Blinker, Aktualisierung der Geschwindigkeit, ADC und Ausgabe --------- alle ca. 256µs
2
{
3
  i++;
4
  if(i == 1800)  //bei 1800*256=460800 und Prescaler=1 --> 57344*0.000008=0.46sec
5
  {
6
    PORTD ^= (1<<BLINKER);    //Blinker toggle
7
    
8
    if(n_turns > 0)
9
    {
10
      TCNT_avrge = TCNT_sum / n_turns;
11
      f_Welle = f_TIMER1 / TCNT_avrge;
12
    }
13
    else
14
      f_Welle = 0;  //Also steht das Rad
15
16
    //Variablentausch
17
    f_Welle_array[0] = f_Welle_array[1];
18
    f_Welle_array[1] = f_Welle_array[2];
19
    f_Welle_array[1] = f_Welle;
20
21
    //Durchschnitt ueber drei Werte und alle 0.92sec
22
    n_turns_i++;
23
    if(n_turns_i == 2)
24
    {
25
      f_Welle_avrge = (f_Welle_array[0] + f_Welle_array[1] + f_Welle_array[2]) / 3;
26
      n_turns_i = 0;
27
    }
28
29
    i = 0;
30
    n_turns = 0;
31
    TCNT_sum = 0;
32
  }
33
34
  if(main_state == state_U_Bat)
35
  {
36
    j++;
37
    if(j == 1850)  
38
      ADCSRA = (1<<ADEN) | (1<<ADSC);
39
    if(!(ADCSRA & (1<<ADSC)) && (j > 1850))
40
    {
41
      ADC_result = ADC;
42
      ADCSRA &= ~(1<<ADEN);  //Energie sparen))            
43
      j = 0;              
44
    }
45
  }
46
47
  
48
  d++;
49
  if(d == 30)
50
  {
51
    if(is_state_km)  //Geschwindigkeitsanzeige oder km-Stand
52
    {
53
      if(main_state == state_Gesamt_km2)
54
      {
55
        if(is_zero && (zahl < 100))
56
          PORTD &= ~(1<<PNP_100);         //PD2 aus --- Hunderterstelle
57
        else
58
          PORTD |= (1<<PNP_100);
59
      }
60
      else
61
      {
62
        if(zahl < 100)
63
          PORTD &= ~(1<<PNP_100);
64
        else
65
          PORTD |= (1<<PNP_100);
66
      }
67
    }
68
    else
69
      PORTD |= (1<<PNP_100);         //PD2 an --- Hunderterstelle
70
71
    PORTB  = Zahl[Hunderter];
72
73
    if(Zahlenart == DEZIMAL2)
74
      PORTB &= ~(1<<DP);    //DP ON
75
    else
76
      PORTB |= (1<<DP);    //DP OFF
77
78
    PORTD &= ~(1<<PNP_1);
79
    PORTD &= ~(1<<PNP_10);
80
81
  }
82
  if(d == 60)
83
  {
84
    if(is_state_km)  //Geschwindigkeitsanzeige oder km-Stand
85
    {
86
      if(zahl < 10)
87
        PORTD &= ~(1<<PNP_10);
88
      else
89
        PORTD |= (1<<PNP_10);
90
    }
91
    else
92
      PORTD |= (1<<PNP_10);         //PD1 an --- Zehnerstelle
93
94
95
    PORTB  = Zahl[Zehner];
96
97
    if(Zahlenart == DEZIMAL1)
98
      PORTB &= ~(1<<DP);    //DP ON
99
    else
100
      PORTB |= (1<<DP);    //DP OFF
101
102
103
    PORTD &= ~(1<<PNP_1);
104
    PORTD &= ~(1<<PNP_100);
105
106
  }
107
  if(d == 90)
108
  {
109
    if(main_state == state_Gesamt_km1 && is_zero)
110
      PORTD &= ~(1<<PNP_1);         //PD0 aus --- Einerstelle
111
    else
112
      PORTD |= (1<<PNP_1);      //PD0 an --- Einerstelle
113
114
115
    PORTB  = Zahl[Einer];
116
117
    PORTB |= (1<<DP);    //DP OFF
118
119
    PORTD &= ~(1<<PNP_10);
120
    PORTD &= ~(1<<PNP_100);
121
122
    d = 0;
123
  }
124
}

von Karl H. (kbuchegg)


Lesenswert?

artur schrieb:

> Ein wichtiger Punkt ist, dass ich die Timer ISR nivht ausschliesslich
> für die Ausgabe der Anzeige benutze. In erster Linie für eine
> Blinkfunktion.

Na passt doch.
Da passt das Multiplexen noch locker mit rein.


> ISR(TIMER2_OVF_vect)  //Blinker, Aktualisierung der Geschwindigkeit, ADC
> und Ausgabe --------- alle ca. 256µs

256 µs ist doch wunderbar zum Multiplexen.

>   d++;
>   if(d == 30)
>   {


Dein Code 'verscheisst' viel mehr Zeit drumherum, als wie wenn du ganz 
einfach eine Stelle nach der anderen bei jedem (oder jedem 2.ten) ISR 
Aufruf einfach die 7-Segment um 1 Stelle updaten würdest.

Sieh dir doch mal an, wie kurz meine ISR-Routine ist und wieviel Arbeit 
du dem µC relativ unnötig in der ISR aufbürdest.

>     if(main_state == state_Gesamt_km1)

Wenn interessiert an dieser Stelle der Status in der Hauptschleife. Wenn 
in der Hauptschleife der Modus um geschaltet wird, dann wird einfach 
eine andere Zahl in OutputNumber reingestopft und die wird ab dann von 
der ISR angezeigt.

Ich kann dir nur Raten, den Anzeigecode von dem was anzuzeigen ist zu 
entkoppeln.

von Martin V. (oldmax)


Lesenswert?

Hi
Ich hab es ja bereits gesagt, in welcher Reihenfolge eine 
Multiplex-Routine arbeiten sollte. Wo ist da das Problem? Ich spreche 
zwar kein C, aber das ist in diesem Fall auch nicht wichtig. Übrigends, 
die Timer ISR wird, wenn du es richtig machst, von der Multiplex-Routine 
überhaupt nicht belastet. Betrachte folgendes:
Irgendwo hast du einen Wert, den du darstellen möchtest. Den jagst du im 
Polling durch den Codierer und das Ergebnis schreibst du in einen 
Ausgabepuffer. Hier ist der Programmzyklus völlig ausreichend. Deine 
Timer-ISR setzt ein Zeitflag ~ 1 mSek. und gut.
In deinem Programm prüfst du nun lediglich, ob dieses Bit gesetzt ist 
und stößt den Multiplexer an. Vielleicht eerledigst du auch noch andere 
Aufgaben, aber sie müssen in das Raster < 1 mSek. passen.  Nach 
Bearbeitung löscht du das Zeitflag und fertig. Der Vorteil dieser 
Vorgehensweise ist änlich einer Ereignisbearbeitung. Nur, wenn ein Flag 
gesetzt ist, wird etwas ausgeführt und das Flag gelöscht. Die 
Programmteile bleiben modular und leicht pflegbar. Mag sein, das es da 
andere Meinungen gibt, aber in meinen Augen sind kleine Routinen, die 
durch ein Flag aufgerufen werden wesentlich leichter zu prüfen. Und 
letztlich macht die Multiplexroutine nix anderes, wie einen Port 
abschalten, einen Zeiger auf den Ausgabepuffer weiterzuschalten, den 
zugehörigen Code auf die Segmente zu schalten und die passende Ziffer 
wieder einzuschalten. Das ist in C genauso einfach wie in Assembler. Und 
nochmal zum mitschreiben der Hinweis: erst die Ziffer ausschalten, dann 
die Segmente neu beschalten und dann die nächste Ziffer wieder 
einschalten! Sonst bekommst du immer ein unerwünschtes "nachleuchten" 
nicht aktiver Segmente.
Gruß oldmax

von artur (Gast)


Lesenswert?

Martin, tut mir leid, ich habe Deinen Beitrag für den von Karl Heinz 
gehalten!

Die Bitte um die richtige Reihenfolge galt also Dir)
Auch das mit dem Zeitflag ist ein Gedanke, der mir nicht gekommen wäre.
Freue mich schon aufs testen.

Gruß Artur

von Martin V. (oldmax)


Lesenswert?

Hi
Na ja, den ersten Tip gab schon KHB mit "ghosting". Es ist ja auch egal, 
wer den entscheidenden Hinweis gibt, wichtig ist, das du das erkennst 
und dich danach richtest. Und das hab ich aus deinen Antworten so nicht 
entnehmen können. Aber noch kurz zu den Zeitflags. Ich arbeite gern mit 
solchen Bits, weil eigentlich nur eine Aktion durchgeführt werden muss, 
wenn sich im Programmstatus etwas ändert. So ein Blinker, der mit 2 Hz 
betrieben wird. Setzt man alle 250 msek. ein Zeitflag, dann kann der 
Ausgang  in der durch das Zeitflag aufgerufenen Routine einfach 
invertiert werden. Danach wird diese Routine nicht wieder aufgerufen, 
erst wieder, wenn ein Flag den Auftrag vergibt. Du brauchst also nicht 
dauernd im Programm prüfen, ob die Zeit abgelaufen ist, nur das 
Zeitflag. Außerdem, so ein Flag ist schnell ersetzt. Du kannst es mit 
Tastern setzen und so die Funktion in "Hand" nutzen. Also, lass dir das 
mal richtig durch den Kopf gehen.
Gruß oldmax

von RS (Gast)


Lesenswert?

artur schrieb:
> An PORTD sind Transistoren...

Transistoren ohne Basiswiderstände? Wenn sie das Überleben (durch die 
wohl geringe Treiberleistung des µC) dann gehen sie ewig in Sättigung 
und das jeweilige Segment bleibt länger an als gewollt. Eventuell gibt 
es Überschneidungen!

von artur (Gast)


Lesenswert?

RS schrieb:
> artur schrieb:
>> An PORTD sind Transistoren...
>
> Transistoren ohne Basiswiderstände? Wenn sie das Überleben (durch die
> wohl geringe Treiberleistung des µC) dann gehen sie ewig in Sättigung
> und das jeweilige Segment bleibt länger an als gewollt. Eventuell gibt
> es Überschneidungen!

Hm, habe ich nicht bedacht, dass die dann länger zum Ausgehen brauchen.
ich habs erst mit 100Ohm probiert, das Ergebnis war eine recht dunkle 
Anzeige.

von Dietrich L. (dietrichl)


Lesenswert?

RS schrieb:
> Transistoren ohne Basiswiderstände?

Das sind Emitterfolger, also kein Problem.

Ich sehe eher ein Problem mit der Dimensionierung des Stroms, denn die 
Summe der Spannungsabfälle an Transistor, LED und ULN sind schon relativ 
groß und es bleibt nicht viel für den Widerstand.
Wenn man alle Toleranzen zusammenrechnet ergibt sich ein Bereich von 
8...40mA, in dem der Strom sich "bewegen" kann, (mal schnell & grob 
abgeschätzt). Die Sache würde entspannter, wenn PNP-Transistoren 
verwendet würden, allerdings dann mit Basiswiderständen ;-)

Gruß Dietrich

von Axel S. (a-za-z0-9)


Lesenswert?

RS schrieb:
> artur schrieb:
>> An PORTD sind Transistoren...
>
> Transistoren ohne Basiswiderstände? Wenn sie das Überleben ...

"Wenn man keine Ahnung hat ... einfach mal die Fresse halten"


XL

von m.n. (Gast)


Lesenswert?

Axel Schwenke schrieb:
> "Wenn man keine Ahnung hat ... einfach mal die Fresse halten"

Eigentlich sollte man deinen Beitrag zum Löschen freigeben.
Andererseits zeigt es in knappen Worten deinen unverschämten Charakter.

von Axel S. (a-za-z0-9)


Lesenswert?

m.n. schrieb:
> Axel Schwenke schrieb:
>> "Wenn man keine Ahnung hat ... einfach mal die Fresse halten"
>
> Eigentlich sollte man deinen Beitrag zum Löschen freigeben.

Warum? Weil ich Recht habe?

> Andererseits zeigt es in knappen Worten deinen unverschämten Charakter.

Darf man einen Idioten jetzt nicht mehr so nennen?

Wir haben hier einen zwar noch unerfahrenen, aber zumindest lernwilligen 
Bastler und eine Menge Leute, die sich redlich bemühen ihm zu helfen.
Und dann kommt so ein anonymer Trottel daher und labert Blödsinn, weil 
er einen Emitterfolger nicht von einer Emitterschaltung unterscheiden 
kann.

Eigentlich könnte mir das egal sein. Aber er verunsichert unseren 
Bastler, der jetzt fälschlich glaubt, ein Emitterfolger würde ohne 
Basisvorwiderstand langsamer abschalten (was er natürlich nicht tut)

Und das sehe ich hier laufend. Ein eigentlich gut laufender Thread, in 
den dann irgendein Idiot reinplatzt und Schwachsinn absondert. Und 
bezeichnenderweise immer anonym. Wenn du nix Besseres zu tun hast, als 
solchen Leuten den Rücken zu stärken, dann solltest du auch besser 
schweigen.


XL

von m.n. (Gast)


Lesenswert?

Der Ton macht die Musik. Scheinbar scheinst du taub zu sein, sonst 
würdest du hören können, wie du hier (wiederholt) herumschreist.

Dietrich L. schrieb:
> RS schrieb:
>> Transistoren ohne Basiswiderstände?
>
> Das sind Emitterfolger, also kein Problem.

Damit war die Sache eigentlich schon auf ganz freundliche Weise geklärt 
und es gab keinerlei Grund für dein Geschreie.

Axel Schwenke schrieb:
> Und dann kommt so ein anonymer Trottel

Mir bist du doch genauso anonym, und etwas sachlich Konstruktives habe 
ich von dir hier nicht gelesen.

von artur (Gast)


Lesenswert?

Hab das mit dem Ghosting verstanden denke ich:
Alle Stellen abschalten.
Wert reinschreiben.
NUR die Stelle, die gerade dran ist, einschalten.

Schaltungstechnik ist nicht wirklich mein Spezialgebiet.
Axel, lass ruhig Dampf ab) aber mit Begründung, dann hab ich die Wahl 
wem ich glauben kann.
Anonym kann hier wirklich jeder, und jedes Mal unter anderem Namen, 
reinplatzen. Deswegen gewichte ich instinktiv die Meinung angemeldeter 
Benutzer mehr.
Hab hier übrigens auch einen Account (Artur Lauk), mein Arbeitrechner 
zwingt mich jedes Mal zur Neuanmeldung, weswegen ich mich gleich als 
Gast anmelde.

von m.n. (Gast)


Lesenswert?

artur schrieb:
> Hab das mit dem Ghosting verstanden denke ich:

Was Du noch machen kannst, das Display von hinten mit schwarzer Tusche 
bepinseln, um Reflektionen zu reduzieren.

Und was Du machen mußt: unbedingt eine rote Filterscheibe verwenden! 
Damit wird gerade bei hellem Umfeld der Kontrast deutlich verbessert.

von Thosch (Gast)


Lesenswert?

wäre allerdings meiner Meinung nach wesentlich sinnvoller, hier zum 
Schalten der Display-Anoden PNP-Transistoren in Emitterschaltung 
einzusetzen.

Dann natürlich mit passendem Basiswiderstand.

Passend wäre hier der BC327-40, mit 680 Ohm als Basiswiderstand.
Emitter an +5V, Kollektor an die gem. LED-Anode der Stelle, Basis über 
680R an den jeweiligen Port-Pin.

Die Programmlogik muß man dann allerdings anpassen, da der 
PNP-Transistor mit Low-Pegel an der Basis durchgesteuert wird.
Die entsprechenden Port-Bits PD4, PD5, PD6 wären also zu invertieren.

von m.n. (Gast)


Lesenswert?

Thosch schrieb:
> wäre allerdings meiner Meinung nach wesentlich sinnvoller, hier zum
> Schalten der Display-Anoden PNP-Transistoren in Emitterschaltung
> einzusetzen.

Das würde ich nicht machen. Allerdings gefällt mir der ULN2004 nicht; 
ein 'aufgeweckter' Transistor schaltet da schneller.

Eher würde ich die acht Segmente von PortD direkt ansteuern und per 
Emitterfolger von PortB die drei Digits ansteuern.
Und, um von Konjuktiv wegzukommen, auch gleich ein Beispiel dafür. 
Beitrag "Frequenz, Drehzahl, 4x7-Segment LED, Multiplex-Betrieb"

von Karl H. (kbuchegg)


Lesenswert?

artur schrieb:

> Hab mal ne zweite Anzeige aufgetrieben und die Rücksite abgeknipst.

Finde ich seltsam, dass auf der Rückseite da sowas wie eine orange 
Beschichtung drauf ist. Ich hätte ja eher eine Farbe erwartet, durch die 
das Licht nicht durch kommt. Oder ist das ein Feature. Sozusagen eine 
Hintergrundbeleuchtung (sieht man ja auch auf dem Foto der Anzeige im 
Betrieb).

Eigenartig. Sowas hab ich bei meinen noch nie beobachtet. Und ich 
verwende auch 08/15 Billig-Anzeigen.

von artur (Gast)


Lesenswert?

Hab die Reihenfolge der Ansteuerung wie empfohlen geändert - leider 
keine Verbesserung.
Mit dem ULN wollte ich ein Paar Ports sparen, hab aber noch genug 
übrig...erstmal.

Vielen Dank für die Anregungen, hab einiges gelernt!

hier noch mal der aktuelle Code:

(ich schalte nicht alle Anzeigen aus, sondern die letzte wirklich 
leuchtende)
@Karl Heinz:
Die Abfrage des State ist dazu da um führende Nullen nicht anzuzeigen...

1
  d++;
2
  if(d == 30)
3
  {
4
    PORTD &= ~(1<<PNP_1);
5
6
    PORTB  = Zahl[Hunderter];
7
8
    if(is_state_km)  //Geschwindigkeitsanzeige oder km-Stand
9
    {
10
      if(main_state == state_Gesamt_km2)
11
      {
12
        if(is_zero && (zahl < 100))
13
          PORTD &= ~(1<<PNP_100);         //PD2 aus --- Hunderterstelle
14
        else
15
          PORTD |= (1<<PNP_100);
16
      }
17
      else
18
      {
19
        if(zahl < 100)
20
          PORTD &= ~(1<<PNP_100);
21
        else
22
          PORTD |= (1<<PNP_100);
23
      }
24
    }
25
    else
26
      PORTD |= (1<<PNP_100);         //PD2 an --- Hunderterstelle
27
28
    if(Zahlenart == DEZIMAL2)
29
      PORTB &= ~(1<<DP);    //DP ON
30
    else
31
      PORTB |= (1<<DP);    //DP OFF
32
33
  }
34
  if(d == 60)
35
  {
36
    PORTD &= ~(1<<PNP_100);
37
38
    PORTB  = Zahl[Zehner];
39
40
    if(is_state_km)  //Geschwindigkeitsanzeige oder km-Stand
41
    {
42
      if(zahl < 10)
43
        PORTD &= ~(1<<PNP_10);
44
      else
45
        PORTD |= (1<<PNP_10);
46
    }
47
    else
48
      PORTD |= (1<<PNP_10);         //PD1 an --- Zehnerstelle
49
50
51
    if(Zahlenart == DEZIMAL1)
52
      PORTB &= ~(1<<DP);    //DP ON
53
    else
54
      PORTB |= (1<<DP);    //DP OFF
55
56
  }
57
  if(d == 90)
58
  {
59
    PORTD &= ~(1<<PNP_10);
60
61
    PORTB  = Zahl[Einer];
62
63
    if(main_state == state_Gesamt_km1 && is_zero)
64
      PORTD &= ~(1<<PNP_1);         //PD0 aus --- Einerstelle
65
    else
66
      PORTD |= (1<<PNP_1);      //PD0 an --- Einerstelle
67
68
69
70
71
    PORTB |= (1<<DP);    //DP OFF
72
73
74
75
    d = 0;
76
  }

von Martin V. (oldmax)


Angehängte Dateien:

Lesenswert?

Hi
Diese Aussage versteh ich nicht so ganz...
>(ich schalte nicht alle Anzeigen aus, sondern die letzte wirklich
>leuchtende)
Beim Multiplexbetrieb ist doch grundsätzlich immer nur eine Ziffer 
zugeschaltet und die wird auch zuerst ausgeknipst. Schau dir mal meine 
Skizze an. Zuerst eine AND- Operation mit  000 auf die Schiebebits und 
auf Port ausgeben.
Schiebebits weitertakten und Adresszeiger vom Ausgabepuffer erhöhen. 
Grenze erreicht, Schiebepuffer wieder mit 1 setzen und Zeiger auf 0. 
Dann Matrix auf Segmentport ausgeben. Anschließend eine And-Operation 
mit 111 auf die Schiebebits und auf Port ausgeben.
Ok, es kann sein, das die Bitlage anders ist, aber hier geht's nur um 
das Prinzip.
Wenn eine neue Ziffer ausgegeben werden soll, müssen alle !! Ziffern 
ausgeschaltet werden!
Gruß oldmax

von artur (Gast)


Lesenswert?

ich plexe zeitlich multi)...alles per SW.

Zu jedem Zeitpunkt ist bei mir auch nur eine Anzeige aktiv (leuchtend).
Und bevor ich die nächste Ziffer ins Ausgaberegister lade und die 
nächste Stelle aktiviere, schalte ich nicht alle anderen Stellen aus, 
sondern eben nur die, die zuletzt am leuchten war. Ich könnte mit einer 
Zeile auch die anderen auch ausknipsen, aber wozu? Sind doch eh aus.

von artur (Gast)


Lesenswert?

Nebenbei:

Gibt es einen IC, mit dem ich alle drei Stellen gleichzeitig leuchten 
lassen kann aber mit der gleichen Anzahl an Ports (a,b...g,DP) auskomme?
Klar zwei Bits für die Adressierung müssen zusätzlich rein.

Wäre erheblich einfacher und besser ablesbar denke ich.

von Karl H. (kbuchegg)


Lesenswert?

Martin Vogel schrieb:

> Wenn eine neue Ziffer ausgegeben werden soll, müssen alle !! Ziffern
> ausgeschaltet werden!

Vor allen Dingen, weil es zeitlich völlig wurscht ist.
Ob man sich die Mühe macht und nur die im letzten ISR-Durchgang 
eingeschaltete abschaltet oder der Einfachheit halber einfach alle 
Stellen, ist vom Zeitverlauf her ziemlich egal. Lediglich der Code ist 
um einiges einfacher.

von Karl H. (kbuchegg)


Lesenswert?

> @Karl Heinz:
> Die Abfrage des State ist dazu da um führende Nullen nicht anzuzeigen...

Du hast es immer noch nicht begriffen, dass du damit diese Entscheidung 
(die if-Abfragen), die du eigentlich nur dann machen müsstest, wenn eine 
neue Zahl zur Ausgabe verfügbar ist, in der ISR viele hundert mal in der 
Sekunde immer wieder neu machst, mit immer wieder dem gleichen Ausgang. 
Denn die anzuzeigende Zahl ändert sich in Relation dazu nur alle heilige 
Zeiten mal. Und dann könnte man das alles genau dann einmalig für die 
neue Zahl feststellen, wodurch die ISR sich darum überhaupt nicht mehr 
kümmern muss. Das vereinfacht die ISR, verkürzt deren Code und macht sie 
schnell. Dann spielt es auch keine Rolle mehr, ob man alle Stellen 
abschaltet oder nur die eine. Denn mehr als abgeschaltet kann eine 
Stelle sowieso nicht sein. Der Zeitunterschied zwischen einer 
if-then-else Leiter mit gezieltem CBI eines Bits und einem IN-AND-OUT 
Zyklus fällt dabei locker zugunsten Letzterm aus.

Diese ganzen Teile
1
   PORTB  = Zahl[Hunderter];
... also die Bestimmung des anzuzeigenden Musters, wenn die Ziffer 
bekannt ist, bzw. die Entscheidung, ob du dieses Muster (für eine 0) 
überhaupt anzeigen willst oder nicht
1
    if(is_state_km)  //Geschwindigkeitsanzeige oder km-Stand
2
    {
3
      if(main_state == state_Gesamt_km2)
4
      {
5
6
...
das alles sind Dinge, die in der ISR lediglich Zeit verbrauchen und 
nicht mehr. Dabei wäre das mit einer kleinen Systemänderung problemlos 
vermeidbar.


Aber ist egal. Ich hab das Gefühl (und ohne jetzt die einzelnen 
Versionen verglichen zu haben), dass du nicht gewillt bist an deinem 
Code sinnvolle Änderungen vorzunehmen, die über Mikrovariationen 
hinausgehen. Noch nicht mal dann, wenn ich (bzw. wir) sie dir vorbeten 
und in Code zeigen. Daher belasse ich es dabei.

: Bearbeitet durch User
von m.n. (Gast)


Lesenswert?

artur schrieb:
> Gibt es einen IC, mit dem ich alle drei Stellen gleichzeitig leuchten
> lassen kann aber mit der gleichen Anzahl an Ports (a,b...g,DP) auskomme?

Beitrag "Re: 7-Segment Anzeige 3-3tellig"
Vielleicht liest Du es ja doch noch. Die notwendigen 3 x 4094 
Schieberegister passen optimal unter die Anzeige (siehe Bild) und die 
Ansteuerung kommt mit drei Leitungen aus, egal ob 3 oder 30 Anzeigen 
anzusteuern sind.

von Michael B. (laberkopp)


Lesenswert?

> Die notwendigen 3 x 4094 Schieberegister passen optimal unter die Anzeige

Das ist aber eine Scheiss-Lösung, deenn es fehlen die Vorwiderstände und 
die Segmente werden daher deutlich unterschiedlich hell, wie 
beispielsweise am RESOL EL1 Temperaturregker erkennbar ist, der zwar ein 
schweinteures kommerzielles Produkt ist, wo aber die Hersteller genau so 
eine Pfusch gebaut haben den du hier vorschlägst.

von m.n. (Gast)


Lesenswert?

Michael Bertrandt schrieb:
> Das ist aber eine Scheiss-Lösung, deenn es fehlen die Vorwiderstände und
> die Segmente werden daher deutlich unterschiedlich hell,

Das stimmt doch garnicht! Die Schaltung mit CMOS4094 verwende ich seit 
Jahrzehnten. Und für die Angsthasen gibt es ja die Möglichkeit mit 
74HC4094 und Widerständen.
Wenn Du es einmal in Deinem Leben gemacht hättest, könntest Du es auch 
wissen. Aber gut, gegen Verbohrtheit kann man nicht argumentieren.

von artur (Gast)


Lesenswert?

Karl Heinz,

das mit der Abfrage des States habe ich nun kapiert.
Den Code bin ich durchaus gewillt anders zu schreiben. Der letzte 
Ausschnitt sollte lediglich meine neue, von Euch empfohlene Reihenfolge 
zum Absegnen freigeben.
Über die anderen Ratschläge mache ich mir Gedanken und der Code wird am 
WE angepasst. Mein generelles Problem war das "Fremdleuchten".

Vielen Dank noch mal

von artur (Gast)


Lesenswert?

m.n. schrieb:
> artur schrieb:
>> Gibt es einen IC, mit dem ich alle drei Stellen gleichzeitig leuchten
>> lassen kann aber mit der gleichen Anzahl an Ports (a,b...g,DP) auskomme?
>
> Beitrag "Re: 7-Segment Anzeige 3-3tellig"
> Vielleicht liest Du es ja doch noch. Die notwendigen 3 x 4094
> Schieberegister passen optimal unter die Anzeige (siehe Bild) und die
> Ansteuerung kommt mit drei Leitungen aus, egal ob 3 oder 30 Anzeigen
> anzusteuern sind.

Habe ich wirklich nicht, tut mir leid)
Es waren viele ICs, aber auf den zweiten Blick scheint es das zu sein, 
was iich brauche.
ich lese es ! vielen Dank

von Michael B. (laberkopp)


Lesenswert?

m.n. schrieb:
> Das stimmt doch garnicht! Die Schaltung mit CMOS4094 verwende ich seit
> Jahrzehnten. Und für die Angsthasen gibt es ja die Möglichkeit mit
> 74HC4094 und Widerständen.
> Wenn Du es einmal in Deinem Leben gemacht hättest, könntest Du es auch
> wissen. Aber gut, gegen Verbohrtheit kann man nicht argumentieren.

Natürlich stimmt das, was ich sage.

Nein, ich mache so was nicht, aber ich sehe die Ergebnisse:
Und sie sind Scheisse, das Display des besagten Temperaturreglers
sieht aus als wäre es kaputt, Zahlen sind nicht klar lesbar weil
man nicht weiss, ob das helbhelle Segment nun aus oder an sein soll.

Daß du in deine miese Lösung verliebt bist mag dich mit Blindheit
strafen, aber schlag so was bloss nicht anderen Menschen vor.

Verbohrt ist hier ein ganz anderer, nämlich du. Alle normalen
Leute verwenden nämlich Vorwiderstände.
Alles Geisterfahrer ? Tausende, tausende...

von m.n. (Gast)


Angehängte Dateien:

Lesenswert?

artur schrieb:
> Es waren viele ICs, aber auf den zweiten Blick scheint es das zu sein,
> was iich brauche.

Das Foto zeigt eine Leerplatine für eine 3-stellige Anzeige passend zu 
dem Frontrahmen, den Du Dir oben schon ausgesucht hattest.
Falls jemand Interesse an Leerplatinen hat, gegen frankierten 
Rückumschlag kann ich diese gerne verschenken. 30 - 40 Stück müßte ich 
noch übrig haben.

Bei Bedarf kann ich einen Schaltplan dazu machen; das Board selbst ist 
mit einer uralt Version von Eagle noch ohne '.sch' und die Platine 
selbst ohne Stopplack gemacht worden. Seinerzeit hatte ein 8051 das Teil 
angesteuert.

von a. l. (artur78)


Lesenswert?

Hallo m.n.,

das wäre riesig!
Schick mir bitte Deine Adr. per PN.

Ein paar Platinen wären super. Den Schaltplan kannst einfach 
abfotografieren. Ich baue ihn dann nach,

Gruß
Artur

von m.n. (Gast)


Angehängte Dateien:

Lesenswert?

Zur obigen Platine habe ich den Schaltplan in Eagle gezeichnet. Er steht 
ein wenig auf dem Kopf, da GND oben und VCC unten liegen. Die Daten 
werden in den Schieberegistern von links nach rechts geschoben: MSD 
zuerst!
Daher bleiben nur die zuletzt ausgegebenen LED-Muster (Bytes) in der 
Anzeige stehen, während höher gewichtete Stellen nach rechts 
herausgeschoben werden. Bei einer Kaskadierung hat das den Vorteil, dass 
die Ausgaberoutine nicht wissen muß, wieviele Schieberegister vorhanden 
sind. Die letzten drei Byte bei einer Ausgabe landen in dieser Anzeige.

Wie gesagt, war diese Anzeige ursprünglich für einen 8051 vorgesehen, 
der beim Reset alle Eingänge per schwachem pullup-Widerstand nach +5V 
zieht. Somit ist 'STROBE' beim Einschalten auf '1' und der als Inverter 
arbeitende BC807 gesperrt. Folglich ist 'OE' beim Einschalten auf '0' 
und die Anzeige bleibt gelöscht - unabhängig vom Einschaltmuster in den 
Schieberegistern.

Am besten ist es daher, zunächst dreimal eine 0x00 auszugeben und dann 
erst den Ausgang 'STROBE' zu aktivieren.
Das weiter oben angedeutete Programm zu 
Beitrag "7-Segm.-LED-Anzeige, 6-stellig, statische Ansteuerung mit (74HC)4094" kann leicht abgeändert, 
ansonsten auch direkt verwendet werden, da die Zuordnung der SR-Ausgänge 
(sieben Segmente sowie der '.') identisch ist. Wichtig: #define OHNE_R 
muß noch ergänzt werden.
Wegen der oben beschriebenen Gründe stört es nicht, die Ausgabe 
6-stellig zu lassen.

von m.n. (Gast)


Angehängte Dateien:

Lesenswert?

Michael Bertrandt schrieb:
> Natürlich stimmt das, was ich sage.
>
> Nein, ich mache so was nicht, aber ich sehe die Ergebnisse:
> Und sie sind Scheisse, das Display des besagten Temperaturreglers
> sieht aus als wäre es kaputt, Zahlen sind nicht klar lesbar weil
> man nicht weiss, ob das helbhelle Segment nun aus oder an sein soll.
>
> Daß du in deine miese Lösung verliebt bist mag dich mit Blindheit
> strafen, aber schlag so was bloss nicht anderen Menschen vor.
>
> Verbohrt ist hier ein ganz anderer, nämlich du. Alle normalen
> Leute verwenden nämlich Vorwiderstände.
> Alles Geisterfahrer ? Tausende, tausende...

Nachdem Du mich neulich freundlichst darauf hingewiesen hast, meine 
Angaben doch noch einmal zu überprüfen, muß ich Dir jetzt vielleicht 
sogar Recht geben.
Anbei das Foto einer 3-stelligen Anzeige, auf dem man ganz deutlich 
erkennen kann, wie unterschiedlich hell die einzelnen Segmente leuchten. 
Noch schlimmer: einige Segemnte scheinen garnicht zu leuchten.
Was mache ich nur falsch?

Für diejenigen, die meine Fehler wiederholen wollen, noch ein kleines 
Programm, mit dessen Hilfe man Zahlen im Bereich von -99 bis 999 
anzeigen kann.
Wer noch mehr mit 7-Segmentanzeigen spielen will, kann sich hier anregen 
lassen. http://www.mino-elektronik.de/7-Segment-Variationen/LCD.htm
Wenn es irgendwann draußen doch noch schneien wird, sollte man seine 
'Digits' schon in der Schublade haben :-)

von Peter Bergmann (Gast)


Angehängte Dateien:

Lesenswert?

Ist zwar kein 7-Segment Display, aber es ist sehr kompakt.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Michael Bertrandt schrieb:
> Verbohrt ist hier ein ganz anderer, nämlich du. Alle normalen
> Leute verwenden nämlich Vorwiderstände.

Nein, das kann bei CMOS schon machen, da intern die Ausgänge 
strombegrenzend wirken. Bis zu einer bestimmten Betriebsspannung ist da 
keine Gefahr für die LED wg. Überstrom zu erwarten. Übetreiben sollte 
man es nicht, also den 4094 mit 12 Volt betrieben oder so.

Ich habe das mit ein paar Schieberegistern und weissen LED auch schon 
lange in Betrieb, die LED leuchten gleich hell und der Strom ist bei 5V 
Vcc etwa 20mA pro LED, das geht also gut. Wie immer bei CMOS gut mit Cs 
abblocken.
Falls es interessiert, kann ich mal den entsprechenden Abschnitt im CMOS 
Kochbuch raussuchen.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Peter Bergmann schrieb:
> Ist zwar kein 7-Segment Display, aber es ist sehr kompakt.

cool, wo gibts denn sowas?

von Axel S. (a-za-z0-9)


Lesenswert?

Wegstaben Verbuchsler schrieb:
> Peter Bergmann schrieb:
>> Ist zwar kein 7-Segment Display, aber es ist sehr kompakt.
>
> cool, wo gibts denn sowas?

Die Frage müßte eher lauten, Wann gibts denn sowas?
Das wäre dann wohl immer zwei Tage nach dem 30. März.


XL

von Conny G. (conny_g)


Lesenswert?

Matthias Sch. schrieb:
> Falls es interessiert, kann ich mal den entsprechenden Abschnitt im CMOS
> Kochbuch raussuchen.

Gerne!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Conny G. schrieb:
> Matthias Sch. schrieb:
>> Falls es interessiert, kann ich mal den entsprechenden Abschnitt im CMOS
>> Kochbuch raussuchen.
>
> Gerne!

Leider gibt es keine Online Version des Buches, deswegen muss ich das 
gedruckte aus meiner Sammlung raussuchen, aber in der AN313 von 
Fairchild fand ich schon mal das:
"For most CD4000 and MM74C CMOS operating at VCC=5V,
the designer does not need to worry about excessive output
currents, since the output transistors usually cannot source
or sink enough current to stress the metal or dissipate exces-
sive amounts of power."
Bei CMOS Gattern basiert das darauf, das sowohl der P als auch der 
N-Channel Ausgangs-FET in der Sättigung als Konstantstromquelle 
fungieren, wie die bekannte Schaltung mit z.B. einem BF245 o.ä.:

      D     S
>------    -o-----> Konstantstrom
       |  | |
      ----- |
      G |   |
        ----+

Gate ist mit der Source verbunden. Je nach Exemplar stellt sich ein 
Konstantstrom von ca. 5-20mA ein. In einer CMOS Gegentaktendstufe (der 
Normalfall) passiert ähnliches, da Gate und Source sich auf gleichem 
Level befinden. Such dir einen beliebigen FET aus der Kiste und probier 
es aus. Die Schaltung ist in einem recht weiten Betriebsspannungsbereich 
eine gute Konstantstromquelle und zufällig auch im Bereich besten 
LED-Stroms.

von Conny G. (conny_g)


Lesenswert?

Cool, wieder was gelernt, danke!

von m.n. (Gast)


Lesenswert?

Matthias Sch. schrieb:
> Leider gibt es keine Online Version des Buches, deswegen muss ich das
> gedruckte aus meiner Sammlung raussuchen, aber in der AN313 von
> Fairchild fand ich schon mal das:

Im Grunde reicht schon aus, sich die Datenblätter der CMOS-Bausteine 
anzusehen. In der Regel ist dort eine Kennlinie des Ausgangsstroms 
abgebildet, die zeigt, dass ab einem gewissen Strom die Ausgänge in den 
Konstantstrombetrieb übergehen.
Ferner ist noch zu sehen, dass bei steigender Temperatur der 
Ausgangsstrom leicht zurückgeht, und damit weiterer interner Erwärmung 
entgegenwirkt.

Testweise habe ich das obige Programm verändert. Betreibt man den 
STROBE-Eingang an einem PWM-Ausgang, kann man die Helligkeit der Anzeige 
dimmen. Und das alles mit nur drei Ausgangspins.

von Reinhard Kern (Gast)


Lesenswert?

Matthias Sch. schrieb:
> Ich habe das mit ein paar Schieberegistern und weissen LED auch schon
> lange in Betrieb, die LED leuchten gleich hell und der Strom ist bei 5V
> Vcc etwa 20mA pro LED

Verbrät also ein Ausgang 20 mA x 3 V = 60 mW. Bei 8 Ausgängen sind das 
480 mW, nach Datenblatt TI ist die maximal erlaubte Leistung 500 mW. Das 
IC wird also an der absoluten Grenze der zulässigen Leistung und 
Temperatur betrieben, zuverlässige Elektronik geht anders. Verteilt auf 
8 Widerstände existiert das Problem nicht mehr.

Ausserdem hat man keine Möglichkeit, den LED-Strom zu betsimmen, man ist 
den zufälligen Werten des Innenwiderstands ausgeliefert.

Funktioniert zwar oft, ist aber trotzdem unverantwortlicher Murks. Das 
kann man hier aber noch so oft schreiben und begründen, trotzdem wird 
immer wieder der Betrieb von LEDs ohne Vorwiderstand empfohlen. Es muss 
sich wohl um die Ärmsten der Armen handeln, wenn 8 Widerstände schon 
unbezahlbar sind.

Gruss Reinhard

von m.n. (Gast)


Lesenswert?

Reinhard Kern schrieb:
> Verbrät also ein Ausgang 20 mA x 3 V = 60 mW.

Bei den 20mA handelt es sich sicher um einen Irrtum; 'normale' 
CMOS-Ausgänge liefern 5-6mA.

Reinhard Kern schrieb:
> Es muss
> sich wohl um die Ärmsten der Armen handeln, wenn 8 Widerstände schon
> unbezahlbar sind.

Warum soll man denn Widerstände einbauen? Um die Anzeige dunkler zu 
bekommen?
Das kann man doch mit Dimmen erreichen, wie ich es gerade geschrieben 
habe.

Reinhard Kern schrieb:
> Ausserdem hat man keine Möglichkeit, den LED-Strom zu betsimmen, man ist
> den zufälligen Werten des Innenwiderstands ausgeliefert.

Mag es der völlige Zufall sein, aber die Ausgangsströme von CMOS-4094 
ICs sind seit Jahrzehnten konstant. Es funktioniert nicht nur oft, 
sondern es funktioniert immer. Aber man muß es auch schon machen, um es 
zu sehen. Daran ändert auch noch so viel Geschreie nichts.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Reinhard Kern schrieb:
> Verbrät also ein Ausgang 20 mA x 3 V = 60 mW. Bei 8 Ausgängen sind das
> 480 mW, nach Datenblatt TI ist die maximal erlaubte Leistung 500 mW. Das
> IC wird also an der absoluten Grenze der zulässigen Leistung und
> Temperatur betrieben, zuverlässige Elektronik geht anders.

Ich habe sicher nicht alle 8 LEDs an einem 4015, um sie dauernd leuchten 
zu lassen. Das ist ein Zufalls/VU/PWM/Lauflicht bei dem die LED ständig 
umgeschaltet werden, ingesamt 18 LED an 3 Schieberegistern.
Da wird nichts warm und es läuft seit Jahren. Allerdings habe ich den 
absoluten Strom jetzt schon lange nicht mehr gemessen, kann auch sein, 
das es weniger als 20mA/LED sind.

von m.n. (Gast)


Lesenswert?

Matthias Sch. schrieb:
> kann auch sein,
> das es weniger als 20mA/LED sind.

Sind es; ein Verweis auf das Datenblatt zeigt es.
http://www.ti.com/lit/ds/symlink/cd4035b.pdf

Allerdings hattest Du nicht erwähnt, welches SR verwendet wird und 
wieviele weiße LEDs angeschlossen sind. Insofern war es noch keine 
verbindliche Aussage.

Prompt wird dann einfach mal 20mA x 8 x 3 hochgerechnet, um ein 
fadenscheiniges Argument dagegen zu finden.
Dass eine weiße LED eher 3,5V 'Brennspannung' hat und der IC-interne 
Spannungsabfall nur 1,5V beträgt, wird natürlich auch schön ignoriert.

Immer wieder das gleiche Spiel.

von Michael B. (laberkopp)


Angehängte Dateien:

Lesenswert?

Matthias Sch. schrieb:
> das kann bei CMOS schon machen,

Es geht nicht um die Frage, ob ein überlasteter CMOS-Ausgang kaputt geht 
oder abschnürt, natürlich schnürt er ab, es geht darum, daß dieser Strom 
absolut nicht definiert oder konstant ist, sondern von Ausgang zu 
Ausgang um 1:2 anders ist, und damit die Helligkeit der LED-Segmente um 
1:2 anders ist und damit ein halbhelles Segment genau zwischen einem 
eingeschalteten und einem ausgeschalteten nicht erkennbar ist ob es ein 
oder aus sein soll.

> Such dir einen beliebigen FET aus der Kiste und probier es aus

http://www.onsemi.com/pub_link/Collateral/BF245A-D.PDF

da kann der IDSS Strom zwischen 2 und 25mA liegen, je nach Exemplar und 
Temperatur, eine Abweichung von 1:2 nennen die schon selektiert. Was 
fpür ein Glück, daß man den Prozess bei CMOS ICs besser beherrscht, dort 
sind 1:2 meist eingehalten.

Es ist wirklich erschreckend, wie denkbehindert die Hobbybastler sind, 
und immer wieder auf dieselbe Sache reinfallen: "Ich bin bei rot über 
die Kreuzung gegangen und es hat funktioniert". Also geht alle bei rot.

Sicher kann mal mal in Einzelfällen Glück haben und die desolate 
Bastelkonstruktion funktioniert. Aber vorschlagen kann man diese Lösung, 
die nur aus Zufall funktionierte nicht, denn beim nächsten klappt es 
vielleicht nicht. Nur Lösungen die immer funktionieren sind Lösungen.

Aber das haben ja nicht mal manche deutschen Elektronikhersteller 
begriffen, siehe Bild, auf dem man Segment C der ersten Stelle als 
halbhell erkennt was bei manchen Zahlen zu Erkennbarkeitsproblemen führt 
und in der 3. Stelle einige Segmente dunkler sind. Im Sonnenlicht sieht 
es noch etwas krasser aus, aber Sonne gab es heute keine.

von m.n. (Gast)


Angehängte Dateien:

Lesenswert?

Michael Bertrandt schrieb:
> Es ist wirklich erschreckend, wie denkbehindert die Hobbybastler sind,
> und immer wieder auf dieselbe Sache reinfallen: "Ich bin bei rot über
> die Kreuzung gegangen und es hat funktioniert". Also geht alle bei rot.

Und im Umkehrschluß machst Du genau das gleiche.
Irgendein Hersteller fabriziert Müll, folglich ist alles Müll.
Zeigt doch mal den Schaltplan der Anzeige und das Datenblatt der 
7-Segment-Displays.
Oder noch einfacher: vergleiche Dein Foto mit diesem hier. Von dem Gerät 
existieren ein paar hundert Stück.

von Michael B. (laberkopp)


Lesenswert?

> Und im Umkehrschluß machst Du genau das gleiche.

Nein. Du kannst den Existenzbeweis nicht.
Eine Lösung ist keine Lösung wenn sie nicht immer funkioniert.
Es reicht ein Gegenbeispiel.
Egal wie oft du bei rot über die Strasse gegangen bist.
Schliesslich soll eine Schaltung auch im Nachbau funktionieren,
und in der Produktion muss sie das erst recht.
Das heisst, daß sie mit allen Datenblattabweichungen zu recht
kommen muss. Und nicht nur mit glücklichen Kombinationen.
Diese von dir ignorierten Grundlagen der Elektronik sind aber
hinlänglich bekannt.


> Irgendein Hersteller fabriziert Müll,

Er produziert genau das hier vorgeschlagene:
5V CD4094 direkt an Siemens HA1105R Display.
Das wurde überigens schon geschrieben.

von m.n. (Gast)


Lesenswert?

Michael Bertrandt schrieb:
> Es reicht ein Gegenbeispiel.

Na gut. Ich habe mal ein Auto gesehen, das vor einen Baum gefahren ist. 
Deine Folgerung: Autos fahren gegen Bäume.

Ich habe auch schon mal einen Widerstand gesehen, der völlig verbrannt 
war. Deine Folgerung: man darf keine Widerstände verwenden, die brennen 
alle durch :-)

Michael Bertrandt schrieb:
> 5V CD4094 direkt an Siemens HA1105R Display.
> Das wurde überigens schon geschrieben.

Ich habe nach HA1105R gesucht. Diese Zeichenfolge existiert im ganzen 
Forum nicht - ausser jetzt.
Meine Schaltung kannst Du oben sehen; die Schaltung, die Du bemängelst, 
fehlt! Das paßt!

von artur (Gast)


Lesenswert?

Hallo nochmal,

ich habe die Schaltung mit Platine von m.n. aufgebaut und es 
funktioniert wunderbar)

Vielen Dank nochmal!

von m.n. (Gast)


Lesenswert?

Dann ist ja gut!
Ich hatte schon gekuckt, ob ich noch einen ATmega8 habe, um mit diesem 
die Ansteuerung zu testen.

Falls Du die Helligkeit steuern möchtest, empfiehlt es sich, für 
LCD_STROBE einen passenden PWM-Ausgang zu nehmen. Leider ist der ATmega8 
dafür schlecht geeignet, aber beim ATmega88 würde sich OC0A anbieten.
Mit OC0A hatte ich es beim ATtiny25 getestet.

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.