Forum: Mikrocontroller und Digitale Elektronik 4 Ziffer 7-Segment Aussetzer?


von Sercan S. (disaster35)


Lesenswert?

Hallo,

 vorerst muss ich gestehen, dass ich ein blutiger Anfänger im Bereich 
Mikrocontrollerprogrammierung bin aber schon ganz fleißig arbeite :D

Ich benutze ein 4-Ziffern 7-Segmentanzeige 
(https://www.conrad.de/de/7-segment-anzeige-rot-high-efficiency-red-14-mm-2-v-ziffernanzahl-4-kingbright-cc56-11ewa-186570.html)

Ich habe mir es selbst die Aufgabe gegeben mit den Mikrocontroller 
ATMEGA8 bis 9999 zu zählen und diese auf den 7-Segmentanzeige anzuzeigen 
und es auch in C Programmiert und auf den Flashspeicher des 
Mikrocontrollers draufgespielt.

Folgende Pinbelegung habe ich PC0-PC3 werden die an oder ausgeschaltet. 
Die Ausgänge PD0-6 werden die Segmente angesteuert. In 3ms-Takt werden 
diese Ziffern halt an und ausgeschaltet. Abgesehen davon, dass ich pro 
minute 2,4 Sekunden langsamer zähle ist programmiertechnisch alles 
bestens.

Nun stimmt die Anzeige nicht ganz, bzw. es scheint so, als könnte der 
Mikrocontroller nicht genug Strom erzeugen. Bei Atmega8 soll es ja pro 
PIN max. 40mA rausgegeben werden soll, wie viel es mA es insgesamt 
rausgeben kann weiß ich leider nicht. Da ich ja "multiplexe" (bzw. der 
Mikrocontroller nicht ich), dürfte ich ja nur den Stromverbrauch eines 
Ziffers in Betracht ziehen. Bei 7-Segmenten, was in meinem Fall 20mA pro 
LED verbraucht, bräuchte ich max. 140mA bei und das bei Ziffer 8. Das 
sollte doch für den ATMEGA8 kein Problem sein oder doch?


PROBLEM:
Was mich auch noch stutzig macht ist, dass immer die Segmente die im 
inneren Bereich sind, nicht richtig dargestellt werden (warum?). Bis 99 
zeigt die Anzeige alles korrekt, ab 100 wird die mittlere Zahl nicht 
angezeigt und ab 1000 drei mal dürft ihr raten fehlen die beiden Nullen 
in der Mitte wieder. Etwa so : SOLL       IST
            9          9
           99         99
          999        9X9
         9999       9XX9

Im obigen Beispiel zeigt die Buchstabe X die Stellen an, die 
ausgeschaltet sind. Ich hoffe ihr könnt mir weiterhelfen...

Liebe Grüße :)

von Sercan S. (disaster35)


Lesenswert?

Das ich 2,4 Sekunden langsamer gezählt habe hing daran, dass ich ein 
Denkfehler reingehauen habe. Es ist so, dass ich bei den Timer 0.26112 
Sekunden pro overflow hatte. Nun ist es so, dass ich gecheckt hatte ob 
mein Zähler >= 1 (also 1 Sekunde vergangen sind) war und habe dann den 
Zähler auf 0 gesetzt, dadurch gingen mir halt jedes mal 0,04448 Sekunden 
verloren gegangen. Nun ziehe ich den Zähler eine Sekunde ab und mir 
verbleiben die 0,04448 Sekunden noch auf den Zähler nicht mehr auf 0.

Jetzt ist das ausgerechnet so, dass jede 6. Sekunde keine Sekunde dauert 
sondern ~0,8 Sekunden, aber was anderes fällt mir nicht ein.


Aber hat niemand eine Idee, warum die Zwischenziffern nicht angezeigt 
werden? :/

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Sercan S. schrieb:
> Aber hat niemand eine Idee, warum die Zwischenziffern nicht angezeigt
> werden? :/

 Um 2 Uhr ?

 Hardware ist es nicht und ohne Code kann dir nur ein Hellseher
 weiterhelfen.

von Peter D. (peda)


Lesenswert?

Ein MC hat keinen eigenen Willen. Er macht immer nur das, was Du 
einprogrammiert hast. Und er bewertet Deinen Code nicht, d.h. er führt 
auch den größten Bockmist aus, ohne mit der Wimper zu zucken.
Alle auftretenden Fehler hast nur Du selber so einprogrammiert.
Es gibt aber einen Trick, mal andere in den Code schauen zu lassen, die 
Quelldatei (*.c) als Anhang posten.

von hinz (Gast)


Lesenswert?

Sercan S. schrieb:
> Bei 7-Segmenten, was in meinem Fall 20mA pro
> LED verbraucht, bräuchte ich max. 140mA bei und das bei Ziffer 8. Das
> sollte doch für den ATMEGA8 kein Problem sein oder doch?

Kann es sein, dass du keine Vorwiderstände drin hast?

von Patrick (Gast)


Lesenswert?

Kommentiere im Code doch mal die einzelnen Ziffern aus, dann kannst du 
eine "Stromknappkeit" ausschließen. Oder einfach mal den Strom messen, 
den deine Schaltung aufnimmt.

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


Lesenswert?

Sercan S. schrieb:
> Aber hat niemand eine Idee, warum die Zwischenziffern nicht angezeigt
> werden? :/
Es könnte am Programm liegen. Oder an der Hardware.
Beides ist leider unbekannt.

von hinz (Gast)


Lesenswert?

Lothar M. schrieb:
> Beides ist leider unbekannt.

Und die Kristallkugeln sind schon wieder so stark verschlissen...

von Michael B. (laberkopp)


Lesenswert?

Sercan S. schrieb:
> es scheint so, als könnte der Mikrocontroller nicht genug Strom erzeugen

Natürlich nicht.

Sercan S. schrieb:
> dürfte ich ja nur den Stromverbrauch eines
> Ziffers in Betracht ziehen. Bei 7-Segmenten, was in meinem Fall 20mA pro
> LED verbraucht, bräuchte ich max. 140mA bei und das bei Ziffer 8.

Ja. Dauerstrom für Dauerleuchten.

> Das sollte doch für den ATMEGA8 kein Problem sein oder doch?

Schau doch einfach ins Datenblatt. Bei mehr als 20mA wird bei den 
Ausgängen nichts mehr garantiert. Warum meinst du wohl, verwenden andere 
Leute extra stromverstärkende Bauteile zwischen uC und Anzeige ?

Wenn du übrigens 4 Ziffern hast die wirklich 20mA (und nicht bloss 10mA 
wie bei den meisten Anzeigen) für Normalhelligkeit brauchen, dann musst 
du, bei 4-stelliger Multiplexanzeige, sogar 1/4 der Zeit 80mA pro 
Segment fliessen lassen, also 560mA pro Stelle, damit die Anzeige so 
hell wie bei Dauerstrom erscheint.

http://www.dse-faq.elektronik-kompendium.de/dse-faq.htm#F.8.1

von Peter R. (Gast)


Lesenswert?

Nimm erst einaml Vorwiderstände für die Segmentleitungen, die den 
Segmentstrom (und damit auch den Stellenstrom) auf einen geringeren 
Strom bringen.

worst case ist bei multiplex-Betrieb etwa: eine Stelle eingeschaltet, 
mit 8 Segmenten ein (eine "8" + dezpkt)um 2,5mA Segmentstrom und 20mA 
Stellenstrom einzustellen.

Da muss der Widerstand zwischen µC-Pin und Segmentpin den Wert haben:
(5V-1,6V) /2,5 mA  = 1,36 kOhm  ( 5V Betriebsspannung, 1,6V Spannung der 
LED im Segment).

Dann leuchtet die Anzeige nicht gerade überwältigend, aber die 
Grenzwerte für den Pin eines atmega8 werden dann eingehalten. 
(Stellenstrom < 8x2,5 mA )

Ich selbst nehme, ganz brutal bastlerisch, meist 330 Ohm, ohne dabei 
wesentliche Störungen zu sehen. (bei "1" sind die Segmente aber etwas 
heller als bei "8")

Bei 150 Ohm machte mit der Zeit der Stellen-Ausgang die Grätsche.

bei größeren Helligkeiten muss man jedenfalls Stellentreiber einsetzen.

Was die fehlenden Zeichen und die falschen Zeiten angeht, das ist sicher 
eine Frage der Software.

von m.n. (Gast)


Lesenswert?

Peter R. schrieb:
> worst case ist bei multiplex-Betrieb etwa: eine Stelle eingeschaltet,
> mit 8 Segmenten ein (eine "8" + dezpkt)um 2,5mA Segmentstrom und 20mA
> Stellenstrom einzustellen.

Die Werte noch einmal mit der Anzahl der Stellen multiplizieren, um die 
effektiven Ströme der Segemente bei Multiplexbetrieb zu erhalten!

> Da muss der Widerstand zwischen µC-Pin und Segmentpin den Wert haben:
> (5V-1,6V) /2,5 mA  = 1,36 kOhm  ( 5V Betriebsspannung, 1,6V Spannung der
> LED im Segment).

Da weitere Spannungsabfälle an den Digit-Treibern (BCxxx oder MOSFET) 
entstehen, rechnet man besser (5 - 2,5) V / (4 x 2,5) mA = 250 Ohm pro 
Segment.
Bei den o.g. Anzeigen ist der Wirkungsgrad mittelprächtig, weshalb man 
besser 100 - 150 Ohm verwendet.

von Sercan S. (disaster35)


Lesenswert?

Hallo,

ich wollte mich bei euch bedanken, dass Ihr euch die Zeit genommen habt 
mir paar Ideen zu nennen. Ich habe das ganze mit 450 Ohm Widerständen 
ausprobiert und anschließend mit 1kOhm versucht zu betreiben und es war 
leider keine Besserung da. Ich bin nochmal mein Code durchgegangen ob 
ich irgendwelche Fehler erkenne und leider bin ich auf nichts gestoßen 
(leider erkennt man an seinem eigenen Code die Fehler nicht direkt), 
außer dass ich die PINs vllt. mal in ein Array reinpacke wo ich die 
durchiterieren kann um die Segmente ein und ausschalten zu können, daran 
wird es aber nicht scheitern, dass die Zwischensegmente wegbleiben. Am 
besten zeige ich euch mal den Code und Ihr habt vllt. ein Idee woran es 
scheitert...
1
ISR (TIMER0_OVF_vect)
2
{
3
  interruptSecondCounter += 0.26112; // Bei 1Mhz, 8-Bit Timer und einem //prescalar von 1024 errechnet sich pro Interrupt so viel Zeit in Sekunden
4
  if(interruptSecondCounter >= 1){
5
    interruptSecondCounter -= 1; //Eine Sekunde ist vergangen, wir //zählen hoch und ziehen, das unserem interruptSecondCounter ab
6
    secondCounter++; //Zählt die tatsächlichen Sekunden
7
8
                //Bsp.: 9999 - (9999 % 1000) /1000 = (9999 - (999)) /1000 = 9
9
    digits[0] = (secondCounter - (secondCounter % 1000)) / 1000;
10
11
                //Bsp.: 9999 - (9999 % 100).... Ahh du heiliger Bimbo...
12
                //Ich kann doch nicht einfach 9999 % 100 machen und es von
13
                //9999 abziehen. Lägen wir bei 99 und das durch 100 sind 0,99
14
                // :D Fehler selbst gefunden...
15
    digits[1] = (secondCounter - (secondCounter % 100)) / 100;
16
    digits[2] = (secondCounter - (secondCounter % 10)) / 10;
17
    digits[3] = secondCounter % 10;
18
  }
19
20
}


Wie ihr in meinem Timer-Interrupt sehen könnt, bin ich selbst auf den 
Fehler gekommen, während ich mein Code kommentiert habe :D :D :D
Nehmen wir an wir haben die Zahl 155 gehabt.
 (155 - 55) / 100 = 1
 (155 - 5) / 10 = 1,5 :D :D :D
 155 % 5        = 5

Da ich die Ziffern einzeln abspeicher, habe ich bei der Berechnung von 
den zwischenstellen folgendes eingefügt:
(155-5 - 100er-Ziffernanzahl * 100 - 1000er Ziffernzahl*1000) / 10 =
(155-5-100-0) / 10 = 5

Wie mein Lehrer damals in der Lehre sagte: "Sercan der Fehler, liegt 
meistens 30 cm vor dem Bildschirm..."

Ich danke euch allen, die versucht haben mir zu helfen. Ich glaube, das 
nächste mal sollte ich mein Code Schritt für Schritt durchgehen...

: Bearbeitet durch User
von Tomato (Gast)


Lesenswert?

Hi Sercan!

Kannst du vielleicht deinen kompletten Code posten, wenn du ihn noch 
hast? Ich hänge gerade vor einem ähnlichen Problem und würde das von dir 
gerne richtig nachvollziehen wollen :)

LG
Tomato

von Martin (Gast)


Lesenswert?

Auch so ein Satz der in jeden zweiten Thread passt :

Mach Debugausgaben im Terminal.

Sercan S. schrieb:
> Ich danke euch allen, die versucht haben mir zu helfen. Ich glaube, das
> nächste mal sollte ich mein Code Schritt für Schritt durchgehen...

nein, sondern SOFORT wenn du auf einen Fehler stößt.

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.