Fork of lichtspiel for mbed
Dependencies: PololuLedStrip mbed
Diff: rotary.cpp
- 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); +}