Forum: Mikrocontroller und Digitale Elektronik Alternative für DOTMATRIXDISPLAY Da super langsam.


von ABSimon (Gast)


Lesenswert?

Hallo Zusammen,

mit LCDs kenne ich mich leider nicht aus, jetzt habe ich eine 
Testplatine
mit einem "DotMatrixDisplay" erhalten.

Das LCD Diplay ist super langsam, in Zeitlupentempo baut ich Anzeige auf
und stoppt die ganz Applikation. Sensorwerte (Gyro) können demnach
nicht vernünftig aufsummiert werden. (wenn ich ein paar hunderstel 
fehlen,
habe ich eine Problem, stimmen die werte nicht mehr.)

Sind "DotMatrixDisplay" grundstätzlich für zeitkritische Anwendungen
geeignet?

Ich kenne nur vom einem PIC32 Demoboard ein LCD Display was super
schnell ist.

Jetzt ist die Frage, lohnt es sich in die "DotMatrixDisplay" Funktionen
mit Befehlssätzen und Timing-Chart einzusteigen, oder ist der
der LCD Typ einfach ungeeignet und muß getauscht werden.

Hilfe wär, stecke wirklich in der Klemme.

Viele Grüße
ABSimon

von Martin (Gast)


Lesenswert?

Ich würde sagen schlecht programmiert.

von ARM-Fan (Gast)


Lesenswert?

>"DotMatrixDisplay"

Ja, welches denn? Alphanumerisch? Grafisch?

>in Zeitlupentempo baut ich Anzeige auf und stoppt die ganz Applikation.

Dann ist es schlichtweg falsch programmiert, wenn die Anzeigefunktion
die restliche Programmausführung blockiert oder umgekehrt. Hat nichts
mit der Anzeige selbst zu tun.

von ABSimon (Gast)


Lesenswert?

Hallo,

vielen Dank.

DOTMATRIXDISPLAYS 2x40
Elektonic Assembly GmbH
LOCHHAMER SCHLAG 17 · D-82166 GRÄFELFING

TECHNISCHE DATEN
* INTEGRIERTER KONTROLLER HD44780 ODER KOMPATIBEL
* EINGANG 4- ODER 8-BIT DATENBUS, 3 STEUERLEITUNGEN (R/W, E, RS)
* ASCII-ZEICHENSATZ UND SONDERZEICHEN IM CHARACTER-ROM
* BIS ZU 8 ZEICHEN (ASCII-CODE 0..7) KÖNNEN FREI DEFINIERT WERDEN
* VERSCHIEDENE FUNKTIONEN MIT EINEM BEFEHL PROGRAMMIERBAR:
- CLEAR DISPLAY, CURSOR HOME, CURSOR ON/OFF, BLINKING CURSOR
- SHIFT DISPLAY, SHIFT CURSOR, READ/WRITE DISPLAY DATA, ETC.
* EINFACHE SPANNUNGSVERSORGUNG (+5V). AUSNAHME: EINIGE TYPEN
WIE z.B. DISPLAYS MIT ERW. TEMPERATURBEREICH
* GERINGER STROMVERBRAUCH (1..4 mA)
* BETRIEBSTEMPERATUR 0..+50°C

OPTIONEN
* ERWEITERTER TEMPERATURBEREICH -20..+70 °C
* KYRILLISCH/ENGLISCHER ZEICHENSATZ
* 6°° ODER 12°° BLICKRICHTUNG
* INTERFACEBOARD MIT RS-232 SCHNITTSTELLE ODER
* RS-422 SCHNITTSTELLE
* INTERFACEBOARD MIT 64 PROGRAMMIERBAREN TEXTEN IM EEPROM
LCD DOTMATRIXDISPLAYS


Genau kenne ich mich hier leider nicht aus.
Gibts hier nicht vielleicht schon fertige Bibliotheken/Funktionen,
die das besser machen?

Wäre klasse, würde mir wohl X Stunden Arbeit ersparen.

Vielen Dank & Viele Grüße
ABSimon

von Johnny (Gast)


Lesenswert?

Ist definitiv schlecht programmiert wenn es so langsam ist.
Für HD44780 kompatible Controller wie bei diesem Display gibt es 
haufenweise implementationen im Internet. Im Zweifelsfalle ist die 
Ansteuerung aber auch selbst in nicht allzu langer Zeit programmierbar, 
sofern man Datenblätter lesen kann und sich mit der 
Firmwareprogrammierung in C auskennt.

Als "Quick-Hack" könntest Du im Sourcecode mal nachschauen, ob die 
benötigten Verzögerungszeiten mit festen "Delays" programmiert sind oder 
ob das Busy-Flag des Displays abgefragt wird. Falls es mit Delays 
gemacht ist, dann sind diese vielleicht viel zu lang gewählt. Auf jeden 
Fall könnte es dann so umprogrammiert werden, dass die Delays mit 
Abfragen des Busy-Flags ersetzt werden.

von Teplotaxl X. (t3plot4x1)


Lesenswert?

>* INTEGRIERTER KONTROLLER HD44780 ODER KOMPATIBEL

Normaler gehts nicht ;)

Dürfte also mit (fast) jeder LCD-lib funktionieren.

von Peter D. (peda)


Lesenswert?

ABSimon wrote:
> Das LCD Diplay ist super langsam, in Zeitlupentempo baut ich Anzeige auf
> und stoppt die ganz Applikation.

Ja, es gibt Programmierer, die unbedingt im 100µs Timerinterrupt das 
komplette Display ausgeben müssen. Und natürlich auch alles float-Werte 
mit sprintf(), daß die CPU nur so qualmt.

Bloß kann kein Mensch in 100µs ein Display ablesen.
Nichtmal ne Fliege kann das und die ist 200-mal schneller.
Etwa 200ms ... 500ms Ausgaberate sind ergomonisch.

Entweder per Timer gesteuert alle 200ms in der Mainloop auf das Display 
ausgeben oder in nem Timerinterrupt alle 1..10ms immer nur 1 Zeichen.


Peter

von ABSimon (Gast)


Lesenswert?

Hallo,

vielen Dank, ich werde mal auf die Suche gehen.
ich versuche mein bestes,

@Johnny ja sind sind feste delay funktionen

Hier der Code - (wer ggf. einen Zeitlupen Quelltext brauch :-))
Sieht aus wie als würde eine Schreibmaschine schreiben,
Zeichen für Zeichen. Für 2 Zeilen braucht man so ca.
4-5 Sekunden.
1
/**************** myLCDInit ****************/
2
unsigned char myLCDInit(void) {
3
4
  setLCDPort(0x00, 0);
5
  __delay_cycles(_100_ms);// delay after lcd powerup
6
  setLCDPort(0x38, 0);
7
  setLCDPort(0x38, 0);
8
  setLCDPort(0x0E, 0);
9
  setLCDPort(0x06, 0);
10
  clearDisplay();
11
  __delay_cycles(_4_ms);
12
  return 0;
13
}
14
15
/*************** setLCDPort ****************/
16
17
unsigned char setLCDPort(unsigned char data, unsigned char dataflag) {
18
  LCDENABLE = 1;     // set enable pin high
19
  if(dataflag) {
20
    LCD_RS = 1;   //transmit data
21
  } else {
22
    LCD_RS = 0;   //transmit command
23
  }
24
  LCD_RW = 0;
25
26
  LCDDATA0 = data ;       //Display Data bit 0 (=DDB 0
27
  LCDDATA1 = data >>1;    //Display Data bit 1 (=DDB 1
28
  LCDDATA2 = data >>2;    //Display Data bit 2 (=DDB 2
29
  LCDDATA3 = data >>3;    //Display Data bit 3 (=DDB 3
30
  LCDDATA4 = data >>4;    //Display Data bit 4 (=DDB 4
31
  LCDDATA5 = data >>5;    //Display Data bit 5 (=DDB 5
32
  LCDDATA6 = data >>6;    //Display Data bit 6 (=DDB 6
33
  LCDDATA7 = data >>7;    //Display Data bit 7 (=DDB 7
34
35
  __delay_cycles(_40_ms);
36
  LCDENABLE = 1;     // set enable pin high
37
  __delay_cycles(_40_ms);
38
  LCDENABLE = 0;     // set enable pin low to start transfer
39
  __delay_cycles(_20_ms);
40
41
  return 0;
42
}
43
44
/************** clearDisplay ***************/
45
46
unsigned char clearDisplay(void) {
47
  setLCDPort(0x00,0);     // get ready for display clear
48
  setLCDPort(0x01,0);     // clear display
49
  __delay_cycles(_20_ms);
50
  return 0;
51
}
52
53
/************* writeLCDString **************/
54
55
unsigned char writeLCDString(unsigned char* string,unsigned char length) {
56
  unsigned char c;
57
58
  clearDisplay();
59
  __delay_cycles(_20_ms);
60
61
  for(c=0;c<length;c++) {
62
    writeLCDChar(string[c]);
63
    if(c==27) {                  //if at last position of first line
64
      moveCursor(0x40);        // go to second line
65
    }
66
  }
67
68
  return 0;
69
}
70
71
/*************** moveCursor ****************/
72
73
unsigned char moveCursor(unsigned char position) {
74
  setLCDPort(position & 0x27,0);
75
  __delay_cycles(_20_ms);
76
  return 0;
77
}
78
79
/************** writeLCDChar ***************/
80
81
unsigned char writeLCDChar(unsigned char symbol) {
82
  setLCDPort(lookUpSymbol(symbol),1);          // second part of symbol
83
  __delay_cycles(_20_ms);
84
85
  return 0;
86
}
87
/************** lookUpSymbol ***************/
88
unsigned char lookUpSymbol(unsigned char symbol) {
89
  return symbol - 'A' + 0x41;     // character code table of display is ASCII table with offset
90
                                  // 0x41 is capital A in LCD char code table
91
}

Danke & Viele Grüße
ABSimon

von Peter D. (peda)


Lesenswert?

ABSimon wrote:
1
>   __delay_cycles(_40_ms);
2
>   LCDENABLE = 1;     // set enable pin high
3
>   __delay_cycles(_40_ms);
4
>   LCDENABLE = 0;     // set enable pin low to start transfer
5
>   __delay_cycles(_20_ms);

Wenn der Name stimmt, also 40ms, dann sind das nur knappe 10000000% 
Zeitverschwendung.
1µs reicht als enable-Puls völlig.


Peter

von P. S. (Gast)


Lesenswert?

Und wie sieht der restliche Code aus?

von ABSimon (Gast)


Lesenswert?

Hallo,

trau ich mich garnicht zu posten :-)

Aufgerufen wird das ganze so
z.B. Anzeigen von VSource
1
  //VSOURCE
2
  adc_0 = Basic_ADC(0x07);
3
4
  adc_0 = (adc_0 * 34)/k; //this factor is due to voltage divider
5
  adc_0 = adc_0 / 10;
6
  a = adc_0 / 100;
7
  b = (adc_0 - 100 * a) / 10;
8
  c = adc_0 - 100*a-b*10;
9
10
  //overload in Basic_ADC is 0xFF -> 6V in display
11
12
  writeLCDString("Spannung VSOURCE =",18);    //write string to display
13
  writeLCDNumb(a);
14
  writeLCDNumb(b);
15
  writeLCDChar('.');
16
  writeLCDNumb(c);
17
  writeLCDChar('V');
18
  writeLCDChar(' ');

Ich hab schon versucht hier nur den Wert (int) adc_0 anzuzeigen aber
die Funktion writeLCDNumb() gibt nur eine Ziffer her.
Abgesehen davon das man für mehrere Werte viel Geduld braucht.

Als am beste komplett auf eine andere Bibliothek umsatteln?

Danke & Viele Grüße
ABSimon

von Jadeclaw D. (jadeclaw)


Lesenswert?

40ms? Wenn das so stimmt, dann wundert mich nichts mehr. Ich habe an 
einem KW-Empfänger ein HD44780-Display als Bargraph dran als 
Feldstärkeanzeige. Das Ding wird 30 mal pro Sekunde komplett neu 
geschrieben, um so ein analoges Verhalten zu erreichen. 100 mal pro 
Sekunde für 16 Zeichen geht auch noch ohne Probleme. Soviel zu der mit 
solchen Displays erreichbaren Update-Rate.

  a = adc_0 / 100;
  b = (adc_0 - 100 * a) / 10;
  c = adc_0 - 100*a-b*10;

Hier wird der Wert in adc_0 auf die 3 Stellen aufgesplittet,

  writeLCDNumb(a);   //Zehner
  writeLCDNumb(b);   //Einer
  writeLCDChar('.'); //Komma
  writeLCDNumb(c);   //1 Nachkommastelle

schreibt die einzelnen Teile dann ins Display.
writeLCDNumb(); kann offensichtlich nur 1 Zeichen auf einmal ausgeben.

> Als am beste komplett auf eine andere Bibliothek umsatteln?
Würde ich mal sagen. Wenn du WinAVR benutzt, dann schau dir dieses 
Tutorial mal an:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial


Gruß
Jadeclaw.

von holger (Gast)


Lesenswert?

>Als am beste komplett auf eine andere Bibliothek umsatteln?

Wenn sie läuft nein.
Du kannst einiges an Zeiten verkürzen.
Als erstes der Tip von Peter mit dem Enable Puls.
1us langt.
1
unsigned char writeLCDChar(unsigned char symbol) {
2
  setLCDPort(lookUpSymbol(symbol),1);          // second part of symbol
3
  __delay_cycles(_20_ms);
4
5
  return 0;
6
}

Da reicht ein Delay von 100us dicke.
Änder das einfach mal und du wirst sehen das dein Display
schon um einiges schneller wird.

Um die Feinheiten kümmern wir uns später ;)

von Johnny (Gast)


Lesenswert?

Die Delays in setLCDPort() würde ich auch mal um den Faktor 10 bis 100 
verkürzen, dann wird es mit dem vorangegangenen Vorschlag wahrscheinlich 
schon genügend schnell laufen.

von ABSimon (Gast)


Lesenswert?

Hallo,

vielen Dank für die Tipps, aktuelle habe nur eine Testversion von ISP
WINAVR wäre somit sowieso in 20 Tagen fällig.

Ich werde jetzt versuchen diese Funktion einzubauen
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#LCD-Ansteuerung

Ich hoffe das ist die richtige Lösung. Und man kann das als LCD
Laie realiseren.

Vielen Dank für die tolle Unterstützung!!

Viele Grüße
ABSimon

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.