Fork of lichtspiel for mbed

Dependencies:   PololuLedStrip mbed

Revision:
0:8dc213146b30
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary.cpp	Sat May 19 14:27:12 2018 +0000
@@ -0,0 +1,68 @@
+#include "Rotary.h"
+
+#define bit_is_set(var, ofs) (((var) & (1<<(ofs))) == (1<<(ofs)))
+
+
+uint8_t Rotary::readEnc() {
+  return (pinA.read() == 1 ? 0b01 : 0b00) | (pinB.read() == 1 ? 0b10 : 0b00);
+}
+
+Rotary::Rotary(PinName _pinA, PinName _pinB):
+    pinA(_pinA, PullUp),
+    pinB(_pinB, PullUp)
+{
+  _prevPos = readEnc();
+  _flags = 0;
+}
+
+Rotary::Action Rotary::read() {
+  Action action = NONE;
+  uint8_t curPos = readEnc();
+
+  if (curPos != _prevPos) {
+
+    if (_prevPos == 0b00) {
+      if (curPos == 0b01 || curPos == 0b10) { // First edge
+        _flags |= curPos;
+      }
+    }
+
+    if (curPos == 0b11) { // “Middle” of a step
+      _flags |= 0b10000;
+    } else if (curPos == 0b00) { // Final edge
+      if (_prevPos == 0b10) {
+        _flags |= 0b00100;
+      } else if (_prevPos == 0b01) {
+        _flags |= 0b01000;
+      }
+
+      // check the first and last edge
+      // or maybe one edge is missing, if missing then require the middle state
+      // this will reject bounces and false movements
+      if (bit_is_set(_flags, 0) && (bit_is_set(_flags, 2) || bit_is_set(_flags, 4))) {
+        action = RIGHT;
+      }
+      else if (bit_is_set(_flags, 2) && (bit_is_set(_flags, 0) || bit_is_set(_flags, 4))) {
+        action = RIGHT;
+      }
+      else if (bit_is_set(_flags, 1) && (bit_is_set(_flags, 3) || bit_is_set(_flags, 4))) {
+        action = LEFT;
+      }
+      else if (bit_is_set(_flags, 3) && (bit_is_set(_flags, 1) || bit_is_set(_flags, 4))) {
+        action = LEFT;
+      }
+
+      _flags = 0;
+    }
+  }
+  _prevPos = curPos;
+  return action;
+}
+
+Rotary::Action Rotary::waitForAction() {
+  Action action;
+  Timer time;
+  time.start();
+  while ((action = read()) == NONE && time.read_ms() < TIMEOUT_MILLIS);
+  return (action == NONE ? TIMEOUT : action);
+}