Repository navigation
Expand file tree
/
Copy pathtemperature.cpp
More file actions
278 lines (254 loc) · 8.54 KB
/
Copy pathtemperature.cpp
File metadata and controls
278 lines (254 loc) · 8.54 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/**
* temperature.cpp - temperature control
*/
#include "temperature.h"
#include "config.h"
#include "fastio.h"
#include "macros.h"
#include "Arduino.h"
enum TempState {
PrepareTempLicor,
MeasureTempLicor,
PrepareTempMacerador,
MeasureTempMacerador,
PrepareTempHervido,
MeasureTempHervido,
StartupDelay // Startup, delay initial temp reading a tiny bit so the hardware
// can settle
};
Olla Temperature::Licor;
Olla Temperature::Macerador;
Olla Temperature::Hervido;
int Temperature::currentTempLicorRaw = 0,
Temperature::currentTempMaceradorRaw = 0,
Temperature::currentTempHervidoRaw = 0;
volatile bool Temperature::temp_meas_ready = false;
unsigned long Temperature::rawTempLicorValue = 0;
unsigned long Temperature::rawTempMaceradorValue = 0;
unsigned long Temperature::rawTempHervidoValue = 0;
/**
* Class and Instance Methods
*/
Temperature::Temperature() {
pinMode(QUEMADOR_LICOR_PIN, OUTPUT);
pinMode(QUEMADOR_MACERADOR_PIN, OUTPUT);
pinMode(QUEMADOR_HERVIDO_PIN, OUTPUT);
}
/**
* Actualiza valores de temperatura
*/
void Temperature::manageTemp() {
if (!temp_meas_ready)
return;
updateTemperaturesFromRawValues();
} // manage_heateu
#define PGM_RD_W(x) (short) pgm_read_word(&x)
// Derived from RepRap FiveD extruder::getTemperature()
// For bed temperature measurement.
float Temperature::analog2temp(int raw) {
float celsius = 0;
byte i;
for (i = 1; i < TEMPTABLE_LEN; i++) {
if (PGM_RD_W(TEMPTABLE[i][0]) > raw) {
celsius = PGM_RD_W(TEMPTABLE[i - 1][1]) +
(raw - PGM_RD_W(TEMPTABLE[i - 1][0])) *
(float)(PGM_RD_W(TEMPTABLE[i][1]) -
PGM_RD_W(TEMPTABLE[i - 1][1])) /
(float)(PGM_RD_W(TEMPTABLE[i][0]) -
PGM_RD_W(TEMPTABLE[i - 1][0]));
break;
}
}
// Overflow: Set to last value in the table
if (i == TEMPTABLE_LEN)
celsius = PGM_RD_W(TEMPTABLE[i - 1][1]);
return celsius;
}
/**
* Get the raw values into the actual temperatures.
* The raw values are created in interrupt context,
* and this function is called from normal context
* as it would block the stepper routine.
*/
void Temperature::updateTemperaturesFromRawValues() {
volatile float temp = 0.00;
//<OLLA LICOR>
temp = Temperature::analog2temp(currentTempLicorRaw);
if (Licor.temperatura != ((temp != 0) ? temp + Licor.ajusteTemperatura : 0)) {
Licor.temperatura = ((temp != 0) ? temp + Licor.ajusteTemperatura : 0);
}
if (Licor.isCalentar) {
if ((Licor.temperatura <= (Licor.tempTarget - Licor.histeresisInf)) &&
(!Licor.isQuemadorOn)) {
digitalWrite(QUEMADOR_LICOR_PIN, HIGH);
Licor.isQuemadorOn = true;
} else if ((Licor.temperatura >=
(Licor.tempTarget + Licor.histeresisSup)) &&
(Licor.isQuemadorOn)) {
digitalWrite(QUEMADOR_LICOR_PIN, LOW);
Licor.isQuemadorOn = false;
}
} else {
digitalWrite(QUEMADOR_LICOR_PIN, LOW);
Licor.isQuemadorOn = false;
}
//</OLLA LICOR>
//<OLLA MACERADOR>
temp = Temperature::analog2temp(currentTempMaceradorRaw);
if (Macerador.temperatura !=
((temp != 0) ? temp + Macerador.ajusteTemperatura : 0)) {
Macerador.temperatura =
((temp != 0) ? temp + Macerador.ajusteTemperatura : 0);
}
if (Macerador.isCalentar) {
if ((Macerador.temperatura <=
(Macerador.tempTarget - Macerador.histeresisInf)) &&
(!Macerador.isQuemadorOn)) {
digitalWrite(QUEMADOR_MACERADOR_PIN, HIGH);
Macerador.isQuemadorOn = true;
} else if ((Macerador.temperatura >=
(Macerador.tempTarget + Macerador.histeresisSup)) &&
(Macerador.isQuemadorOn)) {
digitalWrite(QUEMADOR_MACERADOR_PIN, LOW);
Macerador.isQuemadorOn = false;
}
} else {
digitalWrite(QUEMADOR_MACERADOR_PIN, LOW);
Macerador.isQuemadorOn = false;
}
//</OLLA MACERADOR>
//<OLLA HERVIDO>
temp = Temperature::analog2temp(currentTempHervidoRaw);
if (Hervido.temperatura !=
((temp != 0) ? temp + Hervido.ajusteTemperatura : 0)) {
Hervido.temperatura = ((temp != 0) ? temp + Hervido.ajusteTemperatura : 0);
}
if (Hervido.isCalentar) {
if ((Hervido.temperatura <= (Hervido.tempTarget - Hervido.histeresisInf)) &&
(!Hervido.isQuemadorOn)) {
digitalWrite(QUEMADOR_HERVIDO_PIN, HIGH);
Hervido.isQuemadorOn = true;
} else if ((Hervido.temperatura >=
(Hervido.tempTarget + Hervido.histeresisSup)) &&
(Hervido.isQuemadorOn)) {
digitalWrite(QUEMADOR_HERVIDO_PIN, LOW);
Hervido.isQuemadorOn = false;
}
} else {
digitalWrite(QUEMADOR_HERVIDO_PIN, LOW);
Hervido.isQuemadorOn = false;
}
//</OLLA MACERADOR>
CRITICAL_SECTION_START;
temp_meas_ready = false;
CRITICAL_SECTION_END;
}
/**
* Initialize the temperature manager
* The manager is implemented by periodic calls to manage_heater()
*/
void Temperature::init() {
#ifdef DIDR2
#define ANALOG_SELECT(pin) \
do { \
if (pin < 8) \
SBI(DIDR0, pin); \
else \
SBI(DIDR2, pin - 8); \
} while (0)
#else
#define ANALOG_SELECT(pin) \
do { \
SBI(DIDR0, pin); \
} while (0)
#endif
// Set analog inputs
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
DIDR0 = 0;
#ifdef DIDR2
DIDR2 = 0;
#endif
ANALOG_SELECT(TEMP_LICOR_PIN);
ANALOG_SELECT(TEMP_MACERADOR_PIN);
ANALOG_SELECT(TEMP_HERVIDO_PIN);
// Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt
OCR0B = 128;
SBI(TIMSK0, OCIE0B);
// Wait for temperature measurement to settle
delay(250);
}
/**
* Get raw temperatures
*/
void Temperature::set_current_temp_raw() {
currentTempLicorRaw = rawTempLicorValue;
currentTempMaceradorRaw = rawTempMaceradorValue;
currentTempHervidoRaw = rawTempHervidoValue;
temp_meas_ready = true;
}
/**
* Timer 0 is shared with millies
* - Update the raw temperature values
*/
ISR(TIMER0_COMPB_vect) { Temperature::isr(); }
void Temperature::isr() {
static unsigned char temp_count = 0;
static TempState temp_state = StartupDelay;
#define SET_ADMUX_ADCSRA(pin) \
ADMUX = _BV(REFS0) | (pin & 0x07); \
SBI(ADCSRA, ADSC)
#ifdef MUX5
#define START_ADC(pin) \
if (pin > 7) \
ADCSRB = _BV(MUX5); \
else \
ADCSRB = 0; \
SET_ADMUX_ADCSRA(pin)
#else
#define START_ADC(pin) \
ADCSRB = 0; \
SET_ADMUX_ADCSRA(pin)
#endif
// Prepare or measure a sensor, each one every 12th frame
switch (temp_state) {
case PrepareTempLicor:
START_ADC(TEMP_LICOR_PIN);
temp_state = MeasureTempLicor;
break;
case MeasureTempLicor:
rawTempLicorValue += ADC;
temp_state = PrepareTempMacerador;
break;
case PrepareTempMacerador:
START_ADC(TEMP_MACERADOR_PIN);
temp_state = MeasureTempMacerador;
break;
case MeasureTempMacerador:
rawTempMaceradorValue += ADC;
temp_state = PrepareTempHervido;
break;
case PrepareTempHervido:
START_ADC(TEMP_HERVIDO_PIN);
temp_state = MeasureTempHervido;
break;
case MeasureTempHervido:
rawTempHervidoValue += ADC;
temp_state = PrepareTempLicor;
temp_count++;
break;
case StartupDelay:
temp_state = PrepareTempLicor;
break;
}
if (temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256) = 164ms.
// Update the raw values if they've been read. Else we could be updating
// them during reading.
if (!temp_meas_ready)
set_current_temp_raw();
temp_count = 0;
rawTempLicorValue = 0;
rawTempMaceradorValue = 0;
rawTempHervidoValue = 0;
} // temp_count >= OVERSAMPLENR
}