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
Zeig mal dein Programm. Ich denke eher du hast einen Programmfehler gemacht und Ghosting produziert.
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
Statische Ansteuerung wäre auch eine Möglichkeit. Beitrag "7-Segm.-LED-Anzeige, 6-stellig, statische Ansteuerung mit (74HC)4094"
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!
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.
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.
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.
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
Danke Karl Heinz, über die bin ich auch schon gestolpert. Die sind wie es scheint für 4-stellige Anzeigen - eine Stelle zu breit.
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
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 | }
|
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
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 | }
|
> 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.
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
... artur hat anscheinend vor Verzweiflung schon in die Lochrasterplatine gebissen. :-)
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.
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.
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...
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
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.
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
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 | }
|
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.
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
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
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
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!
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.
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
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
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.
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
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.
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.
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.
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.
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"
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.
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 | }
|
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
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.
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.
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.
> @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
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.
> 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.
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.
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
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
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...
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.
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
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.
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 :-)
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.
Peter Bergmann schrieb: > Ist zwar kein 7-Segment Display, aber es ist sehr kompakt. cool, wo gibts denn sowas?
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
Matthias Sch. schrieb: > Falls es interessiert, kann ich mal den entsprechenden Abschnitt im CMOS > Kochbuch raussuchen. Gerne!
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.
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.
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
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.
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.
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.
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.
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.
> 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.
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!
Hallo nochmal, ich habe die Schaltung mit Platine von m.n. aufgebaut und es funktioniert wunderbar) Vielen Dank nochmal!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.