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
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.
> 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.
Statisch mit Schieberegistern geht's ganz einfach Beitrag "7-Segm.-LED-Anzeige, 6-stellig, statische Ansteuerung mit (74HC)4094"
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.
> 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".
> 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?
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
> 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.
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"
Man könnte (bei den Preisen!) auch mal einen 2. oder noch mehr uC spendieren...
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.
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
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.
> 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.
Habe mal einen Schaltungvorschlag angehängt. So als Idee. Manchmal hilft die 74er Familie beim vereinfachen der Ansteuerung schon ganz gut.
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
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?
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.
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
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?
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
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
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
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???
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.