<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>http://wikihandbk.com/ruwiki/index.php?action=history&amp;feed=atom&amp;title=Arduino%3A%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B%2FTemperatureControl</id>
	<title>Arduino:Примеры/TemperatureControl - История изменений</title>
	<link rel="self" type="application/atom+xml" href="http://wikihandbk.com/ruwiki/index.php?action=history&amp;feed=atom&amp;title=Arduino%3A%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B%2FTemperatureControl"/>
	<link rel="alternate" type="text/html" href="http://wikihandbk.com/ruwiki/index.php?title=Arduino:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B/TemperatureControl&amp;action=history"/>
	<updated>2026-06-24T22:06:43Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>http://wikihandbk.com/ruwiki/index.php?title=Arduino:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B/TemperatureControl&amp;diff=8496023&amp;oldid=prev</id>
		<title>EducationBot в 08:38, 8 июля 2023</title>
		<link rel="alternate" type="text/html" href="http://wikihandbk.com/ruwiki/index.php?title=Arduino:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B/TemperatureControl&amp;diff=8496023&amp;oldid=prev"/>
		<updated>2023-07-08T08:38:30Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Предыдущая версия&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Версия от 12:38, 8 июля 2023&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l315&quot;&gt;Строка 315:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 315:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;references /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;references /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{{Навигационная таблица/Портал/Arduino}}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Категория:Пример]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Категория:Пример]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Категория:Примеры]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Категория:Примеры]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Категория:Пример программирования Arduino]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Категория:Пример программирования Arduino]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Категория:Примеры программирования Arduino]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Категория:Примеры программирования Arduino]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>EducationBot</name></author>
	</entry>
	<entry>
		<id>http://wikihandbk.com/ruwiki/index.php?title=Arduino:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B/TemperatureControl&amp;diff=7673535&amp;oldid=prev</id>
		<title>EducationBot в 14:20, 14 мая 2023</title>
		<link rel="alternate" type="text/html" href="http://wikihandbk.com/ruwiki/index.php?title=Arduino:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B/TemperatureControl&amp;diff=7673535&amp;oldid=prev"/>
		<updated>2023-05-14T14:20:32Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Предыдущая версия&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Версия от 18:20, 14 мая 2023&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l9&quot;&gt;Строка 9:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 9:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Код==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Код==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;syntaxhighlight lang=&quot;c&quot; line=&quot;GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&quot; enclose=&quot;div&lt;/del&gt;&quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;syntaxhighlight lang=&quot;c&quot; line=&quot;GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS&quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;// *** Управление температурой ***&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;// *** Управление температурой ***&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>EducationBot</name></author>
	</entry>
	<entry>
		<id>http://wikihandbk.com/ruwiki/index.php?title=Arduino:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B/TemperatureControl&amp;diff=21168&amp;oldid=prev</id>
		<title>Myagkij: Замена текста — «&lt;syntaxhighlight lang=&quot;c&quot; line=&quot;GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS&quot;&gt;» на «&lt;syntaxhighlight lang=&quot;c&quot; line=&quot;GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS&quot; enclose=&quot;div&quot;&gt;»</title>
		<link rel="alternate" type="text/html" href="http://wikihandbk.com/ruwiki/index.php?title=Arduino:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B/TemperatureControl&amp;diff=21168&amp;oldid=prev"/>
		<updated>2016-12-13T23:36:31Z</updated>

		<summary type="html">&lt;p&gt;Замена текста — «&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS&amp;quot;&amp;gt;» на «&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Arduino панель перехода}}&lt;br /&gt;
{{Перевод от Сubewriter}}&lt;br /&gt;
{{Myagkij-редактор}}&lt;br /&gt;
&lt;br /&gt;
=Управление температурой&amp;lt;ref&amp;gt;[https://github.com/thijse/Arduino-CmdMessenger/blob/master/examples/TemperatureControl/TemperatureControl.ino github.com - TemperatureControl.ino]&amp;lt;/ref&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
Этот пример является расширенной версией примера [[Arduino:Примеры/ArduinoController|«Контроллер Arduino»]] и показывает, как измерять и управлять температурой в бойлере, а также выводить эту температуру на график.&lt;br /&gt;
&lt;br /&gt;
==Код==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
// *** Управление температурой ***&lt;br /&gt;
&lt;br /&gt;
// Это расширенная версия примера «Контроллер Arduino». Теперь PC &lt;br /&gt;
// отсылает на Arduino стартовую команду, а Arduino начинает измерять &lt;br /&gt;
// температуру и управлять нагревателем. Контроллер также начинает &lt;br /&gt;
// отсылать на PC данные о температуре и управлении нагревателем, а PC &lt;br /&gt;
// переводит их в график. Управление нагревателем осуществляется при &lt;br /&gt;
// помощи ползунка и библиотеки PID – с их помощью можно задать &lt;br /&gt;
// целевую температуру.&lt;br /&gt;
&lt;br /&gt;
// Если у вас нет термопары или нагревающего элемента, в этот скетч &lt;br /&gt;
// встроена симуляция бойлера. Чтобы воспользоваться ею, &lt;br /&gt;
// отключите #define REAL_HEATER&lt;br /&gt;
&lt;br /&gt;
// ПРИМЕЧАНИЕ: Если вы для загрузки библиотеки CmdMessenger &lt;br /&gt;
// использовали диспетчер пакетов, убедитесь, что у вас также &lt;br /&gt;
// подключены эти библиотеки: &lt;br /&gt;
// * PID&lt;br /&gt;
// * Adafruit_MAX31855 (в режиме симуляции не обязательна)&lt;br /&gt;
// &lt;br /&gt;
// Пакет, содержащий все эти библиотеки, можно найти тут:&lt;br /&gt;
https://github.com/thijse/Zipballs/blob/master/CmdMessenger/CmdMessenger.zip?raw=true&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;utility\HeaterSim.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
//#define REAL_HEATER;&lt;br /&gt;
#ifdef REAL_HEATER&lt;br /&gt;
#include &amp;lt;Adafruit_MAX31855.h&amp;gt;&lt;br /&gt;
#else&lt;br /&gt;
#include &amp;lt;utility\HeaterSim.h&amp;gt;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;CmdMessenger.h&amp;gt;  &lt;br /&gt;
#include &amp;lt;PID_v1.h&amp;gt;&lt;br /&gt;
#include &amp;lt;utility\\DoEvery.h&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// привязываем экземпляр класса CmdMessenger к последовательному порту:&lt;br /&gt;
CmdMessenger cmdMessenger(Serial); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
const int heaterPwmInterval        = 300; // продолжительность ШИМ-цикла &lt;br /&gt;
const int measureInterval          = 100;  // интервал между измерениями&lt;br /&gt;
&lt;br /&gt;
DoEvery tempTimer(measureInterval);&lt;br /&gt;
DoEvery pidTimer(heaterPwmInterval);&lt;br /&gt;
&lt;br /&gt;
// настройки PID:&lt;br /&gt;
double pidP                        = 1500;&lt;br /&gt;
double pidI                        = 25;&lt;br /&gt;
double pidD                        = 0;&lt;br /&gt;
&lt;br /&gt;
// контакты термопары:&lt;br /&gt;
int thermoDO                       = 3;&lt;br /&gt;
int thermoCS                       = 4;&lt;br /&gt;
int thermoCLK                      = 5;&lt;br /&gt;
&lt;br /&gt;
// контакт для реле:&lt;br /&gt;
const int switchPin                = 4;&lt;br /&gt;
&lt;br /&gt;
bool acquireData                   = false; // флаг для запуска/остановки записи логов&lt;br /&gt;
bool controlHeater 	               = false; // флаг для запуска/остановки управления нагревателем&lt;br /&gt;
&lt;br /&gt;
long startAcqMillis                = 0;&lt;br /&gt;
&lt;br /&gt;
double CurrentTemperature          = 20;    // измеренная температура&lt;br /&gt;
double goalTemperature             = 20;    // целевая температура&lt;br /&gt;
&lt;br /&gt;
bool heaterOn                      = false; // начальное состояние нагревателя &lt;br /&gt;
double heaterSteerValue            = 0;     // начальное нормализированное значение для управления нагревателем&lt;br /&gt;
&lt;br /&gt;
// инициализируем библиотеку для термопары:&lt;br /&gt;
#ifdef REAL_HEATER&lt;br /&gt;
Adafruit_MAX31855 thermocouple(thermoCLK, thermoCS, thermoDO);  &lt;br /&gt;
#else&lt;br /&gt;
HeaterSim heaterSim(20);   // нагреватель находится в месте, где окружающая температура составляет 20 градусов Цельсия&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// инициализируем библиотеку PID:&lt;br /&gt;
PID pid(&amp;amp;CurrentTemperature, &amp;amp;heaterSteerValue, &amp;amp;goalTemperature,pidP,pidI,pidD,DIRECT);&lt;br /&gt;
&lt;br /&gt;
// Это список распознаваемых команд, и эти команды могут быть &lt;br /&gt;
// либо получены, либо отправлены. Чтобы получить команду, к этому &lt;br /&gt;
// событию нужно привязать функцию внешнего вызова.&lt;br /&gt;
enum&lt;br /&gt;
{&lt;br /&gt;
  // команды:&lt;br /&gt;
  kWatchdog            , // команда, запрашивающая ID устройства&lt;br /&gt;
  kAcknowledge         , // команда, подтверждающая получение команды&lt;br /&gt;
  kError               , // команда, сообщающая об ошибках&lt;br /&gt;
  kStartLogging        , // команда, запрашивающая начать запись логов &lt;br /&gt;
  kStopLogging         , // команда, запрашивающая остановить запись логов &lt;br /&gt;
  kPlotDataPoint       , // команда, запрашивающая отображение на графике точек данных&lt;br /&gt;
  kSetGoalTemperature  , // команда, задающая целевую температуру &lt;br /&gt;
  KSetStartTime        , // команда, задающая новое начальное время для записи логов &lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// команды, отсылаемые от PC и получаемые на Arduino; в скетче Arduino &lt;br /&gt;
// нужно задать функцию внешнего вызова для каждой записи из списка ниже: &lt;br /&gt;
void attachCommandCallbacks()&lt;br /&gt;
{&lt;br /&gt;
  // подключаем функции внешнего вызова:&lt;br /&gt;
  cmdMessenger.attach(OnUnknownCommand);&lt;br /&gt;
  cmdMessenger.attach(kWatchdog, OnWatchdogRequest);&lt;br /&gt;
  cmdMessenger.attach(kStartLogging, OnStartLogging);&lt;br /&gt;
  cmdMessenger.attach(kStopLogging, OnStopLogging);&lt;br /&gt;
  cmdMessenger.attach(kSetGoalTemperature, OnSetGoalTemperature);&lt;br /&gt;
  cmdMessenger.attach(KSetStartTime, OnSetStartTime);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ------------------  ФУНКЦИИ ВНЕШНЕГО ВЫЗОВА  ----------------------&lt;br /&gt;
&lt;br /&gt;
// эта функция вызывается, когда к присланной команде не привязано никакой функции:&lt;br /&gt;
void OnUnknownCommand()&lt;br /&gt;
{&lt;br /&gt;
  cmdMessenger.sendCmd(kError,&amp;quot;Command without attached callback&amp;quot;);  //  &amp;quot;Команда без функции внешнего вызова&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void OnWatchdogRequest()&lt;br /&gt;
{&lt;br /&gt;
  // по запросу отсылаем на компьютер эти команду и идентификатор:&lt;br /&gt;
  cmdMessenger.sendCmd(kWatchdog, &amp;quot;77FAEDD5-FAC8-46BD-875E-5E9B6D44F85C&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// функция внешнего вызова, сообщающая о готовности Arduino (т.е. о ее загрузке):&lt;br /&gt;
void OnArduinoReady()&lt;br /&gt;
{&lt;br /&gt;
  cmdMessenger.sendCmd(kAcknowledge,&amp;quot;Arduino ready&amp;quot;);  //  &amp;quot;Arduino готова&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// функция для сбора данных:&lt;br /&gt;
void OnStartLogging()&lt;br /&gt;
{&lt;br /&gt;
  // начинаем сбор данных:&lt;br /&gt;
  acquireData = true;&lt;br /&gt;
  cmdMessenger.sendCmd(kAcknowledge,&amp;quot;Start Logging&amp;quot;);  //  &amp;quot;Начинаем запись логов&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// функция для остановки сбора данных:&lt;br /&gt;
void OnStopLogging()&lt;br /&gt;
{&lt;br /&gt;
  acquireData    = false;&lt;br /&gt;
  cmdMessenger.sendCmd(kAcknowledge,&amp;quot;Stop Logging&amp;quot;);  //  &amp;quot;Останавливаем запись логов&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// функция внешнего вызова, задающая целевую температуру:&lt;br /&gt;
void OnSetGoalTemperature()&lt;br /&gt;
{&lt;br /&gt;
  // считываем аргумент о состоянии светодиода, интерпретируем строку как float:&lt;br /&gt;
  float newTemperature = cmdMessenger.readBinArg&amp;lt;float&amp;gt;();&lt;br /&gt;
  &lt;br /&gt;
  // перед изменением целевой температуры убеждаемся, что аргумент корректен:&lt;br /&gt;
  if (cmdMessenger.isArgOk()) {&lt;br /&gt;
    goalTemperature = newTemperature;&lt;br /&gt;
    &lt;br /&gt;
    // включаем управление нагревателем (вначале оно отключено)&lt;br /&gt;
    controlHeater = true;  &lt;br /&gt;
  &lt;br /&gt;
    // отправляем на PC сообщение с подтверждением:&lt;br /&gt;
    cmdMessenger.sendBinCmd(kAcknowledge,goalTemperature); &lt;br /&gt;
  } else {&lt;br /&gt;
    // в присланной целевой температуре ошибка! Значит, шлем на PC сообщение об этой ошибке:&lt;br /&gt;
    cmdMessenger.sendCmd(kError,&amp;quot;Error in received new goal temperature&amp;quot;);  //  &amp;quot;В новой целевой температуре обнаружена ошибка&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// функция внешнего вызова, задающая начальное время:&lt;br /&gt;
void OnSetStartTime()&lt;br /&gt;
{&lt;br /&gt;
	// считываем аргумент о состоянии светодиода, интерпретируем строку как float:&lt;br /&gt;
	float startTime = cmdMessenger.readBinArg&amp;lt;float&amp;gt;();&lt;br /&gt;
	&lt;br /&gt;
	// перед изменением убеждаемся, что аргумент корректен:&lt;br /&gt;
	if (cmdMessenger.isArgOk()) {&lt;br /&gt;
		unsigned long milis =  millis();&lt;br /&gt;
		// транслируем секунды в миллисекунды для внутренних часов:		startAcqMillis = (unsigned long)((float)startTime*1000.0f);&lt;br /&gt;
		if (startAcqMillis &amp;gt;  milis) { startAcqMillis = milis; }&lt;br /&gt;
		startAcqMillis = milis- startAcqMillis;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ------------------ ГЛАВНАЯ ЧАСТЬ СКЕТЧА ----------------------&lt;br /&gt;
&lt;br /&gt;
// блок исходных операций:&lt;br /&gt;
void setup() &lt;br /&gt;
{&lt;br /&gt;
  // прослушиваем последовательное соединение на предмет сообщений &lt;br /&gt;
  // от PC (115200 – это, как правило, максимальная скорость для &lt;br /&gt;
  // последовательной коммуникации через USB):&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
    &lt;br /&gt;
  // многие макетные платы с bluetooth (вроде HC-05/HC-06) по &lt;br /&gt;
  // умолчанию работают на скорости 9600. Настройки, указанные ниже,&lt;br /&gt;
  // должны этому соответствовать:&lt;br /&gt;
  //Serial.begin(9600);    &lt;br /&gt;
	&lt;br /&gt;
  // в конце команды не пишем символ новой строки, чтобы сократить &lt;br /&gt;
  // размер отправляемых данных:&lt;br /&gt;
  cmdMessenger.printLfCr(false);&lt;br /&gt;
  &lt;br /&gt;
  // инициализируем таймеры:&lt;br /&gt;
  tempTimer.reset();&lt;br /&gt;
  pidTimer.reset();&lt;br /&gt;
&lt;br /&gt;
  // инициализируем переменные PID:&lt;br /&gt;
  pid.SetOutputLimits(0,heaterPwmInterval);&lt;br /&gt;
&lt;br /&gt;
  // считываем текущую температуру:&lt;br /&gt;
  #ifdef REAL_HEATER&lt;br /&gt;
	CurrentTemperature= thermocouple.readCelsius();&lt;br /&gt;
  #else&lt;br /&gt;
	CurrentTemperature = heaterSim.GetTemp();&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // подготавливаем PID-порт для записи:&lt;br /&gt;
  pinMode(switchPin, OUTPUT);  &lt;br /&gt;
&lt;br /&gt;
  // включаем PID и выставляем на автомат:&lt;br /&gt;
  pid.SetMode(AUTOMATIC);&lt;br /&gt;
&lt;br /&gt;
  // выставляем время замера:&lt;br /&gt;
  pid.SetSampleTime(measureInterval);&lt;br /&gt;
&lt;br /&gt;
  // подключаем функции внешнего вызова, заданные пользователем:&lt;br /&gt;
  attachCommandCallbacks();&lt;br /&gt;
&lt;br /&gt;
  // отсылаем на PC сообщение о загрузке Arduino:&lt;br /&gt;
  cmdMessenger.sendCmd(kAcknowledge,&amp;quot;Arduino has started!&amp;quot;);  //  &amp;quot;Arduino запущена!&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// блок повторяющихся операций:&lt;br /&gt;
void loop() &lt;br /&gt;
{&lt;br /&gt;
  // обрабатываем данные, пришедшие по последовательному соединению,&lt;br /&gt;
  // и выполняем функции внешнего вызова:&lt;br /&gt;
  cmdMessenger.feedinSerialData();&lt;br /&gt;
 &lt;br /&gt;
  // каждые 100 миллисекунд обновляем температуру:&lt;br /&gt;
  if(tempTimer.check()) measure();&lt;br /&gt;
 &lt;br /&gt;
  // обновляем таймер PID:&lt;br /&gt;
  pidTimer.check();&lt;br /&gt;
  &lt;br /&gt;
  // проверяем, управляем ли мы нагревателем: &lt;br /&gt;
  if (controlHeater) {&lt;br /&gt;
      // вычисляем новые параметры PID: &lt;br /&gt;
      pid.Compute();&lt;br /&gt;
      &lt;br /&gt;
      // управляем нагревателем при помощи широтно-импульсной модуляции:&lt;br /&gt;
      heaterPWM();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// меряем температуру в бойлере: &lt;br /&gt;
void measure() {&lt;br /&gt;
  if (acquireData) {&lt;br /&gt;
     // рассчитываем время:&lt;br /&gt;
     float seconds     = (float) (millis()-startAcqMillis) /1000.0 ;&lt;br /&gt;
     &lt;br /&gt;
     // измеряем температуру: &lt;br /&gt;
     #ifdef REAL_HEATER&lt;br /&gt;
		CurrentTemperature= thermocouple.readCelsius(); // измеряем при помощи термопары&lt;br /&gt;
     #else &lt;br /&gt;
		CurrentTemperature = heaterSim.GetTemp();       // измеряем температуру в симулированном бойлере&lt;br /&gt;
     #endif   &lt;br /&gt;
         &lt;br /&gt;
     // отправляем данные на PC:    &lt;br /&gt;
     cmdMessenger.sendCmdStart(kPlotDataPoint);  &lt;br /&gt;
     cmdMessenger.sendCmdBinArg((float)seconds);                           // время   &lt;br /&gt;
     cmdMessenger.sendCmdBinArg((float)CurrentTemperature);                // измеренная температура&lt;br /&gt;
     cmdMessenger.sendCmdBinArg((float)goalTemperature);                   // целевая температура&lt;br /&gt;
     cmdMessenger.sendCmdBinArg((float)((double)heaterSteerValue/(double)heaterPwmInterval)); // нормализированное значения для управления нагревателем&lt;br /&gt;
     cmdMessenger.sendCmdBinArg((bool)heaterOn);                        // состояние вкл/выкл во время ШИМ-цикла&lt;br /&gt;
     cmdMessenger.sendCmdEnd();    &lt;br /&gt;
  }  &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
void SetHeaterState(bool heaterOn)&lt;br /&gt;
{&lt;br /&gt;
	// включаем нагреватель, подключенный к реле на контакте switchPin:&lt;br /&gt;
	digitalWrite(switchPin,heaterOn?HIGH:LOW);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// задаем состояние нагревателя:&lt;br /&gt;
void heaterPWM()&lt;br /&gt;
{&lt;br /&gt;
  // включаем/выключаем нагреватель – в зависимости от фазы ШИМ-цикла: &lt;br /&gt;
  heaterOn = pidTimer.before(heaterSteerValue);&lt;br /&gt;
  #ifdef REAL_HEATER&lt;br /&gt;
	SetHeaterState(heaterOn);			  // включаем нагреватель бойлера&lt;br /&gt;
  #else&lt;br /&gt;
	heaterSim.SetHeaterState(heaterOn); // включаем нагреватель симулированного бойлера&lt;br /&gt;
  #endif &lt;br /&gt;
  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=См.также=&lt;br /&gt;
&lt;br /&gt;
=Внешние ссылки=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
[[Категория:Пример]]&lt;br /&gt;
[[Категория:Примеры]]&lt;br /&gt;
[[Категория:Пример программирования Arduino]]&lt;br /&gt;
[[Категория:Примеры программирования Arduino]]&lt;/div&gt;</summary>
		<author><name>Myagkij</name></author>
	</entry>
</feed>