Forum: Mikrocontroller und Digitale Elektronik Drehimpulsgeber drehgeschwindigkeitsabhängig auslesen


von Thomas (Gast)


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?

von sechsdurchdrei (Gast)


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.

von Falk B. (falk)


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

von Gast (Gast)


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

von JojoS (Gast)


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.

von sechshochdrei (Gast)


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.

von Falk B. (falk)


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

von sechshochdrei (Gast)


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)

von Thomas (Gast)


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.

von Thomas (Gast)


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.

von JojoS (Gast)


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.

von sechshochdrei (Gast)


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!

von JojoS (Gast)


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.

von Falk B. (falk)


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

von Thomas (Gast)


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?

von Falk B. (falk)


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).
1
uint8 d;   //Variable zum Erhöhen/verringern des 7-Seg Zählers
2
3
void TimerISR
4
{
5
  static uint8 cnt_aktion;  // Zählerstand seit letzter Links/Rechts Aktion
6
7
  if (cnt_aktion!=255) cnt_aktion++;  // Erhöhen ohne Overflow
8
9
  If(TasterDrehRehts)
10
  {
11
  if (cnt_aktion>100)
12
      d++;
13
    else
14
      d+=5;
15
   cnt_aktion=0;
16
  }
17
  If(TasterDrehLinks)
18
  {
19
  if (cnt_aktion>100)
20
      d--;
21
    else
22
      d-=5;
23
   cnt_aktion=0;
24
  }
25
}

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.
1
uint8 d;   //Variable zum Erhöhen/verringern des 7-Seg Zählers
2
3
void TimerISR
4
{
5
  static uint8 cnt_aktion;  // Zählerstand seit letzter Links/Rechts Aktion
6
  static uint8 cnt_turbo;  // Anzahl schneller Drehpulse
7
8
  if (cnt_aktion!=255) cnt_aktion++;  // Erhöhen ohne Overflow
9
10
  If(TasterDrehRehts || TasterDrehLinks) {
11
  if (cnt_aktion<100)
12
      if (cnt_turbo!=255) cnt_turbo++;
13
    else
14
      cnt_turbo=0;
15
    cnt_aktion=0;
16
  }
17
18
  If(TasterDrehRehts)
19
  {
20
  if (cnt_turbo>3)
21
    d+=5;          // schnell drehen
22
  else
23
    d++;          // langsam drehen
24
  }
25
26
  If(TasterDrehLinks)
27
  {
28
  if (cnt_turbo>3)
29
      d-=5;          // schnell drehen
30
    else
31
      d--;          // langsam drehen
32
  }
33
}


MFG
Falk

von Falk B. (falk)


Lesenswert?

Uups, noch ein kleiner Fehler drin.

1
uint8 d;   //Variable zum Erhöhen/verringern des 7-Seg Zählers
2
3
void TimerISR
4
{
5
  static uint8 cnt_aktion;  // Zählerstand seit letzter Links/Rechts Aktion
6
  static uint8 cnt_turbo;   // Anzahl schneller Drehpulse
7
8
  if (cnt_aktion!=255) cnt_aktion++;    // Erhöhen ohne Overflow
9
10
  if(TasterDrehRehts || TasterDrehLinks) {
11
    if (cnt_aktion<100) {
12
      if (cnt_turbo!=255) cnt_turbo++;
13
    }
14
    else
15
      cnt_turbo=0;
16
    cnt_aktion=0;
17
  }
18
19
  if(TasterDrehRehts)
20
  {
21
    if (cnt_turbo>3)
22
      d+=5;                 // schnell drehen
23
    else
24
      d++;                  // langsam drehen
25
  }
26
27
  if(TasterDrehLinks)
28
  {
29
    if (cnt_turbo>3)
30
      d-=5;                 // schnell drehen
31
    else
32
      d--;                  // langsam drehen
33
  }
34
}


MFG
Falk

von Thomas (Gast)


Lesenswert?

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

Grüße Thomas!

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.