From ef6183ec0d10a2dc5afcf035cec1497fbb12bb91 Mon Sep 17 00:00:00 2001 From: cfif Date: Mon, 30 Mar 2026 12:32:14 +0300 Subject: [PATCH] Init --- APP/inc/ADC_Temp.h | 45 +++---- APP/main.c | 136 ++++----------------- APP/src/ADC_Temp.c | 295 +++++++++++++++++++++------------------------ 3 files changed, 185 insertions(+), 291 deletions(-) diff --git a/APP/inc/ADC_Temp.h b/APP/inc/ADC_Temp.h index 7695932..3cff4c1 100644 --- a/APP/inc/ADC_Temp.h +++ b/APP/inc/ADC_Temp.h @@ -10,23 +10,24 @@ // Константы #define ADC_MAX 4095.0f // 12-битный АЦП -// Типы термисторов -typedef enum { - NTC_TYPE_1 = 0, // Первая таблица (100950 Ом при -40°C) - NTC_TYPE_2 = 1 // Вторая таблица (101000 Ом при -40°C) -} eNTC_Type; +// Параметры Steinhart-Hart для термистора +#define koef_A 0.001741624168166423 +#define koef_B 0.00017003940268680147 +#define koef_C 0.0000004890545443703666 -// Параметры Steinhart-Hart для термисторов -typedef struct { - float A; - float B; - float C; -} SteinhartParams; +#define TABLE_SIZE_LOOKUP 1024 + +// Типы таблиц NTC +typedef enum { + NTC_TYPE_KST45 = 0, // Таблица из документа KST45 (25°C = 3kΩ) + NTC_TYPE_INCAR = 1, // Таблица из документа Incar (25°C = 2795Ω) + NTC_TYPE_CUSTOM = 2 // Пользовательская таблица +} eNtcTableType; // Структура для хранения табличных данных typedef struct { - int temp_c; // Температура (°C) - float r_nom; // Номинальное сопротивление (Ω) + int16_t temp_c; // Температура (°C) + float r_nom; // Номинальное сопротивление (Ω) } ntc_table_entry; typedef enum { @@ -39,20 +40,22 @@ typedef enum { typedef struct { uint16_t adc_value; // Значение АЦП int16_t temp_c; // Температура в °C * 10 (для фиксированной точки) + float resistance; // Сопротивление термистора в Омах } adc_temp_lookup; -// Функции инициализации -void init_ntc(eNTC_Type ntc_type); -void set_r1(float r1_value); // Функция для установки сопротивления делителя -void init_fast_lookup_table(eAlg use_alg); +// Функции инициализации и конфигурации +void init_fast_lookup_table(eAlg use_alg, eNtcTableType table_type, float custom_r1); +void set_custom_ntc_table(const ntc_table_entry* table, uint16_t size, float r1); +void select_ntc_table(eNtcTableType table_type, float custom_r1); // Основные функции float get_temperature_from_adc(uint16_t adc_value, eAlg alg); int16_t get_temperature_fast(uint16_t adc_value); +float get_resistance_from_adc(uint16_t adc_value); +float get_resistance_fast(uint16_t adc_value); -// Функция для получения информации о текущем термисторе -const char* get_ntc_name(void); -uint16_t get_table_size(void); -float get_r1_value(void); // Функция для получения текущего R1 +// Функции для работы с текущей таблицей +eNtcTableType get_current_table_type(void); +float get_current_r1(void); #endif //MDF_ADC_TEMP_KST45_14_2_H \ No newline at end of file diff --git a/APP/main.c b/APP/main.c index 31bb9f4..7bf8ae0 100644 --- a/APP/main.c +++ b/APP/main.c @@ -1,133 +1,45 @@ #include +#include +#include +#include +#include #include "ADC_Temp.h" -void print_table_comparison(void) { - printf("\n=== Сравнение таблиц термисторов ===\n\n"); - printf("Тестирование %s:\n", get_ntc_name()); - printf("Сопротивление делителя R1: %.1f Ом\n", get_r1_value()); - printf("Размер таблицы: %d точек\n\n", get_table_size()); +// value 0..4095 - Это диапазон АЦП, Нужно проверить крайние значения и смоделировать таблицы - printf("ADC\tСопротивление(Ом)\tLinear\tSteinhart\tFull\tFast\n"); - printf("---------------------------------------------------------------\n"); - // Тестируем разные значения АЦП - uint16_t test_adc[] = {500, 1000, 1500, 2000, 2500, 3000, 3500, 4000}; - - for (int i = 0; i < 8; i++) { - uint16_t adc = test_adc[i]; - float resistance = get_r1_value() * adc / (4095.0f - adc); - float linear = get_temperature_from_adc(adc, ALG_LINEAR); - float steinhart = get_temperature_from_adc(adc, ALG_STEINHART); - float full = get_temperature_from_adc(adc, ALG_STEINHART_FULL); - float fast = get_temperature_fast(adc) / 10.0f; - - printf("%d\t%.1f\t\t%.2f\t%.2f\t%.2f\t%.2f\n", - adc, resistance, linear, steinhart, full, fast); - } -} - -void test_temperature_range(void) { - printf("\n=== Тестирование температурного диапазона ===\n\n"); - printf("Примечание: Для точного тестирования необходимы\n"); - printf("функции доступа к таблице термистора\n\n"); - - // Просто показываем несколько значений - uint16_t test_adc[] = {500, 1000, 1500, 2000, 2500, 3000, 3500, 4000}; - - printf("ADC\tРасчетная температура\n"); - printf("------------------------\n"); - - for (int i = 0; i < 8; i++) { - uint16_t adc = test_adc[i]; - float temp = get_temperature_from_adc(adc, ALG_STEINHART); - printf("%d\t%.2f°C\n", adc, temp); - } -} - -void compare_both_ntc_types(void) { - printf("\n=== Сравнение двух типов термисторов ===\n\n"); - printf("ADC\tNTC Type 1\tNTC Type 2\tРазница\n"); - printf("----------------------------------------\n"); - - uint16_t test_adc[] = {500, 1000, 1500, 2000, 2500, 3000, 3500, 4000}; - - for (int i = 0; i < 8; i++) { - uint16_t adc = test_adc[i]; - - // Тестируем первый тип - init_ntc(NTC_TYPE_1); - init_fast_lookup_table(ALG_STEINHART); - float temp1 = get_temperature_from_adc(adc, ALG_STEINHART); - - // Тестируем второй тип - init_ntc(NTC_TYPE_2); - init_fast_lookup_table(ALG_STEINHART); - float temp2 = get_temperature_from_adc(adc, ALG_STEINHART); - - printf("%d\t%.2f°C\t\t%.2f°C\t\t%.2f°C\n", - adc, temp1, temp2, (temp2 - temp1)); - } -} +extern adc_temp_lookup fast_lookup[TABLE_SIZE_LOOKUP]; int main() { - printf("=== Программа для работы с NTC термисторами ===\n"); - printf("Автор: cfif\n"); - printf("Дата: 04.12.2025\n\n"); - // Выбираем первый тип термистора для тестирования - printf("Инициализация термистора Type 1...\n"); - init_ntc(NTC_TYPE_1); - init_fast_lookup_table(ALG_STEINHART); + init_fast_lookup_table(ALG_STEINHART, NTC_TYPE_INCAR, 3300.0f); - // Выводим информацию - printf("Текущий термистор: %s\n", get_ntc_name()); - printf("Сопротивление делителя R1: %.1f Ом\n", get_r1_value()); - printf("Количество точек в таблице: %d\n\n", get_table_size()); +// for (int i = 0; i < TABLE_SIZE_LOOKUP; ++i) { +// printf("{%u,%d}, \n", fast_lookup[i].adc_value, fast_lookup[i].temp_c); +// } - // Тестируем различные значения АЦП - print_table_comparison(); - // Тестируем температурный диапазон - test_temperature_range(); - // Сравниваем оба типа термисторов - compare_both_ntc_types(); + //uint16_t value = 4095 / 2; // Должно быть 25 градусов. Это середина диапазона АЦП + uint16_t value = 1980; - // Пример работы с конкретным значением АЦП - printf("\n=== Пример работы с конкретным значением АЦП ===\n"); - uint16_t test_value = 1980; +// float T_ALG_LINEAR = get_temperature_from_adc(value, ALG_LINEAR); + //float T_ALG_STEINHART = get_temperature_from_adc(value, ALG_STEINHART); + float T_ALG_STEINHART = get_temperature_fast(value); + float T_ALG_STEINHART_1 = get_resistance_fast(value); - init_ntc(NTC_TYPE_2); - init_fast_lookup_table(ALG_STEINHART); + // float T_ALG_STEINHART_FULL = get_temperature_from_adc(value, ALG_STEINHART_FULL); +// float T_FAST = get_temperature_fast(value); +// float T_ATERLUX = calc_temperature(value); - float T_ALG_LINEAR = get_temperature_from_adc(test_value, ALG_LINEAR); - float T_ALG_STEINHART = get_temperature_from_adc(test_value, ALG_STEINHART); - float T_ALG_STEINHART_FULL = get_temperature_from_adc(test_value, ALG_STEINHART_FULL); - float T_FAST = get_temperature_fast(test_value) / 10.0f; +// printf("T_ALG_LINEAR = %f \n", T_ALG_LINEAR); + printf("T_ALG_STEINHART = %f %f\n", T_ALG_STEINHART, T_ALG_STEINHART_1); +// printf("T_ALG_STEINHART_FULL = %f \n", T_ALG_STEINHART_FULL); - printf("Для ADC = %d:\n", test_value); - printf(" Линейная интерполяция: %.2f°C\n", T_ALG_LINEAR); - printf(" Steinhart-Hart: %.2f°C\n", T_ALG_STEINHART); - printf(" Steinhart-Hart полная: %.2f°C\n", T_ALG_STEINHART_FULL); - printf(" Быстрый метод: %.2f°C\n", T_FAST); +// printf("T_FAST = %f \n", T_FAST / 10); +// printf("T_ATERLUX = %f \n", T_ATERLUX / 10); - // Пример изменения сопротивления делителя - printf("\n=== Пример изменения сопротивления делителя ===\n"); - printf("Текущий R1: %.1f Ом\n", get_r1_value()); - set_r1(4700.0f); // Изменяем на 4.7 кОм - init_fast_lookup_table(ALG_STEINHART); - float new_temp = get_temperature_from_adc(test_value, ALG_STEINHART); - printf("После изменения R1 на %.1f Ом, температура: %.2f°C\n", - get_r1_value(), new_temp); - - set_r1(3300.0f); // Возвращаем обратно - init_fast_lookup_table(ALG_STEINHART); - float original_temp = get_temperature_from_adc(test_value, ALG_STEINHART); - printf("После возврата R1 на %.1f Ом, температура: %.2f°C\n", - get_r1_value(), original_temp); - - printf("\n=== Программа завершена ===\n"); return 0; } \ No newline at end of file diff --git a/APP/src/ADC_Temp.c b/APP/src/ADC_Temp.c index c9fda1d..c8c0f93 100644 --- a/APP/src/ADC_Temp.c +++ b/APP/src/ADC_Temp.c @@ -1,12 +1,13 @@ // // Created by cfif on 02.12.2025. // + #include "ADC_Temp.h" #include #include -// Таблица 1: Первый термистор (100950 Ом при -40°C) -static const ntc_table_entry ntc_table_type1[] = { +// Таблица из документа KST45 (25°C = 3000Ω) +static const ntc_table_entry ntc_table_kst45[] = { {-40, 100950.0f}, {-35, 72777.0f}, {-30, 53100.0f}, @@ -35,13 +36,8 @@ static const ntc_table_entry ntc_table_type1[] = { {85, 321.7f} }; -#define TABLE1_SIZE (sizeof(ntc_table_type1) / sizeof(ntc_table_entry)) -#define TABLE1_START_TEMP -40 -#define TABLE1_END_TEMP 85 -#define TABLE1_R1 3300.0f // Сопротивление делителя для первого термистора - -// Таблица 2: Второй термистор (101000 Ом при -40°C) - KST-45 -static const ntc_table_entry ntc_table_type2[] = { +// Таблица из документа Incar (25°C ≈ 2795Ω) +static const ntc_table_entry ntc_table_incar[] = { {-40, 101000.0f}, {-35, 72600.0f}, {-30, 52720.0f}, @@ -54,7 +50,7 @@ static const ntc_table_entry ntc_table_type2[] = { {-3, 11010.0f}, {-2, 10440.0f}, {-1, 9907.0f}, - {0, 9399.0f}, + {0, 9399.0f}, {1, 8924.0f}, {2, 8473.0f}, {3, 8048.0f}, @@ -82,105 +78,29 @@ static const ntc_table_entry ntc_table_type2[] = { {85, 283.0f} }; -#define TABLE2_SIZE (sizeof(ntc_table_type2) / sizeof(ntc_table_entry)) -#define TABLE2_START_TEMP -40 -#define TABLE2_END_TEMP 85 -#define TABLE2_R1 3300.0f // Сопротивление делителя для второго термистора (можно изменить при необходимости) +// Глобальные переменные для текущей конфигурации +static const ntc_table_entry* current_ntc_table = ntc_table_kst45; +static uint16_t current_table_size = sizeof(ntc_table_kst45) / sizeof(ntc_table_entry); +static float current_r1 = 3300.0f; // Сопротивление делителя по умолчанию +static eNtcTableType current_table_type = NTC_TYPE_KST45; -// Параметры Steinhart-Hart для различных термисторов -static const SteinhartParams steinhart_type1 = { - 0.001752169f, // A - 0.000171234f, // B - 0.000000512345f // C (рассчитаны приблизительно) -}; - -static const SteinhartParams steinhart_type2 = { - 0.001741624168166423f, - 0.00017003940268680147f, - 0.0000004890545443703666f -}; - -// Структура для хранения информации о текущем термисторе -typedef struct { - eNTC_Type type; - const ntc_table_entry* table; - uint16_t table_size; - int start_temp; - int end_temp; - float r1; // Сопротивление делителя для данного термистора - SteinhartParams params; - const char* name; -} NTC_Config; - -// Текущая активная конфигурация -static NTC_Config active_ntc; - -// Быстрая таблица поиска -#define FAST_TABLE_SIZE 512 -static adc_temp_lookup fast_lookup[FAST_TABLE_SIZE]; - -// Инициализация с выбором типа термистора -void init_ntc(eNTC_Type ntc_type) { - switch(ntc_type) { - case NTC_TYPE_1: - active_ntc.type = NTC_TYPE_1; - active_ntc.table = ntc_table_type1; - active_ntc.table_size = TABLE1_SIZE; - active_ntc.start_temp = TABLE1_START_TEMP; - active_ntc.end_temp = TABLE1_END_TEMP; - active_ntc.r1 = TABLE1_R1; - active_ntc.params = steinhart_type1; - active_ntc.name = "NTC Type 1 (100950 Ohm @ -40C)"; - break; - - case NTC_TYPE_2: - active_ntc.type = NTC_TYPE_2; - active_ntc.table = ntc_table_type2; - active_ntc.table_size = TABLE2_SIZE; - active_ntc.start_temp = TABLE2_START_TEMP; - active_ntc.end_temp = TABLE2_END_TEMP; - active_ntc.r1 = TABLE2_R1; - active_ntc.params = steinhart_type2; - active_ntc.name = "NTC Type 2 (101000 Ohm @ -40C) - KST-45"; - break; - } -} - -// Функция для установки сопротивления делителя -void set_r1(float r1_value) { - if (r1_value > 0.0f) { - active_ntc.r1 = r1_value; - } -} - -// Функция для получения текущего R1 -float get_r1_value(void) { - return active_ntc.r1; -} +// Глобальная таблица для быстрого доступа +adc_temp_lookup fast_lookup[TABLE_SIZE_LOOKUP]; // Функция расчёта сопротивления NTC из значения АЦП -static float calculate_resistance(uint16_t adc_value) { - if (adc_value == 0) { - return active_ntc.table[0].r_nom * 1.1f; // Экстраполяция +static float calculate_resistance(uint16_t adc_value, float r1) { + if (adc_value == 0 || adc_value >= (uint16_t) ADC_MAX) { + return 0.0f; } - if (adc_value >= (uint16_t) ADC_MAX) { - return active_ntc.table[active_ntc.table_size - 1].r_nom * 0.9f; // Экстраполяция - } - - float R_ntc = active_ntc.r1 * (float)adc_value / (ADC_MAX - (float)adc_value); - - // Ограничиваем физически возможные значения - if (R_ntc < 10.0f) R_ntc = 10.0f; - if (R_ntc > 200000.0f) R_ntc = 200000.0f; - + // Формула делителя напряжения: R_ntc = R1 * adc_value / (ADC_MAX - adc_value) + float R_ntc = r1 * (float) adc_value / (ADC_MAX - (float) adc_value); return R_ntc; } -// Бинарный поиск в активной таблице -static int find_interval_index(float resistance) { +// Бинарный поиск в таблице +static int find_interval_index(float resistance, const ntc_table_entry* table, uint16_t size) { int left = 0; - int right = active_ntc.table_size - 1; - const ntc_table_entry* table = active_ntc.table; + int right = size - 1; // Проверка границ if (resistance >= table[0].r_nom) return 0; @@ -190,7 +110,7 @@ static int find_interval_index(float resistance) { while (left <= right) { int mid = left + (right - left) / 2; - if (mid < active_ntc.table_size - 1 && + if (mid < size - 1 && resistance <= table[mid].r_nom && resistance >= table[mid + 1].r_nom) { return mid; @@ -207,10 +127,8 @@ static int find_interval_index(float resistance) { } // Интерполяция с использованием уравнения Стейнхарта-Харта между точками -static float interpolate_steinhart(float resistance, int index) { - const ntc_table_entry* table = active_ntc.table; - - // Берем две соседние точки из активной таблицы +static float interpolate_steinhart(float resistance, int index, const ntc_table_entry* table) { + // Берем две соседние точки из таблицы float t1 = (float) table[index].temp_c + 273.15f; // в Кельвинах float t2 = (float) table[index + 1].temp_c + 273.15f; float r1 = table[index].r_nom; @@ -227,9 +145,7 @@ static float interpolate_steinhart(float resistance, int index) { } // Линейная интерполяция в логарифмическом масштабе -static float interpolate_log_linear(float resistance, int index) { - const ntc_table_entry* table = active_ntc.table; - +static float interpolate_log_linear(float resistance, int index, const ntc_table_entry* table) { float t1 = (float) table[index].temp_c; float t2 = (float) table[index + 1].temp_c; float r1 = table[index].r_nom; @@ -242,28 +158,32 @@ static float interpolate_log_linear(float resistance, int index) { return t1 + (t2 - t1) * (log_r - log_r1) / (log_r2 - log_r1); } -// Полная версия Steinhart-Hart с коэффициентами для данного термистора -static float interpolate_steinhart_full(float resistance, int index) { +// Более надежная версия с проверкой параметров +static float interpolate_steinhart_full(float resistance, int index, const ntc_table_entry* table) { // Проверка корректности входных данных if (resistance <= 0.0f) { - return -273.15f; + return -273.15f; // Абсолютный ноль при некорректном сопротивлении } + // Для повышения точности можно использовать таблицу как справочную, + // но основное вычисление - по уравнению с коэффициентами double L = logf(resistance); + double L3 = L * L * L; - double inv_T = active_ntc.params.A + active_ntc.params.B * L + active_ntc.params.C * L3; + double inv_T = koef_A + koef_B * L + koef_C * L3; // Проверка на физическую реализуемость if (inv_T <= 0.0f || inv_T > 1.0f) { - return (float)active_ntc.table[index].temp_c; + // В случае ошибки возвращаем температуру из таблицы по индексу + return (float)table[index].temp_c; } double temp_K = 1.0f / inv_T; - // Проверка диапазона - if (temp_K < (active_ntc.start_temp + 273.15f) || - temp_K > (active_ntc.end_temp + 273.15f)) { - return (float)active_ntc.table[index].temp_c; + // Дополнительная проверка диапазона + if (temp_K < 223.15f || temp_K > 423.15f) { + // Возвращаем значение из таблицы как запасной вариант + return (float)table[index].temp_c; } return (float)(temp_K - 273.15f); @@ -271,77 +191,136 @@ static float interpolate_steinhart_full(float resistance, int index) { // Основная функция для получения температуры float get_temperature_from_adc(uint16_t adc_value, eAlg use_alg) { - float resistance = calculate_resistance(adc_value); + float resistance = calculate_resistance(adc_value, current_r1); if (resistance <= 0.0f) { - return -273.15f; + return -273.15f; // Ошибка } - int index = find_interval_index(resistance); + int index = find_interval_index(resistance, current_ntc_table, current_table_size); - if (index < 0 || index >= active_ntc.table_size - 1) { + if (index < 0 || index >= current_table_size - 1) { // Вне диапазона таблицы - const ntc_table_entry* table = active_ntc.table; - if (resistance >= table[0].r_nom) return active_ntc.start_temp; - if (resistance <= table[active_ntc.table_size - 1].r_nom) return active_ntc.end_temp; - return -273.15f; + if (resistance >= current_ntc_table[0].r_nom) return current_ntc_table[0].temp_c; + if (resistance <= current_ntc_table[current_table_size - 1].r_nom) return current_ntc_table[current_table_size - 1].temp_c; + return -273.15f; // Ошибка } if (use_alg == ALG_STEINHART) { - return interpolate_steinhart(resistance, index); + return interpolate_steinhart(resistance, index, current_ntc_table); } else if (use_alg == ALG_STEINHART_FULL) { - return interpolate_steinhart_full(resistance, index); + return interpolate_steinhart_full(resistance, index, current_ntc_table); } else { - return interpolate_log_linear(resistance, index); + return interpolate_log_linear(resistance, index, current_ntc_table); } } -// Инициализация быстрой таблицы поиска -void init_fast_lookup_table(eAlg use_alg) { - uint16_t step = (uint16_t)(ADC_MAX / (FAST_TABLE_SIZE - 1)); +// Функция для получения сопротивления по значению АЦП +float get_resistance_from_adc(uint16_t adc_value) { + return calculate_resistance(adc_value, current_r1); +} - for (uint16_t i = 0; i < FAST_TABLE_SIZE; i++) { - uint16_t adc = i * step; - if (adc > (uint16_t)ADC_MAX) adc = (uint16_t)ADC_MAX; +// Выбор активной таблицы NTC +void select_ntc_table(eNtcTableType table_type, float custom_r1) { + switch (table_type) { + case NTC_TYPE_KST45: + current_ntc_table = ntc_table_kst45; + current_table_size = sizeof(ntc_table_kst45) / sizeof(ntc_table_entry); + current_r1 = (custom_r1 > 0) ? custom_r1 : 3300.0f; + current_table_type = NTC_TYPE_KST45; + break; + case NTC_TYPE_INCAR: + current_ntc_table = ntc_table_incar; + current_table_size = sizeof(ntc_table_incar) / sizeof(ntc_table_entry); + current_r1 = (custom_r1 > 0) ? custom_r1 : 3300.0f; + current_table_type = NTC_TYPE_INCAR; + break; + + case NTC_TYPE_CUSTOM: + // Пользовательская таблица должна быть установлена через set_custom_ntc_table + if (current_ntc_table == NULL) { + // Если пользовательская таблица не установлена, используем KST45 + current_ntc_table = ntc_table_kst45; + current_table_size = sizeof(ntc_table_kst45) / sizeof(ntc_table_entry); + current_r1 = 3300.0f; + current_table_type = NTC_TYPE_KST45; + } + if (custom_r1 > 0) { + current_r1 = custom_r1; + } + break; + } +} + +// Установка пользовательской таблицы NTC +void set_custom_ntc_table(const ntc_table_entry* table, uint16_t size, float r1) { + if (table != NULL && size > 1) { + current_ntc_table = table; + current_table_size = size; + current_r1 = (r1 > 0) ? r1 : 3300.0f; + current_table_type = NTC_TYPE_CUSTOM; + } +} + +// Инициализация таблицы быстрого доступа +void init_fast_lookup_table(eAlg use_alg, eNtcTableType table_type, float custom_r1) { + // Выбираем таблицу NTC + select_ntc_table(table_type, custom_r1); + + // Создаем таблицу для быстрого преобразования АЦП->температура + for (uint16_t i = 0; i < TABLE_SIZE_LOOKUP; i++) { + uint16_t adc = (uint16_t)(i * (ADC_MAX / (TABLE_SIZE_LOOKUP - 1))); float temp = get_temperature_from_adc(adc, use_alg); + float resistance = calculate_resistance(adc, current_r1); fast_lookup[i].adc_value = adc; - - // Ограничиваем температуру разумными пределами - if (temp < active_ntc.start_temp) temp = active_ntc.start_temp; - if (temp > active_ntc.end_temp) temp = active_ntc.end_temp; - - fast_lookup[i].temp_c = (int16_t)(temp * 10.0f); + fast_lookup[i].temp_c = (int16_t) (temp * 10.0f); // Храним с точностью 0.1°C + fast_lookup[i].resistance = resistance; } } -// Быстрое получение температуры с линейной интерполяцией +// Быстрое получение температуры из таблицы int16_t get_temperature_fast(uint16_t adc_value) { - uint16_t step = (uint16_t)(ADC_MAX / (FAST_TABLE_SIZE - 1)); - uint16_t index = adc_value / step; + // Простой поиск в таблице с линейной интерполяцией + uint16_t step = (uint16_t)(ADC_MAX / (TABLE_SIZE_LOOKUP - 1)); + if (step == 0) step = 1; - if (index >= FAST_TABLE_SIZE - 1) { - return fast_lookup[FAST_TABLE_SIZE - 1].temp_c; - } + uint16_t index = adc_value / step; + if (index >= (TABLE_SIZE_LOOKUP - 1)) return fast_lookup[TABLE_SIZE_LOOKUP - 1].temp_c; uint16_t adc1 = fast_lookup[index].adc_value; uint16_t adc2 = fast_lookup[index + 1].adc_value; int16_t temp1 = fast_lookup[index].temp_c; int16_t temp2 = fast_lookup[index + 1].temp_c; - // Линейная интерполяция - if (adc2 != adc1) { - return temp1 + ((temp2 - temp1) * (adc_value - adc1)) / (adc2 - adc1); - } - - return temp1; + // Линейная интерполяция температуры + return temp1 + ((int32_t)(temp2 - temp1) * (adc_value - adc1)) / (adc2 - adc1); } -// Вспомогательные функции -const char* get_ntc_name(void) { - return active_ntc.name; +// Быстрое получение сопротивления из таблицы +float get_resistance_fast(uint16_t adc_value) { + // Простой поиск в таблице с линейной интерполяцией + uint16_t step = (uint16_t)(ADC_MAX / (TABLE_SIZE_LOOKUP - 1)); + if (step == 0) step = 1; + + uint16_t index = adc_value / step; + if (index >= (TABLE_SIZE_LOOKUP - 1)) return fast_lookup[TABLE_SIZE_LOOKUP - 1].resistance; + + uint16_t adc1 = fast_lookup[index].adc_value; + uint16_t adc2 = fast_lookup[index + 1].adc_value; + float r1 = fast_lookup[index].resistance; + float r2 = fast_lookup[index + 1].resistance; + + // Линейная интерполяция сопротивления + return r1 + (r2 - r1) * (adc_value - adc1) / (adc2 - adc1); } -uint16_t get_table_size(void) { - return active_ntc.table_size; +// Получение текущего типа таблицы +eNtcTableType get_current_table_type(void) { + return current_table_type; +} + +// Получение текущего сопротивления делителя +float get_current_r1(void) { + return current_r1; } \ No newline at end of file