int leds[18]={1,2,3,4,5,6,11,16,17,18,19,21,26,31,32,33,34,35};
3
if (buchstabe[0]=="E") {
4
//Hier sollte eigentlich LED-Array gesetzt werden
5
}
6
int len=(sizeof(leds)/sizeof(*leds));
7
for (int i=0; i<100; i++) {
8
LEDsan(leds, len, 100);
9
}
10
}
Damit habe ich nur leider 2 Probleme:
1. Wenn ich das "leds"-Array zwei Zeilen weiter unten setze (also im
IF-Block) scheint es keine Gültigkeit mehr außerhalb des IF-Blocks zu
haben.
Eigentlich wollte ich das irgendwie in den IF-Block bringen, damit ich
andere ELSE IFs noch machen kann (andere Buchstaben also).
Dachte, dass ich vielleicht nur ein public vor "int leds[18]=..." setzen
muss, aber das wird beim compilen als Fehler angezeigt.
2. Ich rufe die Funktion wie folgt auf. Stimmt das?:
1
char string[1]="E";
2
buchstabe(string);
So und dann zu guter letzt noch eine Frage (hat jetzt nicht unbedingt
mit dem Code zu tun):
Da ich immer nur eine LED an einer LED-Matrix anschalte bin ich darauf
angewiesen, dass das Programm schnell abläuft (da die LEDs ja sonst
flackern).
Wenn ich nun an die Funktion LEDan() zusätzlich einen Parameter
übergebe, wie lange nach dem Anschalten einer LED gewartet werden soll,
bis die nächste angeht, dauert das anscheinend ewig und die LED-Matrix
flackert also... Wenn ich aber nun in der LEDan()-Funktion den Wert fest
programmiere, dann funktioniert das ganze super.
Liegt das daran, dass erst ne Kopie des Integers angelegt wird (Call by
Value)? Oder hat das einen anderen Grund? Denn u.A. übergebe ich auch
wie man oben sieht ein 18-stelliges Array, und das stört anscheinend
nicht.
Michael
Michael N. schrieb:> Dachte, dass ich vielleicht nur ein public vor "int leds[18]=..." setzen> muss, aber das wird beim compilen als Fehler angezeigt.
"Denken" ist was Anderes, du hast nur rumprobiert.
http://www.mikrocontroller.net/buecher/
Ohne das Problem wirklich verstanden zu haben, und auch ohne zu wissen,
auf welchem µC das laufen soll und wieviel Speicher der Dinger hat, mal
folgende Idee:
Wie wäre es, wenn Du ein LED-Array anlegst von der Größe der Buchstaben
anlegst, also led[0] steht für 'A', led[1] für 'B' usw.
dann sieht der Zugriff vielleicht so aus:
l = led [ string [index] - 'A' ].
Das sollte dann deutlich schneller sein.
Ciao und viel Spaß noch mit Deinen LEDs
Peter Stegemann schrieb:> "Denken" ist was Anderes, du hast nur rumprobiert.
Ich habe mir gedacht, dass die Variablendeklaration anscheinend nur
innerhalb der geschweiften Klammern des IF-Blocks gilt. Deshalb dachte
ich mir, dass ich die Variable public setze, dann wäre sie ja überall
gültig.
Was würdest du denn denken um das Problem zu lösen?
Der Schelm schrieb:> ohne zu wissen,> auf welchem µC das laufen soll und wieviel Speicher der Dinger hat
Es handelt sich um einen ATmega8-16 mit folgenden Daten:
MHz: 16
Flash: 8
EEProm: 512
RAM: 1K
I/O: 23
Dachte ich hab mich verständlich ausgedrückt. Aber ich erkläre es auch
gerne nochmal (Vielleicht auch mit ein bisschen mehr Hintergrundinfos):
-LEDan(int) macht die LEDs 1-35 an (int ist also zwischen 0 und 35) und
danach wieder aus
-LEDsan(int-array) macht mehrere LEDs hintereinander an (also bei
Arrayinhalt {1,2,3} macht er einfach LEDan(1), LEDan(2), LEDan(3)
Und nun wollte ich eben die Funktion Buchstabe(char) machen. Diese
Funktion soll lediglich zB bei der Übergabe von "A" dann
LEDsan(int-array) ausführen. Nur eben mit dem passenden Array damit der
Buchstabe A erscheint.
Hintergrund warum ich das gerne mit Buchstabe ansprechen würde:
Möchte dann noch eine Funktion Text(string bzw. char-array) schreiben,
die dann die Funktion Buchstabe(char) für jeden Buchstaben nacheinander
aufruft.
Wenn mir jemand Frage 1 beantworten könnte, wäre mir schon sehr viel
weitergeholfen (wie ich das "leds"-array richtig im IF-Block setze)
Hallo Michael,
da gibt's ja einiges zu sagen.
>Wenn ich das "leds"-Array zwei Zeilen weiter unten setze ...>scheint es keine Gültigkeit mehr außerhalb des IF-Blocks zu haben.
Das ist auch richtig so. In C gibt es Block-lokale Variablen. Diese sind
nur innerhalb des Blocks, in dem sie definiert sind, sichtbar und
gültig.
>Dachte, dass ich vielleicht nur ein public vor "int leds[18]=..." setzen>muss
In C gibt es kein public oder private, das gibt es erst in C++ (und in
vielen anderen Sprachen).
>2. Ich rufe die Funktion wie folgt auf. Stimmt das?:
Bist Du Dir klar, dass Du hier einen Zeiger auf das erste Element eines
char-Arrays übergibst? Wenn Du nur einen Buchstaben brauchst, solltest
Du auch nur einen übergeben.
>int len=(sizeof(leds)/sizeof(*leds));
Du teilst hier die Länge des Arrays durch die Länge eines Pointers. Da
im Array aber keine Pointer sind, muss das nicht die Anzahl der
Arrayelemente sein.
>Denn u.A. übergebe ich auch>wie man oben sieht ein 18-stelliges Array
Arrays werden immer by reference übergeben, genauer gesagt wird die
Adresse des ersten Arrayelements by value übergeben.
Ich würde Dir raten, mal ein gutes C-Buch genau durchzuarbeiten, da sind
Dir wohl einige Grundlagen noch nicht so ganz vertraut. Das ist aber
nicht schlimm, jeder hat mal angefangen.
Viel Erfolg beim Lernen,
Oliver
Michael N. schrieb:> if (buchstabe[0]=="E") {
Du vergleichst einen char mit einem char*. Der Vergleich ist immer
falsch, und du solltest die Warnungen des Compilers aktivieren und auch
beachten.
1
if (buchstabe[0] == 'E')
> Hallo,> ich habe folgenden Code:>
1
> void buchstabe(char buchstabe[]) {
2
> int leds[18]={1,2,3,4,5,6,11,16,17,18,19,21,26,31,32,33,34,35};
3
> if (buchstabe[0]=="E") {
4
> //Hier sollte eigentlich LED-Array gesetzt werden
5
> }
6
> int len=(sizeof(leds)/sizeof(*leds));
7
> for (int i=0; i<100; i++) {
8
> LEDsan(leds, len, 100);
9
> }
10
> }
11
>
>> Damit habe ich nur leider 2 Probleme:
Nur zwei? ;-)
> 1. Wenn ich das "leds"-Array zwei Zeilen weiter unten setze (also im> IF-Block) scheint es keine Gültigkeit mehr außerhalb des IF-Blocks zu> haben.
Nicht verwunderlich, weil der if-Block nie ausgeführt wird, s.o.
Zudem wird leds auch nicht mehr verwendet, was einem Compiler bei
Kenntnis von LEDsan ermöglicht, Zuweisungen an leds wegzuoptimiern.
> Eigentlich wollte ich das irgendwie in den IF-Block bringen, damit ich> andere ELSE IFs noch machen kann (andere Buchstaben also).
Ist ja auch ok.
> Dachte, dass ich vielleicht nur ein public vor "int leds[18]=..." setzen> muss, aber das wird beim compilen als Fehler angezeigt.
"public"??? Es geht doch um C, oder?
> So und dann zu guter letzt noch eine Frage (hat jetzt nicht unbedingt> mit dem Code zu tun):> Da ich immer nur eine LED an einer LED-Matrix anschalte bin ich darauf> angewiesen, dass das Programm schnell abläuft (da die LEDs ja sonst> flackern).
Mache einen Unterschied zwischen LEDs ansteuern und ein bestimmtes
Muster setzen. Beim Ansteuern musst du schnell sein, so daß nix
flackert. Ein neues Muster Schreiben kann langsamer sein, weil man zB
nicht so schnell neue Zeichen auf einem Display erkennt.
ZB:
1) In einer ISR werden die einzelnen Muster angezeigt.
2) In der Hauptschleife werden neue Muster generiert, etwa in einen
Puffer, aus dem dann in einer schnellen ISR dargestellt wird.
Du brauchst ja nicht bei jedem PWM-Zyklus das Muster neu zu generieren.
Zudem musst du dir überlegen, wie's mit der Konsistenz der Daten steht
und ob eine Inkonsistenz stört. Etwa dann, wenn das Muster erst halb
geschrieben ist, aber gerade angezeigt werden soll. Was dann adäquat
ist, kannst nur du selbst entscheiden. Mögliche Losungen sind:
- es macht nix
- nur komplette Puffer dürfen auch dargestellt werden. In dem Fall muss
man mehrere Puffer vorhalten (mindestens einen zum Anzeigen und einen
zu Beschreiben, evtl. noch mehr). Der Zugriff wird dann über den
jeweiligen Pointer gemacht, damit nicht der genze Puffer kopiert
werden
muss.
> Wenn ich nun an die Funktion LEDan() zusätzlich einen Parameter> übergebe, wie lange nach dem Anschalten einer LED gewartet werden soll,
Warten ist immer schlecht, weil das dein Programm lahmlegt. Überleg dir
was mit Timern die ablaufen oder was auch immer (Lösungen gibt's hier
zuhauf) aber delay ist eine der einfachsten aber auch der übelsten
Lösungen, weil es alles ausser Interrupts blockiert. Und mit Interrupts
ist es ungenau.
> bis die nächste angeht, dauert das anscheinend ewig und die LED-Matrix> flackert also... Wenn ich aber nun in der LEDan()-Funktion den Wert fest> programmiere, dann funktioniert das ganze super.> Liegt das daran, dass erst ne Kopie des Integers angelegt wird (Call by> Value)?
Das geht schnell, wobei du nicht wirklich int zu brauchen scheinst. Ein
char/unsigned char tut's wohl auch. Wenn das Anzeige-Array statisch ist,
muss es auch nicht immer wieder angelegt werden. Momentan muss das Array
bei jedem Aufruf neu angelegt und initialisiert werden!!
> Oder hat das einen anderen Grund? Denn u.A. übergebe ich auch> wie man oben sieht ein 18-stelliges Array, und das stört anscheinend> nicht.
Nein, du übergibst nicht das Array, du übergibst seine Startadresse. Das
Anlegen ist teuer, nicht seine Adresse zu übergeben.
> Michael
Johann
Oliver schrieb:> In C gibt es kein public oder private, das gibt es erst in C++ (und in> vielen anderen Sprachen).
Würde also heißen, dass ich am besten noch eine Funktion schreibe und
das Array an diese Übergebe... Sonst kann ich mir nicht vorstellen wie
ich das hinbekommen soll, dass ich außerdem des IFs darauf zugreifen
kann.
Oliver schrieb:> Bist Du Dir klar, dass Du hier einen Zeiger auf das erste Element eines> char-Arrays übergibst? Wenn Du nur einen Buchstaben brauchst, solltest> Du auch nur einen übergeben.
Genau das wollte ich. Dazwischen kommt dann die im vorherigen Post
beschriebene Funktion, die den String (bzw. das char Array zerlegt)
Oliver schrieb:> Du teilst hier die Länge des Arrays durch die Länge eines Pointers. Da> im Array aber keine Pointer sind, muss das nicht die Anzahl der> Arrayelemente sein.
Oh, das ist dann echt nen Fehler... Müsste dann ja
int len=(sizeof(leds)/sizeof(int));
heißen, wenn ich mich richtig informiert habe.
Oliver schrieb:> Arrays werden immer by reference übergeben
Das ist mir vollkommen klar. Ich wundere mich nur, warum die Funktion so
viel langsamer wird (komischerweiße schon beim kopieren auf den
Mikrocontroller) wenn ich einen normalen Integer, an die Funktion
übergebe!
Ein int wird ja in C bestimmt auch wie in anderen Sprachen per Call by
Value übergeben. Deshalb dachte ich, dass eben hier womöglich das
Problem liegt.
Sobald ich nicht mehr den übergebenen Integer benutze, sondern einfach
den Wert fest einprogrammiere funktioniert alles super schnell.
Oliver schrieb:> Ich würde Dir raten, mal ein gutes C-Buch genau durchzuarbeiten, da sind> Dir wohl einige Grundlagen noch nicht so ganz vertraut. Das ist aber> nicht schlimm, jeder hat mal angefangen.
Dachte, dass ich vielleicht ein schönes Online-Tutorial finde. Aber
etwas super passendes habe ich leider noch nicht gefunden. (Das Tut auf
dieser Seite hat mir aber auch schon gut geholfen)
Oliver schrieb:> Viel Erfolg beim Lernen,
Dankeschön, ich hoffe den werd ich haben.
Oliver schrieb:>>>int len=(sizeof(leds)/sizeof(*leds));>> Du teilst hier die Länge des Arrays durch die Länge eines Pointers. Da> im Array aber keine Pointer sind, muss das nicht die Anzahl der> Arrayelemente sein.
Das passt schon so wie er das hatte.
Hier ist *leds kein Pointer sondern evaluiert zum ersten Array-Element
und der sizeof nimmt sich dann von dem den Datentyp. Man hätte es auch
als
int len=(sizeof(leds)/sizeof(leds[0]));
schreiben können, da sieht man dann besser was passiert.
> Ich würde Dir raten, mal ein gutes C-Buch genau durchzuarbeiten
Dem kann ich nur beipflichten. Aus der Fragestellung und der ganzen Art
wie sie gestellt wurde, zeigen sich da enorme Defizite im
Grundlagenbereich.
Michael N. schrieb:> Oliver schrieb:>> In C gibt es kein public oder private, das gibt es erst in C++ (und in>> vielen anderen Sprachen).>> Würde also heißen, dass ich am besten noch eine Funktion schreibe und> das Array an diese Übergebe... Sonst kann ich mir nicht vorstellen wie> ich das hinbekommen soll, dass ich außerdem des IFs darauf zugreifen> kann.
Nope.
Das ganze sieht wie ein Zeichensatz für eine LED-Matrix aus.
Das Mittel der Wahl wäre für dich eine 2-dimensionales Array. In der
einen Dimension ist der Buchstabe der Index, in der anderen Dimension
stehen die Codes, die du an die LED-Matrix weiter geben musst.
Michael N. schrieb:>> Bist Du Dir klar, dass Du hier einen Zeiger auf das erste Element eines>> char-Arrays übergibst? Wenn Du nur einen Buchstaben brauchst, solltest>> Du auch nur einen übergeben.>> Genau das wollte ich.
warum tust du es dann nicht?
Die Funktion soll 1 Buchstaben anzeigen. Also bekommt sie auch nur 1
Buchstaben.
1
voidbuchstabe(charbuchstabe)
2
{
3
...
4
}
und der Aufrufer entscheidet, welchen Buchstaben aus einem String er
sehen möchte
1
....
2
3
buchstabe(string[0]);
4
buchstabe(string[1]);
5
...
oder vielleicht nacheinander alle Buchstaben des STrings
Karl Heinz Buchegger schrieb:> Das ganze sieht wie ein Zeichensatz für eine LED-Matrix aus.> Das Mittel der Wahl wäre für dich eine 2-dimensionales Array. In der> einen Dimension ist der Buchstabe der Index, in der anderen Dimension> stehen die Codes, die du an die LED-Matrix weiter geben musst.
Hm, das müsste tatsächlich eine wesentlich bessere Lösung sein.
Array[A][]={1,5,11,23}
Da hätte ich dann für jeden Buchstaben ein eigenes Array mit den LEDs
die geschaltet werden müssen.
Das würde jetzt erstmal das Problem lösen (bzw. übergehen)
Michael N. schrieb:> Da ich immer nur eine LED an einer LED-Matrix anschalte bin ich darauf> angewiesen, dass das Programm schnell abläuft (da die LEDs ja sonst> flackern).> Wenn ich nun an die Funktion LEDan() zusätzlich einen Parameter> übergebe, wie lange nach dem Anschalten einer LED gewartet werden soll,> bis die nächste angeht, dauert das anscheinend ewig und die LED-Matrix> flackert also... Wenn ich aber nun in der LEDan()-Funktion den Wert fest> programmiere, dann funktioniert das ganze super.
Der ganze Ansatz taugt nichts.
Du musst die eigentliche Anzeigeroutine von dem Teil der auswählt welche
LED leuchten soll und welche nicht, komplett trennen.
Die Anzeigeschleife einer LED-Matrix wird in eine Interruptfunktion
gelegt, die sich aus einem Array (welches einen virtuellen Bildschirm
realisiert) in schneller Folge rausholt was im Moment in einer
Zeile/Spalte gerade anzuzeigen ist.
D.h. die LED-Matrix wird im Hintergrund angesteuert. Dein eigentliches
Programm hat dann alle Zeit der Welt, die LED symbolisch ein/aus zu
schalten, in dem sie in diesem virtuellen Bildschirm die entsprechenden
Bits setzt/löscht.
Michael N. schrieb:> Karl Heinz Buchegger schrieb:>> Das ganze sieht wie ein Zeichensatz für eine LED-Matrix aus.>> Das Mittel der Wahl wäre für dich eine 2-dimensionales Array. In der>> einen Dimension ist der Buchstabe der Index, in der anderen Dimension>> stehen die Codes, die du an die LED-Matrix weiter geben musst.>> Hm, das müsste tatsächlich eine wesentlich bessere Lösung sein.> Array[A][]={1,5,11,23}> Da hätte ich dann für jeden Buchstaben ein eigenes Array mit den LEDs> die geschaltet werden müssen.
Nicht für jeden Buchstaben.
Für alle Buchstaben ein einziges Array!
(oder maximal eine Kombination aus einem Pointerarray und zusätzlichen
Arrays, wenn du unterschiedliche Spaltenzahlen pro Buchstabe hast).
Du willst diesen Quatsch mit den 100-tausend if ja gar nicht haben, wenn
es nicht sein muss. Und es muss nicht sein.
Karl Heinz Buchegger schrieb:>>> Bist Du Dir klar, dass Du hier einen Zeiger auf das erste Element eines>>> char-Arrays übergibst? Wenn Du nur einen Buchstaben brauchst, solltest>>> Du auch nur einen übergeben.>>>> Genau das wollte ich.>> warum tust du es dann nicht?
Habe ich falsch formuliert. Ich wollte nen Pointer übergeben und nicht
nur nen Zeichen...Von daher war das für mich schon passend.
Aber könnte natürlich auch einfach nur einen Buchstaben übergeben und
das halt für jeden machen.
Karl Heinz Buchegger schrieb:> Michael N. schrieb:>> Karl Heinz Buchegger schrieb:>>> Das ganze sieht wie ein Zeichensatz für eine LED-Matrix aus.>>> Das Mittel der Wahl wäre für dich eine 2-dimensionales Array. In der>>> einen Dimension ist der Buchstabe der Index, in der anderen Dimension>>> stehen die Codes, die du an die LED-Matrix weiter geben musst.>>>> Hm, das müsste tatsächlich eine wesentlich bessere Lösung sein.>> Array[A][]={1,5,11,23}>> Da hätte ich dann für jeden Buchstaben ein eigenes Array mit den LEDs>> die geschaltet werden müssen.>> Nicht für jeden Buchstaben.> Für alle Buchstaben ein einziges Array!> (oder maximal eine Kombination aus einem Pointerarray und zusätzlichen> Arrays).> Du willst diesen Quatsch mit den 100-tausend if ja gar nicht haben, wenn> es nicht sein muss. Und es muss nicht sein.
Stimmt, das will ich wirklich nicht haben (so viele ifs).
Naja ich meine halt EIN Array... (Sind aber ja wie mehrere Arrays in
einem eben...)
Michael N. schrieb:> Karl Heinz Buchegger schrieb:>>>> Bist Du Dir klar, dass Du hier einen Zeiger auf das erste Element eines>>>> char-Arrays übergibst? Wenn Du nur einen Buchstaben brauchst, solltest>>>> Du auch nur einen übergeben.>>>>>> Genau das wollte ich.>>>> warum tust du es dann nicht?>> Habe ich falsch formuliert. Ich wollte nen Pointer übergeben
Wozu?
> nur nen Zeichen...Von daher war das für mich schon passend.> Aber könnte natürlich auch einfach nur einen Buchstaben übergeben und> das halt für jeden machen.
Du kannst aufbauend auf deiner Buchstaben-Funktion ganz leicht eine
Funktion machen, die einen beliebigen String ausgeben kann
1
voidstring(char*str)
2
{
3
while(*str)
4
buchstabe(*str++);
5
}
Fertig. Jetzt hast du das beste aus 2 Welten. Eine Funktion, die einen
einzelnen Buchstaben ausgeben kann und eine Funktion, die einen
kompletten String ausgeben kann.
1
intmain()
2
{
3
...
4
5
buchstabe('*');
6
string("Hallo");
7
...
8
}
Das Geheimnis der Programmierung besteht nicht darin sich eierlegende
Wollmilchsau-Funktionen zu bauen, sondern aufbauend auf einfachen
Funktionen sich damit einen Baukasten von immer mächtigeren Funktionen
zurecht zu legen.
Einschub:
Wenn du mit Pointern noch nicht so weit bist. Die Funktion string kann
man auch so schreiben
1
voidstring(char*str)
2
{
3
intlen=strlen(str);
4
inti;
5
6
for(i=0;i<len;++i)
7
buchstabe(str[i]);
8
}
Ist aber
* nicht so schön wegen der zusätzlichen Variablen
* langsamer, wegen des zusätzlichen Aufrufs von strlen
* nicht die C-typische Art und Weise, wie man mit Strings in C arbeitet,
wenn man auf die einzelnen Buchstaben runter muss.
Karl-Heinz schrieb:
>Das passt schon so wie er das hatte.>Hier ist *leds kein Pointer sondern evaluiert zum ersten Array-Element>und der sizeof nimmt sich dann von dem den Datentyp
Stimmt, da habe ich Unsinn erzählt. sizeof(*leds) entspricht
sizeof(int), sizeof(&leds) würde sizeof(int*), also der Pointergröße,
entsprechen.
Karl Heinz Buchegger schrieb:> Michael N. schrieb:>> Karl Heinz Buchegger schrieb:>>>>> Bist Du Dir klar, dass Du hier einen Zeiger auf das erste Element eines>>>>> char-Arrays übergibst? Wenn Du nur einen Buchstaben brauchst, solltest>>>>> Du auch nur einen übergeben.>>>>>>>> Genau das wollte ich.>>>>>> warum tust du es dann nicht?>>>> Habe ich falsch formuliert. Ich wollte nen Pointer übergeben>> Wozu?
Naja für die eierlegend Wollmilchsau. Die braucht ja nen char-Array (hab
gelesen, dass es keine normalen Strings in C gibt) um ihn dann zu
zerlegen.
Karl Heinz Buchegger schrieb:> void string( char* str )> {> while( *str )> buchstabe( *str++ );> }
WOW. Das nenn ich mal kurz und knackig. Werd ich gleich mal
ausprobieren.
Wie befülle ich nun das zweidimensionale Array?
In einem Array können ja nur Werte das gleichen Typs gespeichert werden.
D.h. Array[A][0] würde ja schonmal gar nicht gehen.
Ich müsste also Beispielsweise mit Array[0][0] arbeiten (Dann kann ich
aber leider auch nicht direkt ein A eingeben und komme dahin. Höchstens
wieder über den Umweg der ascii-Werte.
Oder geht das mit gemischten Werten irgendwie?
Michael N. schrieb:> Naja für die eierlegend Wollmilchsau
Besonders am Anfang sollte man von unötigen "Tricks" Abstand nehmen und
lieber solide Programmieren...
Und die Doku lesen!
Michael N. schrieb:> Wenn ich nun an die Funktion LEDan() zusätzlich> einen Parameter übergebe
vermutlich nutzt du die delay funktionen und die funktionieren nicht so
sehr gut mit variablen Argumenten! Siehe Doku!
"Die Bibliotheksfunktionen funktionieren allerdings nur dann korrekt,
wenn sie mit zur Übersetzungszeit (beim Compilieren) bekannten
konstanten Werten aufgerufen werden. Der Quellcode muss mit
eingeschalteter Optimierung übersetzt werden, sonst wird sehr viel
Maschinencode erzeugt, und die Wartezeiten stimmen nicht mehr mit dem
Parameter überein."
Tatsächlich da stehen wirklich zwei Sätze darüber in der Doku. Die hab
ich leider beim Durchlesen (da hatte ich das Problem noch nicht) einfach
überlesen.
Wenn Du Platz hast im Speicher, dann schon. Hinter jedem Buchstaben
verbirgt sich ja sein ASCII-Code. Also: Array['p'][0]
Sollen nicht alle Zeichen dargestellt werden, dann Array komprimieren.
Zahlen beginnen bei Index 0: Aufruf => Array[Ziffer][0]
Danach meinetwegen die Großbuchstaben ab Index 10: Aufruf =>
Array[GBuchstabe-'A'+10][0] (kann man auch kürzer schreiben, so ist's
aber übersichtlich und der Compiler verfeinert das sowieso.)
Udo schrieb:> Zahlen beginnen bei Index 0: Aufruf => Array[Ziffer][0]
mir fällt grad auf: Ziffern sind ja hier auch nur Zeichen, also:
Array[Ziffer-'0'][0]
Michael N. schrieb:> int buchstabenarray[50][35
50 x 35 x 2 = 1500 Byte. Bisschen viel.
Michael N. schrieb:> int buchstabenarray[50][35]={> {1,2,3,4,5,6,11,16,17,18,19,21,26,31,32,33,34,35},> {1,2,3}> };
So steuert man doch keine Matrix an.
das ist ein "A":
00010000
00101000
01000100
11111110
10000010
10000010
10000010
00000000
Das kommt ins Array rein. Das wird Zeilenweise ausgegeben und jeder
Buchstabe hat 8 Byte. Macht bei 52 Buchstaben 416 Byte.
mfg.
Edit: Da war mal wieder einer schneller
Immerhin die Variante für 8x8 zeilenweise.
Ich sehe schon, dass ich von Anfang an einiges hätte besser machen
können.
Aber dafür hab ich ja mit Mikrocontrollern angefangen. Möchte ja was
lernen.
Karl Heinz Buchegger schrieb:> int buchstabenarray[50][35]={> {1,2,3,4,5,6,11,16,17,18,19,21,26,31,32,33,34,35},
Ja da gehen dann die LEDs 1,2,3 usw. nacheinander an (so war es
zumindest ursprünglich geplant)
Thomas Eckmann schrieb:> 50 x 35 x 2 = 1500 Byte. Bisschen viel.
Das ist tatsächlich recht viel. Ich werde mich mal mit der 8 Byte-Lösung
beschäftigen (bei mir sinds sogar nur 5 Byte, da ich nur 5x7 LEDs habe)
Allerdings hab ich meine Matrix komplett ohne Transistoren gebaut.
Deshalb möchte ich immer nur eine LED angeschaltet haben.(Lässt sich
damit aber ja natürlich auch machen)
Habe jetzt auch nen super C-Tutorial gefunden. Ich probier jetzt mal, ob
ichs zum laufen bekomme...
Michael N. schrieb:> Ich sehe schon, dass ich von Anfang an einiges hätte besser machen> können.> Aber dafür hab ich ja mit Mikrocontrollern angefangen. Möchte ja was> lernen.
Dein Problem ist, dass eine LED Matrix nicht wirklich etwas für Anfänger
ist. Um das vernünftig hinzukriegen, muss man schon etwas können und
Erfahrung haben.
> Allerdings hab ich meine Matrix komplett ohne Transistoren gebaut.> Deshalb möchte ich immer nur eine LED angeschaltet haben.(Lässt sich> damit aber ja natürlich auch machen)
Autsch. Das wird eng. Deine Matrix wird sehr dunkel werden und ob du das
Flackern in den Griff kriegst, ist eine andere Frage. Murks ist es
allemal.
Michael N. schrieb:> Deshalb möchte ich immer nur eine LED angeschaltet haben.(
Das bringt nichts.
Du hast 35 LEDs. Eine braucht dauerhaft 2 mA, damit sie normal hell
leuchtet. Zusammen also 70mA.
Und das sind nur die Low Current.
In einer Matrix sollen die LEDs aber genauso hell leuchten, obwohl sie
immer wieder nur kurz angeschaltet werden. Das erreicht man dadurch, daß
man den Strom in einer 5x7 Matrix, die Zeilenweise angesteuert wird, auf
das siebenfache erhöht. Dann leuchtet sie für unser Auge bei
ausreichender Wiederholrate ständig. Erhöht man den Strom nicht, glimmt
sie nur leicht.
Steuerst du nacheinander alle 35 LEDs einzeln an, muss der Strom auf das
35-fache erhöht werden. Das macht die LED aber nicht mit. Da gibt es
auch eine Grenze. Der Controllerport kann dir auch keine 70mA liefern.
Wie Karl Heinz schon andeutete, ist das komplizierter als es auf den
ersten Blick scheint.
Karl Heinz Buchegger schrieb:> Dein Problem ist, dass eine LED Matrix nicht wirklich etwas für Anfänger> ist. Um das vernünftig hinzukriegen, muss man schon etwas können und> Erfahrung haben.
mfg.
Thomas Eckmann schrieb:> Du hast 35 LEDs. Eine braucht dauerhaft 2 mA, damit sie normal hell> leuchtet. Zusammen also 70mA.>> Und das sind nur die Low Current.
Ich benutze nicht die lc-Variante sondern gescheide^^ Laut Datenblatt
also 20-30mA/LED
Thomas Eckmann schrieb:> Das erreicht man dadurch, daß> man den Strom in einer 5x7 Matrix, die Zeilenweise angesteuert wird, auf> das siebenfache erhöht. Dann leuchtet sie für unser Auge bei> ausreichender Wiederholrate ständig. Erhöht man den Strom nicht, glimmt> sie nur leicht.
Ist mir auch bekannt.
Habe das ganze allerdings getestet und es funktioniert (selbst mit allen
35 LEDs auf einmal) auch recht gut (Die LED wird an der oberen Grenze
betrieben, die laut Datenblatt möglich ist. Andere Widerstände hatte ich
eh nicht zur Hand^^).
Habe halt ein bisschen am Timer rumgeschraubt, und es geschafft, dass
die LEDs ausreichend stark leuchten und nicht flackern.
Das klappt also soweit schon. (Auch wenn es womöglich heller gehen
würde, so reicht es, sonst blendet es sowieso)
Eine Zeilenweise Ansteuerung wäre bei meiner Matrix aufgrund der Bauart
sowieso nicht möglich (diese Bauweise wurde mir aber hier im Forum
empfohlen, weil ich weniger IO-Pins verbrauche, auch wenn ich genug
gehabt hätte)
Karl Heinz Buchegger schrieb:> Dein Problem ist, dass eine LED Matrix nicht wirklich etwas für Anfänger> ist. Um das vernünftig hinzukriegen, muss man schon etwas können und> Erfahrung haben.
Was wäre denn ein Anfängerprojekt?
Bin gerne für Vorschläge offen.
Michael N. schrieb:> Thomas Eckmann schrieb:>> Du hast 35 LEDs. Eine braucht dauerhaft 2 mA, damit sie normal hell>> leuchtet. Zusammen also 70mA.>>>> Und das sind nur die Low Current.>> Ich benutze nicht die lc-Variante sondern gescheide^^ Laut Datenblatt> also 20-30mA/LED
noch schlimmer. Thomas hat schon zu deinen Gunsten 2mA Low Current LED
angenommen.
denk drann. Deine LED leuchtet nur 1/35 der Zeit. Damit sie wieder auf
normale Helligkeit kommt, muss sie in dieser kurzen Zeit 35 mal so hell
leuchten. D.h. du musst den 35 fachen Strom durchjagen. 35 * 20 = 700mA
Das hält deine LED nicht aus und dein µC auch nicht.
Deshalb sagte ich: deine Matrix wird sehr dunkel werden :-)
> Eine Zeilenweise Ansteuerung wäre bei meiner Matrix aufgrund der Bauart> sowieso nicht möglich (diese Bauweise wurde mir aber hier im Forum> empfohlen, weil ich weniger IO-Pins verbrauche, auch wenn ich genug> gehabt hätte)
Ob zeilenweise oder spaltenweise ist erst mal egal. Hauptsache mehrere
auf einmal. Dann reduziert sich der Multiplex von 1:35 auf 1:7 oder 1:5
und der Strom den du durch jede LED jagen musst reduziert sich.
> Was wäre denn ein Anfängerprojekt?
Lauflichter.
Irgendwann kann man zb mit einer 7-Segment Anzeige das erst mal sich
ansehen, wie Multiplexing überhaupt sinnvoll funktioniert. Und dann
kommt irgendwann die Matrix.
Karl Heinz Buchegger schrieb:> Ob zeilenweise oder spaltenweise ist erst mal egal. Hauptsache mehrere> auf einmal. Dann reduziert sich der Multiplex von 1:35 auf 1:7 oder 1:5> und der Strom den du durch jede LED jagen musst reduziert sich.
Werde mal schauen, was ich an Transistoren da habe, könnte dafür
reichen. Dann bau ich das so um, dass ich wirklich jede Spalte (Wäre am
sinnvollsten weil die Spalten ja länger sind als die Zeilen, nämlich 7
LEDs)
Karl Heinz Buchegger schrieb:> Lauflichter.> Irgendwann kann man zb mit einer 7-Segment Anzeige das erst mal sich> ansehen, wie Multiplexing überhaupt sinnvoll funktioniert. Und dann> kommt irgendwann die Matrix.
Ein bisschen Spektakulärer dürfte es schon sein :)
Lauflichter habe ich schon ein paar gebaut (allerdings halt ohne
Mikrocontroller).
Aber ein Lauflicht würde ich ohne Probleme hinbekommen, jetzt auch mit
Mikrocontroller.
Dann wäre also jetzt deine Empfehlung eine 7-Segment-Anzeige (hab ich
auch schon drüber nachgedacht).
Mal schauen, dann zieh ich vielleicht ein anderes Projekt der jetzigen
LED-Anzeige vor.