#include <Servo.h> // подключение библиотеки Servo
Servo myServo; // создание объекта библиотеки Servo с именем myServo
const int PIN_SERVO = 9; // константа пин 9 подключен к сервоприводу
const int PIN_TEMP = A0; // константа пин A0 подключен к датчику температуры
const int PIN_BTN = 2; // константа пин 2 подключен к кнопке
// Параметры NTC и калибровка
const float R_SERIES = 10000.0; // сопротивление подтягивающего резистора, 10 кОм
const float R0 = 10000.0; // номинальное сопротивление NTC при 25°C, 10 кОм
const float B = 3950.0; // B‑коэффициент термистора
const float T0 = 25.0 + 273.15; // T0 в Кельвинах (25°C)
// Диапазон температур и углов поворота сервопривода
const float T_MIN = -24.0; // при -24°C угол поворота 0°
const float T_MAX = 80.0; // при +80°C угол поворота 90°
const int ANGLE_MIN = 0; // минимальный угол поворота 0°
const int ANGLE_MAX = 90; // максимальный угол поворота 90°
void setup() {
Serial.begin(9600); // инициализация последовательного порта
myServo.attach(PIN_SERVO); // подключение сервопривода к назначенному пину
pinMode(PIN_BTN, INPUT_PULLUP); // настройка пин 2 как входа с включенным внутренним подтягивающим резистором
myServo.write(0); // начальный угол поворота сервопривода 0°
}
void loop() {
// Проверка кнопки
if (digitalRead(PIN_BTN) == LOW) { // проверка нажатия кнопки
delay(50); // задержка для подавления дребезга контактов
if (digitalRead(PIN_BTN) == LOW) { // повторная проверка нажатия (если LOW — считаем нажатие подтверждённым)
myServo.write(0); // поворот сервопривода в положение 0°
Serial.println("Сброс угла поворота серводвигателя на 0° "); // вывод сообщения "Сброс угла поворота серводвигателя на 0° "
Serial.println("Для возвращения в рабочий режим отпустите кнопку"); // вывод сообщения "Для возвращения в рабочий режим отпустите кнопку"
while (digitalRead(PIN_BTN) == LOW); // ожидание отпускания кнопки
}
}
int raw = analogRead(PIN_TEMP); // считывание аналогового значение (0–1023) с пина A0
float tempC = readTemperature(raw); // преобразование аналогового значения в температуру в °C
float tClamped = constrain(tempC, T_MIN, T_MAX); // ограничение температуры диапазоном T_MIN, T_MAX
// Линейное преобразование температуры в угол
float angle = mapFloat(tClamped, T_MIN, T_MAX, ANGLE_MIN, ANGLE_MAX); // преобразование температуры в нужный угол
int angleInt = (int)angle; // округление угла до целого числа
myServo.write(angleInt); // поворот сервопривода на рассчитанный угол
Serial.print("Температура: "); // вывод заголовка "Температура"
Serial.print(tempC); // текущая температура
Serial.print(" °C, Угол поворота серводвигателя: "); // вывод заголовка "Угол поворота серводвигателя"
Serial.print(angleInt); // угол поворота
Serial.println("° "); // вывод "°"
Serial.println("Для поворота серводвигателя на 0° нажмите и удерживайте кнопку"); // вывод заголовка "Для поворота серводвигателя на 0° нажмите и удерживайте кнопку"
delay(200); // задержка до следующего опроса (частота опроса)
}
// Расчёт температуры по термистору (уравнение Стейнхарта–Харта в упрощённой форме)
float readTemperature(int adcValue) {
float R = (float)R_SERIES * adcValue / (1023.0 - adcValue); // вычисление сопротивления термистора по значению
float lnR = log(R / R0); // вычисление натурального логарифма отношения текущего сопротивления к сопротивлению при 25 °C (R0)
float invT = (1.0 / T0) + (lnR / B); // рассчет обратной величины температуры (в кельвинах)
return (1.0 / invT) - 273.15; // перевод температуры из кельвинов в °C
}
// линейное преобразование температуры от −24 °C до 80 °C в угол поворота сервопривода от 0° до 90°
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}