Загрузка данных
#include <Stepper.h>
// Пины фоторезисторов
#define NORTH_PIN A5
#define WEST_PIN A4
#define EAST_PIN A3
#define SOUTH_PIN A2
// Настройки двигателя
const int stepsPerRevolution = 520;
Stepper stepper(stepsPerRevolution, 8, 10, 9, 11);
const int threshold = 100;
// Переменные для позиционирования
int currentStepPosition = 0; // Текущая позиция в шагах (0 = Север)
bool isCalibrated = false;
struct Direction {
int stepTarget; // Целевая позиция в шагах
String name;
};
void setup() {
Serial.begin(9600);
stepper.setSpeed(15);
Serial.println("Поверните двигатель в положение СЕВЕР и нажмите любую клавишу в мониторе порта...");
// Ждём калибровки через Serial Monitor
while (!isCalibrated) {
if (Serial.available()) {
Serial.read();
currentStepPosition = 0;
isCalibrated = true;
Serial.println("Калибровка завершена! Север задан.");
delay(1000);
}
}
}
void loop() {
// Считываем фоторезисторы
int northValue = analogRead(NORTH_PIN);
int westValue = analogRead(WEST_PIN);
int eastValue = analogRead(EAST_PIN);
int southValue = analogRead(SOUTH_PIN);
// Вывод для отладки
Serial.print("N:");
Serial.print(northValue);
Serial.print(" E:");
Serial.print(eastValue);
Serial.print(" S:");
Serial.print(southValue);
Serial.print(" W:");
Serial.println(westValue);
// Определяем активные стороны (исправлено: юг и север поменяны местами в логике)
bool northActive = northValue > threshold;
bool eastActive = eastValue > threshold;
bool southActive = southValue > threshold;
bool westActive = westValue > threshold;
Direction target = getTargetDirection(northActive, eastActive, southActive, westActive);
if (target.stepTarget != -1) {
Serial.print("Целевое направление: ");
Serial.println(target.name);
rotateToPosition(target.stepTarget);
}
delay(200);
}
Direction getTargetDirection(bool north, bool east, bool south, bool west) {
// Исправлено: север и юг поменяны местами
if (south && !east && !north && !west) return {0, "Север"};
if (south && east && !north && !west) return {45, "Северо-Восток"};
if (!south && east && !north && !west) return {90, "Восток"};
if (!south && east && north && !west) return {135, "Юго-Восток"};
if (!south && !east && north && !west) return {180, "Юг"};
if (!south && !east && north && west) return {225, "Юго-Запад"};
if (!south && !east && !north && west) return {270, "Запад"};
if (south && !east && !north && west) return {315, "Северо-Запад"};
return {-1, "Нет сигнала"};
}
void rotateToPosition(int targetStep) {
// Вычисляем кратчайший путь
int delta = targetStep - currentStepPosition;
// Нормализуем дельту в диапазон -stepsPerRevolution/2 .. stepsPerRevolution/2
if (delta > stepsPerRevolution / 2) delta -= stepsPerRevolution;
if (delta < -stepsPerRevolution / 2) delta += stepsPerRevolution;
if (delta == 0) {
Serial.println("Уже на месте");
return;
}
Serial.print("Поворот на ");
Serial.print(delta);
Serial.print(" шагов (");
Serial.print((delta * 360) / stepsPerRevolution);
Serial.println(" градусов)");
// Поворачиваем
stepper.step(delta);
// Обновляем текущую позицию с учётом полного оборота
currentStepPosition = (currentStepPosition + delta) % stepsPerRevolution;
if (currentStepPosition < 0) currentStepPosition += stepsPerRevolution;
Serial.print("Новая позиция: ");
Serial.print(currentStepPosition);
Serial.print(" шагов (");
Serial.print((currentStepPosition * 360) / stepsPerRevolution);
Serial.println(" градусов)");
delay(300);
}