Skip to content

Instantly share code, notes, and snippets.

@xZise
Last active November 30, 2016 21:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xZise/18fcc1981490627a4c011d83f244fa0e to your computer and use it in GitHub Desktop.
Save xZise/18fcc1981490627a4c011d83f244fa0e to your computer and use it in GitHub Desktop.
christmas light
#include <stdint.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include "light_ws2812.h"
#define FPS (33)
#define NUM_OF_LEDS (10)
// Soft limit, if more than this number of LEDs are on it won't reduce wait of
// others. But it might be that more LEDs are on if they are enabled in the same
// frame.
#define MAXIMUM_LEDS (NUM_OF_LEDS >> 1)
#define COUNTER (F_CPU / 1000 / 1024 * (1000 / FPS))
#define MAX_BRIGHTNESS (128) // unused
struct cRGB vals[NUM_OF_LEDS];
uint8_t max[NUM_OF_LEDS];
int8_t delta[NUM_OF_LEDS];
uint8_t wait[NUM_OF_LEDS];
uint8_t active_leds = 0;
volatile uint8_t frame = 0;
int main(void)
{
DDRB |= (1 << PB2);
DDRD |= (1 << PD7) | (1 << PD6);
set_sleep_mode(SLEEP_MODE_IDLE);
uint8_t i;
for (i = 0; i < NUM_OF_LEDS; i++)
{
vals[i].r = 0;
vals[i].g = 0;
vals[i].b = 0;
max[i] = 0;
delta[i] = 0;
wait[i] = (uint8_t) rand();
}
OCR1A = COUNTER;
TIMSK1 = (1 << OCIE1A); // Interrupt on OCR1A overflow
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); // CTC mode and 1024 prescaler
while (1)
{
PORTD &= ~(1 << PD6);
for (i = 0; i < NUM_OF_LEDS; ++i)
{
if (wait[i] > 0)
{
if (active_leds <= MAXIMUM_LEDS)
{
PORTD |= (1 << PD6);
wait[i]--;
}
}
else
{
if (vals[i].r == 0)
{
active_leds++;
max[i] = ((uint8_t) rand() & 0x3F) + 64;
delta[i] = (int8_t) ((rand() & 0x02) + 1);
}
if (delta[i] < 0 && vals[i].r <= delta[i])
{
active_leds--;
vals[i].r = 0;
wait[i] = (uint8_t) rand();
}
else if (vals[i].r + delta[i] < max[i])
{
vals[i].r += delta[i];
}
else
{
vals[i].r = max[i];
wait[i] = (uint8_t) rand() & 0x0F;
delta[i] = -delta[i];
}
}
}
ws2812_setleds(vals, NUM_OF_LEDS);
if (frame == 0)
{
PORTD &= ~(1 << PD7);
sleep_mode();
}
else
{
PORTD |= 1 << PD7;
}
frame = 0;
}
return 0;
}
ISR(TIMER1_COMPA_vect)
{
frame = 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment