mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD: Performance verbessern!


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich möchte über ein Poti einen Wer einstellen der zwischen der laufenden 
Routine bei Änderung des Wertes kurz angezeigt wird.
Es läuft bei mir so:
Vergleich alter Poti-Wert neuer Wert, wenn Unterschied, dann Funktion 
aufreufen(Poti-Wert umrechnen, auf LCD anzeigen, 2s Delay, zurück zur 
Hauptroutine)

Was mir nicht gefällt ist das Delay, da die Anzeige dann ziemlich träge 
auf das Poti reagiert! Wie könnte man es besser machen, so dass ich den 
geänderten Wert noch sehe und der auch schnell reagiert?

Gruß Christian

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Was mir nicht gefällt ist das Delay, da die Anzeige dann ziemlich träge
>auf das Poti reagiert! Wie könnte man es besser machen,

Das Delay weglassen ?

Autor: Marc Meise (bytewood) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wärs mit einem Timerinterrupt und ohne delay-Funktion?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum darf der Poti Wert nicht seinen Stammplatz am LCD haben und
wird dort immer angezeigt?
Dann brauchst du keinen delay.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann sehe ich den angezeigten Wert nicht mehr! Das Hauptprogramm geht, 
wie gesagt, danach weiter mit einer eigenen Display-Ausgabe.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz
Display ist schon voll!

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
..es ist ein numerisches LCD

@Marc

habe ich dann nicht das selbe Problem, dass der Wert erst neu angezeigt 
werden kann, wenn eine bestimmte Zeit abgelaufen ist?!

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dreh das Problem doch einfach um. Wenn ein geänderter
ADC Wert auftaucht verhinderst du für eine bestimmte
Zeit die Ausgabe deines Hauptdisplays.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das ginge evtl. auch,  das Problem bleibt aber, ich müsste in der Zeit 
weiter den Poti-Wert vergleichen, und die "Zeituhr" neu starten, wenn 
sich etwas geändert hat und das geht mit delay nicht, es sei denn ich 
splitte das delay auf...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ungefähr so:

volatile unsigned char timer; // count down inside timerinterrupt 10ms
                              // until zero

int main(void)
{
  for(;;){
    if( poti_changed() ){
      display_poti();
      timer = 200;
    }
    if( timer )
      continue;
    main_program();
  }
}


Peter

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja. Da weder du noch irgendjemand sonst hexen kann, wirst
du wohl damit leben müssen.
Entweder du lässt die Zahl eine Zeitlang dort stehen und verhinderst
dass in dieser Zeit kein anderer auf das Display zugreift
oder du kannst sie nicht lesen, weil sie wieder zu schnell
verschwindet.

Andere Lösungen gibt es nicht.

Man kann das allerdings etwas gefinkelter machen als mit
einem schnöden Delay. Gewöhn dich an das Konzept, dass das
Display einer Funktionseinheit in deinem Programm zugeordnet
ist. Eine Ausgab darf nur dann gemacht werden, wenn die entsprechende
Funktionseinheit die Berechtigung dazu hat. Will die ADC
Einheit ihren Wert ausgeben, dann 'reist sie diese Berechtigung
an sich' wodurch die weiteren Ausgaben vom Hauptprogramm ins
Leere laufen. Gleichzeitig mit diesem an-sich-reissen wird ein
Timer gestartet bzw. neu gestartet, dessen Aufgabe es ist, nach
Ablauf einer vorgegebenen Zeit diese Berechtigung wieder zurückzugeben.

Autor: Marc Meise (bytewood) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian

Der Wert, der angezeigt wird, hängt davon ab, wie häufig ein 
Timeroverflow generiert wird, also wie schnell Dein Timer läuft.
Ich stelle mir das fogendermaßen vor:


TimerInit
{
 10x pro Sekunde, oder wie schnell auch immer
}

main()
{
tu was

interrupts ausschalten
adcWert1 erfassen
adcWert2 erfassen
interrupts einschalten
}


Interruptroutine
{
vergleiche adcWert1 mit adcWert2
WENN Unterschied, DANN
  {
   Darstellung()
  }
}

Darstellung()
{
 interrupts ausschalten
 Stell den Wert dar
 warte ein bischen (delay)*
 lösche die Position, wo der Wert sonst angezeigt würde
 interrupts einschalten
}

------------------------------------
* Das(delay) kann man sich auch sparen, wenn die Timerinterrupts dazu 
genutzt werden, um eine "Anzeigezeit" zu realisieren (Overflows zählen).

Autor: Dennis Nitschke (nilpferd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

verstehe ich das erstmal richtig:
Dein Display zeigt irgendwas an, wenn einer am Poti dreht soll dessen 
Wert angezeigt werden, dann wieder die Anzeige aus dem Hauptprogramm.
Dein Problem ist, daß die Anzeige beim Potidrehen nur alle zwei Sekunden 
aktualisiert wird wegen dem Delay.
Dann mach doch das Delay ans Ende der Schleife, solange sich der Wert 
ändert, sprich einer dreht, bleibst Du in der Poti-Auswertung, erst wenn 
sich nix mehr ändert läuft das Delay los, der Wert wird noch 2 Sekunden 
angezeigt und dann kommt Dein Hauptprogramm wieder zum Zug.
Oder hab ich das Problem falsch interpretiert.

Gruß, Dennis

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Dann mach doch das Delay ans Ende der Schleife, solange sich der Wert
> ändert, sprich einer dreht, bleibst Du in der Poti-Auswertung

Dir dürfte eines nicht klar sein:
Kein Mensch kann ein Poti so schnell drehen, dass sich ein ADC
bzw. der µC dabei nicht langweilen würde. Vor allem in der
Endphase, wenn es darum geht einen Wert exakt einzustellen und
man naturgemäß langsam und feinfühlig dreht.

Autor: Dennis Nitschke (nilpferd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
>> Dann mach doch das Delay ans Ende der Schleife, solange sich der Wert
>> ändert, sprich einer dreht, bleibst Du in der Poti-Auswertung
>
> Dir dürfte eines nicht klar sein:
> Kein Mensch kann ein Poti so schnell drehen, dass sich ein ADC
> bzw. der µC dabei nicht langweilen würde. Vor allem in der
> Endphase, wenn es darum geht einen Wert exakt einzustellen und
> man naturgemäß langsam und feinfühlig dreht.

Ich meinte ja auch, daß bei Änderung des Potiwerts die zwei Sekunden neu 
starten. Passiert innerhalb der zwei Sekunden nix, zurück ins 
Hauptprogramm.
Ansonsten bliebe noch die Variante, nen Taster vorzusehen, wird der 
gedrückt, zeigt das Display den Potiwert, sonst halt nicht. Ist aber 
eben nicht ganz so elegant.

Autor: Ulrich P. (uprinz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also das ist mit einem einfachen Timer-Interrupt doch wunderbar zu 
machen:

Haupt-Anzeige:
HA-Refresh Bit gesetzt?
Ja: Schreibe Haupt-Anzeige, lösche HA-Refresh
...

Poti-ADC:
Ist alt != neu?
JA:
  berechne Werte
  setze alt = neu
  schreibe neu auf Display
  setze Display-Delay auf n Timerzyklen.
NEIN: tu nix
FERTIG

Timer-Interrupt:
wenn Display-Delay > 0
  Display-Delay -1
  wenn Display-Delay == 0
    setze HA-Refresh
FERTIG

Damit wird die Hauptanzeige nur einmal nach Zeit n zur Aktualisierung 
aufgefordert. So lange sich der ADC-Wert ändert, wird dieser angezeigt. 
Und das ganze in ca. 10-15 Zeilen Code. Zugleich kann der ADC unabhängig 
vom Timer gesteuert werden. D.h. man kann ihn z.B. free-running laufen 
lassen um nicht weitere Timer zu blockieren, man kann ihn irgendwo in 
der Hauptschleife abfragen, u.s.w. Trotzdem hat man ein gleichbleibendes 
Verhalten der Anzeige.

Ich mache das immer für Status-LEDs so. Immer wenn ich etwas über den 
UART schicke oder empfange, dann setze ich den Timeout und den Pin für 
die zugehörige LED.
Die Timer-Routine zählt den Timeout wieder runter und schaltet die LED 
aus, ohne, dass ich mich drum kümmern muss. So hat man auch bei hohen 
Geschwindigkeiten und kurzen Datenpaketen eine erkennbar leuchtende LED 
anstelle eines erahnbaren Geflimmers.

Gruß, Ulrich

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Ulrich P. (uprinz)

>Ich mache das immer für Status-LEDs so. Immer wenn ich etwas über den
>UART schicke oder empfange, dann setze ich den Timeout und den Pin für
>die zugehörige LED.
>Die Timer-Routine zählt den Timeout wieder runter und schaltet die LED
>aus, ohne, dass ich mich drum kümmern muss. So hat man auch bei hohen
>Geschwindigkeiten und kurzen Datenpaketen eine erkennbar leuchtende LED
>anstelle eines erahnbaren Geflimmers.

Ein Monoflop in Software.

MFG
Falk

Autor: Ulrich P. (uprinz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Falk
Rrrrichtiiig!
:)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.