Forum: Mikrocontroller und Digitale Elektronik LCD: Performance verbessern!


von Christian (Gast)


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

von holger (Gast)


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 ?

von Marc M. (bytewood) Benutzerseite


Lesenswert?

Wie wärs mit einem Timerinterrupt und ohne delay-Funktion?

von Karl H. (kbuchegg)


Lesenswert?

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

von Christian (Gast)


Lesenswert?

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

von Christian (Gast)


Lesenswert?

@Karl heinz
Display ist schon voll!

von Christian (Gast)


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?!

von holger (Gast)


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.

von Christian (Gast)


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...

von Peter D. (peda)


Lesenswert?

ungefähr so:
1
volatile unsigned char timer; // count down inside timerinterrupt 10ms
2
                              // until zero
3
4
int main(void)
5
{
6
  for(;;){
7
    if( poti_changed() ){
8
      display_poti();
9
      timer = 200;
10
    }
11
    if( timer )
12
      continue;
13
    main_program();
14
  }
15
}


Peter

von Karl H. (kbuchegg)


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.

von Marc M. (bytewood) Benutzerseite


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).

von Dennis N. (nilpferd)


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

von Karl H. (kbuchegg)


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.

von Dennis N. (nilpferd)


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.

von Ulrich P. (uprinz)


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

von Falk B. (falk)


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

von Ulrich P. (uprinz)


Lesenswert?

@Falk
Rrrrichtiiig!
:)

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.