-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCutdown_ADC.cpp
99 lines (84 loc) · 3.03 KB
/
Cutdown_ADC.cpp
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
/* Author: Alex St. Clair
* Filename: Cutdown_ADC.h
* Created: 12-17-18
*
* Defines a driver to use the SAMD21 ADC through the Arduino IDE
*/
#include "Cutdown_ADC.h"
#include "Cutdown_Logger.h"
#include "Cutdown_Configure.h"
// returns the temperature in celsius given the MCP9700A thermistor voltage
float calculate_temperature(float voltage)
{
return (voltage - THERM_OFFSET) * THERM_COEFFICIENT;
}
// returns the temperature in fahrenheit given the MCP9700A thermistor voltage
float calculate_fahrenheit(float voltage)
{
return ((voltage - THERM_OFFSET) * THERM_COEFFICIENT) * (1.8f) + 32;
}
// returns true if the squib is present and not fired (or shorted), false if not
bool check_squib(float voltage)
{
return (voltage < SQUIB_THRESHOLD);
}
// ADC_Channel methods ------------------------------------------
ADC_Channel::ADC_Channel(float last, float divide, uint8_t pin)
{
last_voltage = last;
divider = divide;
pin_number = pin;
}
float ADC_Channel::read(void)
{
last_voltage = (float) analogRead(pin_number) / ADC_MAX * REFERENCE_VOLTAGE / divider;
return last_voltage;
}
float ADC_Channel::check(void)
{
return last_voltage;
}
// Cutdown_ADC methods ------------------------------------------
Cutdown_ADC::Cutdown_ADC() :
thermistor (0.0f, THERM_DIVIDE, THERMISTOR),
squib_pri (0.0f, SQUIB_DIVIDE, VMON_SQUIB_PRI),
squib_bck (0.0f, SQUIB_DIVIDE, VMON_SQUIB_BCK),
v_batt_pri (12.0f, VBATT_DIVIDE, VMON_BATT_PRI), // needs to start above low-battery threshold
v_batt_bck (12.0f, VBATT_DIVIDE, VMON_BATT_BCK) // needs to start above low-battery threshold
{ }
void Cutdown_ADC::init(void)
{
analogReference(AR_INTERNAL2V23); // internal 2.23V reference
analogReadResolution(12); // 12-bit resolution
last_temps[0] = cutdown_config.temp_set_point;
last_temps[1] = cutdown_config.temp_set_point;
last_temps[2] = cutdown_config.temp_set_point;
last_temps[3] = cutdown_config.temp_set_point;
}
// TODO: add hysteresis!
void Cutdown_ADC::thermal_control(void)
{
static bool heating = false;
static uint8_t temp_num = 0;
// get a new reading
float temp = calculate_temperature(thermistor.read());
cutdown_log(LOG_DEBUG, "temp ", temp);
cutdown_log(LOG_DEBUG, "volt ", thermistor.check());
// store the new temp in the circular bufferred array
last_temps[temp_num] = temp;
temp_num = (temp_num + 1) % 4;
// update the running average
float avg_temp = 0.0f;
for (int i = 0; i < 4; i++) avg_temp += last_temps[i];
avg_temp /= 4;
// check if the heater state should change
if (cutdown_config.temp_set_point > avg_temp && !heating) {
digitalWrite(HEATER_GATE, HIGH);
cutdown_log(LOG_DEBUG, "Heater on");
heating = true;
} else if (cutdown_config.temp_set_point < avg_temp && heating) {
digitalWrite(HEATER_GATE, LOW);
cutdown_log(LOG_DEBUG, "Heater off");
heating = false;
}
}