Light a eCandle
Against the darkness of all dangers, fears and sadness, keep a eCandle light.
eCandle
Take a piece a paper, a resistor, a LED, the following lines of code and light a eCandle. This may be a ePrayer for the victims of the vicious terrorist attacks in Paris.
/* Constants */ const int16_t _maxDutyCycle = 256; /* Custom variables */ volatile uint8_t *_outputPort = &PORTB; uint8_t _outputPin = PINB5; int16_t _absMax = (_maxDutyCycle / 1); int16_t _absMin = (_maxDutyCycle / 4); uint16_t _interval = 2; /* Application variables */ volatile uint8_t _pwmOutputPinMask = (1 << _outputPin); uint8_t _defTCCR2B; int16_t _min = _absMin; int16_t _max = _absMax; void setup(void) { /* Initialize PWM */ InitializePWM(); /* Set default values */ } /* Fliker LED attached to the output pin */ void loop(void) { _max = random(_min, _absMax); for (int16_t i = _min; i <= _max; i++) { DutyCycle(i); delay(_interval); } _min = random(_absMin, _max); for (int16_t i = _max; i >= _min; i--) { DutyCycle(i); delay(_interval); } } /* Set up output pin and timer2, clockRate at 5 */ void InitializePWM(void) { cli(); /* Set data direction */ *(_outputPort - 1) |= _pwmOutputPinMask; /* Set timer 2, Mode 3, aka Fast PWM mode */ TCCR2A = (1 << WGM20) | (1 << WGM21); /* Set timer 2 prescaler */ TCCR2B = 0x05; /* Record default value */ _defTCCR2B = TCCR2B; /* Output Compare Match A Interrupt Enable and Overflow Interrupt Enable */ TIMSK2 = (1 << OCIE2A) | (1 << TOIE2); sei(); } void DutyCycle(int16_t dutyCycle) { if (dutyCycle <= 0) { dutyCycle = 0; /* Stop clock */ TCCR2B = 0x00; /* Set output pin to low state */ *(_outputPort) &= ~_pwmOutputPinMask; } else if (dutyCycle >= _maxDutyCycle) { dutyCycle = _maxDutyCycle; /* Stop clock */ TCCR2B = 0x00; /* Set output pin to high state */ *(_outputPort) |= _pwmOutputPinMask; } else { /* Set trigger level for next compare cycle */ OCR2A = dutyCycle; /* resume clock */ TCCR2B = _defTCCR2B; } } /* Invoked after TCNT2 overflows */ ISR(TIMER2_OVF_vect) { /* Set output pin to high state */ *(_outputPort) |= _pwmOutputPinMask; } /* Invoked after TCNT2 equals COMPA */ ISR(TIMER2_COMPA_vect) { /* Set output pin to low state */ *(_outputPort) &= ~_pwmOutputPinMask; }
You may customize your own candle using the custom variables: _outputPort for any port,
_outputPin for any pin from this port, _absMax absolute max intensity, _absMin absolute min intensity and flickering intervals in milliseconds.