Forum: Mikrocontroller und Digitale Elektronik LED-Matrix OK, kurzer Lauftext OK aber langer Lauftext geht schief


von Stefan K. (sktmp)


Angehängte Dateien:

Lesenswert?

Hallo

häufig konnte ich schon von dem AVR Tutorials profitieren. Die sind sehr 
hilfreich. Vielen Dank erst mal dafür.

Nun habe ich aber ein Problem welches ich bisher nicht selbst lösen 
konnte. Wie oben beschrieben möchte ich eine LED-Matrix in Betrieb 
nehmen. Dazu die folgenden Daten:

Mikrocontroller: AtMega88-20PU mit einem 20 Mhz Quarz
LED-Matrix: 5x7 Kingbright TC20-11HWA (zunächst 2 Stück später 4)
Zeilentreiber: UDN2981
Spaltentreiber: ULN2803A
Schieberegister: 74HC595
Entwicklungsumgebung: AVR Studio 6.1 unter Win7 64bit

Ich verwende ein Schieberegister für die 7 Zeilen. Zwei weitere für die 
10 Spalten. Die Eingänge OutputEnable sowie Shift Register Clear von 
allen Schieberegistern hängen fest an der entsprechenden 
Versogungsspannung, so dass die Schieberegister funktionieren. SerialIn, 
RegisterClock und Shift Register Clock hängen am AVR. Die 
Schieberegister für die Spalten hängen also an drei PortPins des AVR und 
die Schieberegister für die Zeilen hängen auch wieder an drei weiteren 
PortPins des AVR. Nur das zweite Schieberegister für die Spalten bekommt 
die Daten (SerIn) vom ersten. Ich schiebe also die Daten für die Spalten 
vom ersten zum zweiten Schieberegister durch.

Nun zum Problem:

Wie im Betreff erwähnt funktioniert die LED-Matrix. Ein kurzer Lauftext 
funktioniert ebenfalls. Wenn der Text jedoch länger wird bleibt alles 
stehen. Ich sehe keine Ausgabe auf der Matrix. Kürze ich den Text klappt 
es wieder.
In der Main-Funktion lege ich die Char-Arrays a1 b1 b2 b3 b4 an. Diese 
übergebe ich an die Funktion TextToScroll. Die Funktion TextToScroll 
soll den Text 1mal auf der Matrix ausgeben. Da klappt solange bis ich 
alle Char-Array nacheinander ausgebe. Also rufe ich TextToScroll einmal 
mit a1 dann mit b1 auf. So klappt es. Füge ich den Aufruf von 
TextToScroll mit b2 und b3 an geht es nicht mehr.
In der Funktion TextToScroll verwende ich ein 2 Dimensionales Array. 
Dieses würde ich gerne vergößern um längere Texte aufnehmen zu können. 
Leider klappt dann die Textausgabe auch nicht mehr. Ich verstehe nicht 
wieso.

Um das Problem einzugrenzen habe ich schon das 2 Dimensionale Array von 
Int auf uint8_t umgestellt. Danach konnte der Text länger sein. Habe ich 
evtl. den Speicher oder den Mikrocontroller überlastet? Habe ich ein 
Denkfehler in meinem Quellcode?

Ich hänge mal meinen Quellcode an. Kann da jemand mal einen blick drauf 
werfen?

Vielen Dank.

grüße

sktmp

: Bearbeitet durch User
von adenin (Gast)


Lesenswert?

Überleg mal wie größ dein RAM ist und wieviel Byte Du für die Arrays 
brauchst, so wie sie jetzt angelegt werden.

von Stefan K. (sktmp)


Lesenswert?

Hallo

danke für den Hinweis. In der Richtung hatte ich vermutet. Mal rechnen:

Das Array ist 2 Dimensional uint8_t. Also 8 Bit pro Element.
1. Dimension 7
2. Dimension 129
Also 903 Elemente von 8 Bit oder 1 Byte
Das Array belegt 903 Byte.
Ram des ATMeag ist 1 KByte.

Der ist ziemlich voll. :-(

Aber wenn ich doch den Text aufteile und in mehrern Stücken nacheinander 
ausgbe sollte es doch klappen oder?
Also wenn ich statt 1 mal 21 Zeichen einfach 3 mal 7 Zeichen ausgebe.

Kann ich den Ram zwischendurch leeren mit einem Free befehl? Würde das 
helfen?

Hatte schon überlegt die Array auf Bool umzustellen. Das würde doch 
platz sparen?

Grüße

sktmp

: Bearbeitet durch User
von Stacker (Gast)


Lesenswert?

Ich habe mir deine Sourcen jetzt nicht angeschaut.
Das Array sollte global definiert sein, nicht innerhalb einer Funktion.
Außerdem sollte es nicht als Funktionsparameter übergeben werden.
Ansonsten wird es auf dem Stack angelegt und der läuft dann schnell über 
und der AVR arbeitet nicht mehr richtig.

Richtig:
1
uint8 Array[x][y];
2
3
foo1(void)
4
{
5
  ...
6
  Array[x][y] = 1;
7
}

Falsch:
1
foo1(uint8 Array[x][y])
2
{
3
  ...
4
}
5
6
foo2(void)
7
{
8
 uint8 Array[x][y];
9
 ...
10
}

von adenin (Gast)


Lesenswert?

Du brauchst noch RAM für die Variablen, Stack und wie es aussieht, hälst 
Du den kompletten Text auch im RAM.

von Hans (Gast)


Lesenswert?

Du solltest die Texte im Programmspeicher (Flash) ablegen, dann brauchen 
sie keinen RAM. Wie das geht, steht hier:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29

von Falk B. (falk)


Lesenswert?

@ Stefan Kokott (sktmp)

>Wie im Betreff erwähnt funktioniert die LED-Matrix. Ein kurzer Lauftext
>funktioniert ebenfalls. Wenn der Text jedoch länger wird bleibt alles
>stehen. Ich sehe keine Ausgabe auf der Matrix. Kürze ich den Text klappt
>es wieder.

Dann solltest du mal diesen Bastlermurks hinter dir lassen und das Thema 
Timer angehen. Dann klappts auch mit langen Texten.
Solche Delaysachen sind meistens Müll. Siehe auch LED-Matrix.

>Int auf uint8_t umgestellt. Danach konnte der Text länger sein. Habe ich
>evtl. den Speicher oder den Mikrocontroller überlastet?

Nö, du hast ihn nur zu 100% ausgebremst!

> Habe ich ein Denkfehler in meinem Quellcode?

Siehe oben.

>Ich hänge mal meinen Quellcode an. Kann da jemand mal einen blick drauf
>werfen?

Ein Schaltplan, der den Namen verdient, sieht auch anders aus!

Schaltplan richtig zeichnen

MfG
Falk

P.S. Und informier dich mal, was für tolle Dinge man mit Arrays machen 
kann. Deine LedChar.cpp ist der reinste Wahnsinn.

P.P.S. Wenn du nicht mal die einfachen Grundlagen von C beherrschst, 
braucht du deine Dateien nicht als C++ kennzeichnen. Die Endung .c 
reicht vollkommen.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Du brauchst einen Bildspeicher 2*5*7 = 10 Byte.

Dann brauchst du einen Zeichensatzspeicher 256*5*7 = 1280 Byte, der 
sollte im Flash liegen.

Und dann brauchst du den Textspeicher 1 Byte je Zeichen, der kann bei 
konstantem Text auch im Flash liegen, sonst im RAM.

Die Lauflichtfunktion holt sich nun die darzustellenen Zeichen aus dem 
Textspeicher, wandelt sie in Pixelmuster und schreibt sie in den 
Bildspeicher.

Der Ausgabeinterrupt holt nur noch die Pixelmuster aus dem Bildspeicher 
und sendet sie an die LEDs, nichts weiter. Er sollte möglichst 100Hz 
Framerate haben, d.h. bei 5 Zeilen Multiplex 500Hz. Das macht 40.000 
CPU-Zyklen je Interrupt, also spielend zu schaffen.

: Bearbeitet durch User
von Stefan K. (sktmp)


Lesenswert?

@Falk Brunner

Dass mein Schlatplan nicht fertig ist ist mir durchaus klar.

Die Information "Deine LedChar.cpp ist der reinste Wahnsinn." Hilft 
leider bei der Problemlösung nicht weiter. Kritik sollte immer 
Konstruktiv sein!

Nicht
Deine LedChar.cpp ist der reinste wahnsinn.

Sondern
Deine LedChar ist schlecht weil, ...
Es ist besser die Daten im Flash abzulegen, da ...

Auch das Ändern der Dateierweiterung löst sicher das Problem nicht.

Ich werde mir den Timer und die Sache mit dem Flash Speicher anschauen.


@peda
Zeichensatzspeicher bedeutet dann 256 Zeichen mit 5x7 Pixeln. Diese 
Zeichen sollten im Flash liegen.
Der Textspeicher nimmt den anzuzeigenden Text auf? Aber was ist mit dem 
Bildspeicher?

Offensichtlich müsste der Speicher des ATMega88 ja dann ausreichen.

Vielen Dank für die Hinweise.

Gruß

sktmp

von Falk B. (falk)


Lesenswert?

@Stefan Kokott (sktmp)

>leider bei der Problemlösung nicht weiter. Kritik sollte immer
>Konstruktiv sein!

Ok. Lies mal ein C-Buch und arbeite es von vor bis hinten durch.

>Zeichensatzspeicher bedeutet dann 256 Zeichen mit 5x7 Pixeln.

Ja, ein normaler Zeichensatz. Wobei man selten alle 256 Zeichen braucht, 
meist reichen die ersten 128 echten ASCII Zeichen. UNd sinnvollerweise 
speichert man auch ein 5x7 Pixel als 7 oder 8 Byte, damit man NICHT 
endlose Bitmanipulationen braucht, um die Daten zu erhalten. 128 
Zeichen a 8 Byte sind gerade mal 1kB Flash.

>Der Textspeicher nimmt den anzuzeigenden Text auf?

Sicher.

> Aber was ist mit dem Bildspeicher?

Die echten Bilddaten, welche aus der Verbindung von Textspeicher mit 
Zeichensatz berechnet wurden. Ändert sich der Text oder wird dieser um 1 
Pixel gescrolt (scheiß Denglisch ;-), muss der Bildspeicher neu 
berechnet werden.

>Offensichtlich müsste der Speicher des ATMega88 ja dann ausreichen.

Locker.

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.