Отказал терморегулятор в холодильнике Атлант МХМ-161-0. Купил новый, а он оказался не рабочим, очевидно бракованный. Решил сделать электронный на Ардуино. Далее, что получилось.
Терморегулятор имеет датчик температуры из терморезистора MF52-10k, по которому измеряется температура в холодильном объёме. При достижении пороговой уставки, компрессор холодильника отключается. При превышении температуры выше уставки порога отключения + дельта, компрессор включается. На экране TFT 0.96" показывается:
Общее время работы холодильника.
Температура в Вольтах и отсчётах.
Уставка порога отключения в Вольтах и отсчётах.
Коэффициент производительности компрессора.
Время работы цикла в минутах.
Время отдыха цикла в минутах.
Схема Терморегулятора
Схема собрана на Arduino Pro Mini (можно использовать любую: Arduino UNO, Arduino Nano и подобные им). Датчик температуры – терморезистор MF52-10k.
Для индикации режимов работы используется экран HL1 типа TFT 0.96" ST7735. Попутно замечу, что этот экземпляр экрана у меня какой-то неправильный. У него коды цвета зеркальные, поэтому пришлось определить нестандартные коды цвета. Если использовать такой же тип экрана, но правильный, то дополнительное определение цветов не потребуется. Попробовал использовать руссификацию этого экрана, но c этим экраном тоже что-то не пошло. Собственно, делал на том, что было . Экран подключен к Ардуино по аппаратной схеме, для быстроты работы. Напряжение питания экрана поступает через небольшой стабилизатор на +3,3 В.
По схеме: конденсаторы C1...C5 блокировочные от помех. Резисторы R2, R3 подстроечные. С помощью R2 устанавливается порог отключения копрессора. С помощью R3 можно смещать характеристику терморезистора. Терморезистор R1 включен между питанием VCC и портом измерения A0, поэтому если температура в холодильном объёме растёт, то и напряжение на измерительном порте A0 тоже растёт.
Чтобы иметь стабильное напряжение на VCC – используется стабилизатор Ардуино. Напряжение питания всего терморегулятора подаётся на контакт RAW. Это же напряжение 9 В поступает и на стабилизатор 78L05, с которого уже 5 В поступает на исполнительное реле, срабатывающее от 5 Вольт. Так сделано, чтобы разгрузить стабилизатор Ардуино и уменьшить влияние реле К1. Реле управляется через порт D3 с помощью транзистора VT1. В коллекторе транзистора VT1, кроме реле К1, включен индикаторный светодиод HL2 синего цвета (можно любой).
В качестве кнопки управления яркостью экрана использована сенсорная кнопка. У неё отсутствует дребезг сигнала на выходе и скетч упрощается. Нет надобности использовать дополнительные библиотеки.
Скетч
Ниже представлен скетч терморегулятора. Особо о нём говорить нечего. Всё и так понятно. Если есть вопросы, то спрашивайте.
Скетч и библиотеку можно скачать в подразделе Приложение.
/**********************************************************
* 2020-02-11 Mr.ALB Тренировка в программировании Ардуино
**********************************************************
* 2020-02-11 v2.0 Терморегулятор для холодильника
* Экран 0.96" TFT ST7735
* включает и выключает компрессор
* в диапазоне значений vterm...vterm_reg+vdelta,
* значения температуры условные, в Вольтах,
* с терморезистором MF52-10k,
* MF52-10k подключить к VCC и через резистор 20к к GND
* Имеется уставка для задания температуры включения
*
* Подключение дисплея аппаратно:
* TFT ST7735 ARDUINO
* GND – GND
* VCC – 3.3V
* SCL – pin13 через резистор 1-2k
* SDA – pin11 через резистор 1-2k
* RES – pin9 через резистор 1-2k
* DC – pin8 через резистор 1-2k
* CS – pin10 через резистор 1-2k
* BLK – pin7
*
* 2020-02-13 v2.1 Управление с помощью реле.
* Управляющий сигнал HIGH.
* Кнопка подсветки сенсорная TTP223
* 2020-02-17 v2.2 Расчёт производительности компрессора
* 2020-02-18 v2.3 Оптимизация кода
**********************************************************/
// Программа: Автор, Версия, Дата, Названиеchar* prog[]={"Mr.ALB ","v2.3","2020-02-18","TR-2 "};
#include<Adafruit_GFX.h>// Графическая библиотека#include<Adafruit_ST7735.h>// Библиотека для ST7735#include<SPI.h>#define TFT_CS 10 // CS#define TFT_RST 9 // RES#define TFT_DC 8 // DC
// SCL – Подключить к pin13
// SDA – Подключить к pin11
// Создание объекта tft. Аппаратное подключение
Adafruit_ST7735 tft = Adafruit_ST7735
(
TFT_CS,
TFT_DC,
TFT_RST
);
/* Определение цветов,
* значения зеркальные к значениям ST7735_COLOR */#define C_BLACK 0x0000
#define C_BLUE 0xF100
#define C_RED 0x008F
#define C_ORANGE 0x0ACF
#define C_DARKGREEN 0x0240
#define C_CYAN 0xFD60
#define C_YELLOW 0x0E7F
#define C_WHITE 0xFFFF
#define C_GRAY 0x455A
#define C_DARKGRAY 0xBCA5
#define C_LIGHTGRAY 0x99CE
#define PIN_TERM A0// Вывод для измерения температуры#define PIN_REG A1// Вывод для регулировки температуры#define PIN_OUT 3 // Вывод для включения компрессора#define BUTTON_BLK 4 // Кнопка подсветки дисплея#define PIN_BLK 6 // Вывод PWM для подсветки дисплея#define DELAY_RUN 180000 // Задержка запуска компрессора#define DELAY_CHECK 3000 // Интервал между измерениями #define DARK_LIGHT 30000 // Задержка гашения экранаuint8_t count_blk_level=1;
//При уровне подсветки blk_level==0 -подсветка выключенаuint8_t blk_level=count_blk_level*25;
boolean flag_blk=false;
uint8_t font_size=1; // Размер шрифта
/* Переменные для времени */uint32_t t1,t2,t3,t4,t_display,dt;
/* Переменные счётчика времени */byte sec_time=0,
min_time=0,
hour_time=0,
day_time=0;
/* Переменные времени работы */uint32_t t_work_stop,t_work_start,
t_work, t_rest;
byte k_work;
int term, term_old; // Переменные температуры#define SCREEN_W 160 // Ширина экрана в px#define SCREEN_H 80 // Высота экрана в pxbyte x_info=36; //Позиция вывода информацииbyte y_term=18; //Позиция вывода температурыbyte y_term_reg=y_term+18;//Позиция вывода уставкиbyte y_work=y_term_reg+21;//Позиция вывода производительностиbyte y_width=SCREEN_W-x_info;//Ширина экрана вывода информацииfloat vcc=5.0; // vcc – Напряжение VCC Ардуиноfloat vdelta=.12; // Дельта гистерезиса в Вольтахfloat vterm=0, vterm_reg=0; // Напряжение датчика и уставкиboolean flag_run=false; // Флаг управления компрессоромboolean flag_first_run=true;// Флаг первого запуска/***********************/
/* Настройка программы */
/***********************/voidsetup(void)
{
pinMode(PIN_BLK,OUTPUT); // Порт управления подсветкой экранаpinMode(PIN_OUT,OUTPUT); // Порт управления компрессоромpinMode(BUTTON_BLK,INPUT);// Порт кнопки управления подсветкой
tft.initR(INITR_MINI160x80);// Инициал. экрана 0.96" TFT ST7735
tft.setRotation(3); // Поворот экрана
// .setRotation(uint8_t r)
// где r:
// 0 – вертикально. поворот на 0°
// 1 – горизонтально. поворот на 90°
// 2 – вертикально. поворот на 180°
// 3 – горизонтально. поворот на 270°analogWrite(PIN_BLK,144); // Яркость заставки
fnZastavka(); // ЗаставкаanalogWrite(PIN_BLK,blk_level); // Яркость на начальную
fnPrintText(); // Вывод основных постоянных надписей
}
/***********************/
/* Рабочая программа */
/***********************/voidloop()
{
t1=millis(); // Текущее время работы программы в мсif(flag_first_run) //Первый запуск
{
flag_first_run=false;
t4=t1;
}
// Установка минимальной яркости через 30 секундif(t1-t_display>DARK_LIGHT)
{
t_display=t1;
count_blk_level=0;
analogWrite(PIN_BLK,3);// Минимум яркости
}
/* Счётчик времени работы */if((t1-dt)>1000) // Прошла секунда
{
fnWorkTimer
(
0,// x_time
0,// y_time
1,// font_size
C_GRAY // color
);
dt=t1;
}
// Проверка времени обновления параметровif((t1-t3)>DELAY_CHECK)
{
t3=t1;
/* Измерение температуры */
term=analogRead(PIN_TERM);
if(term!=term_old)
{
// Напряжение с датчика температуры
term=fnAnalogMeasure(PIN_TERM, 10);
vterm=(float)term*vcc/1024.0;
/* Вывод температуры на экан */
font_size=2;
tft.setTextSize(font_size);
tft.fillRect
(
x_info,
y_term,
SCREEN_W-x_info,
font_size*8*2,
C_BLACK
);
tft.setCursor(x_info, y_term);
tft.setTextColor(C_YELLOW);
if(vterm>0)tft.print("+");
// Температура в V
tft.print(vterm,3);
tft.print("V ");
tft.setTextColor(C_GRAY);
font_size=1;
tft.setTextSize(font_size);
tft.print(term);// Температура в Отсчётах
term_old=term; // Сохраняем значение/* Измерение уставки */// Напряжение по Уставке
term=fnAnalogMeasure(PIN_REG, 10);
vterm_reg=(float)term*vcc/1024.0;
/* Вывод уставки на экан */
font_size=2;
tft.setTextSize(font_size);
tft.fillRect
(
x_info,
y_term_reg,
SCREEN_W-x_info,
font_size*8,
C_BLACK
);
tft.setCursor(x_info, y_term_reg);
tft.setTextColor(C_BLUE);
if(vterm_reg>0)tft.print("+");
// Уставка температуры в V
tft.print(vterm_reg,3);
tft.print("V ");
tft.setTextColor(C_GRAY);
font_size=1;
tft.setTextSize(font_size);
tft.print(term);// Уставка в Отсчётах
}
}
/***************************************/
/* Управление компессором холодильника */
/* Включаем компрессор */if
(
vterm>vterm_reg+vdelta &&
flag_run==false&&
(t1-t4)>DELAY_RUN
)
{
// Задержка запуска (для открывания двери)
t4=t1;
flag_run=true;
digitalWrite(PIN_OUT,HIGH); //Включаем реле
t_work_start=t1; // Старт времени работы
t_rest=(t1-t_work_stop)/1000; // Время отдыха в сек
}
/* Выключаем компрессор */if(vterm<vterm_reg && flag_run==true)
{
digitalWrite(PIN_OUT,LOW);
flag_run=false;
t_work_stop=t1; // Стоп времени работы/* Выводим коэффициент производительности компрессора */
// Вычисляем коэффициент производительности компрессора
// Время работы в сек
t_work=(t_work_stop-t_work_start)/1000;
// Коэф. производительности в %
k_work=(float)t_work*100/(t_work+t_rest);
/* Раскрасим коэф. k_work по значению */if(k_work<=26) // Хорошо
tft.setTextColor(C_DARKGREEN);
if(k_work>26 && k_work<=60) // Норма
tft.setTextColor(C_CYAN);
if(k_work>60) // Плохо
tft.setTextColor(C_RED);
font_size=1;
tft.setTextSize(font_size);
tft.fillRect
(
x_info+8,
y_work,
SCREEN_W-x_info,
font_size*8,
C_BLACK
);
tft.setCursor(x_info+8, y_work);
tft.print(k_work);
tft.print("% [");
tft.print(t_work/60); // Время работы в мин
tft.print("; ");
tft.print(t_rest/60); // Время отдыха в мин
tft.print("]");
}
/* Стираем с экрана прогресс бар подсветки,
* если прошло 3 секунды
*/if((t1-t2)>DELAY_CHECK)
{
tft.fillRect(0, 9*8+2,SCREEN_W, 3, C_BLACK);
flag_blk=false;
}
// Считывание состояния кнопки подсветкиif(digitalRead(BUTTON_BLK) ==HIGH)
{ // Было нажатие кнопки подсветки
t2=t1;
count_blk_level++; // Шаг яркостиif(count_blk_level>10)
{
count_blk_level=0; // Выключаем подсветку
blk_level=3; // Минимум яркости
tft.fillRect(0, 9*8+2,SCREEN_W, 3, C_BLACK);
}
else
{
blk_level=count_blk_level*25;
//Максимальная яркостьif(blk_level == 250) blk_level=255;
}
// Установка яркостиanalogWrite(PIN_BLK,blk_level);
/* Прогресс бар яркости подсветки */uint8_t bar_step=0;
uint8_t bar_step_const=8*2;
for(uint8_t ip=0;ip<count_blk_level;ip++)
{
tft.fillRect
(
1+bar_step,
9*8+2,
bar_step_const-2,
3,
C_WHITE
);
bar_step+=bar_step_const;
}
delay(500);
}
delay(5);
}
/****************************************
* ФУНКЦИИ
****************************************/
/* Функция – Заставка */void fnZastavka()
{
fnClrScreen(); // Очистить экран
tft.setTextWrap(false);
tft.setTextColor(C_ORANGE);
font_size=2;
tft.setTextSize(font_size);
fnCenter(prog[3],font_size,1,0);
tft.print(prog[3]);
font_size=2;
tft.setTextSize(font_size);
fnCenter(prog[0],font_size,2,0);
tft.setTextColor(C_DARKGREEN);
tft.print(prog[0]);
font_size=1;
tft.setTextSize(font_size);
tft.setTextColor(C_GRAY);
fnCenter(prog[1],font_size,6,0);
tft.println(prog[1]);
fnCenter(prog[2],font_size,7,2);
tft.print(prog[2]);
delay(5200);
}
/* Функция – центрирование строки */void fnCenter(
char* string,uint8_t fntsize,uint8_t row,uint8_t offset
)
{
// Подсчёт количества символов в строкеboolean flag=true;
byte i=0;
while(string[i]!='\0')i++;
// Установка позиции вывода строки
tft.setCursor
(
(SCREEN_W-i*fntsize*6)/2+fntsize*6/2,
fntsize*8*row+offset
);
}
/* Функция стирания экрана чёрным цветом */void fnClrScreen()
{
// Очистить экран, т.е. закрасить чёрным
tft.fillScreen(C_BLACK);
// Курсор в начало экрана
tft.setCursor(0, 0);
}
/* Функция – Вывод основных надписей на экран */void fnPrintText()
{
fnClrScreen(); // Очистить экран
font_size=1;
tft.setTextSize(font_size);
tft.setTextColor(C_DARKGRAY);
/* Вывод температуры */
tft.setCursor(0, y_term+4);
tft.print("Term:");
/* Вывод уставки температуры */
tft.setCursor(0, y_term_reg+4);
tft.print("TReg:");
/* Вывод Времён цикла */
tft.setCursor(0, y_work);
tft.print("K_work:");
}
/* Функция измерения с аналогового порта
* Усредняем по n значениям
*/int fnAnalogMeasure(byte pin,byte n)
{
uint16_t p=0;
for (int i=0;i<n;i++) p+=analogRead(pin);
return p/n; // Среднее арифметическое
}
/* Функция – Вывод на экран времени работы программы */void fnWorkTimer
(
byte x_time,byte y_time,byte font_size,int color
)
{
font_size=1;
tft.setTextSize(font_size);
tft.setTextColor(color);
/* Очистка места под индикацию времени работы */
tft.fillRect
(
x_time,
y_time,
SCREEN_W/font_size*6,
font_size*8,
C_BLACK
);
tft.setCursor(x_time,y_time);
sec_time++;
if(sec_time>59) // Ограничение секунд
{
sec_time=0; // Обнуление счётчика секунд
min_time++; // Инкремент минут
}
if(min_time>59) // Ограничение минут
{
min_time=0; // Обнуление счётчика минут
hour_time++; // Инкремент часов
}
if(hour_time>24) // Ограничение часов
{
hour_time=0; // Обнуление счётчика часов
day_time++; // Инкремент дней
}
// Вывод часов и дней
// Если появились часы и дни, то выводим на экран
// а пока нет часов и дней – выводим только мин и секif(day_time>0)
{
tft.print(day_time);
tft.print(" days ");
}
if(hour_time>0)
{
if(hour_time<10)tft.print("0");
tft.print(hour_time);
tft.print(":");
}
// Вывод минут if(min_time<10)tft.print("0");
tft.print(min_time);
tft.print(":");
// Вывод секундif(sec_time<10)tft.print("0");
tft.print(sec_time);
}
Реализация
Терморегулятор выполнен в виде единого блока. В нём две платы. Первая – сам терморегулятор. Вторая плата – блок питания на 9 В. Платы установлены на одном шасси из пластика ABS, с разделяющей их перегородкой. Общие размеры устройства: 96 * 60 * 33 мм.
Напряжение питания ~220 В взято от холодильника через клеммную колодку.
Ниже на фото процесс изготовления терморегулятора.
Вначале макетирование и написание базовой программы, чтобы всё вместе как-то работало, основные узлы.
На фото видно, что подключен зуммер. Использовал его для звуковой индикации, потом эти коды из скетча удалил.
Когда программа в основном была закончена, то перешёл к изготовлению устройства на плате. Плата с односторонней металлизацией. Размеры 5 * 7 см.
Ниже на фото компоненты устройства перед сборкой.
Печатную плату не делаю, не имеет смысла.
На сенсорную кнопку вначале припаивал конденсатор 30 пФ для уменьшения чувствительности кнопки... потом его снял.
После того, как устройство собрал, то промерил токи потребления в различных режимах. Наименьший ток 26,6 мА.
Наибольший ток потребления составил 120,3 мА. Это при включенном реле, индикаторе включения компрессора и при ярком режиме экрана. После этого были внесены изменения в схему – добавил стабилизатор 78L05 для отдельного питания реле.
На фото виден уже установленный стабилизатор 78L05, слева вверху от экрана.
На этом фото стабилизатор 78L05 лучше виден.
На экране информация пока выводится без коэффициента производительности компрессора. В окончательном варианте скетча вывод информации несколько по другому.
А вот и зачинщик проекта . Наш холодильник Атлант МХМ-161-0. До момента отказа терморегулятора отработал почти 23 года. Магнитик с видами Новой Земли привёз сын из армии... там служил.
Снята крышка с отсека управления. Хорошо видно два терморегулятора. Слева – подаёт сигнал на красный светодиод, если в морозильной камере повышенная температура. Справа – отказавший терморегулятор, который отвечает за цикличность работы холодильника. Поддерживает заданную температуру в холодильном отделении. К этому терморегулятору идёт крутилка, для установки требуемой температуры в холодильном отделении.
Снят испорченный терморегулятор. К проводам подсоединён клеммник. От него идут провода ~220 В для питания собранного терморегулятора и от терморегулятора провода на управление компрессором холодильника.
Изучив внутреннее расположение частей отсека управления холодильником, нашёл очень удачное место для установки моего терморегулятора. Габариты этого места определили размеры создаваемого терморегулятора.
В это место и установил свой терморегулятор. Попутно можно заметить о попавшем в кадр кронштейне, который отключает в холодильнике освещение, если дверь закрыта. Это что-то!!! Он самый первый сломался, давно, почти сразу как купили холодильник. Пришлось его чуток переделать. Укрепить пластмассовыми распорками. Конструкция крайне плохая, посмотреть бы на того, кто это придумал . За давностью времён как-то подзабылось.
Терморегулятор включен, датчик температуры заведён в холодильное отделение через штатное отверстие задней стороны холодильника. Идёт режим ожидания или отдыха компрессора.
Терморегулятор включен. Идёт режим работы компрессора. Видно по свечению синего светодиода.
Кроме индикации текущего времени работы, на экран выводится напряжение с терморезистора и напряжение уставки порога отключения компрессора. Дополнительной строчкой ниже выводится коэффициент производительности компрессора. Он расчитывается по формуле:
K = Twork / (Twork + Trest), где
K – коэффициент производительности,
Twork – время работы компрессора,
Trest – время отдыха компрессора.
Считается, что K должен быть в диапазоне 0,2...0,6, при этом чем меньше K, тем более эффективно работает компрессор. Для лучшего восприятия вывел значения коэффициента в %. Тогда диапазон будет: 20%...60%.
Понаблюдал за работой нашего холодильника. В зависимости от того как часто открывается дверь, коэффициент был от 20% до 43%, что вполне приемлемо. Удобно по этому коэффициенту оценивать общую работу холодильника.
Ранее уже делал терморегулятор (TR-1) для холодильника. В нём использовался цифровой датчик DS1820. В этом варианте (TR-2) несколько улучшений и использую доступный и недорогой терморезистор. Можно использовать не только MF52-10k, но и любой подходящий терморезистор.