This commit is contained in:
cfif 2026-05-13 09:36:15 +03:00
parent 1075ecf4ff
commit 2d5e7010d2
2 changed files with 98 additions and 53 deletions

View File

@ -8,6 +8,29 @@ typedef struct {
float resistance_ohm; // Сопротивление в Ом float resistance_ohm; // Сопротивление в Ом
} adc_temp_lookup_entry_t; } adc_temp_lookup_entry_t;
// Функция для сохранения температур в одну строку через пробел (все значения)
void save_temperature_int_one_line(const char* filename, const adc_temp_lookup* table, const char* table_name) {
FILE* file = fopen(filename, "w");
if (file == NULL) {
printf("Ошибка: не удалось создать файл %s\n", filename);
return;
}
fprintf(file, "# Температуры для таблицы %s (одна строка, через пробел)\n", table_name);
fprintf(file, "# VCC=%.2fV, VREF=%.2fV\n", VCC_DIVIDER_MV / 1000.0f, VREF_MV / 1000.0f);
fprintf(file, "# Всего значений: %d\n", TABLE_SIZE_LOOKUP);
fprintf(file, "# Температура в °C * 10 (целые числа)\n\n");
for (int i = 0; i < TABLE_SIZE_LOOKUP; i++) {
if (i > 0) fprintf(file, " ");
fprintf(file, "%d", table[i].temp_c);
}
fprintf(file, "\n");
fclose(file);
printf("Температуры (int one-line) для '%s' сохранены в файл: %s\n", table_name, filename);
}
// Функция для сохранения таблицы в C файл в виде статического массива // Функция для сохранения таблицы в C файл в виде статического массива
void save_table_to_c_file(const char* filename, const adc_temp_lookup* table, void save_table_to_c_file(const char* filename, const adc_temp_lookup* table,
const char* table_name, const char* array_name) { const char* table_name, const char* array_name) {
@ -186,6 +209,7 @@ void save_all_tables_to_files(void) {
save_table_to_c_file("duct_table_array.c", tables->duct, "DUCT", "duct_lookup_table"); save_table_to_c_file("duct_table_array.c", tables->duct, "DUCT", "duct_lookup_table");
save_table_to_csv("duct_table.csv", tables->duct, "DUCT"); save_table_to_csv("duct_table.csv", tables->duct, "DUCT");
save_table_to_txt("duct_table.txt", tables->duct, "DUCT"); save_table_to_txt("duct_table.txt", tables->duct, "DUCT");
// save_temperature_int_one_line("duct_table.txt", tables->duct, "DUCT");
// Сохраняем INCAR таблицу // Сохраняем INCAR таблицу
save_table_to_c_file("incar_table_array.c", tables->incar, "INCAR", "incar_lookup_table"); save_table_to_c_file("incar_table_array.c", tables->incar, "INCAR", "incar_lookup_table");

View File

@ -482,75 +482,93 @@ void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg) {
float max_resistance = table[0].r_nom; // Максимальное сопротивление (мин. температура) float max_resistance = table[0].r_nom; // Максимальное сопротивление (мин. температура)
float min_resistance = table[table_size - 1].r_nom; // Минимальное сопротивление (макс. температура) float min_resistance = table[table_size - 1].r_nom; // Минимальное сопротивление (макс. температура)
// Ищем минимальное ADC, при котором сопротивление <= max_resistance // Ищем минимальное ADC, при котором сопротивление >= max_resistance (низкая температура)
for (uint16_t adc = 1; adc < ADC_MAX; adc++) { // При ADC=0 напряжение на NTC минимально, сопротивление минимально, температура максимальна
// При ADC=max напряжение максимально, сопротивление максимально, температура минимальна
min_valid_adc = 0;
for (uint16_t adc = 0; adc < ADC_MAX; adc++) {
float resistance = calculate_resistance(adc, r1); float resistance = calculate_resistance(adc, r1);
if (resistance <= max_resistance && !isinf(resistance)) { if (resistance >= max_resistance && !isinf(resistance) && resistance > 0) {
min_valid_adc = adc; min_valid_adc = adc;
break; break;
} }
} }
// Ищем максимальное ADC, при котором сопротивление >= min_resistance // Ищем максимальное ADC, при котором сопротивление <= min_resistance (высокая температура)
max_valid_adc = (uint16_t)(ADC_MAX - 1);
for (uint16_t adc = (uint16_t)(ADC_MAX - 1); adc > 0; adc--) { for (uint16_t adc = (uint16_t)(ADC_MAX - 1); adc > 0; adc--) {
float resistance = calculate_resistance(adc, r1); float resistance = calculate_resistance(adc, r1);
if (resistance >= min_resistance && resistance < INFINITY) { if (resistance <= min_resistance && !isinf(resistance) && resistance > 0) {
max_valid_adc = adc; max_valid_adc = adc;
break; break;
} }
} }
printf("DEBUG: %s - min_valid_adc=%u, max_valid_adc=%u\n", // Корректировка: min_valid_adc - начало диапазона низких температур (высокое сопротивление)
// max_valid_adc - конец диапазона высоких температур (низкое сопротивление)
if (min_valid_adc < max_valid_adc) {
uint16_t temp = min_valid_adc;
min_valid_adc = max_valid_adc;
max_valid_adc = temp;
}
printf("DEBUG: %s - min_temp_adc=%u (low temp), max_temp_adc=%u (high temp)\n",
table_type == TABLE_DUCT ? "DUCT" : (table_type == TABLE_INCAR ? "INCAR" : "AMBIENT"), table_type == TABLE_DUCT ? "DUCT" : (table_type == TABLE_INCAR ? "INCAR" : "AMBIENT"),
min_valid_adc, max_valid_adc); min_valid_adc, max_valid_adc);
// Заполняем таблицу // Заполняем таблицу - теперь ADC растет от 0 до MAX
uint32_t adc_step = ((uint32_t)(ADC_MAX - 1) * 1000) / (TABLE_SIZE_LOOKUP - 1); // При ADC=0: минимальное сопротивление, максимальная температура
uint32_t current_adc = 0; // При ADC=MAX: максимальное сопротивление, минимальная температура
uint16_t prev_adc = 0;
for (uint16_t i = 0; i < TABLE_SIZE_LOOKUP; i++) { for (uint16_t i = 0; i < TABLE_SIZE_LOOKUP; i++) {
uint16_t adc; uint16_t adc = i; // Просто индекс = ADC (0...4095)
float resistance; float resistance;
float temp; float temp;
// Определяем ADC для текущей записи
if (i == 0) {
adc = 0;
} else if (i == TABLE_SIZE_LOOKUP - 1) {
adc = (uint16_t)(ADC_MAX - 1);
} else {
current_adc += adc_step;
adc = (uint16_t)(current_adc / 1000);
if (adc <= prev_adc) adc = prev_adc + 1;
if (adc >= (uint16_t)(ADC_MAX - 1)) adc = (uint16_t)(ADC_MAX - 2);
}
// Расчет сопротивления и температуры в зависимости от зоны // Расчет сопротивления и температуры в зависимости от зоны
if (adc <= min_valid_adc) { if (adc >= min_valid_adc) {
// Зона низких ADC (высокая температура) - насыщение // Зона высоких ADC (низкая температура, высокое сопротивление) - насыщение
resistance = min_resistance;
temp = (float)end_temp; // Максимальная температура (+85°C)
}
else if (adc >= max_valid_adc) {
// Зона высоких ADC (низкая температура) - насыщение
resistance = max_resistance; resistance = max_resistance;
if (resistance > 10000000.0f) resistance = 10000000.0f;
temp = (float)start_temp; // Минимальная температура (-40°C) temp = (float)start_temp; // Минимальная температура (-40°C)
} }
else if (adc <= max_valid_adc) {
// Зона низких ADC (высокая температура, низкое сопротивление) - насыщение
resistance = min_resistance;
if (resistance < 1.0f) resistance = 1.0f;
temp = (float)end_temp; // Максимальная температура (85°C или 150°C)
}
else { else {
// Рабочая зона - нормальный расчет // Рабочая зона - нормальный расчет
resistance = calculate_resistance(adc, r1); resistance = calculate_resistance(adc, r1);
if (isinf(resistance) || resistance <= 0.0f) { // Дополнительные проверки сопротивления
temp = (float)start_temp - 10.0f; if (isinf(resistance)) {
} else { resistance = max_resistance;
temp = (float)start_temp;
goto fill_entry;
}
if (resistance <= 0.0f) {
resistance = min_resistance;
if (resistance < 1.0f) resistance = 1.0f;
temp = (float)end_temp;
goto fill_entry;
}
// Ограничиваем сопротивления физическими пределами
if (resistance < 1.0f) resistance = 1.0f;
if (resistance > 10000000.0f) resistance = 10000000.0f;
// Поиск температуры
int index = find_interval_index(resistance, table, table_size); int index = find_interval_index(resistance, table, table_size);
if (index < 0 || index >= table_size - 1) { if (index < 0 || index >= table_size - 1) {
if (resistance >= table[0].r_nom) { if (resistance >= table[0].r_nom) {
temp = (float)start_temp; temp = (float)start_temp;
resistance = max_resistance;
} else if (resistance <= table[table_size - 1].r_nom) { } else if (resistance <= table[table_size - 1].r_nom) {
temp = (float)end_temp; temp = (float)end_temp;
resistance = min_resistance;
} else { } else {
temp = 25.0f; temp = 25.0f;
} }
@ -562,11 +580,15 @@ void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg) {
} else { } else {
temp = interpolate_log_linear(resistance, index, table); temp = interpolate_log_linear(resistance, index, table);
} }
}
// Проверяем полученную температуру на реалистичность
if (temp < (float)start_temp - 5.0f) temp = (float)start_temp;
if (temp > (float)end_temp + 5.0f) temp = (float)end_temp;
} }
} }
// Заполняем запись fill_entry:
// Заполняем запись - теперь ADC=i
fast_table[i].adc_value = adc; fast_table[i].adc_value = adc;
fast_table[i].temp_c = (int16_t)(temp * 10.0f); fast_table[i].temp_c = (int16_t)(temp * 10.0f);
fast_table[i].resistance_ohm = resistance; fast_table[i].resistance_ohm = resistance;
@ -574,8 +596,6 @@ void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg) {
fast_table[i].v_ntc_mv = (adc * VREF_MV) / ADC_MAX; fast_table[i].v_ntc_mv = (adc * VREF_MV) / ADC_MAX;
fast_table[i].v_r1_mv = VCC_DIVIDER_MV - fast_table[i].v_ntc_mv; fast_table[i].v_r1_mv = VCC_DIVIDER_MV - fast_table[i].v_ntc_mv;
fast_table[i].table_type = table_type; fast_table[i].table_type = table_type;
prev_adc = adc;
} }
// Устанавливаем флаг инициализации // Устанавливаем флаг инициализации
@ -588,6 +608,7 @@ void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg) {
} }
} }
// Инициализация таблицы Duct // Инициализация таблицы Duct
void init_duct_table(float r1, eAlg use_alg) { void init_duct_table(float r1, eAlg use_alg) {
init_fast_lookup_table(TABLE_DUCT, r1, use_alg); init_fast_lookup_table(TABLE_DUCT, r1, use_alg);