Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Lamp Controller based on ATMega328
// 2010 Kenneth Finnegan
// kennethfinnegan.blogspot.com
//
// Control System for 4 channel lamp system
//
// Digital outputs are fed into TRIACs to control 120VAC
//
// Digital inputs come from push buttons and 120VAC light switch
// PC[0..3] - Push buttons
// PD2 - Push buttons
//
// 2010 11 15: Intial Revision
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000L
#define NUM_BUTTONS 5
volatile unsigned char newtick = 0;
volatile unsigned char lightstate = 0;
volatile unsigned char buttondebounce[NUM_BUTTONS];
int main(void) {
DDRB = 0x01; // Light output ch4
PORTB = 0x00;
DDRC = 0x00;
PORTC = 0x0F; // Pullups on buttons
DDRD = 0xE0; // Light output ch[1..3]
PORTD = 0x04; // Pullups on buttons
// Setup Timer 0
TCCR0A = 0x00;
// Use /1024 prescaler
TCCR0B = (1<<CS02) | (1<<CS00);
// Enable overflow vector, 64Hz
TIMSK0 = (1<<TOIE0);
// Enable pin change int
PCICR = (1<<PCIE1) | (1<<PCIE0);
PCMSK0 = 0x02;
PCMSK1 = 0x0F; // PC[0..3]
sei();
char i = 0;
while(1) {
if (newtick) { // 64Hz tick
newtick--;
char i;
// decrement debounce timers
for (i=0; i<NUM_BUTTONS; i++) {
if (buttondebounce[i])
buttondebounce[i]--;
}
PORTB = (0xFE & PORTB) | ((lightstate>>3) & 1);
PORTD = (0x1F & PORTD) | ((lightstate<<5));
}
}
}
// 64Hz newtick timer
SIGNAL (SIG_OVERFLOW0) {
newtick++;
}
// Light switch change
SIGNAL (SIG_PIN_CHANGE0) {
if (PINB & 0x02) { // light switch on
lightstate |= 0x05;
} else { // light switch off
lightstate = 0x00;
}
}
// Button presses
SIGNAL (SIG_PIN_CHANGE1) {
char i;
for (i=0; i<4; i++) {
if (!(PINC & (1<<i)) && !buttondebounce[i]) {
lightstate ^= (1<<i);
buttondebounce[i] = 16;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment