David Knight / Mbed 2 deprecated lichtspiel

Dependencies:   PololuLedStrip mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rotary.cpp Source File

rotary.cpp

00001 #include "Rotary.h"
00002 
00003 #define bit_is_set(var, ofs) (((var) & (1<<(ofs))) == (1<<(ofs)))
00004 
00005 
00006 uint8_t Rotary::readEnc() {
00007   return (pinA.read() == 1 ? 0b01 : 0b00) | (pinB.read() == 1 ? 0b10 : 0b00);
00008 }
00009 
00010 Rotary::Rotary(PinName _pinA, PinName _pinB):
00011     pinA(_pinA, PullUp),
00012     pinB(_pinB, PullUp)
00013 {
00014   _prevPos = readEnc();
00015   _flags = 0;
00016 }
00017 
00018 Rotary::Action Rotary::read() {
00019   Action action = NONE;
00020   uint8_t curPos = readEnc();
00021 
00022   if (curPos != _prevPos) {
00023 
00024     if (_prevPos == 0b00) {
00025       if (curPos == 0b01 || curPos == 0b10) { // First edge
00026         _flags |= curPos;
00027       }
00028     }
00029 
00030     if (curPos == 0b11) { // “Middle” of a step
00031       _flags |= 0b10000;
00032     } else if (curPos == 0b00) { // Final edge
00033       if (_prevPos == 0b10) {
00034         _flags |= 0b00100;
00035       } else if (_prevPos == 0b01) {
00036         _flags |= 0b01000;
00037       }
00038 
00039       // check the first and last edge
00040       // or maybe one edge is missing, if missing then require the middle state
00041       // this will reject bounces and false movements
00042       if (bit_is_set(_flags, 0) && (bit_is_set(_flags, 2) || bit_is_set(_flags, 4))) {
00043         action = RIGHT;
00044       }
00045       else if (bit_is_set(_flags, 2) && (bit_is_set(_flags, 0) || bit_is_set(_flags, 4))) {
00046         action = RIGHT;
00047       }
00048       else if (bit_is_set(_flags, 1) && (bit_is_set(_flags, 3) || bit_is_set(_flags, 4))) {
00049         action = LEFT;
00050       }
00051       else if (bit_is_set(_flags, 3) && (bit_is_set(_flags, 1) || bit_is_set(_flags, 4))) {
00052         action = LEFT;
00053       }
00054 
00055       _flags = 0;
00056     }
00057   }
00058   _prevPos = curPos;
00059   return action;
00060 }
00061 
00062 Rotary::Action Rotary::waitForAction() {
00063   Action action;
00064   Timer time;
00065   time.start();
00066   while ((action = read()) == NONE && time.read_ms() < TIMEOUT_MILLIS);
00067   return (action == NONE ? TIMEOUT : action);
00068 }