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
>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 ?
Warum darf der Poti Wert nicht seinen Stammplatz am LCD haben und wird dort immer angezeigt? Dann brauchst du keinen delay.
Dann sehe ich den angezeigten Wert nicht mehr! Das Hauptprogramm geht, wie gesagt, danach weiter mit einer eigenen Display-Ausgabe.
..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?!
Dreh das Problem doch einfach um. Wenn ein geänderter ADC Wert auftaucht verhinderst du für eine bestimmte Zeit die Ausgabe deines Hauptdisplays.
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...
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
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.
@ 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).
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
> 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.
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.
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
@ 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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.