1
1
/*
2
- * Driver for incremental rotary encoder w/support for pushbutton RGB LED.
2
+ * Driver for incremental rotary encoder w/built-in pushbutton and RGB LED.
3
+ *
3
4
*
4
5
* Objective:
5
6
*
46
47
* - Encoder pin 3 to Arduino pin 4 with a 10K pull-down resistor
47
48
* (pushbutton input).
48
49
* - Encoder pins 4, 2 and 1 through current limiting resistors and on to
49
- * Arduino pins 9, 10 and 11, respectively (PWM outputs for RGB LED).
50
+ * Arduino pins 9, 10 and 11, respectively (PWM outputs for RGB LED
51
+ * hooked up to PB1/OC1A, PB2/OC1B and PB3/OC2A, respectively).
50
52
*
51
53
* Diagram:
52
54
*
65
67
* | 5|----------|Vcc |
66
68
* --- -----
67
69
*
68
- * R1-R3: Current-limiting resistors, e.g. 330Ω
70
+ * R1-R3: Current-limiting resistors, e.g. 220Ω
69
71
* R4: Pull-down resistor, e.g. 10KΩ
70
72
*
73
+ *
74
+ * Mode of operation:
75
+ *
71
76
* In the Arduino, the two rotary encoder inputs and the pusbutton input
72
- * trigger interrupts whose handler merely forwards the current state of
73
- * the inputs to the main loop by using a simple ring buffer. This keeps
74
- * the ISR very short and fast. The three PWM outputs are driven using
75
- * analogWrite() from the main loop.
77
+ * trigger a pin change interrupt (PCINT2). The corresponding ISR merely
78
+ * forwards the current state of the input pins to the main loop by using
79
+ * a simple ring buffer. This keeps the ISR very short and fast, and
80
+ * ensures that we miss as few interrupts as possible.
81
+ *
82
+ * The three PWM outputs are driven using analogWrite() from the main loop.
76
83
*
77
84
* Author: Johan Herland <johan@herland.net>
78
85
* License: GNU GPL v2 or later
@@ -85,7 +92,8 @@ byte rb_read; // current read position in ringbuffer
85
92
byte rot_state = 0 ;
86
93
bool button_state = 0 ;
87
94
88
- int rot_value = 0 ;
95
+ byte rot_value = 0 ;
96
+ const byte rot_increment = 4 ;
89
97
90
98
void setup (void )
91
99
{
@@ -95,14 +103,17 @@ void setup(void)
95
103
96
104
// Set up input pins (Arduino pins 2/3/4 == PORTD pins 2/3/4).
97
105
// Set PD2-4 as inputs:
98
- DDRD &= ~( _BV (DDD2) | _BV (DDD3) | _BV (DDD4)) ;
106
+ DDRD &= ~B00011100 ;
99
107
// Enable PD2-3 internal pull-up resistors
100
- PORTD |= _BV (PORTD2) | _BV (PORTD3) ;
108
+ PORTD |= B00001100 ;
101
109
102
110
// Set up PCINT18..20 interrupt to trigger on changing pins 2/3/4.
103
111
PCICR = B00000100; // - - - - - PCIE2 PCIE1 PCIE0
104
112
PCMSK2 = B00011100; // PCINT23 .. PCINT16
105
113
114
+ // Set up pins 9/10/11 (PB1..3) as output (for PWM)
115
+ DDRB |= B00001110;
116
+
106
117
sei (); // Re-enable interrupts
107
118
108
119
Serial.println (F (" Ready" ));
@@ -111,7 +122,7 @@ void setup(void)
111
122
/*
112
123
* PCINT2 interrupt vector
113
124
*
114
- * Append the current values of the relevant input pins to the ring buffer.
125
+ * Append the current values of the relevant input port to the ring buffer.
115
126
*/
116
127
ISR (PCINT2_vect)
117
128
{
@@ -179,13 +190,20 @@ void loop(void)
179
190
Serial.println (F (" ^" ));
180
191
181
192
if (events & ROT_CW) {
182
- rot_value++ ;
193
+ rot_value += rot_increment ;
183
194
Serial.print (F (" -> " ));
184
195
Serial.println (rot_value);
185
196
}
186
197
else if (events & ROT_CCW) {
187
- rot_value-- ;
198
+ rot_value -= rot_increment ;
188
199
Serial.print (F (" <- " ));
189
200
Serial.println (rot_value);
190
201
}
202
+
203
+ // TODO: New CL resistors
204
+ // TODO: R/G/B modes
205
+ // TODO: acceleration in rotation
206
+ analogWrite ( 9 , 0xff - rot_value);
207
+ analogWrite (10 , 0xff - rot_value);
208
+ analogWrite (11 , 0xff - rot_value);
191
209
}
0 commit comments