Welcome to mirror list, hosted at ThFree Co, Russian Federation.

RotaryEncoder.cpp « Display « src - github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 7a220e27d894aa9ef4c1bb555b4cfdd973a933ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "RotaryEncoder.h"

#if SUPPORT_12864_LCD

#include "Pins.h"
#include "Hardware/IoPorts.h"

RotaryEncoder::RotaryEncoder(Pin p0, Pin p1, Pin pb) noexcept
	: pin0(p0), pin1(p1), pinButton(pb), ppc(1), encoderChange(0), encoderState(0), newPress(false), reverseDirection(false) {}

inline unsigned int RotaryEncoder::ReadEncoderState() const noexcept
{
	return (digitalRead(pin0) ? 1u : 0u) | (digitalRead(pin1) ? 2u : 0u);
}

void RotaryEncoder::Init(int pulsesPerClick) noexcept
{
	ppc = max<unsigned int>(abs(pulsesPerClick), 1);
	reverseDirection = (pulsesPerClick < 0);

	// Set up pins
	IoPort::SetPinMode(pin0, INPUT_PULLUP);
	IoPort::SetPinMode(pin1, INPUT_PULLUP);
	IoPort::SetPinMode(pinButton, INPUT_PULLUP);
	delay(2);                  // ensure we read the initial state correctly

	// Initialise encoder variables
	encoderChange = 0;
	encoderState = ReadEncoderState();

	// Initialise button variables
	buttonState = !digitalRead(pinButton);
	whenSame = millis();
	newPress = false;
}

void RotaryEncoder::Poll() noexcept
{
	// State transition table. Each entry has the following meaning:
	// 0 - the encoder hasn't moved
	// 1 or 2 - the encoder has moved 1 or 2 units clockwise
	// -1 or -2 = the encoder has moved 1 or 2 units anticlockwise
	static const int tbl[16] =
	{
		 0, +1, -1,  0,		// position 3 = 00 to 11, can't really do anything, so 0
		-1,  0, -2, +1,		// position 2 = 01 to 10, assume it was a bounce and should be 01 -> 00 -> 10
		+1, +2,  0, -1,		// position 1 = 10 to 01, assume it was a bounce and should be 10 -> 00 -> 01
		 0, -1, +1,  0		// position 0 = 11 to 00, can't really do anything
	};

	// Poll the encoder
	const unsigned int t = ReadEncoderState();
	const int movement = tbl[(encoderState << 2) | t];
	if (movement != 0)
	{
		encoderChange += movement;
		encoderState = t;
	}

	// Poll the button
	const uint32_t now = millis();
	const bool b = !digitalRead(pinButton);
	if (b == buttonState)
	{
		whenSame = now;
	}
	else if (now - whenSame > DebounceMillis)
	{
		buttonState = b;
		whenSame = now;
		if (buttonState)
		{
			newPress = true;
		}
	}
}

int RotaryEncoder::GetChange() noexcept
{
	int r;
	if (encoderChange >= ppc - 1)
	{
		r = (encoderChange + 1)/ppc;
	}
	else if (encoderChange <= 1 - ppc)
	{
		r = -((1 - encoderChange)/ppc);
	}
	else
	{
		r = 0;
	}
	encoderChange -= (r * ppc);
	return (reverseDirection) ? -r : r;
}

bool RotaryEncoder::GetButtonPress() noexcept
{
	const bool ret = newPress;
	newPress = false;
	return ret;
}

#endif

// End