ロータリーエンコーダー (機械接点式インクリメンタル型) の信号をデコードするクラスです。 Rotary Encoder (incremental, mechanical switch type) signal decoder class.

Files at this revision

API Documentation at this revision

Comitter:
tetsuya256
Date:
Sun Sep 07 23:31:47 2014 +0000
Commit message:
First commit.

Changed in this revision

RotaryEncoder.cpp Show annotated file Show diff for this revision Revisions of this file
RotaryEncoder.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r fcf360069f17 RotaryEncoder.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RotaryEncoder.cpp	Sun Sep 07 23:31:47 2014 +0000
@@ -0,0 +1,26 @@
+#include <RotaryEncoder.h>
+
+RotaryEncoder::RotaryEncoder(PinName A, PinName B)
+ : terminalA(A, PullUp), terminalB(B, PullUp) 
+{
+}
+
+void RotaryEncoder::attach(void (*callback)(int)) {
+    callbackFunc = callback;
+    tick.attach_us(this, &RotaryEncoder::smpling, RotaryEncoder_SamplingInterval);
+}
+
+void RotaryEncoder::detach() {
+    tick.detach();
+}
+
+void RotaryEncoder::smpling() {
+    static uint8_t val  = 0xFF;
+    uint8_t now = (terminalA.read() << 1) | (terminalB.read());
+    if (now == (val & 0x03)) return;
+    val = (val << 2) | now;
+    switch (val) {
+        case 0x4B: (*callbackFunc)(1); break; // cw  : 0b01001011 = 0x4B
+        case 0x87: (*callbackFunc)(0); break; // ccw : 0b10000111 = 0x87
+    }
+}
diff -r 000000000000 -r fcf360069f17 RotaryEncoder.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RotaryEncoder.h	Sun Sep 07 23:31:47 2014 +0000
@@ -0,0 +1,112 @@
+#ifndef RotaryEncoder_H
+#define RotaryEncoder_H
+
+#include <mbed.h>
+
+#define RotaryEncoder_SamplingInterval 2000 // Sampling interval (us)
+
+/**
+ * ロータリーエンコーダー (機械接点式インクリメンタル型) の信号をデコードするクラスです。<br />
+ * Rotary Encoder (incremental, mechanical switch type) signal decoder class.<br />
+ * Copyright(C)2014 T.Hoshino<br />
+ * <br />
+ * CAUTION: My English is very poor, it might be wrong. (I rely on Google Translate almost.)
+ * <ul>
+ *  <li>コンストラクタに指定した2つのピンは「入力・内蔵プルアップ有効」に設定されます。外部プルアップは必要ありません。<br />
+ *      Two pins that you specified in constructor parameter is set to "input, built-in pull-up enabled". There is no need for external pull-up.
+ *  </li>
+ *  <li>機械接点のチャタリングは、Ticker による2ミリ秒ごとのサンプリングで回避します。RCローパスフィルタは必要ありません。<br />
+ *      This will debounced by software signal sampling. RC lowpass filter is not required.
+ *  </li>
+ *  <li>回転検出時は #attach で指定したコールバック関数を呼び出します。<br />
+ *      Will invoke the callback function you specified in #attach method when detected rotation.
+ *  </li>
+ *  <li>回転方向はコールバック関数のパラメータで判別できます。右回りなら 1、左回りなら 0 です。<br />
+ *      Can detect rotate direction in the parameter of callback function. If clockwise, It's 1. If counterclockwise, It's 0.
+ *  </li>
+ *  <li>以下のようなデバイスでの正常動作を確認しています。<br />
+ *      It has been confirmed the correct operation of following devices.<br />
+ *      http://akizukidenshi.com/catalog/g/gP-05651/
+ * </ul>
+ * @code
+//----------------------------------------
+// Sample code for ST Nucleo F401RE
+//----------------------------------------
+#include <mbed.h>
+#include <AQM0802A.h>
+#include <RotaryEncoder.h>
+
+AQM0802A      lcd(D14, D15);  // I2C Character LCD
+RotaryEncoder rotary(D8, D9); // <-- this!
+
+// RotaryEncoder callback function
+//   cw = 1:clockwise, 0:counterclockwise
+void rotate(int cw) {
+    static int value = 0;
+    value += cw ? 1 : -1;
+    lcd.cls();
+    lcd.printf("%d", value);
+}
+
+int main() {
+    lcd.printf("Rotary\n Encoder");
+    rotary.attach(&rotate);
+    while(1) {
+        sleep(); // sleep() is optional
+    }
+}
+ * @endcode
+ * ご自由にお使いいただけますが、無保証です。使用は自己責任でどうぞ。<br />
+ * The use of this is free, but no warranty. please use at your own risk.<br />
+ */
+class RotaryEncoder {
+  public:
+
+    /**
+     * コンストラクタです。<br />
+     * Constructor.<br />
+     * ロータリーエンコーダーの信号線に接続されたピンを指定してください。<br />
+     * Specify pins connected to the signal line of rotary encoder.<br />
+     * どちらのピンも「入力、内蔵プルアップ有効」に設定されます。<br />
+     * Both pins are set to "input, built-in pull-up enabled".
+     * @param A Terminal A signal input pin.
+     * @param B Terminal B signal input pin.
+     */
+    RotaryEncoder(PinName A, PinName B);
+
+    /**
+     * ロータリーエンコーダーの回転検出時に呼び出すコールバック関数を登録します。<br />
+     * Register callback function to be called, when detect rotary encoder rotate.<br />
+     * <ul>
+     *  <li>ロータリーエンコーダーの信号サンプリングもここから開始されます。<br />
+     *      Signal sampling of rotary encoder also starts from here.
+     *  </li>
+     *  <li>回転検出時は、回転方向がt時計回りならパラメータに 1 を、反時計回りなら 0 を渡してコールバック関数を呼び出します。<br />
+     *      When detect rotation, Call the callback function with int parameter. If clockwise, parameter is 1. Otherwise(counterclockwise) 0.<br />
+     *      コールバック関数の定義方法は、クラス概要のサンプルコードを参照してください。<br />
+     *      How to define callback function, please refer to the sample code for class description.
+     *  </li>
+     * </ul>
+     * @param callback 登録するコールバック関数。 Callback function to be registered.
+     * @see #detach()
+     */
+    void attach(void (*callback)(int));
+    
+    /**
+     * #attach で登録したコールバック関数を切り離します。<br />
+     * Detach the callback function that was registered in #attach method.<br />
+     * ロータリーエンコーダーの信号サンプリングも停止します。<br />
+     * Also stop signal sampling of rotary encoder.
+     * @see #attach
+     */
+    void detach();
+
+  private:
+    DigitalIn terminalA;
+    DigitalIn terminalB;
+    Ticker    tick;
+    void smpling();
+    void (*callbackFunc)(int);
+};
+
+#endif