@@ -29,10 +29,16 @@ EncoderClass::EncoderClass(const uint8_t LeftPin, const uint8_t RightPin, //
29
29
attachInterrupt (digitalPinToInterrupt (LeftPin),RotateISR,CHANGE); // Attach static internal function //
30
30
attachInterrupt (digitalPinToInterrupt (RightPin),RotateISR,CHANGE); // Attach static internal function //
31
31
attachInterrupt (digitalPinToInterrupt (PushbuttonPin),PushButtonISR,RISING); // Attach static internal function //
32
- if (RedPin==255 &&GreenPin==255 &&BluePin==255 ) SetFade ( false ); // If no LEDs, turn off fader //
33
- else SetFade ( true ); // turn on fader and interrupt //
32
+ if (RedPin==255 &&GreenPin==255 &&BluePin==255 ) SetFadeRate ( 0 ); // If no LEDs, turn off fader //
33
+ else SetFadeRate ( 1 ); // turn on fader to max speed //
34
34
} // of class constructor // //
35
+ /* ******************************************************************************************************************
36
+ ** Define the 5 ISR (Interrupt Service Routines). These definitions are done as static functions which can be set **
37
+ ** directly as part of the Arduino IDE inside a class definition. They, in turn, redirect the interrupt to a class**
38
+ ** member function where the actual interrupt is handled **
39
+ *******************************************************************************************************************/
35
40
ISR (TIMER0_COMPA_vect) {EncoderClass::TimerISR ();} // Call the ISR every millisecond //
41
+ ISR (TIMER0_COMPB_vect) {EncoderClass::TimerISR ();} // Call the ISR every millisecond //
36
42
static void EncoderClass::PushButtonISR (){ClassPtr->PushButtonHandler ();} // Redirect to real handler function//
37
43
static void EncoderClass::RotateISR () {ClassPtr->RotateHandler ();} // Redirect to real handler function//
38
44
static void EncoderClass::TimerISR () {ClassPtr->TimerHandler ();} // Redirect to real handler function//
@@ -42,7 +48,7 @@ static void EncoderClass::TimerISR() {ClassPtr->TimerHandler();} //
42
48
** RGB LEDs of the device. It is also the only place where the actual PWM values for RGB are set. **
43
49
*******************************************************************************************************************/
44
50
void EncoderClass::TimerHandler () { // //
45
- if (_LEDChanged|| !(_RedActual==255 &&_GreenActual==255 &&_BlueActual==255 )){ // only check if we need to //
51
+ if (_LEDChanged || !(_RedActual==255 &&_GreenActual==255 &&_BlueActual==255 )){// Only check if LEDs aren't off //
46
52
_LEDChanged = false ; // Reset the value //
47
53
if (_RedActual!=_RedTarget) { // adjust accordingly //
48
54
if (_RedActual<_RedTarget) _RedActual++; else _RedActual--; // //
@@ -53,7 +59,7 @@ void EncoderClass::TimerHandler() { //
53
59
if (_BlueActual!=_BlueTarget) { // //
54
60
if (_BlueTarget<_BlueTarget) _BlueActual++; else _BlueActual--; // //
55
61
} // of if-then actual and target don't match // //
56
- if (_Fade) { // If we are fading colors, then //
62
+ if (_FadeMillis!= 0 && millis ()%_FadeMillis== 0 ) { // If we are fading colors, then //
57
63
if (_RedTarget !=255 &&_RedActual==_RedTarget) _RedTarget++; // Fade Red if max has been reached //
58
64
if (_GreenTarget!=255 &&_GreenActual==_GreenTarget) _GreenTarget++; // Fade Green " " //
59
65
if (_BlueTarget !=255 &&_BlueActual==_BlueTarget) _BlueTarget++; // Fade Blue " " //
@@ -173,22 +179,31 @@ void EncoderClass::SetEncoderValue(const int16_t NewValue = 0) { //
173
179
_EncoderValue = NewValue; // Set the new value //
174
180
} // of method SetEncoderValue() // //
175
181
/* ******************************************************************************************************************
176
- ** function SetFade() is called to turn the fade functionality on or off. The fade is done by turning on the **
177
- ** Timer0 interrupt. Timer 0 is used by the millis() function and is an 8-bit register with a clock divisor of 64 **
178
- ** which triggers it to overflow at 976.5625Hz. The millis() function uses the TIMER0_OVF_vect so we can't use **
179
- ** that, so we set the TIMER0_COMPA_vect set to 0x01 which trigger when the value is equal to 1. This gives us a **
180
- ** pretty quick trigger rate which suffices to light and fade the LED lights **
182
+ ** function SetFadeRate() is called to turn the fade functionality on or off and adjust the rate at which the fade**
183
+ ** occurs. The fade is done by accessing the Timer0 interrupt, which is used by the millis() function and is an **
184
+ ** 8-bit register with a clock divisor of 64 which triggers it to overflow at a rate of 976.5625Hz, or roughly **
185
+ ** every millisecond. We set the TIMER0_COMPA_vect to 0x01 which triggers when the value is equal to 64. This **
186
+ ** then gives us an identical trigger speed but different trigger point to the millis() function which triggers **
187
+ ** when the Timer0 overflows. The same setup is done for the TIMER0_COMPB_vect but that is set to trigger halfway **
188
+ ** along the full range of 255 at 192, thus giving an interrupt rate of 2 times per milli second. The FadeSpeed **
189
+ ** equates to how many milliseconds ther are between incremental fades, the fastest is 1 which is every 1/2 milli-**
190
+ ** second, 2 is every millisecond, etc. Each time the trigger is reached all of the LED values which are not "off"**
191
+ ** are dimmed by 1/255 of the total value. A setting of 10 would fade the LEDs from full on to OFF 1/255 of their **
192
+ ** brightness in 1.28 seconds **
181
193
*******************************************************************************************************************/
182
- void EncoderClass::SetFade (const bool FadeState ) { // //
183
- _Fade = FadeState; // Set the private variable to value//
184
- if (FadeState ) { // If turning on, set the ISR //
194
+ void EncoderClass::SetFadeRate (const uint8_t FadeSpeed ) { // //
195
+ _FadeMillis = FadeSpeed; // Set the private variable to value//
196
+ if (FadeSpeed ) { // If turning on, set the ISR //
185
197
cli (); // Disable interrupts //
186
- OCR0A = 0x01 ; // Comparison register setup to 1 //
198
+ OCR0A = 0x40 ; // Comparison register A to 64 //
199
+ OCR0B = 0xC0 ; // Comparison register B to 192 //
187
200
TIMSK0 |= _BV (OCIE0A); // TIMER0_COMPA trigger on 0x01 //
201
+ TIMSK0 |= _BV (OCIE0B); // TIMER0_COMPB trigger on 0x80 //
188
202
sei (); // Enable interrupts //
189
203
} else { // If turning off, unset the ISR //
190
204
cli (); // Disable interrupts //
191
205
TIMSK0 &= ~_BV (OCIE0A); // TIMER0_COMPA trigger off //
206
+ TIMSK0 &= ~_BV (OCIE0B); // TIMER0_COMPB trigger off //
192
207
sei (); // Enable interrupts //
193
208
} // of if-then-else we need to turn fading on or off // //
194
- } // of method SetColor // //
209
+ } // of method SetFadeRate // //
0 commit comments