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


#include <Stepper.h>
#include <math.h>

// --- Настройки шагового двигателя ---
const int stepsPerRev = 580;
// Инициализация библиотеки (Пины: 8, 9, 10, 11)
Stepper stepper(stepsPerRev, 11,10,9,8);

// --- Настройки пинов фоторезисторов ---
const int pinNorth = A5; // Север
const int pinWest  = A4; // Запад
const int pinEast  = A3; // Восток
const int pinSouth = A2; // Юг

// --- Переменные состояния ---
int currentStep = 0; // Текущее положение стрелки (от 0 до 519)
                     // При включении считаем, что стрелка смотрит на Восток (0 градусов)

void setup() {
  Serial.begin(9600);
  
  // Устанавливаем скорость вращения (об/мин). 
  // Подберите значение, подходящее для вашего мотора.
  stepper.setSpeed(100); 
}

void loop() {
  // 1. Считываем значения освещенности (от 0 до 1023)
  int valNorth = analogRead(pinNorth);
  int valWest  = analogRead(pinWest);
  int valEast  = analogRead(pinEast);
  int valSouth = analogRead(pinSouth);

  // 2. Вычисляем вектор направления света
  // Если Восток = 500, а Запад = 0, то x = 500 (тянет на Восток)
  float x = valEast - valWest;
  
  // Если Север = 1000, а Юг = 0, то y = 1000 (сильно тянет на Север)
  float y = valNorth - valSouth;

  // Мертвая зона (шумоподавление): если разница слишком мала, 
  // значит освещение равномерное или его нет. Мотор не дергается.
  if (abs(x) < 30 && abs(y) < 30) {
    delay(100);
    return;
  }

  // 3. Вычисляем целевой угол в радианах (от -PI до PI)
  float angle = atan2(y, x);

  // Приводим угол к круговому диапазону от 0 до 2*PI
  if (angle < 0) {
    angle += 2 * PI;
  }

  // 4. Переводим радианы в шаги мотора (от 0 до 519)
  // angle / (2 * PI) — это доля от полного круга
  int targetStep = round((angle / (2 * PI)) * stepsPerRev);
  if (targetStep >= stepsPerRev) targetStep = 0;

  // 5. Находим кратчайший путь вращения
  int diff = targetStep - currentStep;
  
  // Если разница больше половины круга, выгоднее покрутить в обратную сторону
  if (diff > stepsPerRev / 2) {
    diff -= stepsPerRev;
  } else if (diff < -stepsPerRev / 2) {
    diff += stepsPerRev;
  }

  // 6. Двигаем мотор, если цель изменилась
  if (diff != 0) {
    
    stepper.step(-diff); 
    
    // Запоминаем новую позицию
    currentStep = targetStep;

    // Отладочный вывод в монитор порта
    Serial.print("Degree: ");
    Serial.print(angle * 180.0 / PI);
    Serial.print("\tShag: ");
    Serial.print(targetStep);
    Serial.print("\tSdvig: ");
    Serial.println(diff);
  }

  // Небольшая пауза для стабильности системы
  delay(150);
}