Drehimpuslgeber KY-040 entprellen

Hallo zusammen,

gibt es eine möglichkeit eine KY-040 Softwareseitig zu entprellen?

bei meinen ersten Versuchen zählt er Pro Klick mal 1 mal 2 oder mehr. Ich denke er prellt. Kann man das mit der Software lösen?

meine versuche sind bisher gescheiter.

void setup() {
  
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(intPinDT), Zaelen, FALLING);
}


void loop() {
 
  Serial.println (nTemp);
  delay (250);
}



void Zaelen(){

  delayMicroseconds(2500);
  if (digitalRead(intPinDT)!= digitalRead(intPinClk)){
    nTemp++;}
  else{
    nTemp--;
  }
}

aus der Referenz zu ISR habe ich

delayMicroseconds() benutzt keine Zähler und wird deshalb normal funktionieren.

aber irgendwie hat das nicht so hin.

00:07:44.792 -> 0
00:07:45.503 -> 0
00:07:46.254 -> 1
00:07:47.015 -> 1
00:07:47.776 -> 5
00:07:48.544 -> 5
00:07:49.286 -> 6
00:07:50.050 -> 6
00:07:50.796 -> 9
00:07:51.534 -> 10
00:07:52.279 -> 10
00:07:53.052 -> 13
00:07:53.801 -> 15
00:07:54.541 -> 15
00:07:55.312 -> 19
00:07:56.062 -> 21
00:07:56.835 -> 24
00:07:57.575 -> 24
00:07:58.321 -> 23
00:07:59.094 -> 26
00:07:59.833 -> 27
00:08:00.613 -> 27
00:08:01.346 -> 28
00:08:02.116 -> 30
00:08:02.869 -> 30
00:08:03.608 -> 30

das ist jeweils ein klick.

vielen dank schon mal

Hallo Chrisbie,

ich vermute mal du möchtest den Drucktaster entprellen.
Ich hab die Lib Bounce2 benutzt. Hat prima geklappt. Falls du es selber programmieren möchtest, kannst du da mal nachsehen.

Wahrscheinlich kannst du die Lib direkt über die Arduino-IDE einbinden.

Gruß,
Otmar

Es macht keinen Sinn, einen mechanischen Schalter über einen Interrupt einzulesen.
Lies den Schalter im loop ein, und sorge per millis() ( oder zur Not auch über delay() :wink: ) dafür, dass Du ihn nur etwa alle 20-30ms einliest. Damit hast Du ihn entprellt. Die minimal notwendige Zeit ist vom Prellverhalten des Tasters abhängig.

bei meinen ersten Versuchen zählt er Pro Klick mal 1 mal 2 oder mehr. Ich denke er prellt. Kann man das mit der Software lösen?

Ich habe hier Encoder liegen, die machen 4 Flankenwechsel, pro Raste.
Plus ca 20 mal prellen bei dem Vorgang.

Es macht keinen Sinn, einen mechanischen Schalter über einen Interrupt einzulesen.

Dem stimme ich halb zu.

Es ist schon schön praktisch, solche Encoder in einem Timer Interrupt auszulesen.
Ein Pin Interrupt kann dagegen sehr unangenehm werden.

gibt es eine möglichkeit eine KY-040 Softwareseitig zu entprellen?

Ja, sicherlich!
Aber nicht durch ein delayMicroseconds(2500) in einer ISR!
Das ist eine ganz ***** Idee.

Lesestoff: Das Encoder Tutorial des Peda

combie:
Es ist schon schön praktisch, solche Encoder in einem Timer Interrupt auszulesen.

Dem stimme ich ganz zu :wink: ( habe ich auch schon so gemacht ). Das Entprellen hat man da gleich mit erschlagen.

Mein Einwand bezog sich auf das vom TO verwendete Verfahren, dass der Schalter direkt einen Interrupt auslöst.

Mein Einwand bezog sich auf das vom TO verwendete Verfahren, dass der Schalter direkt einen Interrupt auslöst.

Das habe ich auch so verstanden.
(glaube ich)

Ich befürchte, dass es sich hier nicht um den Taster im Encoder dreht, sondern um den Encoder selber.
Und da sind Entprellzeiten eher kontraproduktiv, da sie bei der Bedienung im Weg stehen.
Der Mensch erwartet bei sowas intuitiv einen hohen Dynamikbereich.
Also langsame exakte Bewegungen, so wie auch recht hohe Drehgeschwindigkeiten.
Gerne auch mit "Beschleunigungsfunktion".

Wenn es irgend geht sollte man einem (größeren als 1 bis 2 ms) Zeitfenster aus dem Wege gehen.
z.B. über einen Teiler verhindern, dass ein Wert pendelt.
Eine langsamere Zählrate ist meist angenehmer, als ein hakelige Bedienung.

Hi

Wenn's ein 'normaler' Dreh-Encoder ist, kann ich die Werte doch pollen - Der liefert doch graycode, selbst wenn Da Was prellt, macht Das Nichts.
Die Übernahme des neuen Wert sollte allerdings in dem Wechsel stattfinden, Der der Ruhelage um 180° versetzt ist - sonst hüpft der Wert beim bloßen Angucken des Encoder.

MfG

Das mit dem Taster ha ich wohl fälschlich (um 2:00 Uhr morgens) ins Spiel gebracht.
Ich ging davon aus, dass man beide Pins über Interrupt einlesen müsse.
Hab aber combie's Lesestoff reingezogen und bin nun schlauer.

Ich benutze diesen Encoder über Interrups, der recht gut funktioniert:
http://www.mathertel.de/Arduino/RotaryEncoderLibrary.aspx

In der Lib wird aber der sogenannte externe Zähler erst hochgetählt wenn eine Raste (4 Flanken) erreicht sind. Wenn ich das richtig sehe halbiert sich die Auflösung.
Es wird übrigens ein Interrupt bei steigender und fallender Flanke ausgelöst. An der Auslastung habe ich aber nichts negativ bemerkt.

Auf der Seite wird auch die Möglichkeit über einen Kondensator (100nF) das Prellen zu mindern. Ist das eine Option?

Wenn man das über Timerinterrupt lösen wollte, wäre das folgende Vorgehen sinnvoll?
Messen der Flanken bei max. Drehgeschw. mit dem Oszi.
Annahme: 5 Rasten pro s -> 20 Flanken pro s -> Zeit zwischen den Flanken 50 ms
Wäre dann ein Timerinterrupt alle 25 ms sinnvoll?

Gruß,
Otmar

Wäre dann ein Timerinterrupt alle 25 ms sinnvoll?

Was "ich" für sinnvoll halte habe ich schon gesagt!

Wenn es irgend geht sollte man einem (größeren als 1 bis 2 ms) Zeitfenster aus dem Wege gehen.

Wenn man das über Timerinterrupt lösen wollte, wäre das folgende Vorgehen sinnvoll?

Timer0 wird in der Regel schon von Arduino genutzt.
Allerdings nur der Timer Overflow
Die zwei Compare Interrupts sind noch frei.

Damit bekommt man bei 16MHz AVRs ca alle 1ms einen Interrupt. Und bei 8MHz alle 2ms
Ist also perfekt geeignet.
Da kann man sich einhängen.

In der Lib wird aber der sogenannte externe Zähler erst hochgetählt wenn eine Raste (4 Flanken) erreicht sind.

Es ist richtig, zu teilen!
Denn sonst gibt es zwischen den Raststufen Werte, welche man nicht erreichen kann.
Und das kann so nicht gewollt sein.


Die noch bessere Variante kann man bauen, wenn man einen ARM verwendet.
Denn dessen Timer Hardware (leider nicht jeder Timer) kann direkt den Encoder lesen und auswerten.
Incl. entprellen und teilen.

Dann ist im User Code kein Klimmzug mehr nötig und auch keine ISR.
Außer Timer einrichten und Zählerstand abfragen muss nix gemacht werden.
Das geht dann auch für sehr schnelle Encoder, z.B. die auf einer Motorwelle

Ja das entprellen mit einem Kondensator wäre prinzipiell eine Option, allerdings gerade aktell nicht da es sich nur um eine Bastelei handelt und ich gerade auf Montage im Ausland bin.

Der Encoder ist nur ein Teil eines größeren Projektes, um sicherzugehen dass der Encoder immer gelesen wird deshalb der Interrupt.

der Typ des Encoders ist KY040. Manchmal geht ja auch eine raste. Ich brauche Später eine feine Auflösung von nur 1 pro raste.

eigentlich wollte ich nicht noch eine lib einbinden. aber werde es mal versuchen.

danke schon mal

Zur Lib gibts auch ein Beispiel mit dem Einbinden in Loop. Aber da habe ich auch Schritte verloren. Habs dann auch über Interrupt gemacht.

@combie: Danke für die ausführliche Info :smiley: