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);
}