Ich habe mir selbst eine 7 Segment Anzeige gebaut, um genau zu sein zwei, um alle Zahlen von 0 - 99 anzeigen zu können. Jedes Segment besteht aus 3 LED's.
Nun kommen wir zur Programmierung in C (Arduino UNO, ATmega328p):
ICH WEIß, DASS DAS HIER NICHT OPTIMAL PROGRAMMIERT/GEBAUT IST, MIR GEHT ES NUR MAL UM DEN CODE, ODER VERBESSERUNGSVORSCHLÄGE Jedes Segment wird von einem Digitalen Output angesteuert. Das geht sich perfekt aus mit den insgesamt 14 Segmenten. Im folgenden Programm sind alle Bitmuster/Bitadressen(?) (in HEX) zu den jeweiligen Zahlen/Ziffern als Kommentar eingetragen. Mein Problem ist es, jetzt effektiv von 0-99 zu zählen (sekunden schritte) UND es anzeigen zu lassen. Meine eigenen Lösungen gehen bis jetzt nur auf sehr sehr sehr viel Code hinaus (pro Zaiffer eine Zeile..oder mehr). In der angehängten ZIP Datei befindet sich eine EXCEL-Tabelle, wo man jedes einzelne Bitmuster in BIN sieht (Gelb markiert ist der rechte "Zahl", und Grün die linke), falls es Unklarheiten gibt. 7Segmentx2.c (1.96 KB) Bitmuster.zip (12.2 KB)
Für die Formatierung Deines Codes bekommst Du von mir auf jeden Fall schon einmal ein fettes Kompliment. Der ist echt schön lesbar. Hierzu nur zwei kleine Verbesserungsvorschläge:
Benutze Leerschritte, um Einzüge zu formatieren – zwei Leerschritte je Einzugs-Ebene. Grund: Wie Tabs dargestellt werden, hängt vom Betrachterprogramm ab. Leerschritte werden normalerweise in jedem Programm gleich angezeigt.
Kennzeichne das Ende Deiner Programme mit //eof oder so. Wenn das mal fehlt, weißt Du sofort, dass das betreffende Programm nicht vollständig ist.
Ich habe mir diese Dinge so angewöhnt und bislang nur gute Erfahrungen damit gemacht.
Was den Inhalt Deines Programms angeht, werfe ich später einen genaueren Blick darauf.
Eigentlich sollten sich für die Zifferndarstellung in jeder der beiden Stellen gleiche Bitmuster ergeben, ansonsten ist die Schaltung suboptimal.
Da scheint bei Dir etwas anders zu laufen.
Dann kannst Du die aktuelle Zahl in ihre beiden Stellen aufteilen (Teilweise Pseudocode):
byte ziffernArray[] = {Bitmuster der 10 Ziffern};
int zahl, zehner, einer;
zehner = zahl / 10;
einer = zahl % 10;
Ausgabe Zehner = ziffernArray[zehner];
Ausgabe einer = ziffernArray[einer];
Für die Formatierung Deines Codes bekommst Du von mir auf jeden Fall schon einmal ein fettes Kompliment. Der ist echt schön lesbar. Hierzu nur zwei kleine Verbesserungsvorschläge:
Benutze Leerschritte, um Einzüge zu formatieren – zwei Leerschritte je Einzugs-Ebene. Grund: Wie Tabs dargestellt werden, hängt vom Betrachterprogramm ab. Leerschritte werden normalerweise in jedem Programm gleich angezeigt.
Kennzeichne das Ende Deiner Programme mit //eof oder so. Wenn das mal fehlt, weißt Du sofort, dass das betreffende Programm nicht vollständig ist.
Ich habe mir diese Dinge so angewöhnt und bislang nur gute Erfahrungen damit gemacht.
Was den Inhalt Deines Programms angeht, werfe ich später einen genaueren Blick darauf.
Gruß
Gregor
Hallo Gregor! Danke für dein Feedback! Werde versuchen es mir anzugewöhnen. Danke, dass du dir zeit genommen hast, meinen Code anzusehen.
Tommy56:
Eigentlich sollten sich für die Zifferndarstellung in jeder der beiden Stellen gleiche Bitmuster ergeben, ansonsten ist die Schaltung suboptimal.
Da scheint bei Dir etwas anders zu laufen.
Dann kannst Du die aktuelle Zahl in ihre beiden Stellen aufteilen (Teilweise Pseudocode):
byte ziffernArray[] = {Bitmuster der 10 Ziffern};
int zahl, zehner, einer;
zehner = zahl / 10;
einer = zahl % 10;
Ausgabe Zehner = ziffernArray[zehner];
Ausgabe einer = ziffernArray[einer];
Gruß Tommy
Hallo Tommy! Dass es links nie die gleichen Bitmuster sind, liegt daran, dass das letzte Bit in PORTD zum obersten Segment der rechten Ziffer gehört. Hier ein Bild dazu was ich meine: Dropbox - File Deleted - Simplify your life
Kannst du mir erklären, was genau das "%" Zeichen macht?
Auch dir sage ich danke, dass du dir Zeit genommen hast, den code anzusehen!
Wäre es machbar, die Segmente jeweils auf einen Port zu legen (sollte bei 7 Bit funktionieren). Damit hättest Du vieles einfacher, da Du für eine Stelle nur genau einen Port ansprechen brauchst.
% ist die Modulodivision. Sie ergibt den Rest der Division.
z.B. 23 % 10 ergibt 3.
Du könntest auch für beide Stellen die Segmente über einen Port ausgeben und die Segmente wechseln dazu passend einschalten, also die Stellen multiplexen. Es gibt viele Varianten.
Tommy56:
Wäre es machbar, die Segmente jeweils auf einen Port zu legen (sollte bei 7 Bit funktionieren). Damit hättest Du vieles einfacher, da Du für eine Stelle nur genau einen Port ansprechen brauchst.
% ist die Modulodivision. Sie ergibt den Rest der Division.
z.B. 23 % 10 ergibt 3.
Du könntest auch für beide Stellen die Segmente über einen Port ausgeben und die Segmente wechseln dazu passend einschalten, also die Stellen multiplexen. Es gibt viele Varianten.
Gruß Tommy
Ist nicht machbar, dar der Arduino UNO nur einen Port besitzt, wo wirklich 8Bits sind (das ist der PORTD mit den pins 0-7). PORTB & PORTC(Analog) haben jeweils nur 6 Bits, deswegen muss ich das 8-te Bit von PORTD miteinbinden, um jedes Segment ansteuern zu können.
Wäre es möglich, die Segmente nicht PORT-weise anzusteuern, sondern PIN-weise?
Von der Multiplexvariante hällst Du nix?
Man kann auch über Bitshift die Segmentwerte so aufteilen dass man die beiden Registeranteile bekommt.
Bit 8 von PortD ist welches Segment von der anderen Zahl?
Wir müssen da irgendwie ein sauberes Schema rein bringen.
Schreib doch mal auf, an welchem Bit welches Segment hängt.
Wäre es möglich, die Segmente nicht PORT-weise anzusteuern, sondern PIN-weise?
Wenn du "Arduino" programmieren würdest statt nacktem C, würde sich die Frage gar nicht stellen.
Ansonsten würde ich vorschlagen, den Code bei unseren Freunden vom mikrocontroller.net vorzustellen.
Hier ist er eher verwirrend als hilfreich, denke ich.
Tommy56:
Von der Multiplexvariante hällst Du nix?
Man kann auch über Bitshift die Segmentwerte so aufteilen dass man die beiden Registeranteile bekommt.
Bit 8 von PortD ist welches Segment von der anderen Zahl?
Wir müssen da irgendwie ein sauberes Schema rein bringen.
Schreib doch mal auf, an welchem Bit welches Segment hängt.
Gruß Tommy
Bin noch Anfänger und hab keine Ahnung was multiplexen ist.
Hier siehst du welches Bit wo hängt:
michael_x:
Wenn du "Arduino" programmieren würdest statt nacktem C, würde sich die Frage gar nicht stellen.
Ansonsten würde ich vorschlagen, den Code bei unseren Freunden vom mikrocontroller.net vorzustellen.
Hier ist er eher verwirrend als hilfreich, denke ich.
Das ist mir bewusst, doch ich will es in C =D
Ok werd ich machen!
Gruß
Multiplexen heißt in deinem Fall die beiden Ziffern nicht gleichzeitig, sondern im Wechsel anzusteuern. Da das Auge träge ist, sieht es beide gleichzeitig leuchten.
Dadurch würdest Du nur 7 Bit für die Segmente (oder 8, wenn Du einen Punkt dabei hast) benötigen und 2 Pins für die beiden Ziffern.
Ablauf wäre in etwa so:
Segmente für Ziffer 1 anschalten und GND von Ziffer 1 freigeben = Ziffer 1 leuchtet.
Danach Segmente für Ziffer 2 anschalten und GND von Ziffer 2 freigeben = Ziffer 2 leuchtet.
Wenn Du das > 50 (oder 100) mal pro Sekunde machst, dann merkt man das nicht. So wie beim Fernseher.
Tommy56:
Multiplexen heißt in deinem Fall die beiden Ziffern nicht gleichzeitig, sondern im Wechsel anzusteuern. Da das Auge träge ist, sieht es beide gleichzeitig leuchten.
Dadurch würdest Du nur 7 Bit für die Segmente (oder 8, wenn Du einen Punkt dabei hast) benötigen und 2 Pins für die beiden Ziffern.
Ablauf wäre in etwa so:
Segmente für Ziffer 1 anschalten und GND von Ziffer 1 freigeben = Ziffer 1 leuchtet.
Danach Segmente für Ziffer 2 anschalten und GND von Ziffer 2 freigeben = Ziffer 2 leuchtet.
Wenn Du das > 50 (oder 100) mal pro Sekunde machst, dann merkt man das nicht. So wie beim Fernseher.
Gruß Tommy
Was bedeutet "GND freigeben"? Für jede Ziffer einen eigenen GND.. und dann?
Nochmals vielen Dank, dass du dir hier die Zeit nimmst, mir zu helfen.
Dann kannst Du entweder Ziffer 1 oder Ziffer2 einschalten, indem Du GND freigibst bzw. schaltest. Auf diese Weise sparst Du auf jeden Fall 6 Pins (7 für eine Anzeige minus 1 für einen „GND-Schalter“). Wenn Du schnell genug hin- und herschaltest, sieht es so aus, als würden beide Anzeigen permanent leuchten.
Wie hast Du Deine LED-Segmente derzeit verschaltet? Bei 3 LED wirst Du ja wahrscheinlich einen Transistor drin haben? Sind die LED in Reihe oder parallel?
Wie hast Du Deine LED-Segmente derzeit verschaltet? Bei 3 LED wirst Du ja wahrscheinlich einen Transistor drin haben? Sind die LED in Reihe oder parallel?
Gruß Tommy
Parallel geschaltet. Also hab ich pro Segment ein +. Die Schaltung baue ich erst, da noch Teile fehlen. Mein Plan war es einfach jeweils 3 LED's Parallel, ergibt 14 mal eine Verbindung zu den Arduino Outputs. Danach hätte ich einfach ALLE Kathoden verbunden, also alle an GND.
Da ich (noch) nicht weiß, was ein Transistor genau macht, habe ich auch keinen geplant. Transistoren hätte ich genug da, falls diese notwendig sind.
Mit 3 LED parallel an einem Arduino-Ausgang grillst Du Deinen Prozessor.
Du brauchst also auf alle Fälle eine extra Stromversorgung für Deine LEDs.
Transistor oder FET brauchst Du auf alle Fälle bzw. die Ansteuerschaltkreise, die diese Funktionen übernehmen.
Da gibt es jetzt wieder mehrer Möglichkeiten;)
3 LED parallel - jede mit einem eigenen Vorwiderstand oder 3 LED in Reihe mit einem gemeinsamen Vorwiderstand und dann einer höheren Versorgungsspannung der LED, dafür geringeren Strom.
Für das Multiplexing muss man beide "Enden" entsprechend zusammen schalten und steuern. Ich habe es selbst noch nicht aufgebaut.
Man kann entweder alle Kathoden einer Ziffer zusammen schalten und diesen Punkt steuern oder die Anoden - das wird dann die Ziffernauswahl.
An der anderen Seite werden jeweils die gleichen Segmente beider Ziffern zusammen geschaltet.
Bleibt das noch verständlich? Ich habe gerade keine Schaltung parat.
Tommy56:
Mit 3 LED parallel an einem Arduino-Ausgang grillst Du Deinen Prozessor.
Du brauchst also auf alle Fälle eine extra Stromversorgung für Deine LEDs.
Transistor oder FET brauchst Du auf alle Fälle bzw. die Ansteuerschaltkreise, die diese Funktionen übernehmen.
Da gibt es jetzt wieder mehrer Möglichkeiten;)
3 LED parallel - jede mit einem eigenen Vorwiderstand oder 3 LED in Reihe mit einem gemeinsamen Vorwiderstand und dann einer höheren Versorgungsspannung der LED, dafür geringeren Strom.
Für das Multiplexing muss man beide "Enden" entsprechend zusammen schalten und steuern. Ich habe es selbst noch nicht aufgebaut.
Man kann entweder alle Kathoden einer Ziffer zusammen schalten und diesen Punkt steuern oder die Anoden - das wird dann die Ziffernauswahl.
An der anderen Seite werden jeweils die gleichen Segmente beider Ziffern zusammen geschaltet.
Bleibt das noch verständlich? Ich habe gerade keine Schaltung parat.
Gruß Tommy
Ohne Schaltung kann ich mir das leider schlecht vorstellen, eben wegen den Transistoren, weil ich davon keine Ahnung habe. Warum ist das schlecht wenn ich 3 LED's Parallel schalte? Ziehen die zu viel Strom?
gregorss:
Dann kannst Du entweder Ziffer 1 oder Ziffer2 einschalten, indem Du GND freigibst bzw. schaltest. Auf diese Weise sparst Du auf jeden Fall 6 Pins (7 für eine Anzeige minus 1 für einen „GND-Schalter“). Wenn Du schnell genug hin- und herschaltest, sieht es so aus, als würden beide Anzeigen permanent leuchten.
Gruß
Gregor
Doch wie schalte ich den GND zwischen den beiden Ziffern?
flowww:
Da ich (noch) nicht weiß, was ein Transistor genau macht, habe ich auch keinen geplant. Transistoren hätte ich genug da, falls diese notwendig sind.
Wenn Du die LEDs nicht „direkt“ sondern über einen Transistor schalten würdest, könntest Du haufenweise Pins sparen. Das ist jetzt vielleicht noch nicht wichtig, aber wer weiß schon, was aus Deiner Schaltung noch wird
Ein Beispiel, wie ein Transistor als Schalter benutzt wird, findest Du z. B. hier. An Stelle des CQY99 könntest Du drei parallel geschaltete LEDs steuern.