Forum: Mikrocontroller und Digitale Elektronik 7Sgement 12V Betrieb, per multiplexen


von Dominik W. (dominik_wa)


Angehängte Dateien:

Lesenswert?

Hi zusammen,

Ausgangslage war:
ein flexible einzustellende Zeitanzeige(countdown) zu bauen im Format 
mm:ss
die bis max. 90 min einzustellen geht.

Nach einer kleinen Projektpause habe ich mich wieder an mein Projekt 
begeben um den nächsten Schritt zu vollenden.

Der wäre mein Arduino Programm, was über kleine 7 Segmentanzeigen 
direktangesteuert werden konnte und nun auch  komplett so funktionierte, 
aufzurüsten auf die 8-10 Volt Anzeigen 57mm .Allerdings habe ich dabei 
das nächste Problem das ich meine Anzeigen nur Komplett ansteuern kann 
(sprich es zeigt mir nur die 4* 8 an) und nicht die einzelnen Segmente 
selbst.

Dabei verwende ich die Treiber:
ULN 2803= für die Common Kathode 4 Segmente
2*UDN 2981/ die Toshibar  variante = für meine 7 Segmente mit 12V
1* UDN2981 für die Punktsteuerung mit 5V.

ich hoffe das wird auf den Bild so ersichtlich da ich es nur um einen
 UDN 2981 er gänzt habe sowie das ich ein ARDUINO MEGA 2560 benutze.

Ist dieser Schaltungsaufbau schon falsch?
Ich gehe nicht davon aus das ich an dem Programm was ändern müsste, wenn 
es mir schon bei 5V Betrieb funktioniert hat!?

Wenn mir jemand bei dem Problem behilflich sein kann wäre ich sehr 
verbunden! Leider kenne ich mich in dieser Materie noch nicht so gut 
aus.

vielen Dank schon im voraus.

vg Dome

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

LEDs benötigen Vorwiderstände, auch im Multiplexverfahren.

von Jörg R. (solar77)


Lesenswert?

Dominik W. schrieb:
> Dabei verwende ich die Treiber:
> ULN 2803= für die Common Kathode 4 Segmente
> 2*UDN 2981/ die Toshibar  variante = für meine 7 Segmente mit 12V
> 1* UDN2981 für die Punktsteuerung mit 5V.

Das die Vorwiderstände fehlen wurde schon geschrieben.

Den UDN2981 für die Punktsteuerung verstehe ich nicht. Meinst Du damit 
die Dezimalpunkte? Die haben eine andere Uf als die Segmente, aber das 
kann durch erhöhen des Vorwiderstands ausgeglichen werden.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Siehe LED-Matrix.

von Peter D. (peda)


Lesenswert?

Dominik W. schrieb:
> Ich gehe nicht davon aus das ich an dem Programm was ändern müsste, wenn
> es mir schon bei 5V Betrieb funktioniert hat!?

Na dann zeig dochmal die beiden kompletten Schaltpläne. Und bitte nicht 
so winzig, sondern lesbar!

Dein Code scheint nur die Hälfte zu sein. Ich sehe nirgends den 
Timerinterrupt zum Multiplexen und das Array zum Wandeln der Ziffer in 
7-Segment.

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


Lesenswert?

Dominik W. schrieb:
> Ich gehe nicht davon aus das ich an dem Programm was ändern müsste
Ein Programm, das in der Hauptschleife (das Wort hört sich irgendwie 
wichtig an, oder?) mit delay() aktiv Rechenzeit vernichtet ist 
prinzipiell fehlerhaft. Und auch die Verwendung eines Interrupts für 
einen Taster zeugt von einem unfertigen Programm. Tastereingaben sind 
sooooo langsam, dass geht garantiert mit Polling.
Das Programm muss also sowieso noch grundlegend überarbeitet und auf 
Zustandsautomaten umgebaut werden.

von Dominik W. (dominik_wa)


Angehängte Dateien:

Lesenswert?

@ Knut: danke ich habe nur irgendwo gelesen, dass ich sie mir hierbei 
eben sparen kann da schon Widerstände im IC verbaut sind.


@Jörg: Das war das war überflüssig und habe ich schon mit in dem 
Schaltplan berücksichtig.


@Falk danke für den Link.


@Peter: danke. Hoffe er ist nun groß genug geworden und 
funktionsfähig.:)

Die Thematik mit dem Code, naja ich dachte man schließt nur die ICs 
dazwischen und das Funktioniert dann auch in der großen Version.

> void time_segments_einstellen()
> void convert_time_to_digit()

in diesen zwei Funktionen wird die Umwandlung doch vollzogen oder 
funktioniert mir das hier doch nicht so, auch wenn das kein ARRAY ist?

Beweise habe ich, dass es bei der direkt Ansteuerung mit diesem Code 
funktioniert hat.


@Lothar: danke für deine Info, nur leider verstehe ich gerade nicht so 
viel was du mir sagen willst bzgl.

>Ein Programm, das in der Hauptschleife (das Wort hört sich irgendwie
>wichtig an, oder?) mit delay() aktiv Rechenzeit vernichtet ist
>prinzipiell fehlerhaft.

Das ich meine Taster z.t. paar mal drücken muss stimmt schon, aber 
polling ist doch dafür auch nicht das richtige. Wie ich schon gleich bei 
meiner Suche auf den ersten Seiten gelesen habe und was meinst du mit 
Zustands Automaten???

danke für die ganzen Infos...

von H.Joachim S. (crazyhorse)


Lesenswert?

Lothar M. schrieb:
> mit delay() aktiv Rechenzeit vernichtet ist
> prinzipiell fehlerhaft.

Meist ja, verallgemeinernd nein. Es gibt genug triviale Anwendungsfälle 
für einen MC.

von Jörg R. (solar77)


Lesenswert?

Warum werden die Dezimalpunkte einzeln angesteuert?

von Peter D. (peda)


Lesenswert?

Dominik W. schrieb:
> Beweise habe ich, dass es bei der direkt Ansteuerung mit diesem Code
> funktioniert hat.

Ist der Code wirklich von Dir?
Hast Du ihn auch verstanden?

Ich kann den Code nicht verstehen.
Das Vermanschen des Multiplexen mit der Mainloop erschwert extrem die 
Lesbarkeit.
Außerdem erschwert die Verwendung globaler Variablen den Lesefluß. 
Niemand erkennt so, wo welche Variable geändert oder gelesen wird.
Zudem ist die Formatierung seltsam, Funktionen fängt man in Spalte 1 an.

Delays sollte man nicht mit der Suppenkelle verteilen, sondern nur da, 
wo wirklich nötig. Und dann mit Kommentar, was es bewirken soll.
Die Kommentare sind sehr spärlich.

Da niemand weiß, wie die vorherige Schaltung ausgesehen hat, kann auch 
niemand was dazu sagen, warum es jetzt nicht mehr gehen soll.
Exportier doch den Schaltplan einfach nach PDF. Dann kann ihn sich jeder 
in bequemer Größe anschauen ohne Augenkrebs zu bekommen.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Peter D. schrieb:
> Ist der Code wirklich von Dir?
> Hast Du ihn auch verstanden?

Abgesehen davon weis er auch nicht wie man LEDs polt.
Die SA23-12GWA sind Common Anode laut Datenblatt.

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


Lesenswert?

Dominik W. schrieb:
> @Lothar: danke für deine Info, nur leider verstehe ich gerade nicht so
> viel was du mir sagen willst bzgl.
>> Ein Programm, das in der Hauptschleife (das Wort hört sich irgendwie
>> wichtig an, oder?) mit delay() aktiv Rechenzeit vernichtet ist
>> prinzipiell fehlerhaft.
Die "Hauptschleife" ist deshalb so wichtig, weil sie "hauptsächlich" (= 
ständig, schnellstens, immer) durchlaufen wird.

> Das ich meine Taster z.t. paar mal drücken muss stimmt schon, aber
> polling ist doch dafür auch nicht das richtige. Wie ich schon gleich bei
> meiner Suche auf den ersten Seiten gelesen habe und was meinst du mit
> Zustands Automaten???
Du lässt dein Programm so schnell wie möglich ohne Unterbrechungen durch 
die Hauptschleife laufen. Und in dieser Hauptschleife fragst du nur ab, 
ob irgendeine Funktion ausgelöst werden muss. Konkret bedeutet das: du 
fragst einmal pro Durchlauf der Hauptschleife den (entprellten) Taster 
ab. Wenn der betätigt wurde, dann löst du eine Aktion aus.

Und für zeitliche Abläufe gibts im Arduino die funktion millis(), die 
einen Zählerwert zurückgibt, der die seit Start vergangenen 
Millisekunden darstellt. Damit kann man voll simpel zeitliche Abläufe 
machen:
http://playground.arduino.cc/Learning/BlinkWithoutDelayDe

Hier mal der Rahmen für eine Uhr, die mit einem Taster gestellt werden 
kann:
1
unsigned long tiAkt = 0; // letzter Zählerstand
2
unsigned long tiUhr = 0; // Zeitstempel letzte Uhrenaktion
3
unsigned long tiBtn = 0; // Zeitstempel letzte Tasteraktion
4
unsigned long tiMpx = 0; // Zeitstempel letzte Multiplexeraktion
5
6
unsigned long tiRpt = 500; // Wiederholzeit "Uhr stellen" anfangs 500ms
7
8
boolean up = false;
9
:
10
:
11
:
12
13
void loop(){
14
  tiAkt = millis(); // hier ein einziges Mal die aktuelle Zeit abholen
15
16
  // die Uhr
17
  if ((tiAkt-tiUhr > 1000) || (up==true)) { // gibts was zu tun? Sekunde um oder Taste gedrückt?
18
     up=false;
19
     if(sekunden<59) {
20
       sekunden++;
21
     }
22
     else {
23
       sekunden=0;
24
       if(minuten<59) {
25
         minuten++;
26
       }
27
       else {
28
         minuten=0;
29
         if(sstunden<23) {
30
           sekunden++;
31
         }
32
         else {
33
           stunden=0;
34
         }
35
       }
36
     }
37
     tiUhr=tiAkt;   // Zeitstempel merken
38
  }
39
40
  // Taster zum Uhrzeit stellen
41
  if (digitalRead(Button) == HIGH) // Taster gedrückt?
42
     if (tiakt-tiBtn>tiRpt ) {     // Repeatzeit abgelaufen?
43
        up=true;                   // Flag setzen.
44
        if (tiRpt>50) tiRpt-=10;   // schneller werden...
45
        tiBtn = tiAkt;             // Zeitstempel letzte Aktion merken
46
     }
47
  }
48
  else {                           // Taste nicht gedrückt:
49
    tiRpt = 500;                   // Werte zurücksetzen
50
    tiBtn = tiAkt;
51
  }
52
53
  // weitere Aktionen, z.B. Multiplexen mit 100Hz
54
  if (tiAkt-tiMpx > 10) {          // gibts was zu tun? 
55
     : 
56
     :     
57
     tiMpx=tiAkt;                  // Zeitpunkt letzte Multiplexaktion merken
58
  }
59
60
}
Wie gesagt: wenns nichts zu tun gibt, wird die Hauptschleife mit vollgas 
zigtausend mal pro Sekunde durchlaufen...

: Bearbeitet durch Moderator
von Peter D. (peda)


Lesenswert?

Das Multiplexen im Timerinterrupt ist sogar deutlich einfacher, als in 
der Mainloop.
Man entwickelt erstmal nur das Multiplexen und nichts weiteres. Das 
Multiplexen gibt nur 4 Bytes aus einem Array auf die 4 Anzeigen aus.
Und sobald das läuft, packt man es in den Timerinterrupt. Wenn das auch 
läuft, ist es fertig und man braucht sich nicht mehr darum zu kümmern.
Und auch nicht, wie lange die anderen Main-Funktionen brauchen.
Das 4Byte-Array ist dann quasi ein virtueller 32Bit-Port, an dem die 4 
Anzeigen hängen.
Und falls man im Interrupt Delays benötigt, dann nur ganz kurze, um das 
Ghosting zu vermeiden.

Wichtig ist an jeder Programmieraufgabe, sie in einzelne Module zu 
unterteilen und diese einzeln zu testen. Nur dann hat man Erfolg.

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


Lesenswert?

Peter D. schrieb:
> Das Multiplexen im Timerinterrupt ist sogar deutlich einfacher, als in
> der Mainloop.
Richtig. Und vor Allem: man entkoppelt damit die Aufgabe "Anzeige" von 
der aufgabe "Zählen". Angezeigt wird laufend, unabhängig davon, dass/ob 
der Zähler funktioniert.

> Und falls man im Interrupt Delays benötigt, dann nur ganz kurze, um das
> Ghosting zu vermeiden.
Meist reicht es aus, sich über die Schaltzeiten der beteiligten 
Komponenten Gedanken zu machen und dann den ganz normalen Programmcode 
in der ISR in "geschickter" Reihenfolge hinzuschreiben. Denn wenn man 
z.B. gleich nach dem Eintritt in diese ISR sofort mal die Treiber 
abschaltet, dann reichen die Mikrosekunden, bis man den nächsten Wert 
hat, meist schon aus, um die Treiber sicher abzuschalten.

Ich bleibe dabei: ein delay() in einem Programm braucht eine wichtig 
Ausrede. Die Ausrede: "das ist nur schnell so hingebastelt!" gilt 
bestenfalls bei einem, ders mit mehr Aufwand auch richtig könnte. Wenn 
aber das ganze Programm aus Ausreden besteht, dann gute Nacht...

von Dominik W. (dominik_wa)


Angehängte Dateien:

Lesenswert?

1) habe den Schaltplan in PDF ANgehängt.
2) Ein Ablese fehler hat sich eingeschlichen es sind schon die grünen
Kingbright SC23-12Gwa und somit common Cathode.

3) danke für das Programm Bsp.
4) Wie in der Code Kopfzeile geschildert habe ich das Programm 
umgeändert mit kleinen Tipps Vorort auf die Minuten und Sekunden 
Variablen umgeändert und dann schritt für schritt alles weitere ergänzt. 
Somit ging auch das zählen am Schluss sehr gut bis auf die langsam 
Taster. Zumindest dachte ich das ich es so verstanden habe  zumindest, 
das was ich außerhalb der Bib geschrieben hatte.....

5) wie ist die Frage mit dem DP gemeint die geht doch jetzt auf ein IC 
und meine 500mA Output werden immer noch nicht überschritten.
6) delays sind gleich rausgelöscht.:)
Somit bleib die eher die Schwierigkeit bei dem Code ...

von Peter D. (peda)


Lesenswert?

Dominik W. schrieb:
> 1) habe den Schaltplan in PDF ANgehängt.

Aber doch nicht von hinten durch die Brust ins Auge aus dem PNG, sondern 
direkt aus dem ECAD-Programm im Vektorformat.
Man hat doch nichts davon, wenn man ein unscharfes Bild vergrößert, es 
bleibt unscharf.

von Peter D. (peda)


Lesenswert?

Dominik W. schrieb:
> 5) wie ist die Frage mit dem DP gemeint

Warum Du den DP extra auf verschiedene Pins legst und nicht wie die 
anderen Segmente auf einen.
Das kostet Dich nicht nur einen Treiber-IC, sondern macht auch das 
Programm umständlicher.

von Axel (Gast)


Lesenswert?

Das pnp transistorarray wird nun nicht mehr sicher sperren. Dazu müsste 
der mc ja 12V als H-Pegel schmeißen. Macht aber nur 5V. Somit leiten die 
Treiber immer.
Nein - ich hab mir nicht alles angesehen. Bin mitm Handy unterwegs.

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


Lesenswert?

Peter D. schrieb:
> Warum Du den DP extra auf verschiedene Pins legst und nicht wie die
> anderen Segmente auf einen.
Das heißt übersetzt: warum betrachtest du den Dezimaltpunkt nicht 
einfach wie das 8. Segment deiner "8-Segment-Anzeige" (=7 Segmente für 
die Zahlendarstellung + 1 Segment für den Punkt)? Dann kannst du ihn 
genau gleich wie die anderen Segmente multiplexen...

von Peter D. (peda)


Lesenswert?

Axel schrieb:
> Das pnp transistorarray wird nun nicht mehr sicher sperren.

Nö, die UDN2981 habe eingebaute Levelshifter.

von Dominik W. (dominik_wa)


Lesenswert?

Hi;

wie scharf braucht ihr den die Bilder/Schaltpläne.?Ich kann auf 22Zoll 
alles gut lesen, wenn ich es öffne und erkenne somit auch wo,was 
verbunden ist.

@ Peter: Dann ist mein Gedanke für die Berechnung falsch gewesen?! 
Wollte nur nicht über meine 500mA meines ICs kommen!

Aber dann sollte der Aufbau von der Hardware Mäßigen Seite her 
funktionieren oder müsste ich noch was beachten?

Danke an Peter, Lothar,.....

vg

von Dominik (Gast)


Lesenswert?

Bzw. Dachte/Wollte es wie im alten bsp. Programm machen, dass ich erst 
bei DP setzen auch meine Zeit/Zahl (0_9) pro digit einstellen kann.
Aber ich könnte es auch nur über die common k. Machen?

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Dominik W. schrieb:
> wie scharf braucht ihr den die Bilder/Schaltpläne.

Einfach nur lesbar, anbei ein Beispiel.

Wenn ich dagegen Dein PDF zoome, kriege ich Augenkrebs.
Daß Pin 7 = A ist, muß man erahnen.

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.