Init
This commit is contained in:
parent
3f00536e26
commit
2b48ae3d1e
|
|
@ -40,5 +40,5 @@ int16_t get_temperature_log_fast(uint16_t adc_value);
|
|||
int16_t get_temperature_linear_fast(uint16_t adc_value);
|
||||
float get_resistance_from_adc(uint16_t adc_value); // Новая функция для получения сопротивления
|
||||
|
||||
|
||||
float get_resistance_log_fast(int16_t temperature_c10);
|
||||
#endif //MDF_ADC_TEMP_KST45_14_2_H
|
||||
14
APP/main.c
14
APP/main.c
|
|
@ -18,9 +18,21 @@ int main() {
|
|||
printf("T_FAST = %.1f °C\n", T_FAST / 10.0f);
|
||||
printf("Resistance = %.2f Ω\n", resistance);
|
||||
|
||||
// float R = get_resistance_log_fast(250);
|
||||
// printf("Resistance FAST = %.2f Ω\n", R);
|
||||
|
||||
|
||||
// Пример доступа к таблице
|
||||
printf("\nПример данных из таблицы быстрого поиска:\n");
|
||||
for(int i = 2048; i < 2048 + 5; i++) {
|
||||
for(int i = TABLE_SIZE_LOOKUP - 1; i > TABLE_SIZE_LOOKUP - 5; i--) {
|
||||
printf("ADC: %u, Temp: %.1f °C, Resistance: %.2f Ω\n",
|
||||
fast_lookup[i].adc_value,
|
||||
fast_lookup[i].temp_c / 10.0f,
|
||||
fast_lookup[i].resistance_ohm);
|
||||
}
|
||||
|
||||
printf("\nПример данных из таблицы быстрого поиска:\n");
|
||||
for(int i = 0; i < 5; i++) {
|
||||
printf("ADC: %u, Temp: %.1f °C, Resistance: %.2f Ω\n",
|
||||
fast_lookup[i].adc_value,
|
||||
fast_lookup[i].temp_c / 10.0f,
|
||||
|
|
|
|||
|
|
@ -223,15 +223,55 @@ float get_resistance_from_adc(uint16_t adc_value) {
|
|||
}
|
||||
|
||||
void init_fast_lookup_table(eAlg use_alg) {
|
||||
// Создаем таблицу для быстрого преобразования АЦП->температура
|
||||
for (uint16_t i = 0; i < TABLE_SIZE_LOOKUP; i++) {
|
||||
// Правильное распределение значений АЦП от 0 до ADC_MAX
|
||||
uint16_t adc = (uint16_t) ((float) i * ADC_MAX / (TABLE_SIZE_LOOKUP - 1));
|
||||
float temp = get_temperature_from_adc(adc, use_alg);
|
||||
// Сначала найдем рабочий диапазон АЦП, который дает температуры в пределах таблицы
|
||||
uint16_t min_valid_adc = 0;
|
||||
uint16_t max_valid_adc = 0;
|
||||
float min_temp = TABLE_START_TEMP;
|
||||
float max_temp = TABLE_END_TEMP;
|
||||
|
||||
// Ищем минимальное АЦП, при котором температура >= TABLE_START_TEMP
|
||||
for (uint16_t adc = 1; adc < ADC_MAX; adc++) {
|
||||
float resistance = calculate_resistance(adc);
|
||||
float temp = get_temperature_from_adc(adc, ALG_STEINHART);
|
||||
|
||||
if (temp >= TABLE_START_TEMP && temp <= TABLE_END_TEMP) {
|
||||
min_valid_adc = adc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ищем максимальное АЦП, при котором температура <= TABLE_END_TEMP
|
||||
for (uint16_t adc = (uint16_t)(ADC_MAX - 1); adc > 0; adc--) {
|
||||
float resistance = calculate_resistance(adc);
|
||||
float temp = get_temperature_from_adc(adc, ALG_STEINHART);
|
||||
|
||||
if (temp >= TABLE_START_TEMP && temp <= TABLE_END_TEMP) {
|
||||
max_valid_adc = adc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Если не нашли корректные значения, используем весь диапазон
|
||||
if (min_valid_adc == 0) min_valid_adc = 1;
|
||||
if (max_valid_adc == 0) max_valid_adc = (uint16_t)(ADC_MAX - 1);
|
||||
|
||||
printf("Диапазон АЦП: %u - %u\n", min_valid_adc, max_valid_adc);
|
||||
|
||||
// Заполняем таблицу, равномерно распределяя АЦП в рабочем диапазоне
|
||||
for (uint16_t i = 0; i < TABLE_SIZE_LOOKUP; i++) {
|
||||
// Линейная интерполяция АЦП в рабочем диапазоне
|
||||
float ratio = (float)i / (TABLE_SIZE_LOOKUP - 1);
|
||||
uint16_t adc = min_valid_adc + (uint16_t)(ratio * (max_valid_adc - min_valid_adc));
|
||||
|
||||
float resistance = calculate_resistance(adc);
|
||||
float temp = get_temperature_from_adc(adc, use_alg);
|
||||
|
||||
// Ограничиваем температуру пределами таблицы
|
||||
if (temp < TABLE_START_TEMP) temp = TABLE_START_TEMP;
|
||||
if (temp > TABLE_END_TEMP) temp = TABLE_END_TEMP;
|
||||
|
||||
fast_lookup[i].adc_value = adc;
|
||||
fast_lookup[i].temp_c = (int16_t) (temp * 10.0f); // Храним с точностью 0.1°C
|
||||
fast_lookup[i].temp_c = (int16_t)(temp * 10.0f);
|
||||
fast_lookup[i].resistance_ohm = resistance;
|
||||
}
|
||||
}
|
||||
|
|
@ -305,3 +345,61 @@ int16_t get_temperature_linear_fast(uint16_t adc_value) {
|
|||
|
||||
return temp1 + ((int32_t) (temp2 - temp1) * (adc_value - adc1)) / (adc2 - adc1);
|
||||
}
|
||||
|
||||
|
||||
// Функция для получения сопротивления из температуры (обратное преобразование)
|
||||
float get_resistance_log_fast(int16_t temperature_c10) {
|
||||
// temperature_c10 - температура в °C * 10 (например, 250 = 25.0°C)
|
||||
|
||||
// Защита от выхода за границы
|
||||
if (temperature_c10 <= fast_lookup[0].temp_c) {
|
||||
return fast_lookup[0].resistance_ohm;
|
||||
}
|
||||
if (temperature_c10 >= fast_lookup[TABLE_SIZE_LOOKUP - 1].temp_c) {
|
||||
return fast_lookup[TABLE_SIZE_LOOKUP - 1].resistance_ohm;
|
||||
}
|
||||
|
||||
// Бинарный поиск интервала по температуре
|
||||
int left = 0;
|
||||
int right = TABLE_SIZE_LOOKUP - 1;
|
||||
|
||||
while (left <= right) {
|
||||
int mid = left + (right - left) / 2;
|
||||
|
||||
if (fast_lookup[mid].temp_c <= temperature_c10 &&
|
||||
(mid == TABLE_SIZE_LOOKUP - 1 || temperature_c10 < fast_lookup[mid + 1].temp_c)) {
|
||||
// Нашли интервал
|
||||
if (mid == TABLE_SIZE_LOOKUP - 1) {
|
||||
return fast_lookup[mid].resistance_ohm;
|
||||
}
|
||||
|
||||
// Линейная интерполяция по температуре
|
||||
int16_t temp1 = fast_lookup[mid].temp_c;
|
||||
int16_t temp2 = fast_lookup[mid + 1].temp_c;
|
||||
float res1 = fast_lookup[mid].resistance_ohm;
|
||||
float res2 = fast_lookup[mid + 1].resistance_ohm;
|
||||
|
||||
// Избегаем деления на ноль
|
||||
if (temp2 == temp1) {
|
||||
return res1;
|
||||
}
|
||||
|
||||
// Интерполяция в логарифмическом масштабе для сопротивления
|
||||
// (так как сопротивление изменяется экспоненциально)
|
||||
float log_res1 = logf(res1);
|
||||
float log_res2 = logf(res2);
|
||||
float log_res = log_res1 + (log_res2 - log_res1) *
|
||||
(float)(temperature_c10 - temp1) / (float)(temp2 - temp1);
|
||||
|
||||
return expf(log_res);
|
||||
}
|
||||
|
||||
if (temperature_c10 < fast_lookup[mid].temp_c) {
|
||||
right = mid - 1;
|
||||
} else {
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return fast_lookup[0].resistance_ohm; // Если не нашли, возвращаем первое значение
|
||||
}
|
||||
Loading…
Reference in New Issue