mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Drehimpulsgeber drehgeschwindigkeitsabhängig auslesen


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich bin gerade dabei, mir ein Programm für einen Zähler zu schreiben. 
Mit Hilfe eines Drehimpulsgebers sollen 3 7.Segmentanzeigen 
hoch/runtergezählt werden.

Soweit so gut - bis hier hin funktioniert auch alles wunderbar. Die 
Zahlen lassen sich in 1'er Schritten hochzählen. Der Drehgeber wird über 
einen Timer ausgelesen, wie hier in der Codesammlung schon geschildert 
wurde.

Nun möchte ich mein Programm aber so ändern, dass sich der 
Erhöhungsschritt in Abhängigkeit der Drehgeschwindigkeit ändert.
Bsp.: langsames Drehen ermöglicht Feineinstellung im 1'er-Schritttakt; 
je schneller man nun am Drehimpulsgeber dreht, desto größer sind die 
Schritte. Also, langsam drehen = feineinstellung, schnell drehen = 
Grobeinstellung.

Bis jetzt feht mir zur Umsetzung aber die Idee, wie man an so eine Sache 
heran geht. Hat evtl. jemand eine Idee oder Vorschlag bzw. hat sowas 
schon einmal programmiert?

Autor: sechsdurchdrei (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Bsp.: langsames Drehen ermöglicht Feineinstellung im 1'er-Schritttakt;
>je schneller man nun am Drehimpulsgeber dreht, desto größer sind die
>Schritte. Also, langsam drehen = feineinstellung, schnell drehen =
>Grobeinstellung.

Du müsstest mit einem zweiten Zähler prüfen, wie viele Impulse inerhalb 
einer gewissen Zeitspanne reingekommen sind und daraus ableiten, ob 
schnell oder langsam gedreht wurde.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Thomas (Gast)

>Nun möchte ich mein Programm aber so ändern, dass sich der
>Erhöhungsschritt in Abhängigkeit der Drehgeschwindigkeit ändert.

Das ist aber nicht das Gleiche wie dein Betreff !

>Bsp.: langsames Drehen ermöglicht Feineinstellung im 1'er-Schritttakt;
>je schneller man nun am Drehimpulsgeber dreht, desto größer sind die
>Schritte. Also, langsam drehen = feineinstellung, schnell drehen =
>Grobeinstellung.

Sowas wird auch in Mausbeschleunigern benutzt.

>Bis jetzt feht mir zur Umsetzung aber die Idee, wie man an so eine Sache
>heran geht. Hat evtl. jemand eine Idee oder Vorschlag

Du musst messen/speichern, wann die letzte Änderung des Drehgebers 
stattgefunden hat. Das ist einfach, das machst du direkt nach der 
Auswertung im Timerinterrupt. Wenn dieser Wert mehrfach eine bestimmte 
Schwelle unterschreitet (schnell drehen) wird dein Positionszähler dann 
ebem um beispielsweise 5 und nicht nur 1 erhöht.

MFG
Falk

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du mißt die Zeit zwischen zwei Flanken Deines Drehgebers.

Ist die Zeit < 0,5s addierst/subtrahierst Du 10,
ist die Zeit >= 0,5s addierst/subtrahierst Du 1.

Die Zeitwerte sind hier frei gewählt, solltest Du dann ausprobieren.

Viel Spaß und Erfolg

Autor: JojoS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann man den Drehgeber auch drücken? Ich habe das für einen Timer so 
gelöst das gedrückt halten + drehen die Minuten einstellt, einfaches 
drehen die Sekunden.

Autor: sechshochdrei (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>kann man den Drehgeber auch drücken? Ich habe das für einen Timer so
>gelöst das gedrückt halten + drehen die Minuten einstellt, einfaches
>drehen die Sekunden.

Pass aber auf, dass du dir dabei nicht die Finger brichst! Die 
Verrenkungen will ich gar nicht sehen.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ sechshochdrei (Gast)

>Pass aber auf, dass du dir dabei nicht die Finger brichst! Die
>Verrenkungen will ich gar nicht sehen.

Statt Drücken + Drehen kann man auch Umschalten.

Kurz Drücken schaltet zwischen verschiedenen 
Geschwindigkeiten/Parametern um. Gedreht wird dann ohne drücken.

MfG
Falk

Autor: sechshochdrei (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Falk:

>Statt Drücken + Drehen kann man auch Umschalten.

Ja, hast schon Recht. Der Beitragschreiber wollte aber so einen 
"Mausbeschleuniger" haben (welcher meiner Meinung nach unter Win2k 
irgendwie umgänglicher ist als bei WinXP)

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Drehgeber hat auch eine Tastfunktion, die jedoch schon für etwas 
Anderes reserviert ist. Aber sonnst keine schlechte Idee.
Die Frage ist aber, wie misst man am Besten die Zeit zwischen 2 Flanken 
des Drehgebers? Ich möchte dazu keinen weiteren Timer ver(sch)wenden.
@Falk Brunner: Ich glaube auch schon zu wissen, wie ich deinen Vorschlag 
unsetzen könnte. Muss ich heut Nachmittag mal ausprobieren, ob das so 
funktioniert, wie ich es mir denke.

Ich programmiere das Ganze übrigens in C.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Ganze soll einfach zum Voreinstellen einer bestimmten Zeit sein, die 
über 3 7 Seg. Anzeigen ausgegeben wird. Es wäre ja unsinnig, wenn man 
z.B. x-mal am Drehgeber drehen müsste, um z.B. 5 Minuten auf der Anzeige 
einstellen zu können.

Autor: JojoS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Pass aber auf, dass du dir dabei nicht die Finger brichst! Die
>Verrenkungen will ich gar nicht sehen.

das klappt sehr gut sogar, kommt sicher auch auf den Drehknopf an. Ich 
nutze das für einen Belichtungstimer und komme da mit dem einen 
Drehknopf aus:
Drücken < 0,5s : gespeicherte Zeit laden
Drücken 0,5..3s : Timer Starten oder Stoppen wenn er läuft
Drücken > 3s : eingestellte Zeit speichern

Aber da gibt es viele Möglichkeiten, sollte ja auch nur eine Anregung 
sein.

Autor: sechshochdrei (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
JojoS (Gast) schrieb:
>Drücken < 0,5s : gespeicherte Zeit laden
>Drücken 0,5..3s : Timer Starten oder Stoppen wenn er läuft
>Drücken > 3s : eingestellte Zeit speichern

und

 JojoS (Gast) schrieb:
>kann man den Drehgeber auch drücken? Ich habe das für einen Timer so
>gelöst das gedrückt halten + drehen die Minuten einstellt, einfaches
>drehen die Sekunden.

Sind aber zwei Paar Schuhe!

Autor: JojoS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es ist ein Drehgeber, es ging ja darum :

>Der Drehgeber hat auch eine Tastfunktion, die jedoch schon für etwas
>Anderes reserviert ist.

das es eben trotzdem möglich ist mehrere Tast-Funktionen zu haben und 
auch Drücken+Drehen geht. Die Funktionen werden erst ausgelöst wenn der 
Drehgebertaster losgelassen wird.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Thomas (Gast)

>Die Frage ist aber, wie misst man am Besten die Zeit zwischen 2 Flanken
>des Drehgebers? Ich möchte dazu keinen weiteren Timer ver(sch)wenden.

Hab ich doch schon geschrieben.

"Du musst messen/speichern, wann die letzte Änderung des Drehgebers
stattgefunden hat. Das ist einfach, das machst du direkt nach der
Auswertung im Timerinterrupt."

>Ich programmiere das Ganze übrigens in C.

Kein Problem.

MfG
Falk

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, schon, aber mir fehlt trotzdem noch ein gewisser Leitfaden.
Leider hab ich den Quelltext gerade nicht zur Verfügung, aber im Prinzip 
ist das mit der Tasterabfrage und der darauf zu erfolgenden Reaktion 
folgendermaßen:

_uint8 d;   //Variable zum Erhöhen/verringern des 7-Seg Zählers

void TimerISR
{
  If(TasterDrehRehts)
  {
    d++;
   ###
  }
  If(TasterDrehLinks)
  {
    d--;
   ###
  }
}

So, nun sagst du, dass an der Stelle, wo sich das ### befindet, gemessen 
und gespeichert werden soll. Aber irgendwie muss ich ja auch zählen, wie 
viel Zeit seit dem letzten Impuls vergangen ist. Und wie mach ich das, 
ohne noch einen weiteren Timer zu nutzen?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Thomas (Gast)

>So, nun sagst du, dass an der Stelle, wo sich das ### befindet, gemessen
>und gespeichert werden soll. Aber irgendwie muss ich ja auch zählen, wie
>viel Zeit seit dem letzten Impuls vergangen ist. Und wie mach ich das,
>ohne noch einen weiteren Timer zu nutzen?

Mit einer Variable? Dein Timer wird beispielsweise alle 5ms aufgerufen 
(200Hz).
uint8 d;   //Variable zum Erhöhen/verringern des 7-Seg Zählers

void TimerISR
{
  static uint8 cnt_aktion;  // Zählerstand seit letzter Links/Rechts Aktion

  if (cnt_aktion!=255) cnt_aktion++;  // Erhöhen ohne Overflow

  If(TasterDrehRehts)
  {
  if (cnt_aktion>100)
      d++;
    else
      d+=5;
   cnt_aktion=0;
  }
  If(TasterDrehLinks)
  {
  if (cnt_aktion>100)
      d--;
    else
      d-=5;
   cnt_aktion=0;
  }
}

Wenn mans noch etwas schöner/intuitiver mache will nimmt man einen 
weiteren Zähler, welcher X mal erfasst, ob die Drehabstände eine 
kritische Schwelle unterschritten haben und dieser steuert dann d++ bzw 
d+=5; So kann man beispielsweise dreimal relativ schnell in 
Einerschritten drehen und erst dan wird der Turbo eingeschaltet.
uint8 d;   //Variable zum Erhöhen/verringern des 7-Seg Zählers

void TimerISR
{
  static uint8 cnt_aktion;  // Zählerstand seit letzter Links/Rechts Aktion
  static uint8 cnt_turbo;  // Anzahl schneller Drehpulse

  if (cnt_aktion!=255) cnt_aktion++;  // Erhöhen ohne Overflow

  If(TasterDrehRehts || TasterDrehLinks) {
  if (cnt_aktion<100)
      if (cnt_turbo!=255) cnt_turbo++;
    else
      cnt_turbo=0;
    cnt_aktion=0;
  }

  If(TasterDrehRehts)
  {
  if (cnt_turbo>3)
    d+=5;          // schnell drehen
  else
    d++;          // langsam drehen
  }

  If(TasterDrehLinks)
  {
  if (cnt_turbo>3)
      d-=5;          // schnell drehen
    else
      d--;          // langsam drehen
  }
}


MFG
Falk

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uups, noch ein kleiner Fehler drin.

uint8 d;   //Variable zum Erhöhen/verringern des 7-Seg Zählers

void TimerISR
{
  static uint8 cnt_aktion;  // Zählerstand seit letzter Links/Rechts Aktion
  static uint8 cnt_turbo;   // Anzahl schneller Drehpulse

  if (cnt_aktion!=255) cnt_aktion++;    // Erhöhen ohne Overflow

  if(TasterDrehRehts || TasterDrehLinks) {
    if (cnt_aktion<100) {
      if (cnt_turbo!=255) cnt_turbo++;
    }
    else
      cnt_turbo=0;
    cnt_aktion=0;
  }

  if(TasterDrehRehts)
  {
    if (cnt_turbo>3)
      d+=5;                 // schnell drehen
    else
      d++;                  // langsam drehen
  }

  if(TasterDrehLinks)
  {
    if (cnt_turbo>3)
      d-=5;                 // schnell drehen
    else
      d--;                  // langsam drehen
  }
}


MFG
Falk

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wirklich sehr clever. Vielen Dank für die Codezeilen, die mich echt 
weiter bringen.

Grüße Thomas!

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.