[thermistor] Use vcc reference to obtain an accurate value for the potential divider reference

ADC reference source now selected in hw_config
main-solar-only
Richard Meadows 2016-01-16 19:36:14 +00:00
rodzic e51156b3c7
commit 4ae5371040
6 zmienionych plików z 33 dodań i 16 usunięć

Wyświetl plik

@ -25,6 +25,6 @@
#ifndef THERMISTOR_H #ifndef THERMISTOR_H
#define THERMISTOR_H #define THERMISTOR_H
float thermistor_voltage_to_temperature(float voltage); float thermistor_ratio_to_temperature(float ratio);
#endif /* THERMISTOR_H */ #endif /* THERMISTOR_H */

Wyświetl plik

@ -27,7 +27,7 @@
#include "system/interrupt.h" #include "system/interrupt.h"
#include "hw_config.h" #include "hw_config.h"
float battery_v = 0.0, thermistor_v = 0.0, solar_v = 0.0; float battery_v = 0.0, thermistor_ratio = 0.0, solar_v = 0.0;
#define ADC_GAINF ADC_GAIN_FACTOR_DIV2 #define ADC_GAINF ADC_GAIN_FACTOR_DIV2
#define ADC_GAINF_VAL 0.5 #define ADC_GAINF_VAL 0.5
@ -51,13 +51,13 @@ enum adc_phase_t {
void adc_complete_callback(void); void adc_complete_callback(void);
void configure_adc(enum adc_positive_input input) void configure_adc(enum adc_positive_input input, enum adc_reference reference)
{ {
struct adc_config config_adc; struct adc_config config_adc;
adc_get_config_defaults(&config_adc); adc_get_config_defaults(&config_adc);
config_adc.clock_source = GCLK_GENERATOR_0; config_adc.clock_source = GCLK_GENERATOR_0;
config_adc.reference = ADC_REFERENCE_INT1V; config_adc.reference = reference;
config_adc.clock_prescaler = ADC_CLOCK_PRESCALER_DIV64; config_adc.clock_prescaler = ADC_CLOCK_PRESCALER_DIV64;
config_adc.resolution = ADC_RESOLUTION; config_adc.resolution = ADC_RESOLUTION;
config_adc.gain_factor = ADC_GAINF; config_adc.gain_factor = ADC_GAINF;
@ -96,6 +96,24 @@ enum adc_positive_input adc_get_channel(enum adc_phase_t phase)
default: return SOLAR_ADC_CHANNEL; default: return SOLAR_ADC_CHANNEL;
} }
} }
/**
* Gets the reference to use in the current phase
*/
enum adc_reference adc_get_reference(enum adc_phase_t phase)
{
switch (phase) {
#if BATTERY_ADC
case ADC_PHASE_CONVERT_BATTERY: return BATTERY_ADC_REFERENCE;
#endif
#if THERMISTOR_ADC
case ADC_PHASE_CONVERT_THERMISTOR: return THERMISTOR_ADC_REFERENCE;
#endif
#if SOLAR_ADC
case ADC_PHASE_CONVERT_SOLAR: return SOLAR_ADC_REFERENCE;
#endif
default: return SOLAR_ADC_CHANNEL;
}
}
/** /**
* Assigns the value for the current phase * Assigns the value for the current phase
*/ */
@ -109,7 +127,7 @@ void assign_adc_value(enum adc_phase_t phase, float pin_v)
#endif #endif
#if THERMISTOR_ADC #if THERMISTOR_ADC
case ADC_PHASE_CONVERT_THERMISTOR: case ADC_PHASE_CONVERT_THERMISTOR:
thermistor_v = pin_v / THERMISTOR_ADC_CHANNEL_DIV; thermistor_ratio = pin_v / THERMISTOR_ADC_CHANNEL_DIV;
break; break;
#endif #endif
#if SOLAR_ADC #if SOLAR_ADC
@ -147,7 +165,7 @@ void adc_complete_callback(void) {
if (!is_adc_sequence_done()) { /* Another channel still to do.. */ if (!is_adc_sequence_done()) { /* Another channel still to do.. */
/* Start conversion on this channel */ /* Start conversion on this channel */
configure_adc(adc_get_channel(adc_phase)); configure_adc(adc_get_channel(adc_phase), adc_get_reference(adc_phase));
adc_start_conversion(); adc_start_conversion();
} }
} }
@ -162,7 +180,7 @@ void start_adc_sequence(void)
adc_phase++; adc_phase++;
/* Start conversion on this channel */ /* Start conversion on this channel */
configure_adc(adc_get_channel(adc_phase)); configure_adc(adc_get_channel(adc_phase), adc_get_reference(adc_phase));
adc_start_conversion(); adc_start_conversion();
} }
@ -175,7 +193,7 @@ float get_battery(void)
} }
float get_thermistor(void) float get_thermistor(void)
{ {
return thermistor_v; return thermistor_ratio;
} }
float get_solar(void) float get_solar(void)
{ {

Wyświetl plik

@ -96,7 +96,7 @@ struct tracker_datapoint* collect_data(void)
datapoint.battery = get_battery(); /* Will return zero by default */ datapoint.battery = get_battery(); /* Will return zero by default */
datapoint.solar = get_solar(); /* Will return zero by default */ datapoint.solar = get_solar(); /* Will return zero by default */
datapoint.radio_die_temperature = telemetry_si_temperature(); datapoint.radio_die_temperature = telemetry_si_temperature();
datapoint.thermistor_temperature = thermistor_voltage_to_temperature(get_thermistor()); datapoint.thermistor_temperature = thermistor_ratio_to_temperature(get_thermistor());
/** /**
* ---- Barometer ---- * ---- Barometer ----

Wyświetl plik

@ -25,15 +25,14 @@
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#define SERIES_RESISTOR 100000 #define SERIES_RESISTOR 100000 /* 100k */
#define ADC_MAX_VALUE (1.85)
/** /**
* Calculate the temperature corresponding to the voltage read from the potential divider. * Calculate the temperature corresponding to the voltage read from the potential divider.
* Note: Uses full SteinhartHart equation * Note: Uses full SteinhartHart equation
* Parameters: volatge = raw ADC value from 0 - ADC_MAX_VALUE * Parameters: ratio - divider voltage over supply voltage, 0 - 1
*/ */
float thermistor_voltage_to_temperature(float voltage) float thermistor_ratio_to_temperature(float ratio)
{ {
float resistance; float resistance;
@ -43,7 +42,7 @@ float thermistor_voltage_to_temperature(float voltage)
float C = 0.00000008763737806081768; float C = 0.00000008763737806081768;
/* convert the value to resistance */ /* convert the value to resistance */
resistance = (SERIES_RESISTOR * ADC_MAX_VALUE) / voltage; resistance = SERIES_RESISTOR / ratio;
resistance -= SERIES_RESISTOR; resistance -= SERIES_RESISTOR;
float logR = log(resistance); float logR = log(resistance);

Wyświetl plik

@ -39,6 +39,6 @@ __verification__ void analogue_read_tc(void) {
while (!is_adc_sequence_done()); while (!is_adc_sequence_done());
analogue_read_tc_results.battery = get_battery(); analogue_read_tc_results.battery = get_battery();
analogue_read_tc_results.thermistor = thermistor_voltage_to_temperature(get_thermistor()); analogue_read_tc_results.thermistor = thermistor_ratio_to_temperature(get_thermistor());
analogue_read_tc_results.solar = get_solar(); analogue_read_tc_results.solar = get_solar();
} }

Wyświetl plik

@ -34,5 +34,5 @@ __verification__ void thermistor_equation_tc(void) {
*/ */
thermistor_equation_tc_results.temperature = thermistor_equation_tc_results.temperature =
thermistor_voltage_to_temperature(thermistor_equation_tc_params.value); thermistor_ratio_to_temperature(thermistor_equation_tc_params.value);
} }