DIY Інклінометр (Кутомір)
Прилад для виміру кута нахилу різних об'єктів щодо гравітаційного поля Землі

Готовий DIY інклінометр на базі Arduino
Вступ
Дуже давно хотів зробити свій кутомір, і довго вибирав який датчик використовувати, і нарешті знайшов - це MPU6050 3-х осевий гіроскоп та акселерометр. Це один із найскладніших датчиків для розуміння при низькій вартості, але результат того вартий!
Ви можете запитати: "Навіщо робити самому, якщо можна купити готовий?" І будете праві, але наш саморобний кутомір має свої переваги та коштує значно менше за найдешевший аналог з Китаю.
Що вміє наш інклінометр?
Відображає кут нахилу з високою точністю, включаючи від'ємні значення
Графічне зображення положення рівня на OLED дисплеї
Автоматичний переворот дисплею при кутах більше 60° або менше -60°
Бузер сповіщає про досягнення рівнів 0°, 90°, -90°
Переваги DIY рішення
- Ремонтопридатність: Якщо через рік, два чи навіть 10 років щось перестає працювати - просто міняємо несправний компонент. Розбився дисплей? Не проблема - замінили. Акумулятор не тримає? Теж легко вирішується.
- Індивідуальний корпус: Можна створити корпус саме тих розмірів, які вам потрібні. Планую замовити 3D-друк на myproject.com.ua
- Економічність: Всього 3 основні деталі та корпус. Загальна вартість близько 600 грн проти 2000+ грн за професійний кутомір.
Необхідні компоненти
Основні компоненти:
Для тестування:
Для готового виробу:
Схема підключення
Датчик та дисплей підключаються паралельно до шини I2C.

Детальна схема підключення компонентів

Спрощена схема підключення
⚠️ Важливо! Розміщення датчика в корпусі:
Нижня основа плати повинна бути жорстко закріплена на поверхні паралельно площині, якою буде вимірюватись кут. Довжина плати повинна йти вздовж довжини кутоміра.

Приклад корпусу для кутоміра
Скетч Arduino
Перед завантаженням необхідно встановити бібліотеки для роботи з дисплеєм та датчиком:

Встановлення необхідних бібліотек в Arduino IDE
#include <Wire.h> #include <MPU6050.h> #include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define LED_PIN 2 #define BLINK_DELAY 100 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); MPU6050 mpu; #define LINE_LENGTH 37 #define CENTER_LINE_LENGTH 30 enum RotationState { NORMAL, RIGHT_90, LEFT_90 }; RotationState currentRotation = NORMAL; bool wasAtTargetAngle = false; unsigned long lastBlinkTime = 0; byte blinkCount = 0; void setup() { Serial.begin(9600); Wire.begin(); pinMode(LED_PIN, OUTPUT); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println("Ошибка инициализации OLED"); while(1); } display.clearDisplay(); display.display(); if (!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) { Serial.println("MPU6050 не найден!"); display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 20); display.println("MPU6050"); display.display(); while (1); } mpu.setAccelPowerOnDelay(3); display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(20, 25); display.println("Ready"); display.display(); delay(1000); } void blinkLED() { if (millis() - lastBlinkTime >= BLINK_DELAY) { lastBlinkTime = millis(); if (blinkCount < 4) { digitalWrite(LED_PIN, !digitalRead(LED_PIN)); blinkCount++; } else { digitalWrite(LED_PIN, LOW); } } } void drawLevelIndicator(float angle) { display.clearDisplay(); int leftX, rightX, centerY; if (currentRotation == NORMAL) { leftX = 20; rightX = 108; centerY = 22; } else { leftX = 32; rightX = 96; centerY = 44; } if (currentRotation == NORMAL) { display.drawFastHLine(leftX - LINE_LENGTH/2, centerY, LINE_LENGTH, WHITE); display.drawFastHLine(rightX - LINE_LENGTH/2, centerY, LINE_LENGTH, WHITE); } else { display.drawFastVLine(leftX, centerY - LINE_LENGTH/2, LINE_LENGTH, WHITE); display.drawFastVLine(rightX, centerY - LINE_LENGTH/2, LINE_LENGTH, WHITE); } float angle_rad = radians(angle); int x1, y1, x2, y2; if (currentRotation == NORMAL) { x1 = SCREEN_WIDTH/2 - CENTER_LINE_LENGTH/2 * cos(angle_rad); y1 = centerY - CENTER_LINE_LENGTH/2 * sin(angle_rad); x2 = SCREEN_WIDTH/2 + CENTER_LINE_LENGTH/2 * cos(angle_rad); y2 = centerY + CENTER_LINE_LENGTH/2 * sin(angle_rad); } else if (currentRotation == RIGHT_90) { x1 = SCREEN_WIDTH/2 + CENTER_LINE_LENGTH/2 * sin(angle_rad); y1 = centerY - CENTER_LINE_LENGTH/2 * cos(angle_rad); x2 = SCREEN_WIDTH/2 - CENTER_LINE_LENGTH/2 * sin(angle_rad); y2 = centerY + CENTER_LINE_LENGTH/2 * cos(angle_rad); } else { x1 = SCREEN_WIDTH/2 - CENTER_LINE_LENGTH/2 * sin(angle_rad); y1 = centerY + CENTER_LINE_LENGTH/2 * cos(angle_rad); x2 = SCREEN_WIDTH/2 + CENTER_LINE_LENGTH/2 * sin(angle_rad); y2 = centerY - CENTER_LINE_LENGTH/2 * cos(angle_rad); } display.drawLine(x1, y1, x2, y2, WHITE); display.setTextSize(2); if (currentRotation == NORMAL) { display.setCursor(55, 48); } else { display.setCursor(12, 10); } display.print(angle, 0); display.print((char)247); } void loop() { Vector rawAccel = mpu.readRawAccel(); float accel_angle_x = atan2(rawAccel.YAxis, rawAccel.ZAxis) * 180 / PI; bool atTargetAngle = (abs(accel_angle_x) < 1.0) || (abs(accel_angle_x + 90) < 3.0) || (abs(accel_angle_x - 90) < 3.0); if (atTargetAngle) { if (!wasAtTargetAngle) { blinkCount = 0; lastBlinkTime = millis(); digitalWrite(LED_PIN, HIGH); blinkCount++; } blinkLED(); } else { digitalWrite(LED_PIN, LOW); blinkCount = 0; } wasAtTargetAngle = atTargetAngle; if (accel_angle_x < -60 && currentRotation != RIGHT_90) { currentRotation = RIGHT_90; display.setRotation(1); } else if (accel_angle_x > 60 && currentRotation != LEFT_90) { currentRotation = LEFT_90; display.setRotation(3); } else if (abs(accel_angle_x) <= 60 && currentRotation != NORMAL) { currentRotation = NORMAL; display.setRotation(0); } drawLevelIndicator(accel_angle_x); display.display(); delay(80); }
В коді міняти нічого не потрібно, все готове до використання. Після завантаження коду на дисплеї з'явиться індикація рівня.




Сфера застосування
🏗️ Будівництво та ремонт
- Перевірка рівня стін, підлог, стелі
- Монтаж меблів (шафи, полиці, вішалки)
- Установка дверей та вікон
- Прокладання кафельної плитки
🚗 Автомобільна сфера
- Регулювання розвалу/сходження коліс
- Перевірка кута нахилу підвіски
- Встановлення автозвукового обладнання
🌾 Сільське господарство
- Налаштування сільгосптехніки
- Перевірка ухилу теплиць
- Монтаж систем зрошення
🔧 DIY проекти
- Встановлення антен, супутникових тарілок
- Вивіряння картин, кронштейнів TV
- Проектування рамп для скейтбордингу
📚 Освіта
- Наочний посібник з фізики
- Демонстрація роботи акселерометрів
- Основи програмування мікроконтролерів
🏕️ Туризм та відпочинок
- Встановлення намету на нерівній поверхні
- Перевірка ухилу велосипедного маршруту
- Кріплення спорядження для альпінізму
© 2025 Мій Проект. Автор: Ardu_miha. Використання матеріалів дозволено лише з посиланням на джерело.
Написати коментар