summaryrefslogtreecommitdiff
path: root/ferment.c
blob: 1d282d2cf2f83ffa2a3f4a331c18822ff905f3b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//#define F_CPU 7372800UL
#include <stdint.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <util/delay.h>

#include "serial.h"
#include "stdio.h"
#include "pid.h"

/* port D
 *
 *  4 1- (NMOS, inverted) 
 *  5 1+ (PMOS)
 *  6 2- (NMOS, inverted)
 *  7 2+ (PMOS)
 *
 */

#define D_1_MINUS	(1 << 4)
#define D_1_PLUS	(1 << 5)
#define D_2_MINUS	(1 << 6)
#define D_2_PLUS	(1 << 7)

const int target_temp = 30;
volatile uint16_t adc_res;
volatile uint8_t adc_new;

struct PID_DATA pid_data;

/* Turns the H-bridge off, putting the output
 * into high impedance mode. */
static void bridge_off(void)
{
	PORTD |= D_1_MINUS | D_2_MINUS;
	PORTD &= ~(D_1_PLUS | D_2_PLUS);
}

/* Turns the H-bridge on, setting 1+ 2- */
static void bridge_on_heat(void)
{
	bridge_off();
	_delay_ms(100);
	PORTD |= D_1_PLUS;
	PORTD &= ~D_2_MINUS;
}

/* Turns the H-bridge on, setting 1- 2+ */
static void bridge_on_cool(void)
{
	bridge_off();
	_delay_ms(100);
	PORTD |= D_2_PLUS;
	PORTD &= ~D_1_MINUS;
}

/* Initializes the output port needed for the H-bridge */
static void bridge_init(void)
{
	bridge_off();
	DDRD |= D_1_PLUS | D_1_MINUS | D_2_PLUS | D_2_MINUS;
}

/* initializes ADC */
static void adc_init(void)
{
	adc_new = 0;
	ADMUX = (1 << REFS1) | (1 << REFS0);
	/* select channel x (0 for now) */
	ADMUX |= 0x0;
	ADCSRA = (1 << ADEN) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
}

/* reads ADC */
static void start_temp_conv(void) 
{
	ADCSRA |= (1<<ADSC);
}

/* ADC completion interrupt */
ISR(ADC_vect) 
{
	adc_res = ADCW;
	adc_new = 1;
}

/* ADC results to temperature conversion routine */
int adc_to_centigrade(uint16_t adc_val) {
	return 0;
}

/* Initializes TIMER1 */
static void timer_init(void)
{
	TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10);
	OCR1A = 7200;
	TIMSK|=(1<<OCIE1A);
}

ISR(TIMER1_COMPA_vect)
{
	serial_send("*\r\n", 3, 1);
	start_temp_conv();
}

int main(void)
{
	char params[12];

	serial_init();
	adc_init();
	timer_init();
	bridge_init();

	sei();

	bridge_on_cool();
	while (1) {
		if (adc_new) {
			sprintf(params, "%u\r\n", adc_res);
			serial_send(params, strlen(params), 1);
			adc_new = 0;
		}
		_delay_ms(100);
	}
}