// Тестовые углы и смещение
/*float offset = 150.0f; // 150° на второй шкале = 0° на первой
float testAngles[] = {-180.0f, -90.0f, 0.0f, 90.0f, 180.0f};
// Преобразование угла из [-180, 180] в [0, 360] с учетом смещения нуля
float convertAngleWithOffset(float angle, float offset) {
// Применяем смещение
float result = angle + offset;
// Нормализуем в диапазон [0, 360]
if (result >= 360.0f) {
result -= 360.0f;
} else if (result < 0.0f) {
result += 360.0f;
}
return result;
}
void setup() {
Serial.begin(115200);
Serial.println("Angle Conversion with Offset:");
Serial.println("[-180...+180] -> [0...360]");
Serial.print("Zero offset: ");
Serial.println(offset);
Serial.println("---------------------------");
for (int i = 0; i < sizeof(testAngles) / sizeof(testAngles[0]); i++) {
float converted = convertAngleWithOffset(testAngles[i], offset);
Serial.print("Zero offset: ");
Serial.print(testAngles[i]);
Serial.print(" -> ");
Serial.println(converted);
//Serial.printf("%6.1f° -> %6.1f°\n", testAngles[i], converted);
}
}
void loop() {
}
// Функция для преобразования угла из [0...360] в [360...0]
float convertToReversedRange(float angle) {
// Сначала нормализуем угол в диапазон [0, 360]
float normalized = angle;
while (normalized >= 360.0f) normalized -= 360.0f;
while (normalized < 0.0f) normalized += 360.0f;
// Преобразуем в обратный диапазон [360...0]
float reversed = 360.0f - normalized;
// Для угла 360° возвращаем 0°, для 0° возвращаем 360°
if (reversed == 360.0f) return 0.0f;
return reversed;
}
// Функция с поддержкой смещения нуля
float convertAngleWithOffsetReversed(float angle, float offset) {
// Применяем смещение
float result = angle + offset;
// Нормализуем в диапазон [0, 360]
while (result >= 360.0f) result -= 360.0f;
while (result < 0.0f) result += 360.0f;
// Преобразуем в обратный диапазон
return 360.0f - result;
}
void setup() {
Serial.begin(115200);
Serial.println("Angle Conversion: [0...360] -> [360...0]");
Serial.println("================================");
// Тестовые углы в диапазоне [0...360]
//float testAngles[] = {0.0f, 20.0f, 35.0f, 45.0f, 90.0f, 180.0f, 270.0f, 360.0f, 405.0f, -45.0f};
float testAngles[] = {0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f,
100.0f, 110.0f, 120.0f, 130.0f, 140.0f, 150.0f, 160.0f, 170.0f, 180.0f,
190.0f, 200.0f, 210.0f, 220.0f, 230.0f, 240.0f, 250.0f, 260.0f, 270.0f,
280.0f, 290.0f, 300.0f, 310.0f, 320.0f, 330.0f, 340.0f, 350.0f, 360.0};
Serial.println("Without offset:");
for (int i = 0; i < sizeof(testAngles) / sizeof(testAngles[0]); i++) {
float original = testAngles[i];
float converted = convertToReversedRange(original);
Serial.print(original);
Serial.print("° -> ");
Serial.print(converted);
Serial.println("°");
}
Serial.println("\nWith offset (180°):");
float offset = 360.0f;
for (int i = 0; i < sizeof(testAngles) / sizeof(testAngles[0]); i++) {
float original = testAngles[i];
float converted = convertAngleWithOffsetReversed(original, offset);
Serial.print(original);
Serial.print("° + ");
Serial.print(offset);
Serial.print("° -> ");
Serial.print(converted);
Serial.println("°");
}
}
void loop() {
// Пустой цикл
}
// Морская шкала -> Шкала потенциометра
float convertToMirror(float angle) {
// Применяем смещение 180° и нормализуем
float result = angle + 180.0f;
// Нормализация
if (result >= 360.0f) {
result -= 360.0f;
}
// Преобразуем в обратный диапазон [360...0]
float reversed = 360.0f - result;
// Обработка граничного случая
return (reversed == 360.0f) ? 0.0f : reversed;
}
// Шкала потенциометра -> Морская шкала
float mirrorAngle180(float angle) {
// Применяем смещение 180°
float result = angle + 180.0f;
// Нормализуем в [0...360]
if (result >= 360.0f) {
result -= 360.0f;
}
// Инвертируем диапазон
float reversed = 360.0f - result;
// Граничный случай 360° → 0°
return (reversed == 360.0f) ? 0.0f : reversed;
}
void setup() {
Serial.begin(115200);
Serial.println("Angle Mirroring with 180° offset");
Serial.println("[0...360] -> [360...0] mirrored");
Serial.println("Step: 15 degrees");
Serial.println("================================");
Serial.println("Морская шкала -> Шкала потенциометра");
Serial.println("------------------------");
// Создаем массив углов с шагом 15°
float testAngles[37]; // 0, 10, 20, ..., 360 = 37 значений
// Заполняем массив значениями от 0 до 360 с шагом 15
for (int i = 0; i < 37; i++) {
testAngles[i] = i * 15.0f;
}
// Альтернативно, можно было бы объявить так:
// float testAngles[] = {0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f,
// 100.0f, 110.0f, 120.0f, 130.0f, 140.0f, 150.0f, 160.0f, 170.0f, 180.0f,
// 190.0f, 200.0f, 210.0f, 220.0f, 230.0f, 240.0f, 250.0f, 260.0f, 270.0f,
// 280.0f, 290.0f, 300.0f, 310.0f, 320.0f, 330.0f, 340.0f, 350.0f, 360.0f};
// Выводим все углы
for (int i = 0; i < 37; i++) {
float original = testAngles[i];
float converted = convertToMirror(original);
// Форматированный вывод
if (original < 100) Serial.print(" ");
if (original < 10) Serial.print(" ");
Serial.print(original, 0);
Serial.print("° -> ");
if (converted < 100) Serial.print(" ");
if (converted < 10) Serial.print(" ");
Serial.print(converted, 0);
Serial.println("°");
if (original >= 360) break;
}
Serial.println("\n\nКраткая выжимка (каждые 90°):");
Serial.println("------------------------");
float keyAngles[] = {0.0f, 90.0f, 180.0f, 270.0f, 360.0f};
for (int i = 0; i < 5; i++) {
float original = keyAngles[i];
float converted = convertToMirror(original);
Serial.print(original, 0);
Serial.print("° -> ");
Serial.print(converted, 0);
Serial.println("°");
}
Serial.println("\n\nОбратное преобразование (каждые 15°):");
Serial.println("================================");
Serial.println(" Шкала потенциометра -> Морская шкала");
Serial.println("------------------------");
for (int i = 0; i <= 360; i += 15) {
float original = i * 1.0f;
if (original < 100) Serial.print(" ");
if (original < 10) Serial.print(" ");
Serial.print(original);
Serial.print("° -> ");
Serial.print(mirrorAngle180(i));
Serial.println("°");
}
}
void loop() {
// Оставляем пустым или добавляем непрерывное тестирование
}
*/
// ==============================================
// ПРЯМОЕ ПРЕОБРАЗОВАНИЕ: [0...360] -> [360...0]
// ==============================================
float convertToReversedRange(float angle) {
// Сначала нормализуем угол в диапазон [0, 360]
float normalized = angle;
while (normalized >= 360.0f) normalized -= 360.0f;
while (normalized < 0.0f) normalized += 360.0f;
// Преобразуем в обратный диапазон [360...0]
float reversed = 360.0f - normalized;
// Для угла 360° возвращаем 0°, для 0° возвращаем 360°
if (reversed == 360.0f) return 0.0f;
return reversed;
}
// ==============================================
// ОБРАТНОЕ ПРЕОБРАЗОВАНИЕ: [360...0] -> [0...360]
// ==============================================
float convertFromReversedRange(float reversedAngle) {
// Нормализуем входное значение в диапазон [0, 360]
float normalized = reversedAngle;
while (normalized >= 360.0f) normalized -= 360.0f;
while (normalized < 0.0f) normalized += 360.0f;
// Обратное преобразование: из [360...0] в [0...360]
float original = 360.0f - normalized;
// Корректировка граничных значений
if (original == 360.0f) return 0.0f;
return original;
}
// ==============================================
// ВЕРСИЯ СО СМЕЩЕНИЕМ 180° (ЗЕРКАЛЬНОЕ)
// ==============================================
float mirrorAngle180(float angle) {
// Применяем смещение 180° и нормализуем
float result = angle + 180.0f;
// Нормализация
if (result >= 360.0f) {
result -= 360.0f;
}
// Преобразуем в обратный диапазон [360...0]
float reversed = 360.0f - result;
// Обработка граничного случая
return (reversed == 360.0f) ? 0.0f : reversed;
}
float mirrorAngleReverse(float mirroredAngle) {
// Обратное преобразование для зеркальной системы
float result = 360.0f - mirroredAngle;
result = result - 180.0f;
// Нормализуем в [0, 360)
if (result < 0.0f) result += 360.0f;
if (result >= 360.0f) result -= 360.0f;
return result;
}
// ==============================================
// ТЕСТИРОВАНИЕ
// ==============================================
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("==================================================");
Serial.println("ПРЕОБРАЗОВАНИЕ УГЛОВ: [0...360] ↔ [360...0]");
Serial.println("==================================================");
// Тестовые углы с шагом 30°
Serial.println("\n1. Прямое преобразование convertToReversedRange():");
Serial.println("--------------------------------------------------");
Serial.println("Угол [0...360] -> Обратный [360...0]");
Serial.println("------------------------------------");
for (int angle = 0; angle <= 360; angle += 15) {
float reversed = convertToReversedRange((float)angle);
Serial.print(" ");
if (angle < 100) Serial.print(" ");
Serial.print(angle);
Serial.print("° -> ");
if (reversed < 100) Serial.print(" ");
Serial.print(reversed);
Serial.println("°");
}
// Тест обратного преобразования
Serial.println("\n2. Обратное преобразование convertFromReversedRange():");
Serial.println("------------------------------------------------------");
Serial.println("Обратный [360...0] -> Угол [0...360]");
Serial.println("------------------------------------");
for (int rev = 0; rev <= 360; rev += 15) {
float original = convertFromReversedRange((float)rev);
Serial.print(" ");
if (rev < 100) Serial.print(" ");
Serial.print(rev);
Serial.print("° -> ");
if (original < 100) Serial.print(" ");
Serial.print(original);
Serial.println("°");
}
// Проверка обратимости
Serial.println("\n3. Проверка обратимости преобразований:");
Serial.println("---------------------------------------");
float testAngles[] = {0.0f, 45.0f, 90.0f, 180.0f, 270.0f, 360.0f, 450.0f, -90.0f};
for (int i = 0; i < 8; i++) {
float angle = testAngles[i];
float reversed = convertToReversedRange(angle);
float restored = convertFromReversedRange(reversed);
Serial.print(" Исходный: ");
Serial.print(angle);
Serial.print("° -> Обратный: ");
Serial.print(reversed);
Serial.print("° -> Восстановленный: ");
Serial.print(restored);
if (abs(restored - fmod(angle, 360.0f)) < 0.001) {
Serial.println("° ✓");
} else {
Serial.println("° ✗");
}
}
// Тест зеркального преобразования со смещением 180°
Serial.println("\n4. Зеркальное преобразование со смещением 180°:");
Serial.println("---------------------------------------------");
Serial.println("Угол [0...360] -> Зеркальный [360...0]");
Serial.println("--------------------------------------");
for (int angle = 0; angle <= 360; angle += 45) {
float mirrored = mirrorAngle180((float)angle);
Serial.print(" ");
if (angle < 100) Serial.print(" ");
Serial.print(angle);
Serial.print("° -> ");
if (mirrored < 100) Serial.print(" ");
Serial.print(mirrored);
Serial.println("°");
}
// Проверка зеркальной обратимости
Serial.println("\n5. Проверка зеркальной обратимости:");
Serial.println("-----------------------------------");
float testAngle = 123.0f;
float mirrored = mirrorAngle180(testAngle);
float restored = mirrorAngleReverse(mirrored);
Serial.print(" Тестовый угол: ");
Serial.print(testAngle);
Serial.print("°\n Зеркальный: ");
Serial.print(mirrored);
Serial.print("°\n Восстановленный: ");
Serial.print(restored);
if (abs(restored - testAngle) < 0.001) {
Serial.println("° ✓ СОВПАЛО!");
} else {
Serial.println("° ✗ ОШИБКА!");
}
// Сводная таблица ключевых значений
Serial.println("\n6. Сводная таблица ключевых преобразований:");
Serial.println("------------------------------------------");
Serial.println(" Угол | Обратный | Зеркальный");
Serial.println("------|----------|------------");
float keyAngles[] = {0.0f, 45.0f, 90.0f, 135.0f, 180.0f, 225.0f, 270.0f, 315.0f, 360.0f};
for (int i = 0; i < 9; i++) {
float angle = keyAngles[i];
float reversed = convertToReversedRange(angle);
float mirrored = mirrorAngle180(angle);
// Вывод угла
Serial.print(" ");
if (angle < 100) Serial.print(" ");
Serial.print(angle, 0);
Serial.print("° | ");
// Вывод обратного
if (reversed < 100) Serial.print(" ");
Serial.print(reversed, 0);
Serial.print("° | ");
// Вывод зеркального
if (mirrored < 100) Serial.print(" ");
Serial.print(mirrored, 0);
Serial.println("°");
}
Serial.println("\n==================================================");
Serial.println("ТЕСТИРОВАНИЕ ЗАВЕРШЕНО");
Serial.println("==================================================");
}
// ==============================================
// ДЕМОНСТРАЦИЯ В РЕАЛЬНОМ ВРЕМЕНИ
// ==============================================
void loop() {
static float simulatedAngle = 0.0f;
// Эмуляция изменения угла
simulatedAngle += 5.0f;
if (simulatedAngle > 720.0f) {
simulatedAngle = -360.0f;
}
// Применяем все преобразования
float reversed = convertToReversedRange(simulatedAngle);
float restored = convertFromReversedRange(reversed);
float mirrored = mirrorAngle180(simulatedAngle);
float mirroredBack = mirrorAngleReverse(mirrored);
// Вывод в компактном формате
Serial.print("Угол: ");
Serial.print(simulatedAngle, 1);
Serial.print("° -> Обратный: ");
Serial.print(reversed, 1);
Serial.print("° -> Восст: ");
Serial.print(restored, 1);
Serial.print("° | Зеркало: ");
Serial.print(mirrored, 1);
Serial.print("° -> Назад: ");
Serial.print(mirroredBack, 1);
Serial.println("°");
delay(500); // Задержка для читаемости
}