Copyright Brian Starkey 2012-2014
Valid HTML 4.01 Transitional

Valid CSS!
iconAVR Lightning Effectmax, min, close
Description(top)
iconVideo Playermax, min, close
There isn't a whole lot to say about this - it's basically a lightning effect I made for a halloween costume which runs on an attiny2313. If you ever want to add a lightning effect to something, feel free to use this code. I was pretty pleased with how it turned out.
The flashes are random, and occur in bursts of a random length with random timings between flashes, and the bursts themselves happen at random intervals. The LEDs go to full brightness on a 'bolt' and then fade out according to FADE_SPEED. If another 'bolt' happens before the LEDs have fully faded out, they go back to full brightness and start fading again. This gives quite a convincing effect which the video doesn't really do justice.
It uses timer 0 for the PWM of the LEDs and delays for the timing between bolts and bursts.

Listing(top)
#define F_CPU 8000000

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>

#define FADE_SPEED 3

unsigned volatile char level;

int main(void) {
	DDRB |= (1 << 2);
	PORTB |= (1 << 2);
	_delay_ms(1000);
	PORTB &= ~(1 << 2);
	OCR0A = 0;
	TCCR0A |= 0x83;
	TIMSK |= (1 << TOIE0);
	sei();
	OCR0A = 0;

	for (;;) {
		unsigned char bolt_count = rand() >> 12;
		while (bolt_count--) {
			unsigned char between_bolts = (rand() >> 8);
			between_bolts <<= 1;
			level = 255;
			OCR0A = level;
			TCCR0B |= 0x03;
			TCCR0A |= 0x83;
			_delay_ms(between_bolts);
		}
		_delay_ms(rand() << 10);
	}
}

ISR(TIMER0_OVF_vect) {
	if (level > FADE_SPEED) {
		level -= FADE_SPEED;
		OCR0A = level;
	}
	else {
		TCCR0A = 0;
		TCCR0B &= ~(0x07);
		OCR0A = 0;
		TCNT0 = 0;
	}
}