Forum: Mikrocontroller und Digitale Elektronik riesige LED-Matrix


von Michael N. (garril)


Lesenswert?

Hallo,

möchte eine große LED-Matrix aufbauen (12 Stück 8x8er grün/rot Module).
Das gibt also 768 LEDs (bzw. doppelt so viele, sind ja grün/rot) 
anzusteuern, weshalb mir die Vorplanung sehr sehr wichtig ist.

Habe soetwas noch nie gebaut, deshalb habe ich mir andere Schaltungen 
angeschaut und versucht das auf meine Zwecke umzubauen.

Ich wollte 4 Module nebeneinander und 3 Module untereinander verbauen 
(rein physikalisch, verkabelt sollten alle in einer Reihe nebeneinander 
hängen).
Zum Multiplexen dachte ich, dass ich jeweils eine LED-Zeile jedes Moduls 
anspreche. So kann ich bei 3 Modulen untereinander also im ersten 
Multiplexing-Durchgang 3 LED-Zeilen ansteuern.
Die Helligkeit wäre dann 1/8 wobei die LEDs bis zu 5mal soviel Strom 
vertragen. Das würde mir reichen.

Jetzt habe ich hier mal ein Schaltbild erstellt:
http://s1.directupload.net/images/110918/aklmvr2p.pdf

Passt das soweit (ist mal nur ein 5x7er Modul mit grün/rot)? (Led-Matrix 
hat gemeinsame Kathode und in wirklich sind es pro Modul 8x8)
Wie könnte ich den benötigten Strom verringern (150mA Pulsstrom bei 5V 
sind ja schon einiges)

Schafft das mein Atmega8??
Ich habe ja 12*8 LEDs zu denen ich die Daten per Schieberegister schnell 
genug übertragen muss (12Byte für die Spalten und 1Byte für die Zeile). 
Und das müsste ja 8mal für das ganze Bild passieren. Das wären bei 50 Hz 
dann also 400 Durchgänge oder 5,2kByte/s

von Christian B. (casandro)


Lesenswert?

Was man da häufig macht ist es, ein Schieberegister für eine ganze Zeile 
zu machen, da dann alle Pixel einer Spalte hineinzutakten, so dass alle 
Spaltenleitungen gezeigt werden, und dann die Leitung für die Zeile 
einschalten.

Damit reduzierst Du den Multiplex auf 1:8 oder so, was auch noch eine 
erträgliche Helligkeit macht.

von Karl H. (kbuchegg)


Lesenswert?

Wenn ich das richtig sehe, dann ist das doch im wesentlichen die 
Schaltung von hier
http://www.mikrocontroller.net/articles/LED-Matrix
(nur etwas seltsam gezeichnet. Bei dir muss man dauernd umdenken, weil 
dein + Leitungen, die Spalten, von unten kommen anstelle von oben, so 
wie es üblich ist)

> Led-Matrix hat gemeinsame Kathode

?
In deinem Schaltbild ist das aber anders rum. Du hast gemeinsame Anode 
eingezeichnet.

( Anode ist der + Anschluss, Kathode ist der - Anschluss. Leicht zu 
merken: Der Strom fliesst von + nach -.  Wenn deine Schaltung also das 
Alfabet darstellt, dann trifft er, wenn er von + kommt zuerst auuf das A 
und erst dann auf das K)

von Michael N. (garril)


Lesenswert?

Hierfür ist in diesem Fall ja IC5 gedacht.
Der regelt die Zeilen (hier sinds Spalten, gehört eigentlich gedreht).
Die Register davor, tragen dann die Daten für die Spalten.

Wollte alle 12 Module hintereinander kabeln (eigentlich sind sie eben 
4x3 angeordnet, aber ich kann se ja wie eine Reihe verkabeln).

Ich müsste halt die 12 Schieberegister+das Register für die Zeile jedes 
mal neu mit Daten füttern.
Für einen Multiplexing-Durchlauf bräuchte es 8 Durchgänge womit man pro 
"Bild" schon auf 104Byte kommt.
Und damit es nicht flackert bräuchte man das ganze eben ca. 50mal in der 
Sekunde (macht dann die oben genannten 5,2kByte/s)

Wie du schon schreibst hat das ganze eine Helligkeit von 1/8. Mit dem 
5-fachen Strom kommt man dann effektiv auf ca. 5/8 Helligkeit, was noch 
mehr als die Hälfte ist. Denke das sollte reichen.

Passt meine Schaltung?

von Karl H. (kbuchegg)


Lesenswert?

Ob ich sowohl Zeilen als auch Spalten in eine gemeinsame 
Schieberegisterkette setzen würde hängt wohl davon ab, ob ich knapp an 
Pins bin. Ohne Not würde ich das nicht unbedingt machen.

von Michael N. (garril)


Angehängte Dateien:

Lesenswert?

Jetzt bin ich verwirrt...
Ich häng mal das Bild ausm Datenblatt an. Entweder ich steh total aufm 
Schlauch oder das Datenblatt ist dann falsch. Weil eigentlich haben die 
Module in C für gemeinsame Cathode im Namen.

Ich versuch das mal etwas schöner zu zeichnen.

von Karl H. (kbuchegg)


Lesenswert?

Das R bzw C im Schaltbild steht für "Row" bzw. "Column"

Du hast gemeinsame Anode. Die Anschlüsse aller + aller LED sind 
zusammengeschaltet.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_7-Segment-Anzeige

von Karl H. (kbuchegg)


Lesenswert?

Und Aufbauen würde ich das so machen:

Vom µC werden
die 8 Zeilen direkt (also nicht über SR) angesteuert. Natürlich mit 
einem Treiber dazwischen
Die Spalten (192 Stück) werden über 24 Stück 74595 + Treiber (ULN) 
jeweils nach Masse geschaltet.

Zur Ausgabe: Die Spalten einer Zeile werden komplett in das 
Schieberegister geladen und dann die jeweilige Zeile aktiviert. 
Mulltiplex ist damit 1:8 und solange du nicht dimmen willst, ist das 
timingmässig kein Problem.

von Michael N. (garril)


Lesenswert?

Für was R und C steht ist mir bei diesem Bild bekannt :)
Allerdings handelt es sich um Kingbright Module mit der Bezeichnung 
TBC23...
Und dort steht (sieht man auch auf der Herstellerseite), dass es sich 
hierbei um Module mit "Common Cathode" handelt.
(Die Module sind noch auf dem Weg zu mir. Kanns deshalb nicht 
ausprobieren. Habe eben nur dieses Datenblatt schon bekommen. Und dabei 
handelt es sich um Common Anode...
Habe jetzt mal bei anderen Datenblättern von Kingbright geschaut. 
Aktuell haben die das wohl so gelöst, dass jede LED 4 Pins (2x Anode, 2x 
Kathode) hat...Das hilft mir also auch net weiter.
Muss ich wohl warten bis ich die Module habe...

von Karl H. (kbuchegg)


Lesenswert?

Michael N. schrieb:
> Für was R und C steht ist mir bei diesem Bild bekannt :)
> Allerdings handelt es sich um Kingbright Module mit der Bezeichnung
> TBC23...
> Und dort steht (sieht man auch auf der Herstellerseite), dass es sich
> hierbei um Module mit "Common Cathode" handelt.

Das kann schon sein.
Aber das Matrix-Bild welches du gezeigt hast, hat nun mal gem. Anode.

Zeig deine 'richtige' Schaltung und nicht irgendwas was so ähnlich 
aussieht, dann gibt es auch keine Missverständnisse.

von Michael N. (garril)


Lesenswert?

Die "richtige Schaltung" ist die die ich oben gepostet hatte.
Laut Hersteller- und Artikelbezeichnung haben die Module eben gemeinsame 
Kathode. (wie gesagt, die sind noch aufm Transportweg, deshalb kann ichs 
nicht testen)
Das Datenblatt habe ich schon per Mail im voraus bekommen. Und daher 
stammt das Bild mit gemeinsamer Anode...

Wie läuft das mit den Treibern? Habe noch nie sowas verbaut (ULN2803, 
oder?)

von Matthias (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Ob ich sowohl Zeilen als auch Spalten in eine gemeinsame
> Schieberegisterkette setzen würde hängt wohl davon ab, ob ich knapp an
> Pins bin. Ohne Not würde ich das nicht unbedingt machen.

Dem µC sollte das schnurz-piep-egal sein, wo er die Daten reinschiebt. 
Wenn er das in die gleiche Kette reintaktet, spart das eher Aufwand.

Welchen Vorteil hätte eine getrenne Kette?

von Karl H. (kbuchegg)


Lesenswert?

Matthias schrieb:
> Karl Heinz Buchegger schrieb:
>> Ob ich sowohl Zeilen als auch Spalten in eine gemeinsame
>> Schieberegisterkette setzen würde hängt wohl davon ab, ob ich knapp an
>> Pins bin. Ohne Not würde ich das nicht unbedingt machen.
>
> Dem µC sollte das schnurz-piep-egal sein, wo er die Daten reinschiebt.
> Wenn er das in die gleiche Kette reintaktet, spart das eher Aufwand.
>
> Welchen Vorteil hätte eine getrenne Kette?

Dass ich die Zeile durch Setzen eines Pins ab bzw ein-schalten kann.

Geht mit einer SR Kette natürlich auch.

von Michael N. (garril)


Lesenswert?

Hab das jetzt nochmal mit nur einer Farbe (2 Matrizen nebeneinander) 
aufgezeichnet.
Passt das mit den Treibern so? Halten die das überhaupt aus (besonders 
der für die Zeilen?)

http://s1.directupload.net/images/110918/9h4lp9td.pdf

von Ulrich Radig (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe Schieberegister verwendet 74HC595 für die Zeile sowie 8 Mosfets 
für die Spalte.

Gruß
Ulrich

von Jonathan S. (joni-st) Benutzerseite


Lesenswert?

Sieht doch schon mal gut aus. Nur irgendwie vermisse ich die 
Vorwiderstände (oder sind da schon welche in den Treibern / 
Matrizen?)...

@Ulrich Radig: DAS nenne ich mal eine LED-Matrix! Wie lange hat's 
gedauert, die zu machen...?

von Ulrich Radig (Gast)


Lesenswert?

Habe 30 mal 8 Vorwiderstände verbaut also 240Stück SMD 0805
Das Layout ging relativ schnell via Cut and Paste.

von Michael N. (garril)


Lesenswert?

Wow, der brühmte Ulrich Radig :)
Das ist echt ein Geschütz von LED-Matrix
Was hängt bei dir vor bzw. hinter den 74HC595? Sind ja bestimmt noch 
Transistoren oder irgendein Treiber verbaut?!

Auf jeden Fall brauch ich nicht viel mehr planen bis nicht die Matrizen 
da sind. Denn auf gut Glück nen Schaltplan zu erstellen geht einfach 
nicht...

@Ulrich Radig: Hast du vielleicht noch einen Schaltplan, den du mir 
zukommen lassen könntest?
Stehe noch am Anfang der Elektronik, deshalb ist das alles nicht so 
einfach^^

von Ulrich Radig (Gast)


Lesenswert?

Hinter den hc595 habe ich keinen Treiber die 15 mA reichten mir aus.
Inzwischen würde ich ein Schieberegister mit Konstandstromquelle 
verwenden.
Ich habe von den Anzeigen 50 Stück gebaut und keine Probleme gehabt.

von Ulrich Radig (Gast)


Lesenswert?

Ich kann dir nachher was zukommen lassen bin gerade vom IPhone im Netz. 
Schicke mir mal eine EMail habe auch noch eine Anzeige mit 15 Segmente.

von Michael N. (garril)


Lesenswert?

15mA trotz multiplexing?
Hab bei mir jetzt mal pro LED 100-150mA geplant :O

Kann mir jemand sagen ob ich die Treiber grundsätzlich richtig verbaut 
habe?:
http://s1.directupload.net/images/110918/9h4lp9td.pdf


eidt: @Ulrich Radig: Hab dir eine Mail geschickt. Danke schonmal

von ... (Gast)


Angehängte Dateien:

Lesenswert?

Michael N. schrieb:
> Und dort steht (sieht man auch auf der Herstellerseite), dass es sich
> hierbei um Module mit "Common Cathode" handelt.

Im Datenblatt der TBC23... steht nur "Column Cathode".

Michael N. schrieb:
> Allerdings handelt es sich um Kingbright Module mit der Bezeichnung
> TBC23...

Das Bild im Datenblatt der TBC23... sieht auch anders aus als das was du 
gepostet hast.

von Michael N. (garril)


Lesenswert?

Ja im Datenblatt steht hierzu nichts.
Aber die Bezeichnungen auf folgender Seite sagen eigentlich aus, dass 
alles was dort nen C trägt ne gemeinsame Kathode hat:
http://www.kingbright.com/product_main_1.php?lang=English&product01=20050504115323&product02=20050526043255&level=20050527112133

Das Datenblatt dass ich da habe ist glaub ich auch noch ausm Jahre 2003 
oder so...
Also wenn das Datenblatt wirklich zu denen passt die ich gekauft habe, 
dann haben se eine gemeinsame Anode trotz der C-Bezeichnung...
Im Datenblatt von mir gibt es garnet so viele Pins wie im aktuellen 
Datenblatt (sind wohl schon ältere Module)

von ... (Gast)


Angehängte Dateien:

Lesenswert?

Michael N. schrieb:
> Hab bei mir jetzt mal pro LED 100-150mA geplant :O

Das Datenblatt hast du aber gelesen oder?
An die Absolute Maximum Ratings heranzugehen würde ich aber nicht 
empfehlen.

von ... (Gast)


Angehängte Dateien:

Lesenswert?

Es ist immer schlecht, wenn man nicht weiß was man kauft.

von Michael N. (garril)


Lesenswert?

Genau eben weil ich das Datenblatt gelesen habe, bin ich dadrauf 
gekommen. Sonst hätte ich auch nie so viel durchgejagt.

Wie recht du ja hast...
Und zweifarbig wird das ja auch nen Riesenteil.

Vielleicht sollte ich einfach einfarbig, rote kaufen und am besten mit 
passendem Datenblatt
Gibts da ne günstige Alternative zu den Ebay-China-Modulen?
Weiß jetzt nicht wie die von der Qualität her sind (wobei solche Sachen 
ja meist sowieso dort hergestellt werden). Aber der Versand dauert ja 
auch mindestens 2 Wochen (bis zu 2 Monaten...)

von ... (Gast)


Lesenswert?

Michael N. schrieb:
> Genau eben weil ich das Datenblatt gelesen habe, bin ich dadrauf
> gekommen. Sonst hätte ich auch nie so viel durchgejagt.

Wie gesagt, an die Absolute Maximum Ratings heran zugehen kannst du 
vergessen. Also 20mA sind so der gängige Wert. Wobei die Leuchtkraft 
nicht nur von dem Strom abhängt, sondern vor allem von dem Material aus 
dem die LEDs gebaut wurden. Schau dir mal bei Kingbright die 
Datenblätter an und vergleiche mal die Typ. Iv (ucd) @10mA Werte.
Wenn du dann welche kaufst, schau genau hin, ob das dann auch die Typen 
sind die du haben willst, die unterscheiden sich dann bei Kingbright 
z.B. nur durch den Zusatz hinter der Typenbezeichnung, wie: SEKWA oder 
SURKWA. Klar, dass die mit der geringeren Leuchtdichte billiger sind.

Michael N. schrieb:
> Gibts da ne günstige Alternative zu den Ebay-China-Modulen?

Kingbright ist schon nicht schlecht. Da einen Typ aussuchen und dann bei 
den verschiedenen Lieferanten, Reichelt, Conrad, RS, Farnell, usw. 
schauen, wer bietet was für wie viel.

von Michael N. (garril)


Lesenswert?

Wie kann ich denn dann die komplette Typenbezeichnung entschlüsseln?
(SRCGKWB hängt hintendran)

mit 50mA kann ich aber schon arbeiten oder?
Sieht man die LEDs mit 20 oder 30mA selbst wenn es hell ist noch 
leuchten? (soll ja auch nicht blenden)

von Ulrich Radig (Gast)


Lesenswert?

Hallo,

also ich verwende ein 1/8 Duty cycle und kann die Anzeige mit 15mA sogar 
im Sonnenlicht gut ablesen. Als Anzeige Matrix verwende ich 
OM23881AUY-01

Gruß
Uli

von Ulrich Radig (Gast)


Angehängte Dateien:

Lesenswert?

P.S: Als Anzeigentreiber würde ich heutzutage ein SCT2024 verwenden.

von Michael N. (garril)


Lesenswert?

ok, dann teste ich das mal mit nur 20mA. Wenn das reicht, wäre das ja 
super.

Zum SCT2024:
Beschaffung scheint garnicht so einfach zu sein.
Außerdem kann ich das ohne extra selbstgemachte Platine nicht löten. 
Habe vorher noch nie eine eigene Platine entworfen und wollte das ganze 
deshalb auf Lochraster aufbauen.
Doppelt so viele 8 Bit Register (74HCT595N) sollten es auch tun, oder?

Reicht mein Atmega8 oder soll ich lieber auf was größeres setzen? 
(32er??)

@Ulrich Radig: Vielen Dank für die Mail

von Ulrich Radig (Gast)


Lesenswert?

Schaltplan hat du ja von mir bekommen. So macht es auch die 
Leuchtanzeige von Conrad nur mit 74HC164 Schieberegister.

http://www.conrad.de/ce/de/product/590998/LED-LAUFSCHRIFT-ROT/SHOP_AREA_22608&promotionareaSearchDetail=005

Gruß
Uli

von Ulrich Radig (Gast)


Lesenswert?

Hallo,

ein ATmega8 könnte etwas klein sein. Du könntest aber immerhin noch auf 
einen ATmega328 wechseln. Ich Buffer das anzuzeigende Bild im SRAM 
240Bytes das 2 mal.
Der eine Speicherbereich kann angezeigt werden, im anderen kann ich das 
nächste Bild bearbeiten. Mann kann aber auch fast ohne SRAM auskommen 
und arbeitet mit einen Character Rom. Ist halt die Frage was man machen 
möchte.

Gruß
Uli

von Michael N. (garril)


Lesenswert?

Ok, dann beginnne ich gleich mit einem Atmega32.
Die Enttäuschung wäre zu groß, wenn es dann mit nem Atmega8 nicht 
richtig klappt und ich das nochmal ändern muss :)

Dein Schaltplan hat mich auch zum nachdenken über die Aneinanderreihung 
der 12 Schieberegister gebracht.
Da ich sowieso 4 Stück nebeneinander und 3 Stück untereinander betreiben 
möchte werde ich wahrscheinlich auch 3 Datenpins vom Atmega für die 
Daten nutzen. Dann kann ich parallel die Register für alle 
untereinanderliegenden Matrizen befüllen.

Sollte ich in die Schaltung noch Kondensatoren bauen (sind ja ganz schön 
starke Schwankungen durchs multiplexen)? (Wohin? Wie groß?)

von Ulrich Radig (Gast)


Lesenswert?

Ich verwende an jedem Schieberegister 100µF und 100nF.

von Michael N. (garril)


Lesenswert?

Hängen die dann einfach so am Schieberegister (an SCL) dran?:

SCL--------------->VCC
     |        |
     =100µF   =100nF
     |        |
     -        -
    GND      GND

von Carsten S. (dg3ycs)


Angehängte Dateien:

Lesenswert?

Hi,

Ich habe vor ein paar Jahren auch mal so ein Ding gebaut mit ungefähr 
700 LEDs (genau kenne ich die Menge nicht mehr, wer es genau wissen will 
kann ja nachzählen) um etwas auszuprobieren. Allerdings noch mit 
"Einzel-LEDs.

Gesteuert wurde das ganze von einem PIC16F628. Das Ding war auf 
"zeilenweisen" Betrieb ausgelegt,d.h. es wurden über eine Kette CD4094 
immer die LEDs einer ganzen Zeile UND die jeweils aktuelle Zeile geladen 
und dann umgeschaltet. Es waren also nur drei I/Os am Pic in Verwendung.

Wie weiter oben schon schon geschrieben ergab das dann eine Austastung 
von 1:7. Das hat der kleine PIC noch "sehr Locker" gepackt. Ein ATMEGA8 
müsste es also auch noch locker packen.

Wobei dazu zu sagen ist:
Leistungsreserven sind bei "Bastelprojekten" im Gegensatz zu Gróßserien 
immer vorteilhaft. Zudem war das Programm komplett in ASM geschrieben.
Die angezeigte Grafik wurde während der LAufzeit nur als "Bitfeld" 
beahndelt und vorher umgewandelt.
Ein Größerer µC ist also nicht zwingend nötig - gibt aber sicher mehr 
freiheiten bei der Umsetzung.

Die eigentliche Matrix war mit absoluten Standartbauelementen aufgebaut, 
halt das was die Bastelkiste gerade hergab. Als Spaltentreiber kamen 
BC547 zum Einsatz, als Zeilentreiber BD139.
Funktionierte recht ordentlich, heute hätte ich aber nicht mehr die Zeit 
(und Lust) das so wie auf den Bilder umzusetzen ;-)

Wenn ich aber noch mal eine entwerfen müsste, dann würde ich auf jeden 
Fall bei der zeilenweise Umsetzung bleiben. Die Umsetzung sowohl in SW 
wie auch Hardware ist extrem einfach und man hat einen sehr großen 
Spielraum bei den Multiplexfrequenzen. Immerhin muss man ja auch 
bedenken das je höher die Umschaltfrequenz ist auch um so mehr 
Verlustleistung an den Treibern anfällt, da die Phase der hohen 
Verlustleistung ja viel häufiger durchschritten wird. Und bei 1500LEDs 
kommt schon einiges an Leistung zusammen.

Gruß
Carsten

von Turbo T. (turbotoni)


Angehängte Dateien:

Lesenswert?

Ich habe vor Jahren auch mal so ne Matrix gebaut. Die entsprechenden 
Schaltungen stammen von der Seite von Bascom. Ich habe sie aber etwas 
abgewandelt und neu gezeichnet.

MfG Turbotoni

von Michael N. (garril)


Lesenswert?

Ich habe auch schonmal eine Matrix selbstgebaut (normale 5mm LEDs).
Waren nur 5x7 (also 35 LEDs) aber selbst das hat mir gereicht^^

Habe sowieso einen Atmega32 "auf Lager". Dann nehm ich den dafür.
Wenn die Matrizen da sind überarbeite ich dann meine Schaltung nochmal 
passend (muss die Matrizen vielleicht andersrum einbauen, damit sich 
durch die verschiedenen Farben die Spalten und nicht die Zeilen 
verdoppeln, sonst hätte ich ja 1:16 statt 1:8)
Aber wenn das bei euren Projekten keine Probleme gemacht hat, dürfte das 
mit nem Atmega32 auch klappen (Habe halt dann eigentlich 192 Spalten, 
weil ich ja grün und rot habe)

Hat jemand passenden Code (vorzugsweise in C geschrieben)? Dann kann ich 
mir da auch schonmal gedanken machen (bin am überlegen wie ich schonmal 
die nächste Zeile in den Speicher lade bevor ich die vorherige 
abschalte) Und sobald die nächste Zeile geladen ist darf ich ja net zu 
der umschalten. Wenn dann eine Zeile schneller zu laden geht, leuchtet 
die davor ja kürzer...
Morgen berechne ich mal ein bisschen den benötigten Speicher. Dürfte 
aber gerade noch so auf den Atmega passen.

von Turbo T. (turbotoni)


Lesenswert?

Das Prinzip besteht aus einen Timer-Interupt. In der ISR zuerst die 
aktive Zeile abschalten, Zeile um eins erhöhen und überprüfen ob schon 8 
erreicht ist. Dann die Daten für die neue Zeile ins Register schieben 
und diese Zeile einschalten. RETI und auf den nächsten interrupt warten.

von Michael N. (garril)


Lesenswert?

Dürfte eigentlich nichts großartiges sein (mehr als du beschrieben hast 
braucht man ja erstmal nicht).

Das erste große Problem wird wahrscheinlich ein Zeichensatz...

Später soll das ja auch mal die Uhrzeit anzeigen. Beim Atmega32 gibt es 
einen Extra real-time counter für den man nen 32kHz Quarz anschließen 
soll. Ist das genau genug für eine Uhr? (Wobei das glaube ich nur 
nutzbar ist wenn man sonst den internen Takt nutzt?!)

von Turbo T. (turbotoni)


Lesenswert?

Ja, das ist für ne Uhr genau genug. Allerding lauft die Uhr nur, wenn 
der AtMega mit Spannung versorgt wird und muss nach jeden Stromausfall 
neu gestellt werden.

von Carsten S. (dg3ycs)


Lesenswert?

Michael N. schrieb:
> Dürfte eigentlich nichts großartiges sein (mehr als du beschrieben hast
> braucht man ja erstmal nicht).
>
> Das erste große Problem wird wahrscheinlich ein Zeichensatz...
Naja, Zeichensatz finde ich ist eher eine Fleissarbeit...
Als Vorschlag mal die "C Geeignete" übersetzung meines damaligen 
Vorgehen:

ICh würde das darzustellende Bild als Bitfolge in einem 8x8 (u)Char 
Array ablegen. Dann kannst du den Zeichensatz mittels Vergleich für die 
Anzeige übersetzen.
Danach brauchst du nur noch das array Zeilenweise ausgeben, was eine 
Kleinigkeit ist. Der Vergleich fällt dann nur einmal alle paar tausend 
Darstellungen an wenn sich der Inhalt ändert.
1
unsigned char Input_Stream[7];
2
unsigned char Bild_Stream[7] [7];
3
unsigned char count;
4
//   ...
5
//   ...
6
//   ...
7
8
while (Input_Stream[count] != 0)
9
{
10
  switch (Input_Stream[count])
11
  {
12
    case 'A':
13
      Bild_Stream[0] [count] = 0b00111000 ;
14
      Bild_Stream[1] [count] = 0b01000100 ;
15
      Bild_Stream[2] [count] = 0b01000100 ;
16
      Bild_Stream[3] [count] = 0b01111100 ;
17
      Bild_Stream[4] [count] = 0b01000100 ;
18
      Bild_Stream[5] [count] = 0b01000100 ;
19
      Bild_Stream[6] [count] = 0b01000100 ;
20
      Bild_Stream[7] [count] = 0b00000000 ;
21
      break;
22
23
    case 'B':
24
      Bild_Stream[0] [count] = 0b01111000 ;
25
      Bild_Stream[1] [count] = 0b01000100 ;
26
      Bild_Stream[2] [count] = 0b01000100 ;
27
      Bild_Stream[3] [count] = 0b01111000 ;
28
      Bild_Stream[4] [count] = 0b01000100 ;
29
      Bild_Stream[5] [count] = 0b01000100 ;
30
      Bild_Stream[6] [count] = 0b01111000 ;
31
      Bild_Stream[7] [count] = 0b00000000 ;
32
      break;
33
34
//                   ...
35
//                   ...
36
//                   ...
37
38
    default:
39
      Bild_Stream[0] [count] = 0b00000000 ;
40
      Bild_Stream[1] [count] = 0b00000000 ;
41
      Bild_Stream[2] [count] = 0b00000000 ;
42
      Bild_Stream[3] [count] = 0b00000000 ;
43
      Bild_Stream[4] [count] = 0b00000000 ;
44
      Bild_Stream[5] [count] = 0b00000000 ;
45
      Bild_Stream[6] [count] = 0b00000000 ;
46
      Bild_Stream[7] [count] = 0b00000000 ;
47
      break;
48
    }
49
  count++;
50
}
Die Ausgaberoutine dürfte sich ja selbst erklären. Die ist dann immer 
sehr schnell abgearbeitet und lässt viel "zeit" für sonstige Dinge.

Bei zwei Farben würde ich dann zwei Arrays getrennt nehmen.
Begrenzender Faktor ist hier der interne Speicher...
Evtl. ist dann zugriff auf externen Speicher nötig. Alternativ ein 
größerer µC
(ICh hatte damals nur die "sehr sehr seltene" Änderungen, im 
Normalbetrieb nur die Umschaltung zwischen 1-4 verschiedenen 
vorgegebenen Wörtern. Die Bitfelder habe ich da in vier Arrays in ein 
externes EEProm ausgelagert.)

Bin nicht der ATMEGA spezi, aber ich würde vermuten bei einem ATMEGA32 
sollte noch genug RAM frei sein, oder?

> Später soll das ja auch mal die Uhrzeit anzeigen. Beim Atmega32 gibt es
> einen Extra real-time counter für den man nen 32kHz Quarz anschließen
> soll. Ist das genau genug für eine Uhr? (Wobei das glaube ich nur
> nutzbar ist wenn man sonst den internen Takt nutzt?!)

ICh würde mir das mit den zwei Oszillatoren sparen und alles von einer 
Taktquelle abhängig machen. Auch aus einem 16Mhz Quarz lässt sich die 
genaue Uhrzeit ermitteln. Wobei es evtl. sogar nützlich sein kann mit 
dem Takt runterzugehen (z.B. 4MHz).

Ich würde dazu einen Timer möglichst weit vorgeteilt frei laufen lassen 
und beim Überlauf einen Interrupt auslösen. Die Überläufe werden dann 
gezählt und davon die Bildwechselfrequenz und Uhrzeit abgeleitet.

Als Beispiel: Der Timer löst alle 5ms aus. Dabei werden zwei die 
Variablen "BildWechsel" und "SekundenTakt" hochgezählt. Immer wenn ich 
mit "BildWechsel" feststelle das 4x der Timer übergelaufen ist ändere 
ich die dargestellte zeile. Immer wenn der Timer 200mal übergelaufen ist 
(mit "Sekundentakt"gezählt) erhöhe ich die Uhrzeit um eine Sekunde.

Evtl. "kleine" Fehler kann ich über Software ausbügeln, wenn z.B. meine 
Rechnung ergibt das meine "sekundentakte" nur 999ms lang sind addiere 
ich einfach jede 1000 Sekunde eine Sekunde zusätzlich...

Ist aber wie gesagt nur ein Vorschlag, gibt noch unzählige andere 
Lösungsvarianten...

Gruß
Carsten

von benwilliam (Gast)


Lesenswert?

Hallo garril

habe vorgestern erst selbst eine 7x80 LED matrix zusammengebastelt nach 
dem gleichen prinzip und ebenfalls mit einem ATMega8, daher hier meine 
Erfahrungswerte:

(Atmega8 Systemtakt = 8MHz)
- um 80 Spalten (eine Zeile) zu füllen braucht der ATMega8 über den SPI 
(SPI_CLK = CLK/2) ca. 350 taktzyclen (GCC auf höchter 
optimierungsstufe).
- das "Ausgeben" einer Zeile mache ich per Timerinterrupt wobei sich ein 
Prescaler von 64 und zählen bis 55 (ergibt 3520 taktzyklen) sich für 
mich am praktikabelsten ergeben hat. Dadurch war der Zeilenaufbau 
ausreichend schnell um auch animationen flüssig darzustellen
- ein weiter erfahrungswert: der ATMega8 ist von der rechenleistung und 
Speicher (leider) zu klein :)

wie im IRC chat bereits erwähnt stelle ich gerne meine Rastergraphik lib 
zur verfügung:

ich habe diese gestern noch shcnell hochgeladen: 
https://github.com/benwilliam/AVR/tree/master/LED

es ist ein erster schneller entwurf also bitte seit nicht streng mit mir 
:)

Erklärung zur lib:
diese bietet zeichnen von:
- rechtecken (gefüllt und/oder gedreht)
- kreise (auf wunsch auch gefüllt)
- elipsen
- großen Zeichensatz von 5x7 großen Zeichen, welche man an belibieger X 
Y koordinate zeichnen kann.
- links, rechts, hoch, runter verschieben des ganzen bildes
- "rund herum verschieben" d.h. wenn ein pixel aus dem bild geschoben 
wird, wird es hinten wieder eingefügt

die lib nutzt ebenfalls double buffering, d.h. ein buffer wird als 
ausgabe verwendet während auf einem 2. bereits gezeichnet wird. ist das 
zeichnen fertig, werden die buffer einfach geswitcht.

Probleme der lib:
- furchtbar inperformant (vorallem das verschieben und das füllen von 
geometrischen figuren)
- hoher speicher verbrauch (Atmega8: ca. 95% des Flashs und 75% des 
RAMs)
- manche funktionen sind noch buggy, wenn man fehlerhafte X Y 
koordinaten verwendet. (z.B: wenn der hintere punkt VOR dem vorderen 
punkt liegt)


vorteile:
- es ist komplett in C geschrieben und dadurch hoffentlich etwas 
lesbarer :)
- die lib ist nach möglichkeit etwas allgemeiner gehalten. So kann man 
z.B. in der LEDMatrix.h die dimensionen der eigenen LEDMatrix einstellen 
(höhe, breite, Lowaktiv oder nicht) und es sollten relativ wenige 
anpassungen erforderlich sein.

von Michael N. (garril)


Lesenswert?

@Carsten:
Ich denke das Problem wird beim Quarz nicht die nicht genau passende 
Frequenz (wie du schon sagst, kann man z.B. alle 63 Durchläufe eine 
Sekunde dazuzählen) sondern eher die Ungenauigkeit.
Durch den Herstellungsprozess stimmt die Angabe nicht genau. Und bei 
Temperaturänderung ändert sich das glaube ich auch etwas?!



Muss die LED Matrix per SPI angesprochen werden?
Ist es nicht sinnvoller für die Datenübertragung normale Pins zu nehmen? 
(Taktsignal weiterhin über SPI)

Dachte an einen Programmablauf wie zB (Pseudocode):

var1=0
var2=0
var3=0
Wenn erste LED in Matrix 1 an --> var1=1
Wenn erste LED in Matrix 2 an --> var2=1
Wenn erste LED in Matrix 2 an --> var3=1
Schalte entsprechende 3 Datenpins je nach Wert in var1-3
Sende Taktsignal an Schieberegister

...das alles in einer Schleife...

Vielen Dank für deinen Code.

von Carsten S. (dg3ycs)


Lesenswert?

Michael N. schrieb:
> @Carsten:
> Ich denke das Problem wird beim Quarz nicht die nicht genau passende
> Frequenz (wie du schon sagst, kann man z.B. alle 63 Durchläufe eine
> Sekunde dazuzählen) sondern eher die Ungenauigkeit.
> Durch den Herstellungsprozess stimmt die Angabe nicht genau. Und bei
> Temperaturänderung ändert sich das glaube ich auch etwas?!
>
Ja,

ist schon richtig...
Aber auch Uhrenquarze sind davon betroffen.
Das eine ist die "Calibration Tolerance" (Wie genau bei 20C -manchmal 
auch 25C die Frequenz stimmt, auch Grundgenauigkeit genannt).
Di Abweichung über die Temperatur ist ganz einfach der 
Temperaturkoeffizient.

Wenn man jetzt von Standartquarzen ausgeht, so haben "normale" 
Uhrenquarze eine Calibration Tolerance von ungefähr 20ppm. Einfache 
Taktquarze für 50ct haben 30ppm. Zudem ist die normaltemperatur bei 
Uhrenquarzen meist mit 25C angegeben (Wohnung/Handgelenk ist wärmer), 
bei sonstigen in der TEchnik eingesetzten Quarzen -sofern keine 
Sonderanfertigung- gehe mal von 20C aus.
Der Temperaturkoeffizent ist in etwa ähnlich, wobei die Angaben in den 
Datenblättern manchmal auch recht verwirrend sind. Die einen geben das 
in ppm/Grad an, die anderen gleich für den ganzen Temperaturbereich.

ICh habe gerade mal in die Datennblätter meiner "Standarquarze" 
geschaut.
Die Taktquarzte welche ich verwende haben eine Grundgenauigkeit von 
30ppm und im Temperaturbereich von -20C bis +50C (Aussenbereich) eine 
maximaleAbweichung von -40ppm die "WorstCase" Abweichung bei klirrendem 
Frost oder Direkter Sonnenbestrahlung im Sommer ist also 70ppm.

Die "einfachen" Uhrenquarze die ich einsetzen haben 20ppm 
Grundgenauigkeit und im o.G. Temperaturbereich eine maximale Abweichung 
von -30ppm bei +50C und -80C bei -20C.

Im Endergebniss ergibt sich somit eine Maximale Abweichung von -50ppm im 
Hochsommer und -100ppm in einer in DL noch regelmäßig vorkommenden 
kalten Winternacht.  (-20C am Tage sind dann doch die Ausnahme, nur in 
höheren Lagen regelmäßig)

Es liegt jetzt also NICHT WIRKLICH weit auseinander! Zudem sind das ja 
die MAximalwerte sowohl der billigste µC Quarz als auch der einfache 
Uhrenquarz können bei Raumtemperatur auch genau NULL Abweichung haben. 
Ist halt nur nicht garantiert.

DAs WIRKLICH besondere an Uhrenquarzen ist neben der höheren 
Normaltempertur schlicht das diese sich glatt auf eine Sekunde teilen 
lassen, also mit einem sehr einfachen Digitalteil schon ein genaues 
Sekundensignal vorhanden ist.

Aber das ist kein so großer Unterschied als das ich mir DESWEGEN 
Gedanken
um ein anderes Konzept machen würde. Für "Kurzzeitanwendungen" wie eine 
Anzeige bei einem Wettbewerb schlicht nicht relevant.

Soll es hingegen eine Langzeitanwendung sein, die Uhr also die Uhr nach 
dem Einstellen auch mal einige Wochen odere gar Monate durchlaufen, dann 
würde ich sowieso die billigsten Quarze nur dann verwenden wenn ich noch 
regelmäßig durch eine externe REferenz synchronisiere (DCF, Computer 
usw).
In der Wohnung geht es mit Glück wenn man einen "Guten" erwischt noch 
mit wenigen Sekunden pro Monat. Im Aussenbereich sind es aber auch schon 
mal eine Minute pro Tag bei extremen Temperaturen.

Es gibt (bezahlbare) Präzisionsquarze die eine Grundgenauigkeit von 
besser 10ppm haben und dazu auch noch von -20C bis +60C nur um maximal 
10ppm Wandern, nahe der in DL üblichen Lufttemperaturen fast gar nicht.
Diese sind aber alle meist nur im Frequenzbereich von 1-100Mhz 
angesiedelt.

Oder man greift zum externen "präzisionsoszillator" wie TCXO oder gar 
OCXO. Selbst günstige TCXO bieten schon maximalabweichungen von deutlich 
unter 5ppm über den gesamten in DL vorkommenden 
Aussentemperaturberreich.

Wenn zudem deine Anforderung hisischtlich Frequenz nur ist das das der 
TXCO irgendwo zwischen 8MHz (damit noch schnell genug) und 16MHz (ATMEGA 
maximalfrequenz) liegen soll, da du ja alles andere in SW machen kannst, 
dann wird es ganz einfach. Da wird man meist schon auf dem 
Elektronikschrott fündig. 14,85MHz & 12,8MHz ist früher in der 
Funktechnik und den "großen" Mobiltelefonen (C & Dnetz Autotelefone) 
üblich gewesen. Dazu eine Vielzahl anderer Frequenzen in Industrie- und 
Kommunikationinfrastruktursanwendungen. Oder ansonsten halt für nen 5er 
auf jeden Elektronikflohmarkt oder Ebay. Nur "Glatte" Frequenzen wie 10, 
16 & 20Mhz sind manchmal zwei drei Euro teurer. Evtl. habe ich da auch 
noch ein paar in "ungängigen" Frequenzen wo ich dir was gegen Porto 
schicken kann.

Soviel zur Quarzgeschichte, zur SW schreibe ich später wohl noch was.

Gruß
Carsten

von Carsten S. (dg3ycs)


Lesenswert?

Hi,

dann doch schon mal jetzt die Anmerkung zur SW:

Michael N. schrieb:
> Muss die LED Matrix per SPI angesprochen werden?
> Ist es nicht sinnvoller für die Datenübertragung normale Pins zu nehmen?
> (Taktsignal weiterhin über SPI)

Du kannst die Matrix nach deinem Obigen Schaltplan entweder über ein SPI 
Modul ansprechen oder über Normale I/O Pins.

Es geht aber nicht gemischt, also ENTWEDER Daten und Takt über SPI, ODER 
aber BEIDES selbst erzeugen. (Wobei der Takt ja nicht mehr ist als nach 
einer Änderung des Zustandes am datenpin einmal den CLK Pin zu toggeln, 
da muss kein Timing eingehalten werden)

Die Abarbeitung mit der (missbrauchten) SPI Hardware hat den vorteil das 
der µC mehr "rechenzeit" Frei hat, blockiert aber den SPI Port falls man 
doch externen Speicher anhängen will.
Die Abarbeitung über eigenen Ausgabecode hat den Vorteil das dieses 
Programm noch viel Portabler bleibt. Der Wechsel zwischen Verschiedenen 
µC, ja sogar ganzen Serien/Herstellern ist einfacher. (Für mich 
Hilfreich, aber sehr oft auch völlig irrelevant)

> Dachte an einen Programmablauf wie zB (Pseudocode):
>
> var1=0
> var2=0
> var3=0
> Wenn erste LED in Matrix 1 an --> var1=1
> Wenn erste LED in Matrix 2 an --> var2=1
> Wenn erste LED in Matrix 2 an --> var3=1

Das würde ja in etwas meinem obigen Beispiel entsprechen, nur das du das 
mit Einzelvariablen gelöst hast, was ich mittels eines Arrays gelöst 
habe.
Bei deiner MEthode musst du das Programm komplett ausschreiben, bei 
meiner vorgeschlagenen Methode hast du eine einzige Routine mit der du 
alle 64 Varaiblen abarbeiten kannst, die du in einer Schleife 64mal 
abarbeiten lässt. Es muss nur der Index (Zeiger) mittels Zähler geändert 
werden.
Diese Möglichkeit lässt deine Lösung nicht!

> Schalte entsprechende 3 Datenpins je nach Wert in var1-3
> Sende Taktsignal an Schieberegister
> ...das alles in einer Schleife...

NEE!
Das geht so nicht, dann müsstest du auf µC seite ja noch ein Paralell zu 
SEriell SR haben... MAcht aber überhaupt keinen sinn.
Du sprichts mit der "SR-Kette" nur mit Drei Portleitungen:
Dazu hast du zum Beispiel die folgende Funktion S_Transmit:
1
#define S_Clock             LATCbits.LATC6    //; Port fur Clocksignal
2
#define S_Data              LATCbits.LATC7    //; Datenkanal
3
/* das Define seiht bei AVR ggf. anders aus, müsste das jetzt selber nachsehen! */
4
5
// ...
6
// ...
7
void S_Transmit(unsigned char S_Byte)
8
{ 
9
         unsigned char Temp1 = 8;
10
         S_Clock = 0; 
11
12
  while(Temp1)
13
  {    
14
    Delay10TCYx(1); //PIC Spezifisch, hier AVR Equivalent verwenden!!!
15
    S_Data  = (S_Byte & 0b00000001); 
16
    Delay10TCYx(1);
17
    S_Clock = 1;
18
    Delay10TCYx(1);
19
    S_Clock = 0;
20
21
                  S_Byte >>= 1;  
22
    Temp1--;
23
  }
24
    S_Data  = 0; 
25
}

Im Späteren Programmablauf musst du bei deiner Umsetzung dann 
folgendermaßen arbeiten:
1
#define Zeile            LATb // hier hängen die Zeilentreiber    
2
#define  S_Latch             LATCbits.LATC5 //; Port fur LatchÜbernahme 
3
Zeile = 0b00000000;
4
// ...
5
// ...
6
7
void Anzeige(void)
8
{
9
10
  Zeile = 0b00000000;
11
12
  S_Transmit(var1);
13
  S_Transmit(var2);
14
  S_Transmit(var3);
15
  S_Transmit(var4);
16
  S_Transmit(var5);
17
  S_Transmit(var6);
18
  S_Transmit(var7);
19
  S_Transmit(var8);
20
21
  Zeile = 0;
22
  Delay1TCYx(1);      
23
  S_Latch = 1
24
  Delay1TCYx(1);      
25
  S_Latch = 0;
26
  Zeile = 0b00000001;
27
28
29
  S_Transmit(var9);
30
  S_Transmit(var10);
31
//   ...
32
  S_Transmit(var16);
33
34
  Zeile = 0;
35
  Delay1TCYx(1);      
36
  S_Latch = 1
37
  Delay1TCYx(1);      
38
  S_Latch = 0;
39
  Zeile = 0b00000010;
40
//   ...
41
//   ...
42
//   ...
43
  S_Transmit(var64);
44
45
  Zeile = 0;
46
  Delay1TCYx(1);      
47
  S_Latch = 1
48
  Delay1TCYx(1);      
49
  S_Latch = 0;
50
  Zeile = 0b10000000;
51
}
Und dabei ist die Ausgabe noch das einfachere...
Die Zuweiseung ist noch interessanter ;-)
Und auch die Initialisierung aller 64 Variablen muss auch noch sein!

Wenn du mit dem Array arbeitest geht das aber auch so
1
#define  Zeile  LATb // hier hängen die Zeilentreiber    
2
#define  S_Latch             LATCbits.LATC5 // Port fur LatchÜbernahme 
3
// ...
4
Zeile = 0b00000000;
5
// ...
6
// ...
7
8
void Anzeige(void)
9
{
10
  unsigned char Zeile_Temp = 1;
11
12
  for (unsigned char Zeilenindex=0; Zeilenindex<=7; Zeilenindex++)
13
  {
14
     for (unsigned char Spaltenindex=0; Spaltenindex<=7;Spaltenindex++)
15
     {
16
       S_Transmit(Bild_Stream[Zeilenindex] [Spaltenindex]);
17
     }
18
19
     if (Zeile__Temp)
20
     {  
21
       Zeile_Temp<<=1;
22
     }
23
     else 
24
     {  
25
       Zeile_Temp = 1;
26
     {
27
28
     Zeile = 0;
29
     Delay1TCYx(1);      
30
     S_Latch = 1
31
     Delay1TCYx(1);      
32
     S_Latch = 0;
33
     Zeile = Zeile_Temp;
34
  } 
35
}

NAtürlich könntest du um SPEICHER zu sparen auch immer nur eine ganze 
Zeile oder eine ganze Spalte "übersetzen" und vor jeder einzelnen 
Ausgabe übersetzen. Dann braucht man statt 64 Speicherzellen nur 8 oder 
gar nur eine für den Bildinhalt.
Aber das lastet den µC dann schon deutlich mehr aus, so das nur noch 
wenig Zeit für sonstige Dinge wie "Uhrzeit berechnen bleibt,"

Ich würde das vom Proigrammablauf so machen:
In der "normalschleife" läuft die Berechnung der Uhrzeit aus den 
Zäherlständen die in der Interruptbehandlung gesetzt wurden, der 
Datentransfer für anzuzeigende Texte (Seriell, USB...) und die 
Übersetzung.

Daneben läuft der Timer der regelmäßigt den Interrupt auslöst. In der 
Interruptschleife wird der Zähler für Uhrzeit und Anzeige hochgezählt 
und alle xx Interrups die "Anzeige()" aufgerufen.


WAS ABER UNBEDINGT IMMER ZU BEACHTEN IST:
Wenn du beim Multiplex mit höheren Pulsströmen arbeitest die Wertmäßig 
einiges höher sind als der maximal zulässige "Dauerstrom" deines LED 
Moduls, dann musst du UNBEDINGT sicherstellen das die Routine zum 
Zeilenwechsel regelmäßig aufgerufen wird und es im Fehlerfall 
(programmabbruch) sofort zu einer Abschaltung der Zeilen kommt.

WatchDog ist absolute Pflicht wenn du nicht zu oft die Module wechseln 
willst. Zudem macht es Sinn im Probebetrieb die Betriebsspannung der 
Matrix selbst nur auf maximal den Wert zu legen der in der Folge MAXIMAL 
den für Dauerbetrieb zulässigen Strom ergibt.  Das ist für Erprobung 
allemal hell genug und verhindert Zerstörung bei HArdware- ode 
rProgrammfehler!
Erst wenn das Programm sicher läuft, als ALLERLETZTER Schritt würde ich 
die Spannung auf den Wert erhöhen der dem höhern Pulsstrom entspricht.

Gruß
Carsten

von Michael N. (garril)


Lesenswert?

Wegen dem Quarz:
Dann bestelle ich mir halt einfach nen normales 16Mhz-Quarz.
Kostet 0,19€ und ich kann ja noch etwas nachstellen (mal sehen wie genau 
das wird. Ansonsten blende ich einfach keine Sekunden ein, dann passt 
das schon ne zeitlang ;) )
Beste Lösung wäre wenn die Uhr im Sommer insgesamt eine Minute schneller 
wird und im Winter der Vorsprung wieder verloren geht :D
Aber das türke ich dann einfach Softwaremäßig, damit es einigermasen 
passt (2mal jährlich muss man eh die Uhr umstellen, dann kann man se ja 
um ne Minute oder so ändern)

Zur Software (und ein bisschen Hardware):
Würde das ganze dann lieber per IO-Pins lösen.
SPI frei zu haben ist ja nie verkehrt.

Würde dann auch ein Array verwenden. War halt jetzt mal so Pseudocode um 
einfach zu zeigen wie ich das umsetzen will.

Das mit meinen 3 Datenpins hast du glaube ich falsch verstanden:
Ich splitte die lange SR-Kette (12 SRs) in 3 Ketten auf (die Module 
bilden später sowieso 3 Zeilen für Schriften/Zeichen)

Code wäre dann wie folgt:

Anzeige_Zeile1="Dies"
Anzeige_Zeile2="ist ein"
Anzeige_Zeile3="Test"

Jetzt holt sich der Controller für die ersten Buchstaben jeder Zeile (D, 
i und T) das entsprechende Array (also welche Bits 0 bzw. 1 sein müssen) 
und legt an die SR-Kette1 (für Zeile1) das entsprechende Bit an. Das 
gleiche macht er auch mit dem ersten Bit für Zeile2 und Zeile3 (eben an 
2 anderen Pins)
Jetzt noch das Clocksignal am vierten Port anlegen (die Leitung geht 
dann wieder zu allen SRs) und ich habe mit einem Durchlauf 3 Bit 
gesetzt.

Bringt das nen Geschwinidigkeitsvorteil oder ist das ein Schmarrn?
Dann könnte ich sogar 6 Datenpins verwenden und 3 für rot und 3 für grün 
nehmen. (je 4 SR dran, macht also 24 SR)

Muss ich nach dem Setzen des Daten-Pins wirklich so ne kleine Wartezeit 
(delay_ms(1) oder so) einbauen?
Ist der Controller sonst zu schnell mit dem Taktsignal?

von Carsten S. (dg3ycs)


Lesenswert?

Hi,

Michael N. schrieb:
> Bringt das nen Geschwinidigkeitsvorteil oder ist das ein Schmarrn?
> Dann könnte ich sogar 6 Datenpins verwenden und 3 für rot und 3 für grün
> nehmen. (je 4 SR dran, macht also 24 SR)

also einen wirklichen Geschwindigkeitsvorteil sehe ich jetzt nicht. Du 
Sparst ein paar Clock-Takte, musst dafür aber viel mehr im 
Programmablauf Springen (Denke an den Assemblercode der sich ergibt!) 
gegenüber der Methode mit dem einfach nacheinander reintakten...
Du musst mal ausrehcnen wie viel Zeit sich nichts tut. Du kannst und 
willst) ja auch nicht beliebig schnell "multiplexen.

ISt aber evtl. auch eine Sache von Versuch und Irrtum...
Evtl. kann man das Layot ja so auslegen das man die Schaltung einfach 
mittels zwei Brücken von der drei SR-Ketten Variante mit drei Pins auf 
eine Lange Kette umtrimmen kann. Das Eintakten in das SR kann mit einem 
Bittakt von einigen MHz passieren!

> Muss ich nach dem Setzen des Daten-Pins wirklich so ne kleine Wartezeit
> (delay_ms(1) oder so) einbauen?
> Ist der Controller sonst zu schnell mit dem Taktsignal?

Eine Miniwartezeit verhindert ein ganz ganz leichtes verwischen, was 
aber eh fast niemand wahr nicht. Sst trotzdem etwas sauberer wenn man 
der Logik die Zeit gibt die Pegel zu ändern und nicht bewusst immer 
schon halbleitende Treiber auf beiden Seiten gleichzeitig provoziert.

Aber bei den Wartezeiten reden wir keinesfalls von ms. Eher von 0,x µs.
In Assembler habe ich dafür genau ein NOP gesetzt.

GRuß
Carsten

von Michael N. (garril)


Lesenswert?

Also dann takte ich das ganze einfach in eine Kette von 12 bzw. (für rot 
u. grün) 24 Schieberegister.

Stimmt eine ms ist wohl ein bisschen viel^^ Aber das sollte sich in C ja 
auch gut machen lassen (also mit niedrigerer Wartezeit).

Jetzt brauch ich nur noch die Matrizen und dann mach ich nochmal einen 
groben Schaltplan und dann würde ich mir die benötigen Teile bestellen.
Muss ja erstmal wissen ob die jetzt Common Anode oder Cathode sind...

Traue nur ungern dem Datenblatt wenn die Bezeichnung der Module 
eigentlich was anderes aussagt^^

von benwilliam (Gast)


Lesenswert?

> Muss ich nach dem Setzen des Daten-Pins wirklich so ne kleine Wartezeit
> (delay_ms(1) oder so) einbauen?
> Ist der Controller sonst zu schnell mit dem Taktsignal?

also die gängigen Schieberegister lassen sich mit bis zu 25 MHz takten
da ist der ATmega8 mit seinen (im besten fall) 16/4 Mhz = 4 MHz noch ein 
gutes stückchen entfernt.

wenn man die Zeilen zu schnell aufbaut entsteht (zumindest bei mir) eine 
Art "übersprechen" d.h. nahliegende LED leuchten zwar schwach aber 
sichtbar mit, daher musste ich den kompletten Zeilenaufbau mittels eines 
Timerinterrupts "beschränken"

hab versucht dafür ein Makro zu schrieben das ausgehend von der 
geünschten "Frame per second" die richtigen werte für den timer 
berechnet, hat aber nicht so ganz geklappt :) daher habe ich (erstmal) 
schlichtweg erfahrungswerte genommen.

von Michael N. (garril)


Lesenswert?

Stimmt, da ist der Atmega noch weit davon entfernt.

Das erinnert mich an mein zweites C-Programm für den Atmega8. Hab dort 
an die Funktion delay_ms() eine Variable übergeben. Das konnte dann 
nicht optimiert werden und der Atmega wurde sowas von langsam...
Und ich hab gerätselt woran es liegt (hatte ja absolut garkeine 
Erfahrung)

Naja man muss ja "nur" das menschliche Auge befriedigen. Ob das nun 
genau die optimalen Werte sind ist ja egal (wenn man weiß wie die 
Schaltung funktioniert findet man als Entwickler einfach immer weider 
Verbesserungen obwohl es eigentlich schon gut genug ist)

Wenn jetzt nur meine LED-Matrizen da wären^^...

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.