Вложений: 1
Как точно вычислить температуру со штатного датчика двигателя?
Добрый день! Как вычислить точную температуру с термистора на двигателе? Я снял с него параметры падения напряжения с увеличением температуры - они нелинейны. Собственно, об этом говорят и графики зависимости сопротивления от температуры.
Каким образом (какой формулой) вычислить точное значение температуры в коде ардуины? Линейные приближения дают большую погрешность.
.................................................. .................................................. ...
Чтобы вам не читать все, выкладываю здесь результат.
Подключение к Ардуино ШИМ ключа и остального не рассматриваю, т.к. этого достаточно в других темах. Но если все же будет необходимость - выложу. Система будет затачиваться под мониторинг и регулировку температуры ОЖ, масла ДВС, масла АКПП, масла ГУР и может еще чего.
PHP код:
/*
Программа термоконтроля за системой охлаждения ДВС. Использует плавную регулировку по ШИМ.
Может применяться и в других проектах, где исходные данные будет выдавать термистор (терморезистор).
В качестве исходных данных - 1 проводной температурный датчик (термистор(терморезистор))
двигателя с которого берется информация на штатную приборную панель автомобиля.
Т.к. датчик имеет нелинейную зависимость сопротивления (падения напряжения),
то необходима аппроксимация по заранее известным точкам. Чем выше температура,
тем ниже сопротивление и больше падение напряжения.
Для достоверной работы программы нужно ввести значения проходящего через датчик напряжения при
различных температурах, желательно во всем диапазоне его работы.
За аппроксимацию спасибо SBorovkov.
*/
#include <MyLiquidCrystalRus.h>
#include <avr/pgmspace.h>
#define Temp1Count 10 //Количество точек аппроксимации
#define DestinationEngineTemp 90 //Определяем нужную температуру двигателя
#define EngineTempSensorPin 0 // Аналоговый вход для температурного датчика ОЖ ДВС
#define PowerVentPin 6 //ШИМ выход на вентиляторы основного радиатора ДВС
MyLiquidCrystalRus lcd(12, 11, 10, 5, 4, 3, 2); //Используем ЖК дисплей
//Задаем точки аппроксимации. Первая цифра - разность из 1024 и значения на входе от датчика
//(сделано для того чтобы развернуть график зависимости и сделать так чтобы с ростом температуры значение увеличивалось)
//не переводил в напряжение чтобы не морочиться и оперировать целыми числами с достаточной точностью;
//вторая цифра - значение температуры (заранее измеренное) при данном значении на выходе с датчика.
uint16_t Temp1[Temp1Count][2] PROGMEM = {{0,0}, {471,46}, {655,58}, {713,65}, {772,74}, {775,80}, {850,100}, {864,110}, {874, 120}, {883, 130}};
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("****************");
lcd.setCursor(0,1);
lcd.print("****************");
delay(1000);
}
void loop() {
int i;
int Count = 10; //Количество значений для усреднения
int In = 0; //Начальная точка суммирования
int InSrednee; //Усредненное значение со входа
int PowerAir; //Мощность вентиляторов
uint16_t InTemp; //Входное значение с датчика температуры
uint16_t RealTemp; //Расчетное значение реальной температуры
uint16_t InLeftTemp;
//Начало цикла усреднения значения
for (i = 0; i < Count; i++) {
In = In + analogRead(EngineTempSensorPin);
}
//Конец цикла усреднения значения
InSrednee = In / Count; //Вычисляем среднее значение
InTemp = 1024 - InSrednee; //Переворачиваем график падения напряжения
i=Temp1Count;
do
{
i--;
InLeftTemp=pgm_read_word(&Temp1[i][0]);
}
while ((i>=0)&&(InTemp<InLeftTemp));
uint16_t InRightTemp=pgm_read_word(&Temp1[i+1][0]);
uint16_t OutLeftTemp=pgm_read_word(&Temp1[i][1]);
uint16_t OutRightTemp=pgm_read_word(&Temp1[i+1][1]);
RealTemp=OutLeftTemp+(OutRightTemp-OutLeftTemp)*(InTemp-InLeftTemp)/(InRightTemp-InLeftTemp); //Вычисление значения реальной температуры
float VoltIn = (5.00 / 1024.00 * InSrednee); //Переводим входные данные к абсолютному значению напряжения для мониторинга
//Если температура входит в определнные значения - запускаем вентиляторы на определенную мощность.
if (RealTemp >= DestinationEngineTemp - 5 && RealTemp < DestinationEngineTemp + 1) PowerAir = 255 - 42.50 * (DestinationEngineTemp - RealTemp + 1);
else if (RealTemp >= DestinationEngineTemp + 1) PowerAir = 255;
else PowerAir = 0;
analogWrite (PowerVentPin, PowerAir); //Запускаем выход ШИМ на необходимую мощность
int PowerVentPercent = 100.00/255.00*PowerAir; //Вычисляем значение в процентах текущей мощности вентиляторов
//Выводим все что нам нужно на ЖК дисплей
lcd.clear();
lcd.setCursor(0,0);
lcd.print("ВЛТ:");
lcd.setCursor(4,0);
lcd.print(VoltIn); //Входное напряжение с датчика
lcd.setCursor(8,0);
if (VoltIn > 2.70) {
lcd.print(" ТМП:");
lcd.setCursor(13,0);
lcd.print("MIN"); //Ниже минимальной точки аппроксимации
}
else if (VoltIn < 0.85){
lcd.print(" ТМП:");
lcd.setCursor(13,0);
lcd.print("MAX"); //Выше максимальной точки аппроксимации
}
else {
lcd.print(" ТМП:");
lcd.setCursor(13,0);
lcd.print(RealTemp); //Аппроксимированная температура
}
lcd.setCursor(0,1);
lcd.print("МОЩНОСТЬ:");
lcd.setCursor(9,1);
lcd.print(PowerVentPercent); //Мощность вентиляторов
lcd.print("%");
delay(250);
}
Код буду постепенно совершенствовать и увеличивать функционал.
Re: Как точно вычислить температуру со штатного датчика двигателя?
Лучше всего сделать таблицу из нескольких замеров.
Re: Как точно вычислить температуру со штатного датчика двигателя?
Я думал об этом. Но во первых не хотелось бы раздувать код ардуины подобной матрицой значений, а во вторых нет возможности охладить датчик до тех же -20. Как то проще должно быть по моим ощущениям.
Re: Как точно вычислить температуру со штатного датчика двигателя?
скорее всего, в самом блоке управления двигателем используется кусочно-линейная аппроксимация. То есть берется график зависимости напряжения от температуры, затем он заменяется на ломанную (от количества значений и их выбора зависит точность). Кода - 5 строчек на С (поиск нужного отрезка ломанной+вычисление значения), ломанную хранить - два байта на точку (температура и напряжение), хранить лучше прямо в flash памяти. Займет все это очень немного в результате.
Да, советую использовать целочисленные операции, будет и меньше памяти занимать и работать быстрее.
Re: Как точно вычислить температуру со штатного датчика двигателя?
Можно аппроксимировать экспонентой.
Re: Как точно вычислить температуру со штатного датчика двигателя?
Соглсен, неплохой метод с точки зрения облегчения математики и программного кода.. Но опять же нужно сделать все замеры и в т.ч. при отрицательных температурах, что не совсем удобно в домашних условиях. Я нашел небольшую статью, проливающую свет на математическое моделирования зависимости:
http://www.kit-e.ru/articles/elcomp/2007_6_32.php
Буду сегодня пробовать... Отпишусь о результатах чуть позже.
Re: Как точно вычислить температуру со штатного датчика двигателя?
По статье что я обозначил выше, результаты неплохие, но все равно расходятся с фактически измеренной кривой. По этой формуле вполне можно аппроксимировать определенные диапазоны. Разве так работают "мозги" машин? Что у них заложена какая-то аппроксимация изначально???
И так ли работают "гаджеты" что ставятся отдельно? И у них аппроксимация?
Конечно можно пойти путем инсталляции цифрового датчика типа DS1820 или аналогового типа LM335, но у полупроводников ограничение 120-125 градусов. А мне нужно увидеть температуры выше, если речь пойдет о температуре масла, воздуха из турбины или температуре выхлопных газов.. В последнем случае будет стоять датчик до 900-1000 градусов.
Вложений: 1
Re: Как точно вычислить температуру со штатного датчика двигателя?
Вот графики:
Верхний - реальные замеры с датчика;
Нижний - построение по формуле из статьи с опорным значением на 46 градусах.
Как видно что очень похоже на правду, но чем дальше от опорной температуры - тем больше разбег, поэтому однозначно нужно бить на отрезки и аппроксимировать.
Re: Как точно вычислить температуру со штатного датчика двигателя?
Зачем бить на отрезки? В статье же все черным по белому, всего 1 коэффициент надо найти.
Re: Как точно вычислить температуру со штатного датчика двигателя?
Ну конечно я нашел... еще раз повторюсь, что расчетные отличается от реальных значений.