Скетч для холодильника

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Ребят зацените

Имеем Arduino Pro mini, три релюшки, два DS18B20, LCD экран и кучу проводов.

Задача - навернулся модуль управления холодильником, нужно привести в рабочее состояние.

Скетч управления холодильником с функцией NoFrost (автоматическая оттайка)

#include <Wire.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);// set the LCD address to 0x27 for a 16 chars and 2 line display

#define TEMP_WIRE_BUS 2
OneWire tempWire(TEMP_WIRE_BUS); //объявили переменную датчиков
DallasTemperature TempSensors(&tempWire); //объявили структуру типа Даллас термометр
DeviceAddress coolThermometer = {
0x28, 0xFF, 0x23, 0xFC, 0x43, 0x16, 0x03, 0xEC }; датчик на тэне оттайки
DeviceAddress tenThermometer = {
0x28, 0xFF, 0xC0, 0xC6, 0x43, 0x16, 0x04, 0xA8 };  датчик в морозилке
// define variables
float tempSensor[2]; // массив куда читается температура c датчиков. 
byte qty; // количество градусников на шине. 
byte gradus[8] = {
  0b00110,
  0b01001,
  0b01001,
  0b00110,
  0b00000,
  0b00000,
  0b00000,
  0b00000
}; // символ градуса
//////////////////////////////////////////////////////////////////
//про холодильник
#define ReleCompr 4  // реле компрессора
#define ReleFun 5 // реле вентилятора
#define ReleTen 6 // реле оттайки
#define LedAlarm 13 //пин тревоги // не задействовал пока

// /////////////////////////////////////////////////////////////////
void getTemp(){ // читаем температуру и заполняем массив
  TempSensors.requestTemperatures(); //команда сенсорам заполнить свою память новыми данными
  tempSensor[0] = TempSensors.getTempC(coolThermometer); 
   tempSensor[1] = TempSensors.getTempC(tenThermometer); 
  /*
   for (int i = 0; i < qty; i++) tempSensor[i] = TempSensors.getTempCByIndex(i);//в цикле заполняем массив полученными данными, уже приведенными к градусам Цельсия.
   */
}
// /////////////////////////////////////////////////////////////////
// пороговые значения температуры
float tempC;
float t1 = -11.0; //порог выключения компрессора
float t2 = -9.0; // порог включения компрессора
float t3 = -05.0;    //порог выключения оттайки
float t4 = 02.0; //порог включения оттайки
// /////////////////////////////////////////////////////////////////
// вкл выкл компрессора
void DoCompr()
{
  digitalWrite(ReleCompr, LOW);
  }
void NoCompr()
{
  digitalWrite(ReleCompr, HIGH);
  }
void DoFun()  // вкл выкл вентилятора в морозилке
{
  digitalWrite(ReleFun, LOW);
 }
void NoFun()
{
  digitalWrite(ReleFun, HIGH);
  }
void DoTen()   // вкл выкл тэна оттайки
{
  digitalWrite(ReleTen, LOW);
 }
void NoTen()
{
  digitalWrite(ReleTen, HIGH);
  }
void printData(){
  /////// вывод инфы на экран
        lcd.setCursor(0, 0);
        lcd.print("Temp1: ");
        lcd.print(tempSensor[0]);  // показываем температуру с датчика
        lcd.print("C");
        lcd.setCursor(0, 1);
        lcd.print("Temp2: "); 
        lcd.print(tempSensor[1]);
        lcd.print("C");
        delay(2000); //2 сек пауза
    
}
// /////////////////////////////////////////////////////////////////

// ////////////////////////////////////////////////////////////////////
void setup() {
  pinMode(ReleCompr, OUTPUT);
    pinMode(ReleFun, OUTPUT);
    pinMode(ReleTen, OUTPUT);
    TempSensors.begin(); //инициализируем сенсоры
  lcd.init();
  lcd.backlight();
   Serial.begin(9600);//инициализируем серийный порт
}
// //////////////////////////////////////////////////////////////////

// /////////////////////////////////////////////////////////////////
void loop() {
  getTemp(); // читаем температуру с датчиков
  lcd.clear();//очистили экран от предыдущего вывода
  printData();//печатаем данные
  if(tempSensor[0] > t2) {
    if(ReleTen, LOW) {
      NoCompr();
    }
    else {
    DoCompr();
    DoFun();
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Compr ON");
    }
  }
  if(tempSensor[0] < t1) {
    NoCompr();
    NoFun();
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Compr OFF");
  }
  if(tempSensor[1] < t3) {
    DoTen();
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Ten ON");
  }
  if(tempSensor[1] > t4) {
    NoTen();
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Ten OFF");
      }
     }
// ///////////////////////////////////////////////

 

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Все таки код хромает... Не могу никак при включении оттайки (DoTen) по сигналу датчика 2 не включать реле компрессора (DoCompr) по сигналу датчика 1.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Не только код, но и алгоритм. Одтайку надо производить регулярно по времени. И мерять температуру там не надо.

http://refer.lt/ustrojstvo-xolodilnikov/

От СИСТЕМА УПРАВЛЕНИЯ АВТОМАТИЧЕСКОЙ ОТТАЙКОЙ ХОЛОДИЛЬНИКОВ NO FROST и дальше

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Эту статью я видел. Вы не видели другие статьи (к сожалению не смог сейчас найти для обозрения примера). Есть много разных способов запустить функцию оттайки. Разные производители используют разные алгоритмы. В моем случае второй датчик требуется для фиксации увеличения температуры достижения выключения компрессора. Т.е. в нормальном состоянии разница между двумя датчиками составляет 6 градусов. Датчик на рефрежераторе показывает -13 С, в это время датчик в морозилке должен показать - 7 С, происходить просто выключение компрессора. Если на рефрежераторе образуется шуба, то для достижения в морозилке - 7 С , рефрежератор должен "нагреться" до - 14 С, происходит включения тена для сброса шубы. Это тоже вариант запуска NoFrost  в холодильниках Whirpool.

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Да и влюбом случае при достижении определенного момента (достижения времени включения оттайки) должна включиться какая то функция (в нашем случае оттайка тэном) и игнорироваться другая функция, которая тоже хочет в это же время включиться (включение компрессора по времени). 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

А зачем усложнять алгоритм. Вам же надо просто сделать холодильник а не заниматься проверкой новых веяний.

1 измерить температуру в холодильнике

2 если температура высока, то включить компресор на 1 минуту и разморозку на 10 секунд(после когда компрессор уже отключили)

3 перейти к пункту 1.

ПС: Подобрав в ручную длительность времени работы компрессора и времени разморозки, можно легко получить простую рабочую программу, которую и отлаживать просто.

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

В смысле? все время включать оттайку после работы компрессора?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну да. Такая простая идея обычно не всегда доходит.

Вам же надо не только охладить, но и убрать воду. Точнее в воздухе всегда есть влажность. И с понимажением температуры она выпадает в виде воды или инея. А так как охладитель во время работы и есть такое самое холодное место, то на нем и выпадает все. Так что после работы компресора , на охладителе и остается шуба. Вот ее , а точнее поверхность шубы охладитель нагревают. Что бы снизить сцепление. А дальше под своим весом все падает вниз.  Но по любому надо периодически холодильник размораживать. Так как облединеет и стенки самой камеры. А вот их нагревателями убирать не получится.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

qwone пишет:

ПС: Подобрав в ручную длительность времени работы компрессора и времени разморозки, можно легко получить простую рабочую программу, которую и отлаживать просто.

компрессор фигачит, пока не наберёт необходимую температуру. продвинутые версии контроллеров холодильников выдадут тебе аварийный код ошибки и отключат холодильник, если необходимая температура не набирается за оптимальный период времени - что там вручную подбирать, не понятно.

частота разморозки обусловлена предполагаемым количеством намороженного на радиаторе льда, а не выключением компрессора.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Клапауций 234 пишет:

частота разморозки обусловлена предполагаемым количеством намороженного на радиаторе льда, а не выключением компрессора.

Без комментариев. Верной дорогой идете туда товарищи, но мне туда не надо.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

qwone пишет:

Без комментариев. Верной дорогой идете туда товарищи, но мне туда не надо.

ты нормальный чел? - я тебе пересказал принцип работы своего холодильника.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

qwone пишет:

Ну да. Такая простая идея обычно не всегда доходит.

Вам же надо не только охладить, но и убрать воду. Точнее в воздухе всегда есть влажность. И с понимажением температуры она выпадает в виде воды или инея. А так как охладитель во время работы и есть такое самое холодное место, то на нем и выпадает все. Так что после работы компресора , на охладителе и остается шуба. Вот ее , а точнее поверхность шубы охладитель нагревают. Что бы снизить сцепление. А дальше под своим весом все падает вниз.  Но по любому надо периодически холодильник размораживать. Так как облединеет и стенки самой камеры. А вот их нагревателями убирать не получится.

qwone, ты рассказываешь о старых моделях холодильников - в современных отсутствуют обледеневающие стенки камеры. стенки камер хранения пластмассовые, холодный воздух из охладающего блока холодильника гонится вентилляторами в плюсовую и мородильные камеры, радиатор охлаждения выглядит так и расположен в закрытом техническом отсеке

148d0bca4798.jpg

Stas046
Offline
Зарегистрирован: 10.12.2014

У родителей в стареньком холодильнике трудится тинька 13-я, взамен сдохнувшего мехтаймера. Тупо таймер, работает 3 или 4 года, полет нормальный. Единственно, если память не изменяет, при отключении питания сохраняется состояние таймера.

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Диалоги ни о чем...

Ребят, выложил скетч, просто гляньте - нормально? Хочу предусмотреть запрет включения компрессора во время включения оттайки. Тупо не знаю как правильно это сделать.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Клапауций 234 пишет:

qwone, ты рассказываешь о старых моделях холодильников - в современных отсутствуют обледеневающие стенки камеры. стенки камер хранения пластмассовые, холодный воздух из охладающего блока холодильника гонится вентилляторами в плюсовую и мородильные камеры, радиатор охлаждения выглядит так и расположен в закрытом техническом отсеке

Если отсутствуют обледеневающие стенки камеры , то и обледевания нет. Ну да пласмасса очень плохой теплопроводник, чем металл. И если поверхность хладогенератора не достигает 0, то лед не образуется.  Тогда нагреватели нужны для быстрой разморозки холодитьника. То есть у холодильника 2 режима холодильник и Разморозка. Датчик температуры должен быть один, но тогда нужна кнопка-"ВКЛ РАЗМОРОЗКУ". Или нагреватели там не нужны, если холодильник не намораживает в себя лед.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

qwone пишет:

Если отсутствуют обледеневающие стенки камеры , то и обледевания нет. 

отсутствует камера в том понимани, как ты её представляешь, в современном холодильнике

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Вариант с включением оттайки после каждого включения компрессора не подходит и не рассматривается. Тупо денег жалко на эл.энергию, да и не практично это. В выложенном тобой материале о работе холодильников указано, что оттайку включает таймер через 6-8 часов после достижения минусовой температуры в камере.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Dimmm пишет:

Диалоги ни о чем...

Ребят, выложил скетч, просто гляньте - нормально? Хочу предусмотреть запрет включения компрессора во время включения оттайки. Тупо не знаю как правильно это сделать.

ну, а твой скетч о чём?

каков оригинальный алгоритм работы охлаждающей систмы твоей модели холодильника?

насколько точно ты воспроизвёл сабж?

у тебя оттайка борется с компрессором? и, кто побеждает?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Dimmm , я не знаю какой у вас холодильник, и в каком режиме он работал. Так что без знания этого я ничего не скажу. А если и вы не знаете, тода точно что бы вы напишете будет или не работать, или работь не так как задумано производителем.

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Клапауций 234 пишет:

Dimmm пишет:

Диалоги ни о чем...

Ребят, выложил скетч, просто гляньте - нормально? Хочу предусмотреть запрет включения компрессора во время включения оттайки. Тупо не знаю как правильно это сделать.

ну, а твой скетч о чём?

каков оригинальный алгоритм работы охлаждающей систмы твоей модели холодильника?

насколько точно ты воспроизвёл сабж?

у тебя оттайка борется с компрессором? и, кто побеждает?

Оригинальный алгоритм работы как описано в статье http://refer.lt/ustrojstvo-xolodilnikov/, т.е. включение оттайки по таймеру: в морозилке стало -5 С, время пошло. Прошло 4 часа - включаем тэн оттайки. Температура в камере поднялась до +1, сброс таймера, включается компрессор. Температура достигла - 5 С, запуск таймера. Прошло 4 часа, включается тэн оттайки.... и т.д.

В большинстве холодильников таймер механический и серво мотор, поворачивая сердцевину, замыкает -размыкает контаткы, в более продвинутых версиях таймер программный.

У меня включение оттайки по принцыпу, который использует Самсунг - величина ледяной шапки на радиаторе. Суть от этого не меняется. То ли включаем при достижении времени, то ли при достижении температуры.

Своим постом хотел попросить проверить скетч (все-таки холодильник, который будет работать без присмотра) и попросить совета как написать скетч, чтоб при выполнении оттайки блокировалось включение компрессора. Ведь даже при достижении времени для оттайки по таймеру, возможны потуги программы включить компрессор, который включается от температуры.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Dimmm пишет:

Своим постом хотел попросить проверить скетч (все-таки холодильник, который будет работать без присмотра) и попросить совета как написать скетч, чтоб при выполнении оттайки блокировалось включение компрессора. Ведь даже при достижении времени для оттайки по таймеру, возможны потуги программы включить компрессор, который включается от температуры.

ок. не вдаваясь в подробности технической реализаци и оригинальных или не оригинальных алгоритмов.

рекомендации по архитектуре программы управления холодильником:

- режимы работы прописать в отдельные подпрограммы.

- подпрограммы связать между собой условиями выполнения и таймерами.

*в таком случае у тебя невозможен вариант, о котором ты говоришь, когда что-то включается в то время, когда что-то работает и выполнение этих режимов практически запрещено. как так? с какого это у тебя может включиться компрессор, если работа компрессора во время оттайки не соответсвует условию запуска компресора?

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Может так

void DoCompr()
{
 if (digitalRead(ReleTen){
  digitalWrite(ReleCompr, LOW);
 }  
}
Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Сейчас я сделал так

if(tempSensor[0] > t2) {
    if(digitalRead(ReleTen) == LOW) {
      NoCompr();
      NoFun();
    }
    else {
    DoCompr();
    DoFun();
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Compr ON");
    lcd.setCursor(0, 0);
    lcd.print("Fun ON");
    }
  }

не знаю сработает ли.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Dimmm пишет:

Сейчас я сделал так

if(tempSensor[0] > t2) {
    if(digitalRead(ReleTen) == LOW) {
      NoCompr();
      NoFun();
    }
    else {
    DoCompr();
    DoFun();
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Compr ON");
    lcd.setCursor(0, 0);
    lcd.print("Fun ON");
    }
  }

не знаю сработает ли.

писец оптимальный код.

а почему не такая последовательность

lcd.clear();
lcd.print("Fun ON");
lcd.setCursor(0, 1);
lcd.print("Compr ON");

 

 

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Перед первым принтом не выставлять курсор?

я сейчас вообще по другому сделал

void DoCompr()
{
  digitalWrite(ReleCompr, LOW);
  lcd.setCursor(0, 1);
    lcd.print("Compr ON");
  }
void NoCompr()
{
  digitalWrite(ReleCompr, HIGH);
  lcd.setCursor(0, 1);
    lcd.print("Compr OFF");
  }
void DoFun()
{
  digitalWrite(ReleFun, LOW);
  lcd.setCursor(0, 0);
    lcd.print("Fun ON");
 }
void NoFun()
{
  digitalWrite(ReleFun, HIGH);
  lcd.setCursor(0, 0);
    lcd.print("Fun OFF");
  }
void DoTen()
{
  digitalWrite(ReleTen, LOW);
  lcd.setCursor(0, 0);
    lcd.print("Ten ON");
 }
void NoTen()
{
  digitalWrite(ReleTen, HIGH);
  lcd.setCursor(0, 0);
    lcd.print("Ten OFF");
  }

вывод на экран в микропрограмме поставил и далее в исполнении уже не требуется вывод 

void loop() {
  getTemp(); // читаем температуру с датчиков
   printData();//печатаем данные
  
  if(tempSensor[0] > t2) {
    if(digitalRead(ReleTen) == LOW) {
      NoCompr();
      NoFun();
    }
    else {
    DoCompr();
    DoFun();
      }
  }
  if(tempSensor[0] < t1) {
    NoCompr();
    NoFun();
      }
  if(tempSensor[1] < t3) {
    DoTen();
     }
  if(tempSensor[1] > t4) {
    NoTen();
         }
           }

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

lcd.clear(); уже выставляет курсор в верхнюю позицию.

Fun ON,Fun OFF,Ten ON,Ten OFF вообще заменяют на значки , как вы градус написали и ставят в определеную позицию. 

Ну в мобилках есть такой прием . заряд батареи . уровень связи. Так что даже lcd.clear(); не надо. Его новый знак закроет старый.

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Обнаружилась еще одна проблема.

Не знаю аппаратная или программная. 

Короче код работает. Холодильник отработал примерно часа 2,5. Очередной раз выключился компрессор, и вдруг с экрана lcd  все пропало, подсветка горит, на ардуинке диод питания горит, на релюшках диоды питания горят, а на экране ничего нет. И ничего не происходит. Не включается, не выключается. после нажатия кнопки резет на ардуинке, все запускается в штатном режиме и стабильно работает. Второй раз та же ситуация через 1,5 часа. После резета опять все работает.

Что это?

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

qwone пишет:

lcd.clear(); уже выставляет курсор в верхнюю позицию.

Fun ON,Fun OFF,Ten ON,Ten OFF вообще заменяют на значки , как вы градус написали и ставят в определеную позицию. 

Ну в мобилках есть такой прием . заряд батареи . уровень связи. Так что даже lcd.clear(); не надо. Его новый знак закроет старый.

А, понял, спасибо! Соптимизирую.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Dimmm пишет:

Что это?

качественный блок питания дуино с сетевым фильтром от промышленных помех, релейные модули с опторазрязкой, алгоритм программы, корректно отрабатывающий процесс обслуживания силовых модулей холодильника после внезапного отключения питания. 

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

ну да, ну да. Хорошо, понял спасибо! Очень доходчиво. Самое главное понятно что делать.

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Вот рабочий скетч холодильника. Не могу сказать, что на 100%, но пока 8 часов - полет нормальный.

#include <Wire.h>
#include <DallasTemperature.h>
#include <OneWire.h>

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);// set the LCD address to 0x27 for a 16 chars and 2 line display

#define TEMP_WIRE_BUS 2
OneWire tempWire(TEMP_WIRE_BUS); //объявили переменную датчиков
DallasTemperature TempSensors(&tempWire); //объявили структуру типа Даллас термометр
DeviceAddress coolThermometer = {
0x28, 0xFF, 0xC0, 0xC6, 0x43, 0x16, 0x04, 0xA8 };
DeviceAddress tenThermometer = {
0x28, 0xFF, 0x23, 0xFC, 0x43, 0x16, 0x03, 0xEC };
// define variables
float tempSensor[2]; // массив куда читается температура c датчиков. 
byte qty; // количество градусников на шине. 
byte gradus[8] = {
  0b00110,
  0b01001,
  0b01001,
  0b00110,
  0b00000,
  0b00000,
  0b00000,
  0b00000
}; // символ градуса
//////////////////////////////////////////////////////////////////
//про холодильник
#define ReleCompr 4  // реле компрессора
#define ReleFun 5 // реле вентилятора
#define ReleTen 6 // реле оттайки
#define LedAlarm 13 //пин тревоги

// /////////////////////////////////////////////////////////////////
void getTemp(){ // читаем температуру и заполняем массив
  TempSensors.requestTemperatures(); //команда сенсорам заполнить свою память новыми данными
  tempSensor[0] = TempSensors.getTempC(coolThermometer);
   tempSensor[1] = TempSensors.getTempC(tenThermometer); 
  /*
   for (int i = 0; i < qty; i++) tempSensor[i] = TempSensors.getTempCByIndex(i);//в цикле заполняем массив полученными данными, уже приведенными к градусам Цельсия.
   */
}
// /////////////////////////////////////////////////////////////////
// пороговые значения температуры
float tempC;
float t1 = -6.5; //порог выключения компрессора
float t2 = -4.5; // порог включения компрессора
float t3 = -13.95;    //порог включения оттайки
float t4 = -4.0; //порог выключения оттайки
// /////////////////////////////////////////////////////////////////
// вкл выкл компрессора
void DoCompr()
{
  digitalWrite(ReleCompr, LOW);
    lcd.setCursor(0, 1);
    lcd.print("Compr ON");
  }
void NoCompr()
{
  digitalWrite(ReleCompr, HIGH);
  lcd.setCursor(0, 1);
    lcd.print("Compr OFF");
  }
void DoFun()
{
  digitalWrite(ReleFun, LOW);
  lcd.setCursor(0, 0);
    lcd.print("Fun ON");
 }
void NoFun()
{
  digitalWrite(ReleFun, HIGH);
  lcd.setCursor(0, 0);
    lcd.print("Fun OFF");
  }
void DoTen()
{
  digitalWrite(ReleTen, LOW);
  lcd.setCursor(0, 0);
    lcd.print("Ten ON");
 }
void NoTen()
{
  digitalWrite(ReleTen, HIGH);
  lcd.setCursor(0, 0);
    lcd.print("Ten OFF");
  }
void printData(){
  /////// вывод инфы на экран
        lcd.setCursor(0, 0);
        lcd.print("Temp1: ");
        lcd.print(tempSensor[0]);  // показываем температуру с датчика
        lcd.print("C");
        lcd.setCursor(0, 1);
        lcd.print("Temp2: "); // число датчиков
        lcd.print(tempSensor[1]);
        lcd.print("C");
        delay(2000); //2 сек пауза
        lcd.clear();
    
}
// /////////////////////////////////////////////////////////////////

// ////////////////////////////////////////////////////////////////////
void setup() {
  pinMode(ReleCompr, OUTPUT);
    pinMode(ReleFun, OUTPUT);
    pinMode(ReleTen, OUTPUT);
    TempSensors.begin(); //инициализируем сенсоры
  lcd.init();
  lcd.backlight();
   Serial.begin(9600);//инициализируем серийный порт
}
// //////////////////////////////////////////////////////////////////

// /////////////////////////////////////////////////////////////////
void loop() {
  getTemp(); // читаем температуру с датчиков
   printData();//печатаем данные
  
  if(tempSensor[0] > t2) {
    if(digitalRead(ReleTen) == LOW) {
      NoCompr();
      NoFun();
    }
    else {
    DoCompr();
    DoFun();
      }
  }
  if(tempSensor[0] < t1) {
    NoCompr();
    NoFun();
      }
  if(tempSensor[1] < t3) {
    DoTen();
     }
  if(tempSensor[1] > t4) {
    NoTen();
         }
         delay(1000);
    }
// ///////////////////////////////////////////////

Можно добавить задержку выключения вентилятора после выключения компрессора.

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Блин, виснет и все. Не пойму в чем дело. Все нормально работает, семь-восемь часов, все циклы в норме, вдруг раз, на произвольном месте виснет. На дисплее либо пусто, либо надпись после последнего действия. И больше ничего не делает. После нажатия кнопки резет - нормально работает. 

Serega16
Offline
Зарегистрирован: 16.09.2016

Используй wdt

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Да, эти не требуют разморозки раз в полгода, есть такое

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

а что это?

bwn
Offline
Зарегистрирован: 25.08.2014

Serega16 пишет:

Используй wdt

Все таки костыль, можно держать если сбой раз в полгода-год.
Лучше еще раз прошерстить цепи питания, добавить керамики. Собака скорее всего роется именно там.

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Всем спасибо! Совет про wdt (посмотрел что это) навел на мысль об изучении "среды" работы ардуинки. Так вот это же холодильник! Рядом компрессор с высоко индуктивной обмоткой! Просто наводка и все. Ардуинка же "голая", без защиты что называется. Плюс пуск компрессора связан с кратковременным скачком напруги в сети, а розетка то одна. Вот и происходит сбой в работе. Стало понятно что делать дальше. Спасибо!

konik180
Offline
Зарегистрирован: 07.04.2014

Dimmm пишет:

Блин, виснет и все. Не пойму в чем дело. Все нормально работает, семь-восемь часов, все циклы в норме, вдруг раз, на произвольном месте виснет. На дисплее либо пусто, либо надпись после последнего действия. И больше ничего не делает. После нажатия кнопки резет - нормально работает. 

надо проверить подтяжку на линиях SDA и SCL, если нету может зависать при выводе на LCD

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Dimmm пишет:

Всем спасибо! Совет про wdt (посмотрел что это) навел на мысль об изучении "среды" работы ардуинки. Так вот это же холодильник! Рядом компрессор с высоко индуктивной обмоткой! Просто наводка и все. Ардуинка же "голая", без защиты что называется. Плюс пуск компрессора связан с кратковременным скачком напруги в сети, а розетка то одна. Вот и происходит сбой в работе. Стало понятно что делать дальше. Спасибо!

внезапное прозрение после того, как выполнил все рекоментации... или забил на рекомендации и продолжил тупить, не взирая?..

*подключись от розетки соседней элекростанции.

Клапауций 234 пишет:

Dimmm пишет:

Что это?

качественный блок питания дуино с сетевым фильтром от промышленных помех, релейные модули с опторазрязкой, алгоритм программы, корректно отрабатывающий процесс обслуживания силовых модулей холодильника после внезапного отключения питания. 

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Клапауций 234 пишет:

Dimmm пишет:

Всем спасибо! Совет про wdt (посмотрел что это) навел на мысль об изучении "среды" работы ардуинки. Так вот это же холодильник! Рядом компрессор с высоко индуктивной обмоткой! Просто наводка и все. Ардуинка же "голая", без защиты что называется. Плюс пуск компрессора связан с кратковременным скачком напруги в сети, а розетка то одна. Вот и происходит сбой в работе. Стало понятно что делать дальше. Спасибо!

внезапное прозрение после того, как выполнил все рекоментации... или забил на рекомендации и продолжил тупить, не взирая?..

*подключись от розетки соседней элекростанции.

Клапауций 234 пишет:

Dimmm пишет:

Что это?

качественный блок питания дуино с сетевым фильтром от промышленных помех, релейные модули с опторазрязкой, алгоритм программы, корректно отрабатывающий процесс обслуживания силовых модулей холодильника после внезапного отключения питания. 

Соединил все в одно целое. Конечно воспользовался рекомендациями. Предпочитаю слушать (или читать) и пользоваться советами бывалых в этой области людей.

Спасибо!

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Dimmm пишет:

Конечно воспользовался рекомендациями. 

запости фото сетевого фильтра блока питания дуино - просто интересно, почему после установки фильтра, продолжились глюки.

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Клапауций 234 пишет:

Dimmm пишет:

Конечно воспользовался рекомендациями. 

запости фото сетевого фильтра блока питания дуино - просто интересно, почему после установки фильтра, продолжились глюки.

Завтра сделаю. К слову, с момента пропайки контактов, установки упса, выведением дуины дальше от компрессора прошло уже более суток, за это времч ни одного глюка.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Dimmm пишет:

Завтра сделаю. К слову, с момента пропайки контактов, установки упса, выведением дуины дальше от компрессора прошло уже более суток, за это времч ни одного глюка.

какого упса? зачем тебе бесперебойник на холодильнике?

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Клапауций 234 пишет:

Dimmm пишет:

Завтра сделаю. К слову, с момента пропайки контактов, установки упса, выведением дуины дальше от компрессора прошло уже более суток, за это времч ни одного глюка.

какого упса? зачем тебе бесперебойник на холодильнике?

не совсем бесперебойник, сетевой от APS.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Dimmm пишет:

не совсем бесперебойник, сетевой от APS.

ок. тогда фото не нужно - там должно быть всё в порядке.

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Скетч выше абсолютно рабочий, но все-таки требуется оттайка по времени. Никак не могу реализовать таймер. 

Задача - через 6 часов после включения, включить тэн для оттайки на 15 секунд, при этом исключить включение компрессора и вентилятора, которые включаются при определенной температуре от термодатчика. Обнулить таймер, опять с учетом температуры включать - выключать компрессор с вентилятором, снова через 6 часов включить оттайку, игнорируя компрессор и т.д.

Что не могу завязать привязать. Гляньте, кому интересно и, если можете, помогите.

#include <Wire.h>
#include <DallasTemperature.h>
#include <OneWire.h>

// дисплей 1602
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);// set the LCD address to 0x27 for a 16 chars and 2 line display

// два датчика температуры DS18B20 на пин 2
#define TEMP_WIRE_BUS 2
OneWire tempWire(TEMP_WIRE_BUS); //объявили переменную датчиков
DallasTemperature TempSensors(&tempWire); //объявили структуру типа Даллас термометр
DeviceAddress coolThermometer = {
0x28, 0xFF, 0xC0, 0xC6, 0x43, 0x16, 0x04, 0xA8 };
DeviceAddress tenThermometer = {
0x28, 0xFF, 0x23, 0xFC, 0x43, 0x16, 0x03, 0xEC };
// define variables
float tempSensor[2]; // массив куда читается температура c датчиков. 
byte qty; // количество градусников на шине. 

// счетчик
unsigned long prevMillisCompr = 0; // последний момент времени, когда вкл компрессор
unsigned long prevMillisTen = 0; // последний момент времени, когда вкл оттайка
unsigned long prevMillis = 0; // последний момент времени, когда вкл оттайка

// таймер
long OnTimeTen = 600000; // длительность работы тэна (в миллисекундах)
long OnTime = 12000; // длительность работы тэна (в миллисекундах)
//////////////////////////////////////////////////////////////////
//про холодильник
int ReleCompr = 4;  // реле компрессора
int ReleFun = 5; // реле вентилятора
int ReleTen = 6; // реле оттайки
int LedTen = 13; // свет оттайки
// /////////////////////////////////////////////////////////////////
void getTemp(){ // читаем температуру и заполняем массив
  TempSensors.requestTemperatures(); //команда сенсорам заполнить свою память новыми данными
  tempSensor[0] = TempSensors.getTempC(coolThermometer);
   tempSensor[1] = TempSensors.getTempC(tenThermometer); 
  /*
   for (int i = 0; i < qty; i++) tempSensor[i] = TempSensors.getTempCByIndex(i);//в цикле заполняем массив полученными данными, уже приведенными к градусам Цельсия.
   */
}
// /////////////////////////////////////////////////////////////////
// пороговые значения температуры
float tempC;
float t1 = -10; //порог выключения компрессора
float t2 = -8; // порог включения компрессора
float t3 = -14;    //порог включения оттайки
float t4 = -5.0; //порог выключения оттайки
// /////////////////////////////////////////////////////////////////
// работа компрессора
void ComprFun()
{
  
     }
 
void printData(){
  /////// вывод инфы на экран
        lcd.setCursor(0, 0);
        lcd.print("Temp1: ");
        lcd.print(tempSensor[0]);  // показываем температуру с датчика
        lcd.print("C");
        lcd.setCursor(0, 1);
        lcd.print("Temp2: "); // число датчиков
        lcd.print(tempSensor[1]);
        lcd.print("C");  
}
// /////////////////////////////////////////////////////////////////

// ////////////////////////////////////////////////////////////////////
void setup() {
  pinMode(ReleCompr, OUTPUT);
    pinMode(ReleFun, OUTPUT);
    pinMode(ReleTen, OUTPUT);
    pinMode(LedTen, OUTPUT);
    
  TempSensors.begin(); //инициализируем сенсоры
  lcd.init();
  lcd.backlight();
 
   Serial.begin(9600);//инициализируем серийный порт
}
// //////////////////////////////////////////////////////////////////

// /////////////////////////////////////////////////////////////////
void loop() {
    
  getTemp(); // читаем температуру с датчиков
   printData();//печатаем данные
   
  unsigned long currentMillis = millis(); // текущее время в миллисекундах   
  if(currentMillis - prevMillis >= OnTime)
  {
  digitalWrite(ReleTen, LOW);
  digitalWrite(LedTen, LOW);
 if (currentMillis - prevMillisTen >= OnTimeTen) {
  digitalWrite(ReleTen, HIGH);
  digitalWrite(LedTen, HIGH);
  prevMillisTen = currentMillis; 
   }
   prevMillis = currentMillis; 
}
    else {
   if(tempSensor[0] > t2) {
    digitalWrite(ReleCompr, LOW);
    digitalWrite(ReleFun, LOW);
        }
  if(tempSensor[0] < t1) {
   digitalWrite(ReleCompr, HIGH);
   digitalWrite(ReleFun, HIGH);
      }
        }
}
// ///////////////////////////////////////////////

 

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Dimmm пишет:

Задача - через 6 часов после включения, включить тэн для оттайки на 15 секунд, при этом исключить включение компрессора и вентилятора, которые включаются при определенной температуре от термодатчика. Обнулить таймер, опять с учетом температуры включать - выключать компрессор с вентилятором, снова через 6 часов включить оттайку, игнорируя компрессор и т.д.

таймер здесь класс титановый велосипед для delay без delay().

остальное - говорил же, как:

if (таймер) {оттайка;}

if (!оттайка) {компрессор; вентиллятор;}

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Клапауций 234 пишет:

Dimmm пишет:

Задача - через 6 часов после включения, включить тэн для оттайки на 15 секунд, при этом исключить включение компрессора и вентилятора, которые включаются при определенной температуре от термодатчика. Обнулить таймер, опять с учетом температуры включать - выключать компрессор с вентилятором, снова через 6 часов включить оттайку, игнорируя компрессор и т.д.

таймер здесь класс титановый велосипед для delay без delay().

остальное - говорил же, как:

if (таймер) {оттайка;}

if (!оттайка) {компрессор; вентиллятор;}

Спасибо! Сейчас попробую.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
/*
//#1
 компрессор            -> 4(Compr_pin) 1 вкл/0 откл
 вентилятор            -> 5(Fun_pin)   1 вкл/0 откл

DS18B20                   -> 2    (TEMP_WIRE_BUS)
  1 датчик (coolThermometer)
  2 датчик (tenThermometer)

  I2C LCD1602          GND -> GND
                      +5V -> +5V
                      SDA -> A4(SDA)
                      SCL -> A5(SCL)
 //#2
 оттайка               -> 6(Ten_pin)  1 вкл/0 откл
 светодиод оттайки     -> 13(LedTen_pin)  1 вкл/0 откл
*/
//#1
const int Compr_pin = 4; // реле компрессора
const int Fun_pin   = 5; // реле вентилятора
uint8_t Comp; // состояние реле копрессора(вентилятора) 1 вкл/0 откл
const float temp_Compr_OFF = -10; //порог выключения компрессора
const float temp_Compr_ON = -8; // порог включения компрессора

#include <Wire.h>
#include <DallasTemperature.h>
#include <OneWire.h>

#define TEMP_WIRE_BUS 2
OneWire tempWire(TEMP_WIRE_BUS); //объявили переменную датчиков
DallasTemperature TempSensors(&tempWire); //объявили структуру типа Даллас термометр
DeviceAddress coolThermometer = {
  0x28, 0xFF, 0xC0, 0xC6, 0x43, 0x16, 0x04, 0xA8
};
DeviceAddress tenThermometer = {
  0x28, 0xFF, 0x23, 0xFC, 0x43, 0x16, 0x03, 0xEC
};
float tempSensor[2]; // массив куда читается температура c датчиков.
void getTemp() {    // читаем температуру и заполняем массив
  TempSensors.requestTemperatures(); //команда сенсорам заполнить свою память новыми данными
  tempSensor[0] = TempSensors.getTempC(coolThermometer);
  tempSensor[1] = TempSensors.getTempC(tenThermometer);
}

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);// set the LCD address to 0x27 for a 16 chars and 2 line display

void printData() {   /////// вывод инфы на экран
  lcd.setCursor(0, 0);
  lcd.print("Temp1: ");
  lcd.print(tempSensor[0]);  // показываем температуру с датчика 1
  lcd.print("C");
  lcd.setCursor(0, 1);
  lcd.print("Temp2: ");
  lcd.print(tempSensor[1]);  // показываем температуру с датчика 2
  lcd.print("C");
}
//#2
const int Ten_pin   = 6; // реле оттайки
const int LedTen_pin   = 13; // свет оттайки
uint8_t Ten; // состояние реле оттайки 1 вкл/0 откл

void setup() {
  Serial.begin(9600);//инициализируем серийный порт
  //#1
  pinMode(Compr_pin, OUTPUT); // подключить ноги компрессора и вентилятора
  pinMode(Fun_pin, OUTPUT);
  digitalWrite(Compr_pin, Comp = 0); // и выключить их
  digitalWrite(Fun_pin, Comp);

  TempSensors.begin(); //инициализируем сенсоры
  lcd.backlight();
  //#2
  pinMode(Ten_pin, OUTPUT); // подключить ноги отморозки и его индикатора
  pinMode(LedTen_pin, OUTPUT);
  digitalWrite(Ten_pin, Ten = 0); // и выключить их
  digitalWrite(LedTen_pin, Ten);
}
void loop() {
  static uint32_t MILLIS = millis(); // текущее время в миллисекундах
  //#1
  getTemp(); // читаем температуру с датчиков
  printData();//печатаем данные
  if (!Ten && tempSensor[0] > temp_Compr_ON) { // если температура поднялась и нет режима разморозки
    digitalWrite(Compr_pin, Comp = 1); // и включить вентилятор и компрессор
    digitalWrite(Fun_pin, Comp);
  }
  if (tempSensor[0] < temp_Compr_OFF) {
    digitalWrite(Compr_pin, Comp = 0); // и выключить вентилятор и компрессор
    digitalWrite(Fun_pin, Comp);
  }
  //#2 oттайка  раз в 6 часов оттайка 12 сек
  static uint32_t past2 = 0; // последнее время сработки
  static uint32_t past1_2 = 0;  // последнее время начала оттайки
  if (Ten && (MILLIS - past1_2 >= 12000)) { // если прошло время разморозки 12 сек
    digitalWrite(Ten_pin, Ten = 0); // и выключить разморозку
    digitalWrite(LedTen_pin, Ten);
  }
  if (MILLIS - past2 >= 600000) { // если прошло 6 часов
    past2 = MILLIS;
    digitalWrite(Compr_pin, Comp = 0); // и выключить вентилятор и компрессор
    digitalWrite(Fun_pin, Comp);
    digitalWrite(Ten_pin, Ten = 1); // и включить разморозку
    digitalWrite(LedTen_pin, Ten);
    past1_2 = MILLIS;
  }
}

 

Барон
Offline
Зарегистрирован: 17.11.2016

Dimmm пишет:

Скетч выше абсолютно рабочий, но все-таки требуется оттайка по времени. Никак не могу реализовать таймер. 

Задача - через 6 часов после включения, включить тэн для оттайки на 15 секунд, при этом исключить включение компрессора и вентилятора, которые включаются при определенной температуре от термодатчика. 

Давно читаю ваш форум и думал зарегаться чуть позже, но увидив темку практически по моей специальности (холодильщик) решил направить в нужное русло (только по логике работы, в кодах не разбираюсь), после входа в режим оттайки, вы должны контролировать температуру на испарителе, после достижения температуры плюс 5, вы должны выключить тен, и дать несколько минут для: 1 того что бы капли стекли, 2 (эта причина, почему нельзя делать оттайку 15 сек)  дело в том, если вы будете включать и выключать компрессор (менее 5 мин. примерно) то он вскоре выйдет из строя. Это делать нельзя! 

есть еще момент: в схеме управления ТЕНом, объязательно должен стоять предохранитель (впринципе можно организовать размыкание цепи при привышении температуры более 50С, или тупо плавкую вставку) сделано это для того что бы исключить перегрев тена, если контакты реле заклинило - это защита, и игнорировать ее нельзя! Слашал что холодильники просто сгорали в прямом смысле.

еще вам нужно выяснить каким способом потдерживается температура в среднетемпературной камере (самая большая секция), там вариантов много как пример - установка воздушной заслонки, которая перепускает воздух с морозилки.

попытался на доступном языке написать, если что спрашивайте - помогу.

Dimmm
Dimmm аватар
Offline
Зарегистрирован: 07.11.2016

Ну ничего себе! Большое спасибо! Загружаю, щас глянем работоспособность.