KY-040 Kodierter Drehschalter (Rotary Encoder): Unterschied zwischen den Versionen

Aus Linkerkit.de

Wechseln zu: Navigation, Suche
(Pin-Belegung)
Zeile 59: Zeile 59:
 
</div>
 
</div>
 
</div>
 
</div>
</div>
+
 
 
</div>
 
</div>
  
 +
</div>
 
==Pin-Belegung==
 
==Pin-Belegung==
[[Datei:5_CLK_DT_SW_V_G.png|457x294px|none]]
+
[[Datei:5_CLK_DT_SW_V_G.png|none|457x294px]]
  
 
==Codebeispiel Arduino==
 
==Codebeispiel Arduino==
<pre class="brush:cpp">int redPin = 2;
+
Hier bei handelt es sich um ein Beispielprogramm, welches eine LED zum Leuchten bringt, wenn am Sensor ein Signal detektiert wurde. Als LED können z.B. auch unter anderem die Module KY-011, KY-016 oder KY-029 verwendet werden.
int yellowPin = 3;
+
 
int greenPin = 4;
+
<pre class="brush:cpp">
int aPin = 6;
+
// Initialisierung benötigter Variablen
int bPin = 7;
+
int Counter = 0;  
int buttonPin = 5;
+
boolean Richtung;
int state = 0;
+
int Pin_clk_Letzter;
int longPeriod = 5000; // Time at green or red
+
int Pin_clk_Aktuell;
int shortPeriod = 700; // Time period when changing
+
 
int targetCount = shortPeriod;
+
// Definition der Eingangs-Pins
int count = 0;
+
int pin_clk = 3;
void setup ()
+
int pin_dt = 4;  
{
+
int button_pin = 5;
  pinMode (aPin, INPUT);
+
  pinMode (bPin, INPUT);
+
  pinMode (buttonPin, INPUT);
+
void setup()  
  pinMode (redPin, OUTPUT);
+
{  
  pinMode (yellowPin, OUTPUT);
+
  // Eingangs-Pins werden initialisiert...
  pinMode (greenPin, OUTPUT);
+
  pinMode (pin_clk,INPUT);
}
+
  pinMode (pin_dt,INPUT);
void loop ()
+
  pinMode (button_pin,INPUT);
{
+
 
  count++;
+
  // ...und deren Pull-Up Widerstände aktiviert
  if (digitalRead (buttonPin))
+
  digitalWrite(pin_clk, true);
  {
+
  digitalWrite(pin_dt, true);
    setLights (HIGH, HIGH, HIGH);
+
  digitalWrite(button_pin, true);
  }
+
 
  else
+
  // Initiales Auslesen des Pin_1
  {
+
  Pin_clk_Letzter = digitalRead(pin_clk); 
    int change = getEncoderTurn ();
+
  Serial.begin (115200);
    int newPeriod = longPeriod + (change * 1000);
+
}  
    if (newPeriod  >= 1000 && newPeriod <= 10000)   {      longPeriod = newPeriod;
+
 
    }
+
// Das Programm überprüft, falls eine Änderung der Pin-Zustände sich ereignet hat, welcher der beiden
    if (count> targetCount)
+
// Pins sich zuerst geändert hatte, was auf die Drehrichtung schließen lässt.
    {
+
// Diese Information erhält man, in dem man einen der beiden Pin-Werte aus einem vorherigen
      setState ();
+
// Druchlauf mit dem Wert des aktuellen Durchlaufs vergleicht.
      count = 0;
+
 
    }
+
void loop()
  }
+
{  
  delay (1);
+
  // Auslesen des aktuellen Statuses 
}
+
  Pin_clk_Aktuell = digitalRead(pin_clk);
int getEncoderTurn ()
+
 
{
+
  // Überprüfung auf Änderung
  // Return -1, 0, or +1
+
  if (Pin_clk_Aktuell != Pin_clk_Letzter)
  static int oldA = LOW;
+
  {
  static int oldB = LOW;
+
  int result = 0;
+
if (digitalRead(pin_dt) != Pin_clk_Aktuell)  
  int newA = digitalRead (aPin);
+
{
  int newB = digitalRead (bPin);
+
// Pin_CLK hat sich zuerst verändert
  if (newA != oldA || newB != oldB)
+
Counter ++;
  {
+
Richtung = true;
    //Something has changed
+
}  
    if (oldA == LOW && newA == HIGH)
+
    {
+
else  
      result = - (oldB * 2 - 1);
+
{       // Andernfalls hat sich Pin_DT zuerst verändert
    }
+
Richtung = false;
  }
+
Counter--;
  oldA = newA;
+
}
  oldB = newB;
+
Serial.println ("Drehung erkannt: ");
  return result;
+
Serial.print ("Drehrichtung: ");
}
+
int setState ()
+
if (Richtung)
{
+
{
  if (state == 0)
+
  Serial.println ("Im Uhrzeigersinn");
  {
+
}
    setLights (HIGH, LOW, LOW);
+
else
    targetCount = longPeriod;
+
{
    state = 1;
+
  Serial.println("Gegen den Uhrzeigersinn");
  }
+
}
  else if (state == 1)
+
  {
+
Serial.print("Aktuelle Position: ");
    setLights (HIGH, HIGH, LOW);
+
Serial.println(Counter);
    targetCount = shortPeriod;
+
Serial.println("------------------------------");
    state = 2;
+
  }
+
  }
  else if (state == 2)
+
 
  {
+
  // Vorbereitung für den nächsten Druchlauf:
    setLights (LOW, LOW, HIGH);
+
  // Der Wert des aktuellen Durchlaufs ist beim nächsten Druchlauf der vorherige Wert
    targetCount = longPeriod;
+
  Pin_clk_Letzter = Pin_clk_Aktuell;
    state = 3;
+
 
  }
+
  // Reset-Funktion um aktuelle Position zu speichern
  else if (state == 3)
+
  if (!digitalRead(button_pin) && Counter!=0)
  {
+
    {
    setLights (LOW, HIGH, LOW);
+
      Counter = 0;
    targetCount = shortPeriod;
+
      Serial.println("Position resettet");
    state = 0;
+
    }
  }
+
   
}
+
}  
void setLights (int red, int yellow, int green)
+
 
{
+
 
  digitalWrite (redPin, red);
+
</pre>
  digitalWrite (yellowPin, yellow);
+
 
  digitalWrite (greenPin, green);
+
'''Anschlussbelegung Arduino:'''
}
+
 
 +
{| style="height: 58px; padding-left: 30px;" width="228"
 +
|-
 +
||CLK
 +
||=
 +
||[Pin 3]
 +
|-
 +
||DT
 +
||=
 +
||[Pin 4]
 +
|-
 +
||Button
 +
||=
 +
||[Pin 5]
 +
|-
 +
||+
 +
||=
 +
||[Pin 5V]
 +
|-
 +
||GND
 +
||=
 +
||[Pin GND]
 +
|}
 +
 
 +
'''Beispielprogramm Download'''
 +
 
 +
[[Medium:KY-040_RotaryEncoder.zip|KY-040_RotaryEncoder.zip]]
 +
 
 +
==Codebeispiel Raspberry Pi==
 +
Programmierbeispiel in der Programmiersprache Python
 +
 
 +
<pre class="brush:py"># Benoetigte Module werden importiert und eingerichtet
 +
import RPi.GPIO as GPIO
 +
import time
 +
 +
GPIO.setmode(GPIO.BCM)
 +
 +
# Hier wird der Eingangs-Pin deklariert, an dem der Sensor angeschlossen ist. Zusaetzlich wird auch der PullUP Widerstand am Eingang aktiviert
 +
GPIO_PIN = 24
 +
GPIO.setup(GPIO_PIN, GPIO.IN, pull_up_down = GPIO.PUD_UP)
 +
 +
print "Sensor-Test [druecken Sie STRG+C, um den Test zu beenden]"
 +
 +
# Diese AusgabeFunktion wird bei Signaldetektion ausgefuehrt
 +
def ausgabeFunktion(null):
 +
        print("Signal erkannt")
 +
 +
# Beim Detektieren eines Signals (fallende Signalflanke) wird die Ausgabefunktion ausgeloest
 +
GPIO.add_event_detect(GPIO_PIN, GPIO.FALLING, callback=ausgabeFunktion, bouncetime=100)  
 +
 +
# Hauptprogrammschleife
 +
try:
 +
        while True:
 +
                time.sleep(1)
 +
 +
# Aufraeumarbeiten nachdem das Programm beendet wurde
 +
except KeyboardInterrupt:
 +
        GPIO.cleanup()
 +
 
 +
</pre>
 +
'''Anschlussbelegung Raspberry Pi:'''
 +
 
 +
{| style="height: 58px; padding-left: 30px;" width="228"
 +
|-
 +
||Signal
 +
||=
 +
||GPIO24
 +
||[Pin 18]
 +
|-
 +
||+V
 +
||=
 +
||3,3V
 +
||[Pin 1]
 +
|-
 +
||GND
 +
||=
 +
||Masse
 +
||[Pin 6]
 +
|}
 +
'''Beispielprogramm Download'''
 +
 
 +
[[Medium:SensorTest_RPi.zip|SensorTest_RPi.zip]]
 +
 
 +
Zu starten mit dem Befehl:
 +
 
 +
<pre class="brush:bash">sudo python SensorTest_RPi.py
 
</pre>
 
</pre>

Version vom 8. April 2016, 14:24 Uhr

Bild

ky-040.jpg

Technische Daten / Kurzbeschreibung

Die aktuelle Position des Drehschalters wird kodiert über die Ausgänge gegeben.


Kodierung

Die Idee bei einem Drehschalter/Drehgeber ist es, dass zu jedem gedrehten "Schritt", sich der Zustand jeweils immer nur einer der beiden Ausgangs-Pins ändert. Je nachdem welhcer der beiden sich zuerst geändert hat, so kann man auf die Drehrichtung schließen, wenn man auf die folgende Kodierung achtet.

Im Uhrzeigersinn [A ändert sich zuerst] -> Pin_CLK

A B
0 0
1 0
1 1
0 1
0 0


Gegen den Uhrzeigersinn [B ändert sich zuerst] -> Pin_DT

A B
0 0
0 1
1 1
1 0
0 0

Pin-Belegung

5 CLK DT SW V G.png

Codebeispiel Arduino

Hier bei handelt es sich um ein Beispielprogramm, welches eine LED zum Leuchten bringt, wenn am Sensor ein Signal detektiert wurde. Als LED können z.B. auch unter anderem die Module KY-011, KY-016 oder KY-029 verwendet werden.

// Initialisierung benötigter Variablen
int Counter = 0; 
boolean Richtung;
int Pin_clk_Letzter;  
int Pin_clk_Aktuell;

// Definition der Eingangs-Pins
int pin_clk = 3;  
int pin_dt = 4; 
int button_pin = 5;
 
 
void setup() 
{ 
   // Eingangs-Pins werden initialisiert...
   pinMode (pin_clk,INPUT);
   pinMode (pin_dt,INPUT);
   pinMode (button_pin,INPUT);
   
   // ...und deren Pull-Up Widerstände aktiviert
   digitalWrite(pin_clk, true);
   digitalWrite(pin_dt, true);
   digitalWrite(button_pin, true);
   
   // Initiales Auslesen des Pin_1
   Pin_clk_Letzter = digitalRead(pin_clk);   
   Serial.begin (115200);
 } 

// Das Programm überprüft, falls eine Änderung der Pin-Zustände sich ereignet hat, welcher der beiden
// Pins sich zuerst geändert hatte, was auf die Drehrichtung schließen lässt.
// Diese Information erhält man, in dem man einen der beiden Pin-Werte aus einem vorherigen
// Druchlauf mit dem Wert des aktuellen Durchlaufs vergleicht.

void loop()
{ 
   // Auslesen des aktuellen Statuses  
   Pin_clk_Aktuell = digitalRead(pin_clk);
   
   // Überprüfung auf Änderung
   if (Pin_clk_Aktuell != Pin_clk_Letzter)
   { 
		 
		if (digitalRead(pin_dt) != Pin_clk_Aktuell) 
		{  
			// Pin_CLK hat sich zuerst verändert
			Counter ++;
			Richtung = true;
		} 
		 
		else 
		{       // Andernfalls hat sich Pin_DT zuerst verändert
			Richtung = false;
			Counter--;
		}
		Serial.println ("Drehung erkannt: ");
		Serial.print ("Drehrichtung: ");
		
		if (Richtung)
		{
		   Serial.println ("Im Uhrzeigersinn");
		}
		else
		{
		   Serial.println("Gegen den Uhrzeigersinn");
		}
		
		Serial.print("Aktuelle Position: ");
		Serial.println(Counter);
		Serial.println("------------------------------");
		 
   } 
   
   // Vorbereitung für den nächsten Druchlauf:
   // Der Wert des aktuellen Durchlaufs ist beim nächsten Druchlauf der vorherige Wert
   Pin_clk_Letzter = Pin_clk_Aktuell;
   
   // Reset-Funktion um aktuelle Position zu speichern
   if (!digitalRead(button_pin) && Counter!=0)
     {
       Counter = 0;
       Serial.println("Position resettet");
     }
     
 } 


Anschlussbelegung Arduino:

CLK = [Pin 3]
DT = [Pin 4]
Button = [Pin 5]
+ = [Pin 5V]
GND = [Pin GND]

Beispielprogramm Download

KY-040_RotaryEncoder.zip

Codebeispiel Raspberry Pi

Programmierbeispiel in der Programmiersprache Python

# Benoetigte Module werden importiert und eingerichtet
import RPi.GPIO as GPIO
import time
 
GPIO.setmode(GPIO.BCM)
 
# Hier wird der Eingangs-Pin deklariert, an dem der Sensor angeschlossen ist. Zusaetzlich wird auch der PullUP Widerstand am Eingang aktiviert
GPIO_PIN = 24
GPIO.setup(GPIO_PIN, GPIO.IN, pull_up_down = GPIO.PUD_UP)
 
print "Sensor-Test [druecken Sie STRG+C, um den Test zu beenden]"
 
# Diese AusgabeFunktion wird bei Signaldetektion ausgefuehrt
def ausgabeFunktion(null):
        print("Signal erkannt")
 
# Beim Detektieren eines Signals (fallende Signalflanke) wird die Ausgabefunktion ausgeloest
GPIO.add_event_detect(GPIO_PIN, GPIO.FALLING, callback=ausgabeFunktion, bouncetime=100) 
 
# Hauptprogrammschleife
try:
        while True:
                time.sleep(1)
 
# Aufraeumarbeiten nachdem das Programm beendet wurde
except KeyboardInterrupt:
        GPIO.cleanup()

Anschlussbelegung Raspberry Pi:

Signal = GPIO24 [Pin 18]
+V = 3,3V [Pin 1]
GND = Masse [Pin 6]

Beispielprogramm Download

SensorTest_RPi.zip

Zu starten mit dem Befehl:

sudo python SensorTest_RPi.py