Forum: Mikrocontroller und Digitale Elektronik 15x 7-Segmentanzeigen (5x 3er) mit Bascom


von David S. (tischler)


Lesenswert?

Hallo allerseits!

Ich habe schon vor langer Zeit einen Zähler "entwickelt" - es soll der 
Punktestand von 5 Spielern gezählt werden. Mit einem Taster wird der 
Spieler ausgewählt, mit zwei Tastern der Punktestand um 1 erhöht / 
verringert und mit einem 3. auf 0 gesetzt. (Nach Adam Riese: 8 Taster). 
Dieses System, mit 7-Segment-Anzeigen (2 Stück pro Spieler) habe ich 
Analog aufgebaut - dies führte zu einer riesigen Schaltung. Man hat mir 
- sinnvollerweise natürlich - geraten, die Schaltung doch mit einem µC 
zu programmieren...


Nun ist es soweit, die ersten Sachen sind mit einem µC programmiert, und 
ich habe mein altes Projekt wieder rausgekramt - wohl auch nun mit einer 
3-stelligen 7-Segment-Anzeige (gemeinsame Kathode).

Nun stellt sich jedoch die Frage, wie geht man dies am besten an:

# alle 5 3-stelligen Anzeigen direkt am µC multiplexen? wären 7 LED 
Ausgänge, 15 Multiplexing-Ausgänge, 8 Tastereingänge und 5 Ausgänge für 
eine LED um den ausgewählten Spieler anzuzeigen.

# Treiber IC? Max7219  Max7221  ICM7218 / SAA1064 ?

# I2C-Portexpander wie z.B. PCF8574?

# Stellentreiber wie ULN2003 und ULN2803?

Dies sind zumindest die Varianten, welche ich auf Anhieb herausgefunden 
habe. Vielleicht kann ja einer sagen "ach, so ne große Anzeige löst du 
am besten direkt mit dem XYZ" - dann kann ich mich in ein Bauteil 
reinfuchsen, und nicht in alle :)

Danke, Tischler

P.S.: Programmiert soll im Anschluss alles mit Bascom

von Mega16 (Gast)


Lesenswert?

Hallo,
der ATMega16 hat 4 vollständige Port, also 32 frei verfügbare Portpins.
Das reicht für dein Projekt.
Klar ist der Einsatz der I2C Portexpander etwas eleganter, bedeutet aber 
zusätzlichen Aufwand.
Ob du zusätzliche Treiber brauchst, hängt vom Strombedarf der Anzeigen 
und von der gewünschten Helligkeit ab.

von David S. (tischler)


Lesenswert?

> der ATMega16 hat 4 vollständige Port, also 32 frei verfügbare Portpins.
> Das reicht für dein Projekt.

Naja - 15 + 7 + 8 + 5 = 35...

Und ich habe mit dieser Lösung glaube ich den größten 
Verdrahtungsaufwand - bin mir hiermit aber nicht sicher.

von m.n. (Gast)


Lesenswert?

Statisch mit Schieberegistern geht's ganz einfach
Beitrag "7-Segm.-LED-Anzeige, 6-stellig, statische Ansteuerung mit (74HC)4094"

von Mega16 (Gast)


Lesenswert?

auweija, ja, hab die 7 übersehen,

Na dann muss doch ein PCF her. Z.B um die Eingänge zu erfassen oder die 
Spieler-LED zu schalten.

Verdrahtungsaufwand hast du sowieso, egal ob die Anzeigen am Expander 
oder am Portpin hängen. Wenn du es hinbekommst, die komplette 
Spielstandsanzeige mit Portexpandern zu konstruieren und diese auf die 
Leiterplatte der Lichtschachtanzeigen zu packen, reduziert sich die 
Verdrahtung auf den I2C (oder SPI wenn du willst) Bus

Ev könnte man die Anzeige des aktuellen Spielers blinken lassen um die 
Spieler LED einzusparen, oder BCD zu 7 Segment Dekoder einsetzen.

von David S. (tischler)


Lesenswert?

> Statisch mit Schieberegistern geht's ganz einfach
> Beitrag "7-Segm.-LED-Anzeige, 6-stellig, statische Ansteuerung mit (74HC)4094"

Der Schaltungsaufwand ist in der Tat sehr simpel... Aber: Meine 3er 
7-Segment-Anzeigen sind nicht einzeln anzusteuern, also nicht jedes 
Segment einzeln - die haben 12 Pins: a, b, c, d, e, f, g, 3x Multiplex, 
+ und -
Es sind 3 Anzeigen in einem "Block".

von David S. (tischler)


Lesenswert?

> Ev könnte man die Anzeige des aktuellen Spielers blinken lassen um die
> Spieler LED einzusparen, oder BCD zu 7 Segment Dekoder einsetzen.

Die Spieler LED möchte ich schon behalten, ständig etwas blinken zu 
lassen sieht doof aus, und außerdem hat man ja dann einen noch größeren 
/ komplizierteren Programmieraufwand.
Aber den BCD zu 7-Segment-Dekoder habe ich vergessen, den könnte man ja 
nehmen - dann würde das wieder passen und könnte mit dem Atmega16 ganz 
ohne weitere IC's auskommen.

Ist es denn "ratsam", dies so aufzubauen?

Hat jemand eine "klassische-Multiplex-Programmierung" zur Hand bzw. in 
seinem Programm, und kann mir die flux hier rein kopieren?

von Martin V. (oldmax)


Lesenswert?

Hi
Mal eine ganz bescheidene Anfrage, habt ihr bei eurem Spiel einen PC in 
Reichweite ? 15 Anzeigen zu multiplexen wird m.E. nicht so gute 
Ergebnisse bringen. Meine Rentneruhr hat 12 Anzeigen und da hab ich 
schon 2 Gruppen gemultiplext. Wenn ihr aber einen PC irgendwo habt, dann 
lasst doch die Anzeige über den Monitor laufen. Ist viel spannender, 
Ergebnisse können archiviert werden und mit VB ist das gar nicht so 
schwer, ein gutes Anwenderprogramm zu erstellen. Der Controller macht 
die Hardware, also Punkte aus irgendwelchen Ereignissen zählen und 
liefert diese dann per RS232 an die VB-Anwendung. VB 2008 hab ich 
irgendwo im kostenlosen Download gesehen. Mach dich bei Interesse mal 
schlau.
Gruß oldmax

von David S. (tischler)


Lesenswert?

> Mal eine ganz bescheidene Anfrage, habt ihr bei eurem Spiel einen PC in
> Reichweite?

Ne, ein PC ist nicht dabei - es soll eine mobile / portable Lösung sein.

von m.n. (Gast)


Lesenswert?

David Schwandt schrieb:
> Es sind 3 Anzeigen in einem "Block".

Gut, dann mußt Du multiplexen.

David Schwandt schrieb:
> Hat jemand eine "klassische-Multiplex-Programmierung" zur Hand bzw. in
> seinem Programm, und kann mir die flux hier rein kopieren?

Beitrag "Frequenz, Drehzahl, 4x7-Segment LED, Multiplex-Betrieb"
Es hängt vom Wirkungsgrad der Anzeigen ab, wieviele Anzeigen man direkt 
mit einem µC multiplexen kann. 4-6 Stellen sind zumeist machbar.

Vielleicht gefallen Dir auch LC-Anzeigen?
Ideal für eine mobile Lösung.
Beitrag "7-Segm. LCD-Ansteuerung, 4-stelliges Einbaumodul, Attiny45"

von Joerg (Gast)


Lesenswert?

Man könnte (bei den Preisen!) auch mal einen 2. oder noch mehr uC 
spendieren...

von Karl H. (kbuchegg)


Lesenswert?

Joerg schrieb:
> Man könnte (bei den Preisen!) auch mal einen 2. oder noch mehr uC
> spendieren...

Würde ich nicht tun.
Verkompliziert nur die Programmierung um eine zusätzliche 
Kommunikationskomponente.

von Karl H. (kbuchegg)


Lesenswert?

Die 15 kann man noch runterbrechen.
Einen 16 aus 4 Dekoder benutzen. Dann braucht man an Pins

4 fürs Multiplexen
7 für die Segmente
5 für die Taster der Spieler
2 für +-
1 für Clear
---
19 Pins

Allerdings ist ein 15:1 Multplex schon grenzwertig. Hmm.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

David Schwandt schrieb:

>> der ATMega16 hat 4 vollständige Port, also 32 frei verfügbare Portpins.
>> Das reicht für dein Projekt.
>
> Naja - 15 + 7 + 8 + 5 = 35...

Falsch gerechnet. Wenn man sowieso LEDs muxed, dann nutzt man natürlich 
sinnvollerweise die Spalten oder Zeilen der LED-Matrix gleich auch als 
Spalten und Zeilen einer Tastaturmatrix. D.h.: Deine 8 Taster kosten 
nicht acht Pins, sondern gar nur einen, was zu folgender Rechnung führt:

15 + 7 + 1 + 5 = 28 -> 40-poliger ATMega hat noch Reserven

> Und ich habe mit dieser Lösung glaube ich den größten
> Verdrahtungsaufwand

Kommt drauf an. Jedes zusätzliche Bauelement erhöht prinzipiell die Zahl 
der Signale. Ob der Verdrahtungsaufwand dadurch erhöht wird, hängt 
einfach davon ab, welche Signale verdrahtet werden müssen. Wenn nur zu 
den LEDs
Strippen gezogen werden müssen, ist der Verdrahtungsaufwand unabhängig 
von der Implementierung der Ansteuerung, denn die Zahl der LED-Signale 
bleibt ja konstant bei 10 pro dreistelliger Einheit.

von David S. (tischler)


Lesenswert?

> Falsch gerechnet. Wenn man sowieso LEDs muxed, dann nutzt man natürlich
> sinnvollerweise die Spalten oder Zeilen der LED-Matrix gleich auch als
> Spalten und Zeilen einer Tastaturmatrix. D.h.: Deine 8 Taster kosten
> nicht acht Pins, sondern gar nur einen, was zu folgender Rechnung führt:

Das musst du mir etwas anders Erklären, das verstehe ich nicht ganz...

> Vielleicht gefallen Dir auch LC-Anzeigen?

Nee, die 7-Segment gefallen mir von der Optik her besser, außerdem habe 
ich die bereits auf Lager. Desweiteren finde ich es schöner - da das 
"Gerät" später in etwas abgedunkeltem Licht genutzt wird, wenn die 
Ziffern leuchten und nicht der Hintergrund.

von Ideas (Gast)


Angehängte Dateien:

Lesenswert?

Habe mal einen Schaltungvorschlag angehängt.
So als Idee. Manchmal hilft die 74er Familie beim vereinfachen der 
Ansteuerung schon ganz gut.

von Martin V. (oldmax)


Angehängte Dateien:

Lesenswert?

Hi
Fünfzehn Anzeigen zu multiplexen ist machbar, aber das Ergebnis 
sicherlich nicht erfreulich. Geh mal davon aus, das du im mSek. Takt die 
Ziffern durchschaltest. Das bedeutet, du hast jede Ziffer alle 15 mSek. 
genau für eine mSek. angesteuert, die Schaltzeiten der Treiber mal 
vernachlässigt. Du wirst auf diese Weise die Anzeigen wirklich 
grenzwertig ansteuern müssen, um überhaupt Helligkeit rein zu bekommen. 
Vielleicht, wenn du ein paar IC's einsetzt läßt es sich mit 5 Gruppen 
und 5 74xx47 (7Segment-Decoder) aufbauen. Du brauchst dazu 5*4 für die 
Ziffer der Azeigegruppe, 3 für die Selektierung der Ziffer, das sind 23 
Pins. Das liefert dir ein Atmega 16 und du hast genug Pins für andere 
Zwecke. Wichtig ist, das du die Ziffern erst ausschaltest, die neue Zahl 
ausgibst und dann die Ziffern wieder einschaltest, sonst erhältst du ein 
"Überleuchten" der Anzeige.
Hab die mal eine Skizze angehängt. Die Signalpegel sind noch anzupassen 
und auch die Zifferntreiber hab ich weggelassen. Die sind zwingend 
erforderlich, da du dort den Segmentstrom von 5*7 Segmenten hast. Also 
bis zu 700 mA bei einem Segmentstrom von 20 mA. Das treibt kein Ausgang 
eines Controllers!
Gruß oldmax

von Mega16 (Gast)


Lesenswert?

Martins Idee finde ich gut. Damit reduziert man alles auf ein 1 aus 3 
Multiplexing.
Also leuchten immer 5 Anzeigen gleichzeitig. Führende Nullen ev  über 
den Decoder ausblenden?

von David S. (tischler)


Lesenswert?

Ich denke auch, die Idee von Martin ist die beste - sie "passt" auf den 
Atmega16 was die Pins angeht, und ich habe nur 3 Multiplexer, und es 
werden - wie ihr schon geschrieben hat - 5 Ziffern gleichzeitig 
angezeigt und nicht nur eine.
Heute Abend / Nacht plane ich mal einen genaueren Schaltplan.

Der Haken: wie gehe ich denn jetzt hier die Programmierung an? 
Multiplexing habe ich bisher noch nicht programmiert, und erst recht 
nicht solch verschachtelte. Ist ein Standard-Bascom-Multiplexing-Code 
vorhanden, den ich dann vll. umändern kann?

Führende Null ausblenden? Auf jedenfall - sieht schöner aus, ist 
energiesparsamer und sinnvoller - sie wird nicht benötigt.

von Karl H. (kbuchegg)


Lesenswert?

David Schwandt schrieb:

> Der Haken: wie gehe ich denn jetzt hier die Programmierung an?
> Multiplexing habe ich bisher noch nicht programmiert,


dann wirds Zeit.

> und erst recht
> nicht solch verschachtelte.

Ob eine oder 5 gleichzeitig ist auch schon wurscht.

> Ist ein Standard-Bascom-Multiplexing-Code
> vorhanden, den ich dann vll. umändern kann?

Warum schreibst du nicht einen.
Letzten Endes ist das nichts anders als ein Timer mit zugehöriger 
Interrupt Routine. In der Interrupt Routine wird 1 Stelle einer Anzeige 
ausgegeben. Mit jedem Aufruf eine andere Stelle.
Ok, bei dir ist es nicht 1 Anzeige sondern deren 5, aber der Mechanismus 
ist für alle 5 gleich,

> Führende Null ausblenden?

Ja, kann man machen.
Ist jetzt aber nicht dein vorrangiges Ziel.

Erst mal muss der Timer-Interrupt die Leuchtmuster ausgeben. Und erst 
dann beschäftigst du dich damit, wie die Leuchtmuster für jede Stelle zu 
erzeugen sind.

: Bearbeitet durch User
von David S. (tischler)


Angehängte Dateien:

Lesenswert?

Was meint ihr - ist das der richtige Ansatz, oder bin ich ganz auf dem 
Holzweg?
Mit Timer und Co habe ich bisher noch nicht gearbeitet - aber braucht 
man ihn denn?

von Martin V. (oldmax)


Angehängte Dateien:

Lesenswert?

Hi
Gut, in Bascom kenn ich mich nicht aus aber ein Programmschema kann ich 
dir Liefern. Dazu noch ein Tipp: Du brauchst die Taster nicht per 
Interrupt einlesen. Die kannst du locker einmal am Schleifenanfang lesen 
und dann auswerten. Den Übertrag vom Zähler zu Ziffer machst du nur, 
wenn sich die Zahl ändert. Der Timer arbeitet für sich und adressiert 
die Ziffern, einmal für die Anzeige und einmal für die Variable. Das 
Schema gibt dir die Möglichkeit, einzelne Blöcke zu programmieren und zu 
testen. Hast du einen Kanal fertig, kannst du die anderen aufbauen. Es 
ist immer ratsam, sich eine solche Skizze hinzulegen. Das Programm wird 
danach entwickelt. So behältst du den Überblick. An die Module schreibst 
du die Information, welche Subroutine, welche Variable. Du wirst sehen, 
es ist ganz einfach. Ach ja, der 7447 ist für deine Anzeige nicht 
geeignet. Der 7449 jedoch ist für Anzeigen mit gem. Kathode. Die 
Widerstände must du ausprobieren, ich denke so bei 150 - 180 Ohm sollten 
passen. Bei den Transistoren denk ich tut es ein 1kOhm.
Und nun viel Spaß, mehr werd ich nicht beitragen können.
Gruß oldmax

: Bearbeitet durch User
von Hubbse (Gast)


Lesenswert?

Schau wie Martin hier arbeitet: erstmal ein Blockdiagramm. Mach dein 
eigenes, beschrifte es ausführlich.
Egal in welcher Programmiersprache du das umsetzt, allem voran geht ein 
Programmablaufplan auf PAPIER.

Der Timer soll den Takt für die gesamte Abarbeitung der Routinen 
vorgeben. Maßgeblich ist er für den Multiplextakt verantwortlich. Es 
geht auch ohne Timer mit 1000en Waits, das ist aber recht albern und 
wird früher oder später zum Probierspiel.
Timer sind ganz einfach, Timerinterrupts auch. Teste mal die Timer mit 
einer LED oder Piepser am Portpin.

Ich würde die beiden Halbbytes (Nibbles) für die Ziffernwerte nicht 
bitweise deklarieren, sondern den ganzen Port als Byte bearbeiten. Das 
obere Nibble  des Port wird mit +16 (&HA0) um "eins" erhöht, das untere 
mit +1. Soll ja nur aufwärts zählen, oder?

Tom

von Martin V. (oldmax)


Angehängte Dateien:

Lesenswert?

Hi
Fünf Minuten hab ich noch. Da du für jeden Spieler einen eigenen Taster 
willst, ok, da wirst du mit einer Tastenmatrix arbeiten müssen. Dafür 
nimmst du die Ausgänge, mit denen du die Ziffern beim Multiplexen 
selektierst, und legst diese jeweils auf die Taster. (statt GND) Damit 
kannst du schon mal 3x3 also 9 Tastersignale erstellen. Um anzuzeigen, 
welcher Spieler grad aktuell angewählt ist, reicht eine LED, oder du 
spendierst einen weiteren Baustein, um eine 7-Segmentanzeige 
anzusteuern. In der Timer-ISR liest du dann die Eingänge und ordnest 
diese dann zu. Die Pull-Down Widerstände benötigst du, wenn du aktive 
High Selectausgänge hast. Bei active Low genügt der Interne. Evtl. 
brauchst du auch Dioden, wenn die Möglichkeit gegeben sein soll, das 
auch mehrere Taster gleichzeitig betätigt werden. Wenn du mit active Low 
arbeitest, dann sind die Dioden natürlich anders herum einzubauen. 
Außerdem ist es ratsam, im Programm den logischen Status zu drehen, denn 
im Kopf ist ein gedrückter Taster "1". Bei Taster, die GND schalten, ist 
es aber invers. Irgendwann einmal fällst du damit auf die Nase und 
suchst dir einen Wolf. Also, darauf achten.
Gruß oldmax

von David S. (tischler)


Angehängte Dateien:

Lesenswert?

So - also "eigentlich" ist das Programm fertig - aber es will noch nicht 
so ganz...

@ Martin - die Tasten habe ich erstmal nicht in eine Tastenmatrix 
eingearbeitet

Im Anhang mein Code.
Was passiert?

Ich wähle den Spieler mit Tastendruck auf "Spieler5tast" aus, und drücke 
auf die Taste "Tastup" und löse den Interrupt "Zahlup" aus. Da "Spieler 
= 5", lande ich bei "Spieler5inc". Hier habe ich nun mit Absicht "If 
Punkte5e = 1 Then Portc.0 = 1" eingebaut, um zu sehen ob er bis hier hin 
landet - das tut er auch.
Wenn ich 5 mal nun "Tastup" auswähle, müsste "Punkte1e" normalerweise 
den Wert "5" haben und PortC.1 müsste high werden - wird es aber nie, 
egal wie oft ich auf die Tasten haue.

Nun habe ich unter "Spieler4inc" am Ende "portc.0 = 0" eingebaut, um die 
LED wieder zu deaktivieren. Spieler4tast gedückt, "Spieler = 4", 
"Tastup", lande bei "Spieler4inc", und die LED ist wieder aus.

Wähle ich jetzt wieder Spieler 5 aus, und drücke "Tastup", sollte man ja 
meinen, dass die LED aus bleibt - da Punkte1e bereits 1 ist, und nun um 
1 erhöht wird. Es steht ja "if Punkte5e = 1 then ..." - aber die LED 
geht wieder an!
D.h. mein größtes Problem ist im Moment, dass der Gute gar nicht zählt 
oder nicht zählen will :D
Die Variablen sind alle als Byte deklariert.

Übersehe ich irgendetwas???

von Martin V. (oldmax)


Lesenswert?

Hi
Bitte versteh mich richtig, ich will hier nicht an der Art und Weise der 
Programmierung Kritik üben, sondern dir einen Tip geben, wie du deine 
Programme besser aufbauen und prüfen kannst.
Du hast 5 Zählgruppen, die alle im Pronzip das Selbe machen: hoch und 
runterzählen, je nach Ereignis. Du hast einen Zähler, der die Gruppen 
selektiert.
Also beginne:
Eine Subroutine, der du den Index der gewählten Gruppe mitgibst. Für 
deine Zähler baust du ein Array, keine einzelnen Variablen. Wie das nun 
in BACOM deklariert wird, weiß ich nicht, aber in etwa so
DIM Spieler as ARRAY[1..5, 1..3] as Integer
Dim Spieler_Select as Integer
In der Subroutine greifst du auf das Array über den Spieler_Select zu
Sub Count_UP(Index as Integer)
  Inc Spieler(Index, 1)
  if ....
 etc
End Sub
Aufruf entsprechend
  Count_Up(Spieler_Select)

Der Vorteil: Funktioniert diese Subroutine einmal, kannst du davon 
ausgehen, das es bei allen Spielern funktioniert.
Gleiches gilt dann für den Multiplexer. Bau dir ein Array, welches alle 
Ziffern aufnehmen kann.
DIM Anzeigepuffer as Array(1..15) as Integer ( Byte)
Dim Multiplex_Cnt as Integer

Deine Multiplexroutine greift entsprechend auf das Array zurück:
Sub Multiplexen()
    Anzeige_aus(Multiplex_Cnt)
    Inc(Multiplex_Cnt)
    If Multiplex_Cnt>15 then Multiplex_Cnt = 1
    Port = Anzeigepuffer(Multiplex_Cnt)
    Anzeige_ein(Multiplex_Cnt)
End Sub

Anzeige_aus(Ziffer_Sel as Integer)
    ....
End Sub

Anzeige_Ein(Ziffer_Sel as Integer)
    ....
End Sub
 Diese Programmblöcke nimmst du nach und nach in Betrieb. Nun kommt der 
Zeitpunkt, wo du Änderungen in den Zählerständen in das Multiplexarray 
übertragen musst. Das kannst du entsptechend für den Spieler mit ein 
wenig Mathematik abarbeiten.
Sub Werte_Aenderung( Index as Integer)
   Dim I as Integer
   Dim Gruppe as Integer
   Gruppe = (Index) -1*3  '
   For I = 1 to 3
      AnzeigePuffer(Gruppe+i)=Spieler(Index,I)
   next i
End Sub

Anfangs testest du mit festen Werten. Erst wenn es funktioniert, setzt 
du die Variablen ein.  Ansonsten, es hilft, sich Skizzen anzufertigen 
und danach zu arbeiten.
Gruß oldmax

von David S. (tischler)


Lesenswert?

Hallo oldmax,

danke für deine Hilfe - und dass du es auch nur Gut meinst, ist klar ;)

Jedoch komme ich mit deinem Programm-Auszug nicht ganz klar... Es fängt 
schon hier an:
"DIM Spieler as ARRAY[1..5, 1..3] as Integer"
Warum als Integer? und warum [1..5, 1..3], soll es Spieler11, 12 ... 53 
generieren? Glaube nicht dass das in Bascom geht...
Ich bin was Bascom bzw. allgemein µC angeht noch recht frisch und brauch 
daher etwas länger bis ich fremde Code-Fragmente verstanden habe ;)

An für sich sollte mein Programm ja auch laufen... nur hängt es 
wahrscheinlich an einer idiotischen Kleinigkeit, da mein lieber zu doof 
zum zählen ist (einfach ausgedrückt)...

Gruß, Tischler

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.