You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MicroDexed/third-party/MD_REncoder/src/MD_REncoder.cpp

152 lines
4.2 KiB

/*
MD_REncoder - Library for Rotary Encoders
See header file for comments
This version copyright (C) 2014 Marco Colli. All rights reserved.
Original library copyright 2011 Ben Buxton. Licenced under the GNU GPL Version 3.
Contact: bb@cactii.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* \file
* \brief Implements core MD_REncoder class methods
*/
#include <MD_REncoder.h>
/*
* The below state table has, for each state (row), the new state
* to set based on the next encoder output. From left to right in,
* the table, the encoder outputs are 00, 01, 10, 11, and the value
* in that position is the new state to set.
*/
#define R_START 0x0
#if ENABLE_HALF_STEP
// Use the half-step state table (emits a code at 00 and 11)
#define R_CCW_BEGIN 0x1
#define R_CW_BEGIN 0x2
#define R_START_M 0x3
#define R_CW_BEGIN_M 0x4
#define R_CCW_BEGIN_M 0x5
const unsigned char ttable[][4] =
{
// 00 01 10 11
{R_START_M, R_CW_BEGIN, R_CCW_BEGIN, R_START}, // R_START (00)
{R_START_M | DIR_CCW, R_START, R_CCW_BEGIN, R_START}, // R_CCW_BEGIN
{R_START_M | DIR_CW, R_CW_BEGIN, R_START, R_START}, // R_CW_BEGIN
{R_START_M, R_CCW_BEGIN_M, R_CW_BEGIN_M, R_START}, // R_START_M (11)
{R_START_M, R_START_M, R_CW_BEGIN_M, R_START | DIR_CW}, // R_CW_BEGIN_M
{R_START_M, R_CCW_BEGIN_M, R_START_M, R_START | DIR_CCW} // R_CCW_BEGIN_M
};
#else
// Use the full-step state table (emits a code at 00 only)
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6
const unsigned char ttable[][4] =
{
// 00 01 10 11
{R_START, R_CW_BEGIN, R_CCW_BEGIN, R_START}, // R_START
{R_CW_NEXT, R_START, R_CW_FINAL, R_START | DIR_CW}, // R_CW_FINAL
{R_CW_NEXT, R_CW_BEGIN, R_START, R_START}, // R_CW_BEGIN
{R_CW_NEXT, R_CW_BEGIN, R_CW_FINAL, R_START}, // R_CW_NEXT
{R_CCW_NEXT, R_START, R_CCW_BEGIN, R_START}, // R_CCW_BEGIN
{R_CCW_NEXT, R_CCW_FINAL, R_START, R_START | DIR_CCW}, // R_CCW_FINAL
{R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START} // R_CCW_NEXT
};
#endif
MD_REncoder::MD_REncoder(uint8_t pinA, uint8_t pinB):
_pinA (pinA), _pinB (pinB), _state(R_START)
#if ENABLE_SPEED
, _period(DEFAULT_PERIOD), _count(0), _spd(0), _timeLast(0)
#endif
{
}
void MD_REncoder::begin(void)
{
pinMode(_pinA, (ENABLE_PULLUPS ? INPUT_PULLUP : INPUT));
pinMode(_pinB, (ENABLE_PULLUPS ? INPUT_PULLUP : INPUT));
value=0;
last_dir=DIR_NONE;
}
void MD_REncoder::update(void)
// Grab state of input pins, determine new state from the pins
// and state table, and return the emit bits (ie the generated event).
{
uint8_t pinstate = (digitalRead(_pinB) << 1) | digitalRead(_pinA);
_state = ttable[_state & 0xf][pinstate];
#if ENABLE_SPEED
// handle the encoder velocity calc
if (_state & 0x30) _count++;
if (millis() - _timeLast >= _period)
{
_spd = _count * (1000/_period);
_timeLast = millis();
_count = 0;
}
#endif
switch(_state & 0x30)
{
case DIR_CW:
value++;
last_dir=DIR_CW;
break;
case DIR_CCW:
last_dir=DIR_CCW;
value--;
break;
}
}
int32_t MD_REncoder::read_value(void)
{
return (value);
}
int8_t MD_REncoder::read(void)
{
switch(last_dir)
{
case DIR_CW:
last_dir=DIR_NONE;
return(4);
case DIR_CCW:
last_dir=DIR_NONE;
return(-4);
}
return(0);
}
void MD_REncoder::write(int32_t v)
{
value=v;
}