mikrocontroller.net

Forum: Compiler & IDEs Potentiometer und Festwerte


Autor: Pinkuss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe einen Potentiometer und 5 verschiedene Taster für feste Werte 
an einem ATmega128 angeschlossen und möchte nun folgende Featurette in 
mein Dimmerprogramm einbauen:

Startet man den Controller, wird ganz normal der Potiwert verwendet 
(verstellt die PWM...). Drückt man einen der Taster wird der fest 
einprogrammierte Wert übernommen und der Poti wird erstmal deaktiviert.

Nun kommts: Dreht man wieder an dem Poti, soll verhindert werden, daß 
Sprünge in den Helligkeitswerten auftreten. Ich hatte es mir so 
vorgestellt, daß man entweder den Poti zuerst auf 0 drehen muss um dann 
den per Taster eingestellten Wert beim Hochdrehen zu "fangen" (vgl. mit 
einem mechanischem Mitnehmer, o.Ä.) oder der Poti erst wieder aktiv 
wird, wenn der Wert sich in der Nähe des Festwertes befindet.

Jetzt habe ich folgendes Codefragment, aber es funktioniert nicht 
zufriedenstellend, weil wenn der Poti nahe einem Tasterwert steht, 
dieser nicht immer übernommen wird... Problem ist, daß ich eine 
Gammakorrektur eingebaut habe (Poti ist linear, Helligkeit soll aber 
logarithmisch sein) und der Poti nicht immer fängt, zumal meine 
Abfrageroutine nur alle 50ms erfolgt, was einerseits die Entprellung der 
Taster brachte, andererseits aber zu große Abstände liefert, wenn man zu 
schnell am Poti dreht.

  switch ( index )
  {
    case 19 : pwm_setting[0] = BEDECKT; moon_status = 1; break;
    case 20 : pwm_setting[0] = NEUMOND; moon_status = 1; break;
    case 21 : pwm_setting[0] = HALBMOND1; moon_status = 1; break;
    case 22 : pwm_setting[0] = HALBMOND2; moon_status = 1; break;
    case 23 : pwm_setting[0] = VOLLMOND; moon_status = 1; break;
  }

  if ( moon_status != 1 ) {
    pwm_setting[0] = gamma_pwm(7,0);    // Value Poti 7 to PWM-Channel 0
  }
  
  if ( (abs(pwm_setting[0] - gamma_pwm(7,0))) < 16  ) {
    moon_status = 0;  
  }

  pwm_update();


Hat jemand vielleicht eine Idee, wie man das eleganter lösen könnte, 
bzw. das wie man die Rückkehr zur Poti-Bedienung am besten realisieren 
könnte.

Herzlichen Dank schonmal für Eure Kommentare.

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

Bewertung
0 lesenswert
nicht lesenswert
Pinkuss wrote:

> Hat jemand vielleicht eine Idee, wie man das eleganter lösen könnte,
> bzw. das wie man die Rückkehr zur Poti-Bedienung am besten realisieren
> könnte.

Schmeiss das Poti raus und hol dir einen Drehgeber.
Das Problem ist, dass ein Poti einen Absolutwert liefert, du in dieser 
Aufgabenstellung aber mit einem relativen Wert (User dreht nach links, 
User dreht nach rechts, dementsprechend erhöht/erniedrigt sich ein Wert) 
besser bedient bist.

Autor: liinterpo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder du interpolierst über eine bestimmte zeit hinweg die geänderten 
werte. so kriegst du immer einen weichen übergang.

Autor: liinterpo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
t = (aktuellezeit - übergangsstartzeit) / übergangsdauer
wert = alterwert * (1-t) + neuerwert * t

Autor: was-willst-du (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du schon beim Ändern bist: Verkürz auch die Zeit von 50ms.

Tasten prellen nicht so lange, wenn es Deine doch tun, schmeiß sie 
einfach weg.

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

Bewertung
0 lesenswert
nicht lesenswert
liinterpo wrote:
> t = (aktuellezeit - übergangsstartzeit) / übergangsdauer
> wert = alterwert * (1-t) + neuerwert * t

Kann man so machen, würd ich aber nicht tun.

Ich würd so machen:
Eine ISR wird in regelmässigen Zeitabständen aufgerufen, damit hab ich 
mal eine Zeitbasis.

Dazu gibt es dann noch für den interessierenden Wert 2 Variablen. Eine 
die den tatsächlichen Wert enthält und der mit der PWM-Stellung 
korrespondiert. Die 2-te Variable enthält die Benutzervorgabe.
In der ISR wird dann ganz einfach festgestellt, ob der tatsächliche Wert 
von der Benutzervorgabe abweicht. Tut er das, wird der tatsächliche Wert 
ein klein wenig in Richtung der Benutzervorgabe nachgestellt. Über viele 
ISR Aufrufe gesehen wird also der tatsächliche Wert immer auf den vom 
Benutzer vorgegebenen Wert nachgeführt.

Vorteil:
* wenig zu rechnen
* unkompliziert
* die Benutzervorgaben können sich in schneller Folge in jede beliebige 
Richtung verändern, ohne dass das für mich ein rechnerischer Mehraufwand 
bedeutet.
* Durch Steuerung der ISR-Aufruffrequenz kann man ganz leicht bestimmen, 
wie schnell dieser Nachführvorgang abläuft
* Die Nachführung ist ohne sonstiges Zutun automatisch linear
* Falls gewünscht, ist es auch kein Problem bei großen Differenzen eine 
schnelle Nachführung zu realisieren, die sich verlangsamt, wenn die 
Benutzervorgabe nahezu erreicht ist.
* Auf und Ab-Dimmen kann trivial mit unterschiedlichen Raten 
implementiert werden.
uint16_t actValue;
volatile uint16_t userWants;


...
ISR( .... )   // zb. ein Overflow oder ein CTC-Interrupt
{
  if( actValue != userWants ) {
    if( actValue < userWants )
      actValue++;
    else
      actValue--;

    SetPWMValue( actValue );
  }
}

Durch Zuweisungen an userWants wird die PWM 'langsam' an genau diesen 
Wert herangeführt.

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.