Drehimpulsgeber Ky-040: Unterschied zwischen den Versionen

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
 
(77 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
[[Kategorie:Arduino]]
[[Kategorie:Sensoren]]
[[Datei:KY-040-Rotary-Encoder-top.png|thumb|rigth|300px|Abb. 1:[https://funduinoshop.com/elektronische-module/keypads-und-buttons/rotary-encoder/ky-040-drehimpulsgeber-rotary-encoder Drehimpulsgeber Funduino 31.03.2025] ]]
[[Datei:KY-040-Rotary-Encoder-top.png|thumb|rigth|300px|Abb. 1:[https://funduinoshop.com/elektronische-module/keypads-und-buttons/rotary-encoder/ky-040-drehimpulsgeber-rotary-encoder Drehimpulsgeber Funduino 31.03.2025] ]]
'''Autoren:''' [[Benutzer:Marc Ebmeyer| Marc Ebmeyer]]  
'''Autoren:''' [[Benutzer:Marc Ebmeyer| Marc Ebmeyer]], [[Benutzer:Ulrich_Schneider| Prof. Dr.-Ing. Schneider]]  


== Einleitung ==
== Einleitung ==
Einstellräder sind ein wichtiges haptisches Benutzer Interface, sie ermöglichen schnelle intuitive Bedingung von Geräten.
Analoge Einstellräder sind ein wichtiges haptisches Benutzer Interface, sie ermöglichen schnelle intuitive Bedingung von Geräten. Dieses wurde früher mit Ein- und Mehrgangs-Potentiometern gelöst, welche aber einem Verschleiß unterliegen und nur eine (in Ausnahme fällen bis zu 10) Umdrehungen zulassen, zudem sind sie kostenintensiv in der Herstellung.
Dieses wurde früher mit Ein- und Mehrgangs-Potentiometern gelöst, welche aber einem Verschleiß unterliegen und nur eine (in Ausnahme fällen bis zu 10) Umdrehungen zulassen, zudem sind sie kostenintensiv in der Herstellung.
 
Um diese Probleme zu umgehen, wurden sogenannte Drehimpulsgeber (auch bekannt als Inkrementalgeber, Quadraturencoder, Drehencoder) konstruiert.
Um diese Probleme zu umgehen, wurden digitale Drehimpulsgeber entwickelt. Diese sind kostengünstig in der Fertigung und bieten unendliche Umdrehungen.
Welche Kostengünstiger in der Fertigung, unendliche Umdrehungen bieten und  mit integrierten Tastern daher kommen.
Dieses wurde erst möglich durch die Einführung kostengünstiger Mikrocontroller, welche die Aufgabe der anfallenden Software Auswertung übernehmen.
Dieses wurde erst möglich durch die Einführung kostengünstiger Mikrocontroller, welche die Aufgabe der anfallenden Software Auswertung übernehmen.
Bei der Drehimpulsmessung gibt es verschiedene verfahren, am häufigsten sind optische, magnetische und mechanische Verfahren.
Bei der Drehimpulsmessung gibt es verschiedene verfahren, am häufigsten sind optische, magnetische und mechanische Verfahren.
Zeile 16: Zeile 13:
Da man die Anzahl an Unterbrechungen messen kann und die Zeitspanne in der sie ausgeführt wurden.
Da man die Anzahl an Unterbrechungen messen kann und die Zeitspanne in der sie ausgeführt wurden.
Durch hinzufügen einer weiteren Scheibe deren Löcher leicht versetzt zu ersten Scheibe sind, lässt sich nun auch die Drehrichtung der Achse erkennen.
Durch hinzufügen einer weiteren Scheibe deren Löcher leicht versetzt zu ersten Scheibe sind, lässt sich nun auch die Drehrichtung der Achse erkennen.
Fügt man eine weitere Scheibe ein, bekommt man die Möglichkeit absolute Positionen zu bekommen. Dieses kann durch einen einzelnen Schlitz sein, der bei jeder Umdrehung die absolute Position bestätigt, oder auch mehrere mit unterschiedlichen Breiten, sodass man mehrere Referenz Positionen bekommt.
Fügt man eine weitere Scheibe ein, bekommt man die Möglichkeit absolute Positionen zu bekommen. Dieses kann durch einen einzelnen Schlitz sein, der bei jeder Umdrehung die absolute Position bestätigt, oder auch mehrere mit unterschiedlichen Breiten, sodass man mehrere Referenz Positionen bekommt.  
Der hier verwendete Drehimpulsgeber ist ein einfacher mechanischer, bei ihm finden kleine Phasen versetzte Micro Schleifkontakte ihre Anwendung, welche über eine leitfähige Lochscheibe schleifen und so zwei Phasen versetzte Signale erzeugen, als wenn man zwei Lochscheiben hätte.
Der hier verwendete Drehimpulsgeber ist ein einfacher mechanischer, bei ihm finden kleine Phasen versetzte Micro Schleifkontakte ihre Anwendung (siehe Abb.3) , welche über eine leitfähige Lochscheibe schleifen und so zwei Phasen versetzte Signale erzeugen, als wenn man zwei Lochscheiben hätte (siehe Abb.2).


= Technische Übersicht =
== Technische Übersicht ==
{| class="wikitable"
{| class="wikitable"
! style="font-weight: bold;" | Eigenschaft
! style="font-weight: bold;" | Eigenschaft
! style="font-weight: bold;" | Daten
! style="font-weight: bold;" | Daten
|-
|-
| Spannungsversorgung<br/> || VCC 3-5&thinsp;V  
| Spannungsversorgung<br/> || 3thinsp;V -5&thinsp;V DC
|-
|-
| Rastungen<br/> || 20&thinsp;<br/>
| Rastungen<br/> || 20&thinsp;<br/>
Zeile 32: Zeile 29:
| Gewicht<br/> || 8&thinsp;g<br/>
| Gewicht<br/> || 8&thinsp;g<br/>
|}
|}
*Was ist ein Impunlskreis?


== Pinbelegung ==
== Pinbelegung ==
 
Dies ist die Pinbelegung zum in Abb. 1 dargestellten Sensor.
{| class="wikitable"
{| class="wikitable"
! style="font-weight: bold;" | Pin
! style="font-weight: bold;" | Pin
! style="font-weight: bold;" | Belegung
! style="font-weight: bold;" | Belegung
! style="font-weight: bold;" | Benennung
! style="font-weight: bold;" | Signal
! style="font-weight: bold;" | Signal
! style="font-weight: bold;" |Anschluss am Arduino
|-
|-
| 1 ||Masse GND  ||  0&thinsp;V
| 1 ||Masse|| GND  ||  0&thinsp;V ||
|-
|-
| 2 ||  Betriebsspannung Vcc || 3-5&thinsp;V
| 2 ||  Betriebsspannung ||Vcc || 3-5&thinsp;V||
|-
|-
| 3 || Taster Ausgang SW || Wird intern auf Masse gezogen beim betätigen des Tasters.
| 3 || Taster Ausgang ||SW || 0 oder VCC &thinsp;V||Wird intern auf Masse gezogen beim betätigen des Tasters siehe Abb.4. Anschluss an z.B. D4
|-
|-
| 4 || Signalausgang_B DT || An einem Interrupt fähigem Pin des Arduino Uno anschließen z.B. D2
| 4 || Signalausgang_B ||DT || 0 oder VCC &thinsp;V||An einem Interrupt fähigem Pin des Arduino Uno anschließen z.B. D2
|-
|-
| 5 || Signalausgang_A CLK || An einem Interrupt fähigem Pin des Arduino Uno anschließen z.B. D3
| 5 || Signalausgang_A ||CLK || 0 oder VCC &thinsp;V ||An einem Interrupt fähigem Pin des Arduino Uno anschließen z.B. D3
|}
|}


= Prinziperklärung =
== Prinziperklärung ==
Die unter der Platine befindlichen drei Widerstände sind Pullup Widerstände für die zwei Encoder und den Taster.
Die unter der Platine befindlichen drei Widerstände (siehe Abb.6) sind Pullup Widerstände für die zwei Encoder und den Taster.
Der KY-040 ist ein Inkrementalgeber.
Der KY-040 ist ein Inkrementalgeber.
Je nach dem ob man rechts oder links herum dreht, wird erst der Pin A oder der Pin B high, da beide versetzt auf der Drehencoderscheibe sitzen.
Je nach dem ob man rechts oder links herum dreht, wird erst der Pin A oder der Pin B high, da beide versetzt auf der Drehencoderscheibe sitzen (siehe Abb.3).
Damit bekommt man einen Gray-Code am Ausgang vom Signalausgang A und B. Gray-code ähneld dem Binär-Code nur wird bei ihm bei jedem Sprung nach oben oder unten jeweils nur ein Wert verändert.
Damit bekommt man einen Gray-Code am Ausgang vom Signalausgang A und B. Gray-code ähneld dem Binär-Code nur wird bei ihm bei jedem Sprung nach oben oder unten jeweils nur ein Wert verändert.
Damit bekommen wir die Drehrichtung, den Drehwinkel und die Drehgeschwindigkeit.
Damit bekommen wir die Drehrichtung, den Drehwinkel und die Drehgeschwindigkeit.
Zeile 64: Zeile 62:
Teilen wir die Anzahl an CLK durch die vorhandene Inkremente und durch die Zeitspanne der Messung, bekommen wir die Drehzahl.
Teilen wir die Anzahl an CLK durch die vorhandene Inkremente und durch die Zeitspanne der Messung, bekommen wir die Drehzahl.


[[Datei:Ky40 Drehimpulsgeber offen beschriftet.png |600px|Abb. 2: offener Drehencoder]]
[[Datei:Ky40 Drehimpulsgeber offen beschriftet.png |thumb|left|600px|Abb. 2: Blick in den offenen Drehencoder, hier ein Modell mit 15 Teilungen und 30 Rastungen]]


[[Datei:Ky40 Drehimpulsgeber offen beschriftet Phasenversatz.png |thumb|center||600px|Abb. 3: Blick auf die Phasenverschobenen Signalabnehmer]]
Bezug zur Prinzipskizze?
Bezug zur Prinzipskizze?


Zeile 88: Zeile 87:
*[https://www.youtube.com/watch?v=QK5zKGSheug Video Erklärung]
*[https://www.youtube.com/watch?v=QK5zKGSheug Video Erklärung]


= Messschaltung =
== Messung==
???
[[Datei:Screenshot 2025-10-24 113152.png|left|thumb|300px|Abb. 4 Messung]]
= Messung=
 
???
[[Datei:Screenshot 2025-10-31 155624.png|center|thumb|600px|Abb. 5 Messung]]
 
== Demo ==
Die beiden Demos basieren auf den oben genanten Prinzip.
Drückt man den Taster (Achsentaster), dann wird der Nullpunkt neu gesetzt, diese Änderung wird dann aber erst beim weiterdrehen angezeigt.
 
[https://svn.hshl.de/svn/Informatikpraktikum_1/trunk/Arduino/ArduinoLibOrdner/ArduinoUnoR3/examples/DemoDrehencoderKY_040/DemoDrehencoderKY_040.ino SVN ohne Interrupt]
 
[https://svn.hshl.de/svn/Informatikpraktikum_1/trunk/Arduino/ArduinoLibOrdner/ArduinoUnoR3/examples/DemoDrehencoderKY_040_interrupt/DemoDrehencoderKY_040_interrupt.ino SVN mit Interrupt]
 
 
 
 
 
 
 
 
 
Demo-Quelltext [https://svn.hshl.de/svn/Informatikpraktikum_1/trunk/Arduino/ArduinoLibOrdner/ArduinoUnoR3/examples/DemoDrehencoderKY_040_interrupt/DemoSwitchCase.ino <code>DemoDrehencoderKY_040_interrupt.ino</code>]
<syntaxhighlight lang="c" style="background-color: #EFF1C1; font-size:larger">
 
//---------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------
//Drehencoder KY040 auslesen (20 Rastungen 40 Positionen / Umdrehung)
//
//  Anschlüsse:
 
//  Drehencoder  |  Arduino
//  ----------------------------------
//      GND      |    GND
//      +      |    +5V
//      SW      |    D4
//      DT      |    D2
//      CLK      |    D3
//
// Ausgabe der Position und der Drehrichtung und Winkel
//
//
//
//
//
//
// https://wiki.hshl.de/wiki/index.php/Ky-040-Drehimpulsgeber#Pinbelegung
//
//31.10.2025 Marc Ebmeyer
//
//---------------------------------------------------------------------------------------------------------
 
//---------------------------------------------------------------------------------------------------------
const byte SW_u8 = 4; // Pin zum Messen vom Schalter 
const byte DT_u8 = 2; // Pin zum Messen Interrupt PIN
const byte CLK_u8 = 3; // Pin zum Messen des Taktes Interrupt pin
const unsigned int Pos_u16 = 40; // Anzahl an Positionen des Drehencoders
volatile int CLK_pos_alt_s16; // letzte Position von CLK
volatile int CLK_pos_neu_s16;
volatile bool drehtimUhr_bit; // dreht der Drehencoder im Uhrzeigersinn? true =ja
volatile int PosZaehler_s16 =0; // Zähler der Position
volatile float WinkelZaehler_f32 =0.0;// Winkel Zähler initialisieren Startposition= o
volatile bool drehtsich_bit =false;
//-------------------------------------------------------------------------------------------------------
 
void alarm_DT()
{
  CLK_pos_neu_s16 = digitalRead(CLK_u8); // auslesen der Position von CLK und zwischen speichern in Hilfsvariable
  if (CLK_pos_neu_s16 != CLK_pos_alt_s16)// Drehencoder dreht sich
    {       
    if (digitalRead(DT_u8) != CLK_pos_neu_s16) // Drehrichtungserkennung
      { // CLK ändert sich zuerst -
      PosZaehler_s16 ++; // hoch zählen da im Uhrzeigersinn
      drehtimUhr_bit = true; //mit dem Uhrzeigersinn
      }
    else // DT ändert sich zuerst wodurch wir uns gegen dem Uhrzeigersinn drehen
      {
      drehtimUhr_bit = false; // gegen dem Uhrzeigersinn
      PosZaehler_s16 --;  //  runterzählen
      }
 
    }
   
    drehtsich_bit =true; //AusgabeBit setzen das der Drehencoder sich dreht
}
//-------------------------------------------------------------------------------------------------------
 
void alarm_CLK()
{
  CLK_pos_neu_s16 = digitalRead(CLK_u8); // auslesen der Position von CLK und zwischen speichern in Hilfsvariable
  if (CLK_pos_neu_s16 != CLK_pos_alt_s16)// Drehencoder dreht sich
    {       
    if (digitalRead(DT_u8) != CLK_pos_neu_s16) // Drehrichtungserkennung
      { // CLK ändert sich zuerst -
      PosZaehler_s16 ++; // hoch zählen da im Uhrzeigersinn
      drehtimUhr_bit = true; //mit dem Uhrzeigersinn
      }
    else // DT ändert sich zuerst wodurch wir uns gegen dem Uhrzeigersinn drehen
      {
      drehtimUhr_bit = false; // gegen dem Uhrzeigersinn
      PosZaehler_s16 --;  //  runterzählen
      }
 
    }
   
    drehtsich_bit =true; //Ausgabe Bit setzen das der Drehencoder sich dreht
}
//-------------------------------------------------------------------------------------------------------
 
 
void setup()  //definition von Serieller Schnittstelle und der Pins als Eingang
  {
  Serial.begin(115200); //Übertragungsrate und initialisieren der seriellen Schnittstelle
  pinMode(SW_u8, INPUT);  // Definition als Eingang
  pinMode(DT_u8, INPUT_PULLUP);  // Definition als Eingang
  pinMode(CLK_u8, INPUT_PULLUP);  // Definition als Eingang
  CLK_pos_alt_s16=digitalRead(CLK_u8);  // einlesen damit Wert vorhanden
  attachInterrupt(digitalPinToInterrupt(DT_u8), alarm_DT, CHANGE);// Interrupt 0 auf Pin 2
  attachInterrupt(digitalPinToInterrupt(CLK_u8), alarm_CLK, CHANGE);// // Interrupt 1 auf Pin 3
  CLK_pos_neu_s16 = digitalRead(CLK_u8); // auslesen der Position von CLK und zwischen speichern in Hilfsvariable
  }
 
 
//-------------------------------------------------------------------------------------------------------
void loop()
  {
   
    if(digitalRead(SW_u8)==false) // Wenn taster gedrückt wird Winkel auf null gesetzt
    {
      PosZaehler_s16=0;
    }
    if (drehtsich_bit)
    {
      float WinkelZaehler_f32= ((float ) PosZaehler_s16/ Pos_u16 )* 360;// teilen der Position durch die Anzahl an Positionen am Drehencoder und Umrechnen auf 360 Grad
   
      Serial.print ("es dreht sich :-): ");//Ausgabe der Ergebnisse
 
      if (drehtimUhr_bit) //Drehrichtungsausgabe
      {
      Serial.print ("mit dem Uhrzeiger");
      }
      else
      {
        Serial.print("gegen den Uhrzeiger");
      }
      Serial.print("Position: "); // Positionsausgabe
      Serial.print(PosZaehler_s16);
      Serial.print("  Winkel: "); // Positionsausgabe
      Serial.println(WinkelZaehler_f32);
      drehtsich_bit=false;
    }
    else
    {
    //Serial.println ("es dreht sich nicht ;-(: ");//Ausgabe der Ergebnisse
    }
 
    CLK_pos_alt_s16 = CLK_pos_neu_s16;  //neuer Messwert wird u altem Messwert für den nächsten Durchlauf
  }
 
 
 
 
 
</syntaxhighlight>
|-
|}
----


= Demo =
???
==Hardwareaufbau==
==Hardwareaufbau==
*[https://funduino.de/nr-32-der-rotary-encoder-ky-040  Funduino Anleitung]
 
 
[[Datei:KY-040Aufbau der Platine .png|thumb|left||600px|Abb. 6: Ky-040 Aufbau der Platine]]
 
[[Datei:Screenshot 2025-10-27 141555.png|thumb|center||300px|Abb. 7: Verkabelung mit Arduino]]


= Datenblätter =
= Datenblätter =
*[[:Datei:SE055.pdf | Datenblatt KY-040 Reichelt 02.04.2025]]
*[[Medium:SE055.pdf|Datasheet Rotary Encode Module (SE055) (EN)]]




Zeile 105: Zeile 268:


== Weiterführende Artikel ==
== Weiterführende Artikel ==
 
* [https://funduino.de/nr-32-der-rotary-encoder-ky-040 Funduino: Rotary Encoder KY-040]





Aktuelle Version vom 12. November 2025, 16:36 Uhr

Abb. 1:Drehimpulsgeber Funduino 31.03.2025

Autoren: Marc Ebmeyer, Prof. Dr.-Ing. Schneider

Einleitung

Analoge Einstellräder sind ein wichtiges haptisches Benutzer Interface, sie ermöglichen schnelle intuitive Bedingung von Geräten. Dieses wurde früher mit Ein- und Mehrgangs-Potentiometern gelöst, welche aber einem Verschleiß unterliegen und nur eine (in Ausnahme fällen bis zu 10) Umdrehungen zulassen, zudem sind sie kostenintensiv in der Herstellung.

Um diese Probleme zu umgehen, wurden digitale Drehimpulsgeber entwickelt. Diese sind kostengünstig in der Fertigung und bieten unendliche Umdrehungen. Dieses wurde erst möglich durch die Einführung kostengünstiger Mikrocontroller, welche die Aufgabe der anfallenden Software Auswertung übernehmen. Bei der Drehimpulsmessung gibt es verschiedene verfahren, am häufigsten sind optische, magnetische und mechanische Verfahren. Das Grundprinzip sind aber immer eine oder mehre runde Lochscheiben, wobei die Löcher der einzelnen Scheiben gegeneinander versetzt angeordnet sind. Dreht sich die Scheibe so, triff das Licht (beim optischen Verfahren), welches durch die erste Scheibe abwechselnd durchgelassen und geblockt wird auf einen Sensor, der den Lichtwechsel detektiert und in ein elektrisches Signal umwandelt. Dadurch kann man bei Verwendung nur einer Scheibe, schon mal die Drehzahl und den Drehwinkel detektieren unter dem wissen der Anzahl an Schlitzen in der Lochscheibe. Da man die Anzahl an Unterbrechungen messen kann und die Zeitspanne in der sie ausgeführt wurden. Durch hinzufügen einer weiteren Scheibe deren Löcher leicht versetzt zu ersten Scheibe sind, lässt sich nun auch die Drehrichtung der Achse erkennen. Fügt man eine weitere Scheibe ein, bekommt man die Möglichkeit absolute Positionen zu bekommen. Dieses kann durch einen einzelnen Schlitz sein, der bei jeder Umdrehung die absolute Position bestätigt, oder auch mehrere mit unterschiedlichen Breiten, sodass man mehrere Referenz Positionen bekommt. Der hier verwendete Drehimpulsgeber ist ein einfacher mechanischer, bei ihm finden kleine Phasen versetzte Micro Schleifkontakte ihre Anwendung (siehe Abb.3) , welche über eine leitfähige Lochscheibe schleifen und so zwei Phasen versetzte Signale erzeugen, als wenn man zwei Lochscheiben hätte (siehe Abb.2).

Technische Übersicht

Eigenschaft Daten
Spannungsversorgung
3thinsp;V -5 V DC
Rastungen
20 
Abmessungen
32*20*30 mm
Gewicht
8 g

Pinbelegung

Dies ist die Pinbelegung zum in Abb. 1 dargestellten Sensor.

Pin Belegung Benennung Signal Anschluss am Arduino
1 Masse GND 0 V
2 Betriebsspannung Vcc 3-5 V
3 Taster Ausgang SW 0 oder VCC  V Wird intern auf Masse gezogen beim betätigen des Tasters siehe Abb.4. Anschluss an z.B. D4
4 Signalausgang_B DT 0 oder VCC  V An einem Interrupt fähigem Pin des Arduino Uno anschließen z.B. D2
5 Signalausgang_A CLK 0 oder VCC  V An einem Interrupt fähigem Pin des Arduino Uno anschließen z.B. D3

Prinziperklärung

Die unter der Platine befindlichen drei Widerstände (siehe Abb.6) sind Pullup Widerstände für die zwei Encoder und den Taster. Der KY-040 ist ein Inkrementalgeber. Je nach dem ob man rechts oder links herum dreht, wird erst der Pin A oder der Pin B high, da beide versetzt auf der Drehencoderscheibe sitzen (siehe Abb.3). Damit bekommt man einen Gray-Code am Ausgang vom Signalausgang A und B. Gray-code ähneld dem Binär-Code nur wird bei ihm bei jedem Sprung nach oben oder unten jeweils nur ein Wert verändert. Damit bekommen wir die Drehrichtung, den Drehwinkel und die Drehgeschwindigkeit.

Geht zum Beispiel erst CLK auf high und dann DT, dann drehen wir rechts rum. Geht erst der DT Pin auf high und dann der CLK Pin, dann drehen wir links rum.

Teilen wir die Anzahl an CLK durch die vorhandene Inkremente und durch die Zeitspanne der Messung, bekommen wir die Drehzahl.

Abb. 2: Blick in den offenen Drehencoder, hier ein Modell mit 15 Teilungen und 30 Rastungen
Abb. 3: Blick auf die Phasenverschobenen Signalabnehmer

Bezug zur Prinzipskizze?

Zahlenwert Binär-Code Gray-Code
0 00 00
1 01 01
2 10 11
3 11 10


Messung

Abb. 4 Messung
Abb. 5 Messung

Demo

Die beiden Demos basieren auf den oben genanten Prinzip. Drückt man den Taster (Achsentaster), dann wird der Nullpunkt neu gesetzt, diese Änderung wird dann aber erst beim weiterdrehen angezeigt.

SVN ohne Interrupt

SVN mit Interrupt





Demo-Quelltext DemoDrehencoderKY_040_interrupt.ino

//---------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------
//Drehencoder KY040 auslesen (20 Rastungen 40 Positionen / Umdrehung)
// 
//  Anschlüsse:

//  Drehencoder  |  Arduino
//  ----------------------------------
//      GND      |    GND
//       +       |    +5V
//      SW       |     D4 
//      DT       |     D2
//      CLK      |     D3
//
// Ausgabe der Position und der Drehrichtung und Winkel
//
//
// 
// 
// 
//
// https://wiki.hshl.de/wiki/index.php/Ky-040-Drehimpulsgeber#Pinbelegung
//
//31.10.2025 Marc Ebmeyer
//
//---------------------------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------------------------
const byte SW_u8 = 4; // Pin zum Messen vom Schalter  
const byte DT_u8 = 2; // Pin zum Messen Interrupt PIN
const byte CLK_u8 = 3; // Pin zum Messen des Taktes Interrupt pin
const unsigned int Pos_u16 = 40; // Anzahl an Positionen des Drehencoders 
volatile int CLK_pos_alt_s16; // letzte Position von CLK
volatile int CLK_pos_neu_s16;
volatile bool drehtimUhr_bit; // dreht der Drehencoder im Uhrzeigersinn? true =ja 
volatile int PosZaehler_s16 =0; // Zähler der Position
volatile float WinkelZaehler_f32 =0.0;// Winkel Zähler initialisieren Startposition= o
volatile bool drehtsich_bit =false;
//-------------------------------------------------------------------------------------------------------

void alarm_DT()
{
   CLK_pos_neu_s16 = digitalRead(CLK_u8); // auslesen der Position von CLK und zwischen speichern in Hilfsvariable
  if (CLK_pos_neu_s16 != CLK_pos_alt_s16)// Drehencoder dreht sich
    {        
    if (digitalRead(DT_u8) != CLK_pos_neu_s16) // Drehrichtungserkennung
      { // CLK ändert sich zuerst -
      PosZaehler_s16 ++; // hoch zählen da im Uhrzeigersinn
      drehtimUhr_bit = true; //mit dem Uhrzeigersinn
      } 
    else // DT ändert sich zuerst wodurch wir uns gegen dem Uhrzeigersinn drehen
      {
      drehtimUhr_bit = false; // gegen dem Uhrzeigersinn
      PosZaehler_s16 --;  //  runterzählen 
      }

    }
    
    drehtsich_bit =true; //AusgabeBit setzen das der Drehencoder sich dreht
}
//-------------------------------------------------------------------------------------------------------

void alarm_CLK()
{
  CLK_pos_neu_s16 = digitalRead(CLK_u8); // auslesen der Position von CLK und zwischen speichern in Hilfsvariable
  if (CLK_pos_neu_s16 != CLK_pos_alt_s16)// Drehencoder dreht sich
    {        
    if (digitalRead(DT_u8) != CLK_pos_neu_s16) // Drehrichtungserkennung
      { // CLK ändert sich zuerst -
      PosZaehler_s16 ++; // hoch zählen da im Uhrzeigersinn
      drehtimUhr_bit = true; //mit dem Uhrzeigersinn
      } 
    else // DT ändert sich zuerst wodurch wir uns gegen dem Uhrzeigersinn drehen
      {
      drehtimUhr_bit = false; // gegen dem Uhrzeigersinn
      PosZaehler_s16 --;  //  runterzählen 
      }

    }
    
    drehtsich_bit =true; //Ausgabe Bit setzen das der Drehencoder sich dreht
}
//-------------------------------------------------------------------------------------------------------


void setup()  //definition von Serieller Schnittstelle und der Pins als Eingang
  {
  Serial.begin(115200); //Übertragungsrate und initialisieren der seriellen Schnittstelle
  pinMode(SW_u8, INPUT);   // Definition als Eingang
  pinMode(DT_u8, INPUT_PULLUP);   // Definition als Eingang
  pinMode(CLK_u8, INPUT_PULLUP);   // Definition als Eingang
  CLK_pos_alt_s16=digitalRead(CLK_u8);   // einlesen damit Wert vorhanden
  attachInterrupt(digitalPinToInterrupt(DT_u8), alarm_DT, CHANGE);// Interrupt 0 auf Pin 2
  attachInterrupt(digitalPinToInterrupt(CLK_u8), alarm_CLK, CHANGE);// // Interrupt 1 auf Pin 3
  CLK_pos_neu_s16 = digitalRead(CLK_u8); // auslesen der Position von CLK und zwischen speichern in Hilfsvariable
  }


//-------------------------------------------------------------------------------------------------------
void loop() 
  {
    
    if(digitalRead(SW_u8)==false) // Wenn taster gedrückt wird Winkel auf null gesetzt
    {
      PosZaehler_s16=0;
    }
    if (drehtsich_bit)
    {
      float WinkelZaehler_f32= ((float ) PosZaehler_s16/ Pos_u16 )* 360;// teilen der Position durch die Anzahl an Positionen am Drehencoder und Umrechnen auf 360 Grad
    
      Serial.print ("es dreht sich :-): ");//Ausgabe der Ergebnisse 

      if (drehtimUhr_bit) //Drehrichtungsausgabe
      {
       Serial.print ("mit dem Uhrzeiger");
      }
      else
      {
        Serial.print("gegen den Uhrzeiger");
      }
      Serial.print("Position: "); // Positionsausgabe
      Serial.print(PosZaehler_s16);
      Serial.print("  Winkel: "); // Positionsausgabe
      Serial.println(WinkelZaehler_f32);
      drehtsich_bit=false;
    }
    else
    {
    //Serial.println ("es dreht sich nicht ;-(: ");//Ausgabe der Ergebnisse 
    }

    CLK_pos_alt_s16 = CLK_pos_neu_s16;  //neuer Messwert wird u altem Messwert für den nächsten Durchlauf
  }

|- |}


Hardwareaufbau

Abb. 6: Ky-040 Aufbau der Platine
Abb. 7: Verkabelung mit Arduino

Datenblätter


Literatur

Weiterführende Artikel



→ zurück zum Hauptartikel: HSHL-Mechatronik-Baukasten