Загрузка данных


#include <DHT.h>
#include <Adafruit_Sensor.h>
#include <Servo.h>
#include <SoftwareSerial.h>

SoftwareSerial bluetooth(10, 11); // создание переменных для блютуз
Servo servo1;
DHT dht(2, DHT11); // причисление датчику пина

int currentAngle = 90; // текущее положение стрелки в градусах
String input = "";      // буфер для входящих команд по Bluetooth
// создание переменных для лимита температуры
float minTemp = 0.0;   // при 0°C -> 0°
float maxTemp = 40.0;  // при 40°C -> 180°

// корректное линейное преобразование для float значений
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) {
  if (in_max == in_min) return out_min; // защита от деления на ноль
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void setup() {
  dht.begin();            // запуск DHT
  Serial.begin(9600);     // для отладки через компьютер
  bluetooth.begin(9600);  // скорость Bluetooth-модуля
  servo1.attach(9);       // подключение серво к пину 9
  servo1.write(90);       // начальное положение (середина)
  delay(1000);
  bluetooth.println("Термометр готов"); // сообщение при старте
}

void loop() {
  // Чтение температуры
  float t = dht.readTemperature();

  // Если чтение успешно, пересчитываем угол и двигаем серво
  if (!isnan(t)) {
    // mapFloat возвращает float, округляем и приводим к int
    int angle = (int)round(mapFloat(t, minTemp, maxTemp, 0.0, 180.0));
    angle = constrain(angle, 0, 180); // защита от выхода за пределы
    currentAngle = angle;
    servo1.write(currentAngle);       // поворот сервопривода
  } 
  else {
    // При ошибке чтения оставляем предыдущий угол.
  }

  // Обработка входящих данных по Bluetooth
  // Учёт разных окончаний строк: '\n' и '\r'
  while (bluetooth.available()) {
    char c = bluetooth.read();
    if (c == '\n' || c == '\r') {
      if (input.length() > 0) {
        input.trim(); // убираем пробелы по краям

        // Команда "temp" — отправляем текущую  с 1 знак после запятой
        if (input.equalsIgnoreCase("temp")) {
          if (!isnan(t)) {
            bluetooth.print("Температура: ");
            bluetooth.print(t, 1); // формат с 1 десятичным знаком
            bluetooth.println("°C");
          } else {
            bluetooth.println("ERR_READ"); // ошибка чтения датчика
          }

        // Команда "angle" — возвращаем текущий угол
        } else if (input.equalsIgnoreCase("angle")) {
          bluetooth.println(currentAngle);

        // Команда "SET:<число>" — ручная установка угла
        } else if (input.startsWith("SET:")) {
          int manualAngle = input.substring(4).toInt();
          if (manualAngle >= 0 && manualAngle <= 180) {
            currentAngle = manualAngle;
            servo1.write(currentAngle);
            bluetooth.println("OK");
          } else {
            bluetooth.println("ERR"); // неверный диапазон
          }

        } else {
          bluetooth.println("UNKNOWN"); // неизвестная команда
        }
      }
      input = ""; // очищаем буфер после обработки
    } else {
      input += c; // накапливаем символы команды
    }
  }

  delay(100); // небольшая пауза перед следующим циклом
}