123 lines
3.6 KiB
C
123 lines
3.6 KiB
C
/* Reflow Oven Controller
|
|
*
|
|
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
|
*
|
|
* This file is part of the Reflow Oven Controller Project.
|
|
*
|
|
* The reflow oven controller is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with the reflow oven controller project.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <reflow-controller/temp-converter.h>
|
|
#include <reflow-controller/temp-converter-data.h>
|
|
#include <helper-macros/helper-macros.h>
|
|
#include <stdbool.h>
|
|
|
|
static const float temp_lookup[(TEMP_CONVERSION_MAX_RES-TEMP_CONVERSION_MIN_RES) / TEMP_CONVERSION_RES_STEP+1] = {TEMP_CONVERSION_ARRAY_DATA};
|
|
|
|
int temp_converter_convert_resistance_to_temp(float resistance, float *temp_out)
|
|
{
|
|
int ret_val;
|
|
unsigned int i;
|
|
unsigned int lower_idx = COUNT_OF(temp_lookup) - 1;
|
|
float diff_to_low_resistance;
|
|
float diff_high_low;
|
|
float low;
|
|
|
|
/* Check pointer */
|
|
if (!temp_out)
|
|
return -1000;
|
|
|
|
if (resistance < TEMP_CONVERSION_MIN_RES) {
|
|
*temp_out = temp_lookup[0];
|
|
ret_val = -1;
|
|
goto return_ret_val;
|
|
} else if (resistance > TEMP_CONVERSION_MAX_RES) {
|
|
*temp_out = temp_lookup[COUNT_OF(temp_lookup)-1];
|
|
ret_val = 1;
|
|
goto return_ret_val;
|
|
}
|
|
|
|
/* Resistance is in range */
|
|
ret_val = 0;
|
|
|
|
/* Calculate lower index for given reistance */
|
|
for (i = 1; i < COUNT_OF(temp_lookup); i++) {
|
|
if (resistance <= TEMP_CONVERSION_MIN_RES + TEMP_CONVERSION_RES_STEP * i) {
|
|
lower_idx = i - 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Get the lower temperature limit of the current range */
|
|
low = temp_lookup[lower_idx];
|
|
|
|
/* Difference to higher limit */
|
|
diff_high_low = temp_lookup[lower_idx+1] - low;
|
|
|
|
/* Resistance difference to lower limit's resistance value */
|
|
diff_to_low_resistance = resistance - (float)(TEMP_CONVERSION_MIN_RES + TEMP_CONVERSION_RES_STEP * lower_idx);
|
|
|
|
/* Calculate output temperature */
|
|
*temp_out = (diff_to_low_resistance * (1.0f / TEMP_CONVERSION_RES_STEP)) * diff_high_low + low;
|
|
|
|
return_ret_val:
|
|
return ret_val;
|
|
}
|
|
|
|
int temp_converter_convert_temp_to_resistance(float temp, float *resistance_out)
|
|
{
|
|
int retcode = 0;
|
|
unsigned int i;
|
|
float lower_temp;
|
|
float upper_temp;
|
|
float lower_resistance;
|
|
float upper_resistance;
|
|
float temp_ratio;
|
|
bool found = false;
|
|
|
|
if (!resistance_out)
|
|
return -1000;
|
|
|
|
if (temp < temp_lookup[0]) {
|
|
/* Requested temperature is smaller than minimum value in lookup table */
|
|
*resistance_out = temp_lookup[0];
|
|
retcode = -1;
|
|
goto exit;
|
|
} else if (temp > temp_lookup[COUNT_OF(temp_lookup) - 1]) {
|
|
/* Requested temperature is higher than maximum value in lookup table */
|
|
*resistance_out = temp_lookup[COUNT_OF(temp_lookup) -1];
|
|
retcode = 1;
|
|
goto exit;
|
|
}
|
|
|
|
for (i = 0U; i < (COUNT_OF(temp_lookup) - 1); i++) {
|
|
if (temp >= temp_lookup[i] && temp <= temp_lookup[i+1]) {
|
|
upper_temp = temp_lookup[i+1];
|
|
lower_temp = temp_lookup[i];
|
|
lower_resistance = TEMP_CONVERSION_MIN_RES + TEMP_CONVERSION_RES_STEP * (i);
|
|
upper_resistance = lower_resistance + TEMP_CONVERSION_RES_STEP;
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
return -100;
|
|
|
|
temp_ratio = (temp - lower_temp) / (upper_temp - lower_temp);
|
|
*resistance_out = lower_resistance + (upper_resistance - lower_resistance) * temp_ratio;
|
|
|
|
exit:
|
|
return retcode;
|
|
}
|