diff options
Diffstat (limited to 'controller.c')
-rw-r--r-- | controller.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/controller.c b/controller.c new file mode 100644 index 0000000..29ac0ab --- /dev/null +++ b/controller.c @@ -0,0 +1,105 @@ +#include <avr/io.h> +#include <avr/interrupt.h> + +#include "controller.h" + +#include "bridge.h" + +static void adc_init(void) +{ + /* Configure the ADC */ + ADMUX = (1 << REFS1) | (1 << REFS0); + /* select channel x (0 for now) */ + ADMUX |= 0x0; + ADCSRA = (1 << ADEN) | (1 << ADIE) + | (1 << ADPS2) | (1 << ADPS1) + | (1 << ADPS0); +} + +/* Initializes TIMER1 */ +static void timer_init(void) +{ + TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); + OCR1A = 7200; + TIMSK|=(1<<OCIE1A); +} + +static volatile char controller_in_init; +static volatile char controller_active; +static volatile long controller_target_temp; +static volatile char controller_num_iterations; +static volatile uint16_t controller_measured_temp; + +void controller_init(void) +{ + controller_active = 0; + controller_in_init = 1; + + bridge_init(); + adc_init(); + timer_init(); +} + +int controller_set(long target) +{ + if (target < 50 || target > 974) + return 1; + + controller_target_temp = target; + controller_num_iterations = 1; + controller_active = 1; + return 0; +} + +long controller_get(void) +{ + return controller_measured_temp; +} + +void controller_off(void) +{ + controller_active = 0; + bridge_off(); +} + +ISR(TIMER1_COMPA_vect) +{ + /* Start adc measurement */ + ADCSRA |= (1<<ADSC); +} + +ISR(ADC_vect) +{ + if (controller_in_init) { + controller_measured_temp = ADCW; + controller_in_init = 0; + } else { + controller_measured_temp = (0.8 * controller_measured_temp) + + (0.2 * ADCW); + } + + if (! controller_active) + return; + + controller_num_iterations--; + if (controller_num_iterations) + return; + + controller_num_iterations = 60; + + if ((long)controller_measured_temp < controller_target_temp - 20) { + /* Cooling required */ + bridge_on_cool(); + return; + } + + if ((long)controller_measured_temp > controller_target_temp + 20) { + /* Heating required */ + bridge_on_heat(); + return; + } + + /* Temperature is roughly okay, turn bridge off until next + * measurement. */ + bridge_off(); +} |