Вольтметр, термометр с выводом параметров по RS232

Данное устройство было разработано для замены этой разработки

Примечание: Это устройство не умеет закрывать шибер при догорании твёрдого топлива.
Но это можно решить наличием 3 канала регулирования и гибкой настройкой управляющих выходов.

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

Схема устройства:

Схема устройства

Внешний вид поставляемого ПО:

ПО предоставляется на двух языках: RU и UK.

Инструкция по настройке устройства

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

Меню имеет линейную структуру, что упрощает изучение.
Для перемещения по меню необходимо нажимать кнопку «МЕНЮ».

Меню: «OUTPUT1″ — настраивает температуру срабатывания первого выхода.
в диапазоне: от 1 до 100 градусов Цельсия .

Меню: «OUTPUT2″  — настраивает температуру срабатывания второго выхода.
в диапазоне: от 1 до 100 градусов Цельсия .

Меню: «OUTPUT3″  — настраивает температуру срабатывания третьего выхода.
в диапазоне: от 1 до 100 градусов Цельсия .

Меню: «DELTA1″ — настраивает дельту 1 выхода .
Алгоритм следующий: при режиме нагрева — выход №1 подаёт лог. 1 если температура
привязанного датчика Td <= (Т1уст. — Дельта1) . И если температура Td >= T1уст. выход генерирует лог.0.

Меню: «DELTA2″ — настраивает дельту 2 выхода .
Алгоритм следующий: при режиме нагрева — выход №2 подаёт лог. 1 если температура
привязанного датчика Td <= (Т2уст. — Дельта2) . И если температура Td >= T2уст. выход генерирует лог.0.

Меню: «DELTA3″ — настраивает дельту 2 выхода .
Алгоритм следующий: при режиме нагрева — выход №3 подаёт лог. 1 если температура
привязанного датчика Td <= (Т3уст. — Дельта3) . И если температура Td >= T3уст. выход генерирует лог.0.

Внимание! Td — это датчики , которые работают в зависимости от запрограммированной логики в специальном меню (OUT TYPE) . Далее, я распишу подробнее об этом.

Меню: «OUT TYPE« — выбор алгоритма работы датчиков температуры и выходов.
Значение «0» — выходы работают в классическом режиме.
Датчик №1 управляет выходом №1 , датчик №2 управляет выходом №2, датчик №3 управляет выходом №3.

Значение «1» — выходы работают в альтернативном режиме №1.
Датчик №1 управляет выходом №1 и выходом №2 и выходом №3.
Состояние выходов зависит от настроек температуры и дельты этих выходом.
Датчики №2,3 работают как термометр , без функции термостатирования.

Значение «2» — выходы работают в альтернативном режиме №2.
Датчик №2 управляет выходом №1 и выходом №2 и выходом №3.
Состояние выходов зависит от настроек температуры и дельты этих выходов.
Датчики №1,3 работают как термометр , без функции термостатирования.

Значение «3» — выходы работают в альтернативном режиме №3.
Датчик №3 управляет выходом №1 и выходом №2 и выходом №3.
Состояние выходов зависит от настроек температуры и дельты этих выходов.
Датчики №1,2 работают как термометр , без функции термостатирования.

Значение «4» — выходы работают в альтернативном режиме №4.
Датчик №1 управляет выходом №1
Датчик №2 управляет выходом №2 и выходом №3.
Состояние выходов зависит от настроек температуры и дельты этих выходов.
Датчик №3 работает как термометр , без функции термостатирования.

 

Меню: «HEAT/COOLING» — настраивается характер работы термостата.
Значение «1» — режим охлаждения.
Значение «0» — режим нагревателя.

Меню: «VOLT LO« — настраивается нижний порог реле напряжения.

Меню: «VOLT HI« — настраивается верхний порог реле напряжения.

Меню: «OUT CTRL« — меню управления выходом общего назначения.
Также , выходом можно управлять с ПК и специальной кнопкой.
При управлении с ПК или с кнопки и если мы находимся в другом меню — выскакивает всплывающее меню , и отображается состояние выхода на несколько секунд. После, программа возвращается в прежний пункт меню.

Меню: «DOOR CTRL« — меню управления электрозамком.
Также, замком можно управлять с ПК и специальными кнопками.
При управлении с ПК или с кнопки и если мы находимся в другом меню — выскакивает всплывающее меню , и отображается состояние замка на несколько секунд. После, программа возвращается в прежний пункт меню.

Для перемещения по меню, нужно нажимать кнопку «MENU».
Кнопками «+» и «-» — набирается необходимое значение в настройках.

Внимание! С ПК можно программировать устройство. Задавать значения температуры, дельты, режима работы термостата, алгоритма и т.д.

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

К примеру:
 — в квартире 
 — в частном доме 
 — в инкубатор 
  и т.д. 

Дополнение статьи:

По просьбе трудящихся , выкладываю сюда два куска кода для обмена по RS232.
PS: Прошу только не критиковать код, особенно это касается кода приложения для ПК, опыта еще мало . Это было моё второе приложение под OS Windows. 

1) Со стороны МК. код написан на языке C.

2) Со стороны ПК код написан на C# (Си шарп).

Итак , со стороны МК:

 void rx_tx_func()   // функция обработки приема/передачи данных {   unsigned char x=0;                printf("T= %d %d %d xf8C ENDnr", temp0/10,  temp1/10, temp2/10);         printf("U= %dV nr", read_adc(0));                   printf("W nr");     // отправляем запрос данных        delay_ms(25);  // ждем пока получим           #asm("cli")                                          if (rx_buffer[x] == 'P')  // получаем настройки температуры      {          }      else if(rx_buffer[0] == 'X')  // нет данных для сохранения (ПК не хочет отправлять настройки)      {          printf("OK ARTOS! nr");// устройство подключено к ПК и синхронизировано      }      else if(rx_buffer[0] == 'D')  // ответ ПК "Данные корректны!"  Температура и время циклов      {         printf("OK ARTOS! SETTING TEMPnr");// подтверждаем что приняли ответ                         }      else if(rx_buffer[0] == 'O')  // включаем устройство      {         printf("OK ARTOS! POWER ON DEVICES nr");// подтверждаем что приняли ответ                    if(power) power=0; else power=1;      }      else if(rx_buffer[0] == 'R')  // сбрасываем / анулируем работу      {          printf("OK ARTOS! RESET DEVICES nr");// подтверждаем что приняли ответ                      flags_start=0;          }      else if(rx_buffer[0] == 'E')  // стартуем !      {         printf("OK ARTOS! START DEVICES nr");// подтверждаем что приняли ответ                     flags_start=1;      }      else if(rx_buffer[0] == 'A')      {         printf("Devices connect! nr");  //  устройство подключено к ПК!      }      else      {          printf("Devices disconnect! nr");  // ERROR устройство не подключено к ПК!      }                                                                                                                     for(x=0; x<59; x++)  rx_buffer[x] = 0;  // стираем буфер и обнуляем счетчик                                     rx_wr_index=0;                                     #asm("sei")     }

Со стороны ПК:

             public MainForm() 		{ 			// 			// The InitializeComponent() call is required for Windows Forms designer support. 			// 			InitializeComponent(); 			 			// 			// TODO: Add constructor code after the InitializeComponent() call. 			//              			StreamReader reader = new StreamReader("Config.cnf"); 			string[] mass = reader.ReadLine().Split(' '); 			baudRate = Convert.ToInt32(mass[0]);             portName = mass[1];             data_text[11] = Convert.ToInt16(mass[2]);             data_text[12] = Convert.ToInt16(mass[3]);             data_text[13] = Convert.ToInt16(mass[4]);             data_text[14] = Convert.ToInt16(mass[5]);             data_pass_code = mass[6]; // хранимый пароль             reader.Close();              if (flags_write_file == false) data_disp6 = "Test Stop!";           //textBox1.Enabled = false;          //textBox2.Enabled = false;          //textBox3.Enabled = false;          //textBox4.Enabled = false;          //textBox5.Enabled = false;          //textBox6.Enabled = false;          //textBox7.Enabled = false;          //textBox8.Enabled = false;          //textBox9.Enabled = false;          //textBox10.Enabled = false;          //textBox11.Enabled = false;          button1.Enabled = false;          //button2.Enabled = false;          //button3.Enabled = false;          //button4.Enabled = false;          button5.Enabled = false;          button6.Enabled = false;          button11.Enabled = false;           select_ = 5;           t = new Thread(PortCommunication);	//Initializes thread          t.Start();	//Starts the thread    		}   void PortCommunication() 		{ 			//Creates new port 			System.IO.Ports.SerialPort Port = new System.IO.Ports.SerialPort(); 			//Uses selected PortName and BaudRate from buffer variables, which changing in the main programm 			Port.PortName = portName; 			Port.BaudRate = Convert.ToInt32(baudRate); 			 			try{ 				Port.Open();	//Opens port 				while(true) 				{   						Port.Read(buffer, 0, buffer.Length);                          for (int i = 0; i < buffer.Length; i++)                         {                                                         if (buffer[i] == 'T' && buffer[i + 1] == '=' && buffer[i + 2] == ' ' && flags_read == 1)                             {                                 int buffer_m = Convert.ToInt16(buffer[i + 5] - 23);                                 if (buffer_m == 100)                                 {                                     data_disp0 = Convert.ToString((buffer[i + 3] - 23) + "°С");                                     data_disp1 = Convert.ToString((buffer[i + 4] + 16) + "V");                                     data_disp3 = Convert.ToString((buffer[i + 6] - 23) + "°С");                                     data_disp4 = Convert.ToString((buffer[i + 7] - 23) + "°С");                                     data_disp5 = Convert.ToString((buffer[i + 8] - 23) + "°С");                                       if ((buffer[i + 9] - 23) == 49)                                     {                                         if (++timer_ > 100)                                         {                                             this.Controls["button23"].BackColor = Color.FromName("yellow");                                             timer_ = 101;                                         }                                         timer_1 = 0;                                     }                                     else if ((buffer[i + 9] - 23) == 48)                                     {                                         timer_ = 0;                                         if (++timer_1 > 100)                                         {                                             this.Controls["button23"].BackColor = Color.FromName("grey");                                             timer_1 = 101;                                         }                                     }                                                                             if (((buffer[i + 9] - 23) & 0x10) == 0x10) data_disp7 = "TEN ON!";                                         else data_disp7 = "TEN OFF!";                                                                          if (((buffer[i + 9] - 23) & 0x04) == 0x04) data_disp2 = "";                                     else if (((buffer[i + 9] - 23) & 0x04) == 0x00) { data_disp2 = ""; }                                                                          if (((buffer[i + 9] - 23) & 0x01) == 1) end_process = true;                                     else end_process = false;                                                                           data_disp9 = Convert.ToString(buffer[i + 10] - 23);                                     data_disp10 = Convert.ToString(buffer[i + 11] - 22);                                                                         }                                 else if (buffer_m == 50)                                 {                                     data_disp0 = "ERR!";                                     data_disp3 = "---";                                     data_disp4 = "---";                                     data_disp5 = "---";                                     data_disp1 = Convert.ToString((buffer[i + 4] + 16) + "V");                                 }                                 else if (buffer_m == 49)                                 {                                     data_disp0 = "HOT!";                                     data_disp1 = Convert.ToString((buffer[i + 4] + 16) + "V");                                     data_disp3 = "---";                                     data_disp4 = "---";                                     data_disp5 = "---";                                 }                                 else                                 {                                     data_disp0 = "FERR!";                                     data_disp1 = Convert.ToString((buffer[i + 4] + 16) + "V");                                     data_disp3 = "---";                                     data_disp4 = "---";                                     data_disp5 = "---";                                 }                                     if (select_ == 5)                                 {                                     for (int x = 0; x < 15; x++) // принимаем настройки                                     {                                         data_text[x] = buffer[i + 12]-23;                                          i++;                                     }                                     data_disp2 = "Read setting OK!";                                      flags_up = 1;                                     select_ = 4;                                 }                                 flags_read = 0;                                 flags_devices = true;                             }                                                           else if (buffer[i] == 'W' && buffer[i + 1] == '=' && buffer[i + 2] == ' ')                             {                                 flags_read = 1;                                 switch (select_)                                 {                                     case 0:                                         Port.Write("O");                                          Flags_thread = 1;                                                                                  for (int x = 0; x < buffer.Length; x++)                                             buffer[x] = 0x00;                                         break;                                     case 1:                                         Port.Write("EEEEEEE");                                          Flags_thread = 1;                                                                                  for (int x = 0; x < buffer.Length; x++)                                             buffer[x] = 0x00;                                         break;                                     case 2:                                         Port.Write("RRRRRRR");                                          Flags_thread = 1;                                                                                  for (int x = 0; x < buffer.Length; x++)                                             buffer[x] = 0x00;                                         break;                                     case 3:                                             Port.Write("S"); // отправляем команду на запись настроек темп+циклы                                             for (int x = 0; x < data_text.Length; x++) // отправляем настройки                                             {                                                                                                    data_port[x] = (byte) (data_text[x]+23);                                                                                                }                                                                                                Port.Write(data_port, 0, data_port.Length);                                                                                   break;                                     case 4:                                         Port.Write("A"); // отсылаем ответ: "устройство подключено"                                            break;                                     case 5:                                           break;                                     case 6:                                         Port.Write("ooooooo"); // on light                                         select_ = 4;                                          break;                                     case 7:                                         Port.Write("fffffff"); // off light                                         select_ = 4;                                          break;                                     case 8:                                         Port.Write("nnnnnnn"); // one                                          select_ = 4;                                          break;                                     case 9:                                         Port.Write("ddddddd"); // off light                                         select_ = 4;                                         break;                                  }                                 flags_devices = true;                              }                             else if (buffer[i] == 'P' && buffer[i + 1] == 'O' && buffer[i + 2] == 'K')                             {                                 select_ = 4;                                 flags_devices = true;                             }                                                                              };                       Thread.Sleep(200);		//Thread freeses for 200 ms before the next iteration                     Flags_thread = 1;                     flags_buff = 1; 				} 				 			} 			catch(Exception ThreadAbortException /*ex*/ /*ThreadAbortException*/){	//If there is abort exception 				Port.Close();	//Closes port to avoid access and dispose problems 			  //MessageBox.Show("Ошибка СОМ порта! Пожалуйста, проверьте настройки");               flags_devices = false; 			} 		}

 

Полный проект для ПК можно взять с архива: «модификация! Основной код.rar».

Возможен также вариант модификации как прошивки так и программного обеспечения для ПК по индивидуальному заказу.

В этой теме можно оперативно получить помощь по данной разработке

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
U1 МК AVR 8-бит ATmega16 1
U2-U4 Датчик температуры DS18B20 3
U5 Линейный регулятор LM1117-N 1 На напряжение 5 Вольт
Q1 MOSFET-транзистор IRLML2402TR 1
Q2, Q3 MOSFET-транзистор AUIRL3705N 2
D1-D7 Выпрямительный диод 1N4148 7
С1, С2 Конденсатор 22 пФ 2
С3 Конденсатор 1000 пФ 1
С4-С6 Конденсатор 0.1 мкФ 4 С5 в схеме именуется дважды
С7, С7 Электролитический конденсатор 100 мкФ 2 Также именуется дважды
R1, R4, R5 Резистор 4.7 кОм 3
R2 Резистор 220 кОм 1
R3 Резистор 10 кОм 1
R6 Резистор 75 Ом 1
R7, R10, R10 Резистор 1 кОм 3
R8, R9, R9 Резистор 47 кОм 3
R11 Резистор 1 Ом 1
RV1 Переменный резистор 22 кОм 1
Х1 Кварцевый резонатор 12 МГц 1
LCD1 LCD-дисплей LM016L 1
Тактовая кнопка 6
BUZ1 Буззер 1
RL1, RL2 Реле NTE-R24-12 2
Моторизированный замок 1