-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRotaryEncoderExample.ino
More file actions
144 lines (124 loc) · 2.54 KB
/
Copy pathRotaryEncoderExample.ino
File metadata and controls
144 lines (124 loc) · 2.54 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <LiquidCrystal.h>
#define ROT_PORT PORTC
#define ROT_PIN PINC
#define ROT_A _BV(1)
#define ROT_B _BV(2)
#define ROT_BTN _BV(3)
#define ROT_DELAY 110
#define ROT_BTN_DELAY 255
#define ROT_LED_PORT PORTD
#define ROT_LED_DDR DDRD
#define ROT_LED_R _BV(7)
#define ROT_LED_G _BV(6)
#define ROT_LED_B _BV(5)
#define ROT_LED_RGB (ROT_LED_R | ROT_LED_G | ROT_LED_B)
const int rs = 2, en = 4, d4 = 8, d5 = 9, d6 = 10, d7 = 11;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
byte smiley[8] = {
B10000,
B10001,
B00000,
B00000,
B10001,
B01110,
B00000,
};
void setup() {
pinMode(3, OUTPUT);
lcd.begin(20, 4);
lcd.createChar(0, smiley);
Serial.begin(9600);
OCR2A = ROT_DELAY;
TCCR2B = 0;
TCCR2A = _BV(WGM20);
TIFR2 |= _BV(OCF2A);
TIMSK2 |= _BV(OCIE2A);
ROT_LED_DDR |= ROT_LED_RGB;
ROT_PORT |= ROT_A | ROT_B;
PCMSK1 |= ROT_A | ROT_B | ROT_BTN;
PCIFR |= _BV(PCIF1);
PCICR |= _BV(PCIE1);
}
volatile int _v = 0;
volatile int _b = 0;
volatile byte _lastRot = 0;
volatile char _sign = 0;
ISR(TIMER2_COMPA_vect) {
TCCR2B = 0;
if (_sign == 0)
_b++;
else
_v += _sign;
}
ISR(PCINT1_vect) {
byte _rot = ROT_PIN;
if ((_lastRot ^ _rot) & ROT_A && (_rot & ROT_B) == 0) {
if (_rot & ROT_A) {
TCCR2B = 0;
} else {
_sign = -1;
setDelay(ROT_DELAY);
}
}
if ((_lastRot ^ _rot) & ROT_B && (_rot & ROT_A) == 0) {
if (_rot & ROT_B) {
TCCR2B = 0;
} else {
_sign = 1;
setDelay(ROT_DELAY);
}
}
if ((_lastRot ^ _rot) & ROT_BTN) {
if (_rot & ROT_BTN) {
TCCR2B = 0;
} else {
_sign = 0;
setDelay(ROT_BTN_DELAY);
}
}
_lastRot = _rot;
}
void setDelay(byte dly) {
OCR2A = dly;
TCNT2 = 1;
TCCR2B = _BV(CS22) | _BV(CS20) | _BV(WGM22);
}
int _last = 0;
int _lastB = 0;
byte _led[4] = {
ROT_LED_R,
ROT_LED_G,
ROT_LED_B,
ROT_LED_RGB
};
void loop() {
int v = _v;
if (v != _last || _b != _lastB)
{
byte led = _led[umod(_v + _b, 4)];
// active-LOW
ROT_LED_PORT |= ROT_LED_RGB ^ led;
ROT_LED_PORT &= ~led;
byte i = umod(_last, 5 * 8);
byte j = umod(v, 5 * 8);
smiley[j / 5] ^= 1 << (4-(j % 5));
smiley[i / 5] ^= 1 << (4-(i % 5));
lcd.createChar(0, smiley);
lcd.setCursor(0, 0);
lcd.print(v);
lcd.print(" ");
lcd.setCursor(5, 0);
lcd.print(_b);
lcd.setCursor(0, 3);
lcd.write((byte)0);
_last = v;
_lastB = _b;
Serial.print(_v);
Serial.print("\t");
Serial.print(_b);
Serial.println();
}
}
byte umod(int n, byte mod) {
return ((n % mod) + mod) % mod;
}