Skip to content

Instantly share code, notes, and snippets.

@dtudury
Created August 4, 2013 22:54
Show Gist options
  • Save dtudury/6152304 to your computer and use it in GitHub Desktop.
Save dtudury/6152304 to your computer and use it in GitHub Desktop.
/*
* lights2.c
*
* Created: 6/24/2013 10:06:23 PM
* Author: dtudury
*/
#ifndef F_CPU
#define F_CPU 8000000UL // or whatever may be your frequency
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//D3 GRN
//D6 BLU
//B1 RED
static uint16_t meters = 5;
static uint16_t ledsPerMeter = 32;
static uint16_t numLEDs = 5 * 32;
int *pixels;
int *channels;
int channel;
void pwmInit() {
//https://sites.google.com/site/qeewiki/books/avr-guide/pwm-on-the-atmega328
//set up red pin on timer 1, B1 (OCR1A)
TCCR1A = (1 << WGM12) | (1 << WGM10);
TCCR1A |= (1 << COM1A1) | (1 << COM1A0);
TCCR1B = (1 << CS10);
DDRB |= (1 << DDB1);
//set up green pin on timer 2, D3 (OCR2B)
TCCR2A = (1 << WGM21) | (1 << WGM20);
TCCR2A |= (1 << COM2B1) | (1 << COM2B0);
TCCR2B = (1 << CS20);
DDRD |= (1<<DDD3);
//set up blue pin on timer 0, D6 (OCR0A)
TCCR0A = (1 << WGM01) | (1 << WGM00);
TCCR0A |= (1 << COM0A1) | (1 << COM0A0);
TCCR0B = (1 << CS00);
DDRD |= (1<<DDD6);
}
void interruptInit() {
//set up A pin on D0 (PCINT16)
DDRD &= ~(1 << DDD0);
PORTD |= (1 << PORTD0);
PCMSK2 |= (1 << PCINT16);
//set up B pin on D1 (PCINT17)
DDRD &= ~(1 << DDD1);
PORTD |= (1 << PORTD1);
PCMSK2 |= (1 << PCINT17);
PCICR |= (1 << PCIE2);
//set up button (SW) on C5 (PCINT13)
DDRC &= ~(1 << DDC5);
PORTC |= (1 << PORTC5);
PCMSK1 |= (1 << PCINT13);
PCICR |= (1 << PCIE1);
sei(); // turn on interrupts
}
uint8_t map(uint8_t v) {
v++;
return rand() % (v % 128) | 0b10000000;
}
void writeBit(uint8_t on) {
if (on) PORTC |= 0b00000010;
else PORTC &= ~0b00000010;
//toggle clock
PORTC |= 0b00000001;
PORTC &= ~0b00000001;
}
void write8(uint8_t d) {
for (uint8_t i=0; i<8; i++) {
writeBit(d & _BV(7-i));
}
}
void show(uint16_t r, uint16_t g, uint16_t b) {
uint16_t i;
write8(0);
write8(0);
write8(0);
write8(0);
for (i=0; i<numLEDs; i++ ) {
write8(map(g / 4));
write8(map(r / 4));
write8(map(b / 4));
}
for (i=0; i<meters; i++ ) {
write8(0);
}
}
int main(void) {
pwmInit();
interruptInit();
DDRC |= 0b00000011;
pixels = (int *)malloc(numLEDs * 3);
channels = (int *)malloc(3);
channels[0] = 30;
channels[1] = 30;
channels[2] = 30;
channel = 0;
updatePin();
while(1) {
show(channels[0], channels[1], channels[2]);
}
}
int lastA = 0;
int lastB = 0;
int step = 0;
void inc() {
channels[channel]++;
}
void dec() {
channels[channel] += 511;
}
void updatePin() {
OCR1A = 0;
OCR2B = 0;
OCR0A = 0;
if(channel == 0) {
OCR1A = (channels[0] / 4) % 128 + 1;
} else if(channel == 1) {
OCR2B = (channels[1] / 4) % 128 + 1;
} else {
OCR0A = (channels[2] / 4) % 128 + 1; //blue pin
}
}
ISR (PCINT2_vect) {
int A = PIND & (1 << PIND0);
int B = PIND & (1 << PIND1);
if(A && B) {
if(!lastA && lastB) {
inc();
} else if(lastA && !lastB) {
dec();
}
} else if(A) {
if(lastA && lastB) {
inc();
} else if(!lastA && !lastB) {
dec();
}
} else if(B) {
if(!lastA && !lastB) {
inc();
} else if(lastA && lastB) {
dec();
}
} else {
if(lastA && !lastB) {
inc();
} else if(!lastA && lastB) {
dec();
}
}
updatePin();
lastA = A;
lastB = B;
}
ISR (PCINT1_vect) {
if(PINC & (1 << PINC5)) {
channel++;
channel %= 3;
}
updatePin();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment