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


#include <ESP32Servo.h>

// Пины сервопривода и ультразвукового датчика
#define SERVO_PIN    13
#define TRIG_PIN     12
#define ECHO_PIN     14

// Границы движения серво (0-180°, но ограничим ±30° от центра)
#define CENTER_POS    90    // центральная позиция (0° отклонения)
#define MAX_OFFSET    30    // максимальное отклонение от центра в градусах
#define MIN_ANGLE     (CENTER_POS - MAX_OFFSET)  // 60°
#define MAX_ANGLE     (CENTER_POS + MAX_OFFSET)  // 120°

// Параметры сканирования
#define SCAN_STEP      2    // шаг сканирования в градусах
#define SCAN_DELAY    50    // задержка после поворота (мс)

Servo myServo;
int currentAngle = CENTER_POS;   // текущий угол
int targetAngle = CENTER_POS;    // целевой угол (за объектом)

void setup() {
  Serial.begin(115200);
  
  // Настройка пинов ультразвукового датчика
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  
  // Подключение серво
  myServo.attach(SERVO_PIN);
  
  // Стартовая позиция — центр (90°)
  myServo.write(CENTER_POS);
  currentAngle = CENTER_POS;
  delay(500);
  
  Serial.println("Радар запущен. Начальная позиция: центр.");
  Serial.print("Диапазон движения: от ");
  Serial.print(MIN_ANGLE);
  Serial.print("° до ");
  Serial.print(MAX_ANGLE);
  Serial.println("°");
}

void loop() {
  // Поиск объекта — медленное сканирование в пределах MIN_ANGLE..MAX_ANGLE
  targetAngle = findClosestObject();
  
  // Плавно поворачиваем серво к цели
  moveToAngle(targetAngle);
  
  delay(50);
}

// Функция сканирования: возвращает угол, где обнаружен ближайший объект
int findClosestObject() {
  float minDistance = 200.0;   // максимальная дистанция (см)
  int bestAngle = CENTER_POS;
  
  // Сканируем от MIN_ANGLE до MAX_ANGLE
  for (int angle = MIN_ANGLE; angle <= MAX_ANGLE; angle += SCAN_STEP) {
    myServo.write(angle);
    delay(SCAN_DELAY);
    
    float distance = getDistance();
    
    // Если объект ближе 100 см — считаем
    if (distance > 2 && distance < 100) {
      Serial.print("Угол: ");
      Serial.print(angle);
      Serial.print("°  Расстояние: ");
      Serial.print(distance);
      Serial.println(" см");
      
      if (distance < minDistance) {
        minDistance = distance;
        bestAngle = angle;
      }
    }
  }
  
  if (minDistance < 100) {
    Serial.print("Ближайший объект найден на угле ");
    Serial.print(bestAngle);
    Serial.print("°, дистанция ");
    Serial.print(minDistance);
    Serial.println(" см");
    return bestAngle;
  } else {
    // Если ничего не найдено, остаёмся в центре
    return CENTER_POS;
  }
}

// Плавное перемещение серво к целевому углу
void moveToAngle(int target) {
  // Ограничиваем целевой угол допустимыми пределами
  target = constrain(target, MIN_ANGLE, MAX_ANGLE);
  
  // Движение с шагом 1° для плавности
  while (currentAngle != target) {
    if (currentAngle < target) currentAngle++;
    else currentAngle--;
    
    myServo.write(currentAngle);
    delay(10);
  }
}

// Измерение расстояния через HC-SR04
float getDistance() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  
  long duration = pulseIn(ECHO_PIN, HIGH, 30000); // таймаут 30 мс
  if (duration == 0) return 200.0; // нет эха
  
  float distance = duration * 0.034 / 2; // в см
  return distance;
}