INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 1 Bewertungen - 5 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Pins am Drehregler (Rotary Encoder)
06.03.2015, 19:46
Beitrag #33
RE: Pins am Drehregler (Rotary Encoder)
Wo war die Lösung von HaWe, wo die Drehgeschwindigkeit drin ist, in HaWe's Link war das doch nicht, bin ein bisschen verwirrt... Habe ich was übersehen?

Danke schön

Gruß Alex
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
06.03.2015, 20:39 (Dieser Beitrag wurde zuletzt bearbeitet: 06.03.2015 20:40 von HaWe.)
Beitrag #34
RE: Pins am Drehregler (Rotary Encoder)
hi, ich glaube, das war nicht in diesem Thread sondern in einem anderen wo ich das geschrieben habe.
Aber das Prinzip war schon richtig von tito wiedergegeben:
du misst im festen Zeitabstand in loops per delay und stoppst die exakte Zeit zwischen den loops.
DrehGeschwindigkeit = deltaWinkel/dt, das ist die Drehgeschwindigkeit.
Mach das mal und lass dir einfach die DrehGeschwindigkeit ausgeben, damit man weiß, in welchen Bereichen sich das bei dir bewegt.

Wenn du es ganz super machen willst, schreib die Werte und auch das max der Absolutwerte dahinter, ist aber sicher nicht unbedingt nötig.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
06.03.2015, 22:22
Beitrag #35
RE: Pins am Drehregler (Rotary Encoder)
Ich hab' ja auch so meine Probleme mit der geschwindigkeitsabhängigen Vergrösserung der Werte. Mein Verdacht ist zwischenzeitlich auch, dass die Drehencoder nicht High-End-Qualität haben ;-) ...
Es passiert - gefühlt - alle 5 "Rasten", dass der Encoder plötzlich ein Bitmuster liefert welches eigentlich der negativen Drehrichtung entspricht obwohl der Encoder in positiver Richtung gedreht wurde. Das erklärt auch, weshalb es dann "Geschwindigkeitssprünge" gibt.
Ich hoffe mal, ihr findet eine funktionierende Lösung. Ich hab' zwischenzeitlich schon mindestens 5 Ansätze ausprobiert aber noch nix wirklich funktionierendes hinbekommen :-( Aber irgendwie / irgendwann wird's schon noch klappen :-)

Gruss
Ralf
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
06.03.2015, 22:33 (Dieser Beitrag wurde zuletzt bearbeitet: 07.03.2015 10:01 von HaWe.)
Beitrag #36
RE: Pins am Drehregler (Rotary Encoder)
dann mach doch mal das gleiche -
Dreh-Geschwindigkeit ausrechnen und seriell ausgeben.

Dann gucken, ob linksrum drehen immer negative und rechtsrum immer positive Werte ergeben.
Das wär doch mal der erste Schritt...

anschließend könnt ihr dasselbe Grundprogramm benutzen, die inc- und dec-Werte geschwindigkeitsabhängig auszurechnen und anzuzeigen.

Und dann, als letzten, die Werte den Ziel-/Steuerwerten hinzurechnen oder subtrahieren.

Code:
encWert     encSpeed    fincrement  SteuerwertAlt  SteuerwertNeu
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
06.03.2015, 22:47
Beitrag #37
RE: Pins am Drehregler (Rotary Encoder)
Hallo an alle,

ich habe mir nicht alle bisherigen Beiträge angeschaut.Rolleyes
Es also möglich das der Link schon mal da war. Sorry, wenn dem so ist.

Hat schon jemand diesen Code probiert?

Ansonsten gibt es neben Drehencoder mit mechanischen Kontakten auch welche mit optischem Abgriff. Vermutlich sind die preislich aber außer Reichweite.

Gruß
Arne

ExclamationMit zunehmender Anzahl qualifizierter Informationen bei einer Problemstellung, erhöht sich zwangsläufig die Gefahr auf eine zielführende Antwort.Exclamation
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.03.2015, 16:33 (Dieser Beitrag wurde zuletzt bearbeitet: 07.03.2015 16:36 von facebraker.)
Beitrag #38
RE: Pins am Drehregler (Rotary Encoder)
Hallo HaWe,

das ist soweit klar, aber auf welchen Code sollen wir aufbauen?

Ich habe den hier:

Code:
#include <Arduino.h>

/* Read Quadrature Encoder
  * Connect Encoder to Pins encoder0PinA, encoder0PinB, and +5V.
  *
  * Sketch by max wolf / www.meso.net
  * v. 0.1 - very basic functions - mw 20061220
  *
  */
uint32_t elaptime, savetime;


int val;
int encoder0PinA = 3;
int encoder0PinB = 4;
float encoder0Pos = 0;
float incVal=0;
int encoder0PinALast = HIGH;
int n = HIGH;

void setup() {
   pinMode (encoder0PinA,INPUT);
   //digitalWrite(encoder0PinA, HIGH); // Pull Up Widerstand aktivieren
   pinMode (encoder0PinB,INPUT);
   //digitalWrite(encoder0PinB, HIGH); // Pull Up Widerstand aktivieren
   Serial.begin (9600);
   savetime=0;
   Serial.println("Hello World");
}

void loop() {
   n = digitalRead(encoder0PinA);
   if ((encoder0PinALast == HIGH) && (n == LOW)) {
     elaptime=millis()-savetime;

     Serial.print("letzte: ");
     Serial.print(savetime);
     Serial.print("  ");
     Serial.print("Jetzt: ");
     Serial.print(millis());
     Serial.print("  ");
     Serial.print("Elapt:");
     Serial.print(elaptime);
     Serial.print("  ");


     if (digitalRead(encoder0PinB) == HIGH) {
       if (elaptime>=1000) {incVal+=0.01;
            delay(50);
       }
       else if (elaptime <=500 && elaptime > 100) incVal+=0.1;
       else if (elaptime <=100 && elaptime > 50) incVal+=1;
       else if (elaptime <=50) incVal+=10;

       encoder0Pos+=incVal;
       //Serial.print("GUZ");
       Serial.print("  ");
       Serial.print("Inkrwert: ");
       Serial.print("  ");
       Serial.print(incVal);
       incVal=0;
       delay(10);
     } else {
       if (elaptime>=1000) {incVal-=0.01;
            delay(50);
       }

       else if (elaptime <=500 && elaptime > 100) incVal-=0.1;
       else if (elaptime <=100 && elaptime > 50) incVal-=1;
       else if (elaptime <=50 ) incVal-=10;

       encoder0Pos+=incVal;
       //Serial.print("IUZ");
       Serial.print("  ");
       Serial.print("Inkrwert: ");
       Serial.print("  ");
       Serial.print(incVal);
       incVal=0;

       delay(10);
     }
     Serial.print("  ");
     Serial.print("Anzwert:");
     Serial.println (encoder0Pos);
     //Serial.print ("/");
     savetime=millis();
   }
   encoder0PinALast = n;

}
[
Das geschwindigabhängige hochzählen funktioniert, ich habe aber immer mal negative aureisser drin wenn ich schnell drehe wie kann ich die eleminieren?


Oder meinst du wir sollen den Code mit den Timergesteuerten Interrupt nehmen?

Sorry wenn ich nerve aber der Faden ist irgendwie abhanden gekommen :-(

Sag einfach der Code oben ist Bullshit nimm den XYZ und versuche das einzubauen!

Oder nimm deinen o.g. Code, du kannst es mit ABC optimieren!

ICH WEISS NICHT ABER WIR REDEN HIER VON VERSCHIEDENEN DINGEN.
Vielleicht erläutern wir uns er einmal die Philosophie wie wir an die Sache rangehen:

Mein Encoder hat 16 Schritte, ich prüfe bei JEDEN Schritt wie lange ist es her seit der letzte Schritt war (elaptime), von daher ist meine Geschwindigkeit immer abs(22°)/elaptime.
Da habe ich mir den Schritt gespart um noch die Geschwindigkeit auszurechnen, ich kann anhand der Zeit auf die Geschwindkeit schliessen >50ms ==Sehr schnell, >50ms && <=100ms == schnell ; >100ms && <=500ms langsam; >=1000ms sehr langsam.

Darum die fehlende Geschwindigkeit, ich nehme die Zeit zwischen den erreichen der nächsten Rastung :-(

Meine Vermuting, bei schnellen drehen, habe ich kein sauberes Debouncing, und der Sensor ist schrottig, wie kann ich das abfangen? hier ein Ausdruck, den dir bei "Elapt:" eindfach Geschwindigkeit, bei "Inkrwert" gibt er den Wert aus um den er erhöht hat, zuletzt der Anzeige wert:

Zitat:letzte: 0 Jetzt: 3969 Elapt:3968 Inkrwert: 0.01 Anzwert:0.01
letzte: 4030 Jetzt: 4691 Elapt:660 Inkrwert: 0.00 Anzwert:0.01
letzte: 4703 Jetzt: 5449 Elapt:745 Inkrwert: 0.00 Anzwert:0.01
letzte: 5460 Jetzt: 5478 Elapt:12 Inkrwert: 10.00 Anzwert:10.01
letzte: 5531 Jetzt: 5554 Elapt:12 Inkrwert: 10.00 Anzwert:20.01
letzte: 5608 Jetzt: 5629 Elapt:5 Inkrwert: 10.00 Anzwert:30.01
letzte: 5683 Jetzt: 5727 Elapt:44 Inkrwert: 10.00 Anzwert:40.01
letzte: 5758 Jetzt: 6479 Elapt:721 Inkrwert: 0.00 Anzwert:40.01
letzte: 6491 Jetzt: 6513 Elapt:22 Inkrwert: -10.00 Anzwert:30.01
letzte: 6564 Jetzt: 6586 Elapt:3 Inkrwert: 10.00 Anzwert:40.01
letzte: 6639 Jetzt: 6661 Elapt:15 Inkrwert: 10.00 Anzwert:50.01
letzte: 6715 Jetzt: 7432 Elapt:717 Inkrwert: 0.00 Anzwert:50.01
letzte: 7443 Jetzt: 7461 Elapt:18 Inkrwert: 10.00 Anzwert:60.01
letzte: 7516 Jetzt: 7537 Elapt:1 Inkrwert: -10.00 Anzwert:50.01
letzte: 7591 Jetzt: 7613 Elapt:5 Inkrwert: 10.00 Anzwert:60.01
Ich drehe immer in postiver = im Uhrzeigersinn Richtung


Ich habe mir auch den Timer gesteuerten Interrupt angesehen und den Code mal geladen, ABER ICH HABE KEINEN BLAUEN DUNST WO ICH DORT DIE ZEITMESSUNG BZW. DIE GESCHWINDKEIT EINBAUEN SOLL SadSadSadSadSadSad

Sorry für den Roman, aber ich musste mal grund reinbringen!

Danke schön fürs helfen

Gruß Alex
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.03.2015, 17:12 (Dieser Beitrag wurde zuletzt bearbeitet: 07.03.2015 17:18 von HaWe.)
Beitrag #39
RE: Pins am Drehregler (Rotary Encoder)
hier gilt wie in der Medizin:

"Wer heilt, hat recht".

ich halte das mit elaptime für keine gute Idee, ich würde feste Leseintervalle verwenden und dann die echte Drehgeschwindigkeit berechnen (z.B. alle 50 oder alle 100ms).

ich halte auch deine Methode, die Encoderpins zu triggern, für keine gute Idee, ich würde Timer-IRQs nehmen (und zwar z.B. im 250µs-Intervall).

Ich halte auch deine Berechnung der Encoderwinkel für keine gute Idee, ich habe dagegen gute Erfahrung mit der Pin-Shift-Maske gemacht (in 1/4, oder 1/2 , oder 1/1 Auflösung).

ich halte es auch für keine gute idee, immer wieder neu alle möglichen Leute über alle möglichen Varianten zu fragen, denn auch hier gilt, wie in der Medizin:

"Frage 2 Ärzte - und du erhältst drei Meinungen". :-)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.03.2015, 17:54 (Dieser Beitrag wurde zuletzt bearbeitet: 07.03.2015 17:55 von facebraker.)
Beitrag #40
RE: Pins am Drehregler (Rotary Encoder)
(07.03.2015 17:12)HaWe schrieb:  ich halte es auch für keine gute idee, immer wieder neu alle möglichen Leute über alle möglichen Varianten zu fragen, denn auch hier gilt, wie in der Medizin:

"Frage 2 Ärzte - und du erhältst drei Meinungen". :-)

Sorry es tut mir leid, aber das ist die Philosophie eines Forums, dass manchmal sich noch ein Arzt ;-) mit einschaltet, und es ist ja nicht mein Anliegen meinen Kopf durchzusetzen, sondern ich habe ein Problem und brauche Hilfe und gehe davon aus jeder Arzt hat eine Heilung für mich :-D


(07.03.2015 17:12)HaWe schrieb:  ich halte das mit elaptime für keine gute Idee, ich würde feste Leseintervalle verwenden und dann die echte Drehgeschwindigkeit berechnen (z.B. alle 50 oder alle 100ms).

ich halte auch deine Methode, die Encoderpins zu triggern, für keine gute Idee, ich würde Timer-IRQs nehmen (und zwar z.B. im 250µs-Intervall).

Ich habe deinen tipp vom Anfang aufgegriffen und den Timerinterrupt noch einmal angesehen, wenn ich dich oder Tito letztens richtig verstanden habe, sollte ich ein Delay in der Loop() Funktion einbauen und dann sehen wieviele Schritte in der Zeit mit den Drehencoder gemacht wurden? Richtig?
Ich merke mir also den Wert des Encoders vom letzten mal und subtrahiere den jetztigen Wert und weiß wie viele Schritte gemacht wurden, je mehr um so schneller?

Hier mein Code:

Code:
#include <Arduino.h>

/************************************************************
*
* Demo-Programm zur Auswertung eines händisch betriebenen
* Drehencoders (Quadraturencoder) mit dem Arduino im
* Timer-Interrupt mit einer Abfragefrequenz von rd. 1kHz
*
* Copyright (C) 2014 Ralf Hübben - www.meinDUINO.de
*
* Dieses Programm ist freie Software. Sie können es unter den
* Bedingungen der GNU General Public License, wie von der
* Free Software Foundation veröffentlicht, weitergeben und/oder
* modifizieren, entweder gemäß Version 3 der Lizenz oder (nach
* Ihrer Option) jeder späteren Version.
*
* Die Veröffentlichung dieses Programms erfolgt in der Hoffnung,
* dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE
* GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE
* oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details
* finden Sie in der GNU General Public License.
*
* Sie sollten ein Exemplar der GNU General Public License
* zusammen mit diesem Programm erhalten haben. Falls nicht,
* siehe <http://www.gnu.org/licenses/>.
* Inoffizielle deutsche Übersetzung:
* http://www.gnu.de/documents/gpl.de.html
*
**************************************************************/

// An die Pins 3 und 4 ist der Encoder angeschlossen
#define encoderA 3
#define encoderB 4

// Globale Variablen zur Auswertung in der
// Interrupt-Service-Routine (ISR)
volatile int8_t altAB = 0;
volatile int encoderWert = 0;

// Die beiden Schritt-Tabellen für volle oder 1/4-Auflösung
// 1/1 Auflösung
//int8_t schrittTab[16] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};

// 1/4 Auflösung
int8_t schrittTab[16] = {0,0,0,0,0,0,0,-1,0,0,0,0,0,1,0,0};


//Variablen
int last_state =0;
int dif_state =0;


/*************************************************************
*
* Interrupt Service Routine
*
* Wird aufgerufen, wenn der entsprechende Interrupt
* ausgelöst wird
*
*************************************************************/
ISR(TIMER1_COMPA_vect) {
  altAB <<= 2;
  altAB &= B00001100;
  altAB |= (digitalRead(encoderA) << 1) | digitalRead(encoderB);
  encoderWert += schrittTab[altAB];
}


/*************************************************************
*
* void setup()
*
* Wird einmal beim Programmstart ausgeführt
*
*************************************************************/
void setup() {
  pinMode(encoderA, INPUT);
  pinMode(encoderB, INPUT);

  noInterrupts(); // Jetzt keine Interrupts
  TIMSK1 |= (1<<OCIE1A);  // Timer 1 Output Compare A Match Interrupt Enable

  TCCR1A = 0; // "Normaler" Modus

  // WGM12: CTC-Modus einschalten (Clear Timer on Compare match)
  //        Stimmen OCR1A und Timer überein, wird der Interrupt
  //        ausgelöst
  // Bit CS12 und CS10 setzen = Vorteiler: 1024
  TCCR1B = (1<<WGM12) | (1<<CS12) | (1<<CS10);

  // Frequenz = 16000000 / 1024 / 15 = rd. 1042Hz
  // Überlauf bei 14, weil die Zählung bei 0 beginnt
  OCR1A = 14;

  interrupts(); // Interrupts wieder erlauben

  Serial.begin(9600);
}


/*************************************************************
*
* void loop()
*
* Wird immer wieder durchlaufen
*
*************************************************************/
void loop() {
    dif_state=encoderWert-last_state;
    Serial.print(encoderWert);
    Serial.print("  ");
    Serial.print(dif_state);
    Serial.print("  ");
    Serial.println(last_state);
    last_state=encoderWert;
    delay(250);
}

Verändert habe ich nur das hier, ich habe eine Hemmung von 250ms und lasse mir die Differenz ausgeben:

Code:
void loop() {
    dif_state=encoderWert-last_state;
    Serial.print("Encoderwert:");
    Serial.print(encoderWert);
    Serial.print("  ");
    Serial.print("Differenz");
    Serial.print(dif_state);
    Serial.print(" Speed: ");
    speed=abs(dif_state*22);
    Serial.println(speed/250,3);
    last_state=encoderWert;
    delay(250);
}
}

Ich bekomme die Geschwindigkeit angezeigt, kann sie auch quantifizieren, aber wie kann ich die größe der Inkrements und Dekrements verändern, bzw. wo.
Wird ja alles in den Interrupts gemacht?

Danke schön!

Gruß Alex
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Uno gehen zwei digital Pins nicht edlosijagen 15 597 07.07.2016 19:22
Letzter Beitrag: Bitklopfer
  mehr PWM Pins WIMunios 8 1.122 20.03.2016 00:19
Letzter Beitrag: hotsystems
  Welche Pins für Software Serial BennIY 1 509 27.01.2016 23:02
Letzter Beitrag: hotsystems
  Mit Rotary Encoder Tastatur simulieren? noxx 9 1.488 17.11.2015 17:18
Letzter Beitrag: Binatone
  Wie viele PINs werden für LCD 2x16 benötigt? torsten_156 4 1.343 05.02.2015 09:11
Letzter Beitrag: xuino
  Belastbarkeit des +5Volt Pins Kyrill 2 1.261 16.01.2015 06:33
Letzter Beitrag: Kyrill
  I²C Pins "verlegen" Marcel5291 2 1.228 18.11.2014 15:18
Letzter Beitrag: rkuehle
  Frage zu motorshield und PINs torsten_156 9 4.923 27.10.2014 15:53
Letzter Beitrag: torsten_156
  Arduino Due: pins mit 5V ?? pins 22-24, 50-53? HaWe 1 1.896 27.10.2014 13:19
Letzter Beitrag: Bitklopfer
  LCD Shield & 4Kanal Relais Shield gleiche Pins hannes77 3 1.677 04.06.2014 00:25
Letzter Beitrag: ArduTux

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste