Двухосевой солнечный трекер на Arduino UNO — DIY выравнивание солнечной панели
Компоненты и материалы
| Компонент | Количество |
|---|---|
| Arduino UNO | 1 |
| Микросервопривод SG90 | 2 |
| Фоторезистор (LDR) 5 МОм | 4 |
| Резистор 330 Ом | 4 |
| Потенциометр (любой) | 1 |
| Таковая кнопка | 2 |
| Мини солнечная панель | 1 |
Инструменты и ПО
- Arduino IDE
- PLX-DAQ (макрос для Excel — логирование данных в реальном времени)
О проекте
Открытый стенд для тестирования двухосевого солнечного трекера на Arduino Uno. Трекер вращается по азимуту (восток-запад) и высоте (юг-север) с помощью двух сервоприводов, управляемых четырьмя LDR-сенсорами. Режимы: автоматический (по LDR) и ручной (потенциометр). Переключение кнопками. Данные (напряжение, ток, мощность, режим) выводятся в Excel через PLX-DAQ.
Механическая конструкция
3D-модель в CATIA: фотоэлемент, два сервопривода (лево-право и вверх-вниз), 4 LDR в углах панели. LDR помещены в тёмные трубки с малой дыркой — это увеличивает робастность к боковому освещению. По горизонтали используется подшипник для плавности.
Аппаратная часть
- Автоматический режим: Arduino считывает 4 LDR (A0–A3), управляет сервоприводами по PWM (D5, D6). Алгоритм: сравнивает средние значения верхних/нижних и левых/правых пар LDR. Если разница > порога (10), поворачивает серво на 2° в сторону большего освещения. Стабилизация в диапазоне ±10.
- Ручной режим: Потенциометр (A4) управляет выбранным серво. Кнопка (D11) переключает ось, кнопка (D12) — режим.
- Измерение мощности: Напряжение панели на A5 (делитель 1:1), ток = U/20Ом, мощность = U×I. Данные по USB в Excel.
- LDR схема: Делитель напряжения 5В / 330Ом / LDR / GND. Выход на аналоговый вход.
- Сервоприводы: MG996R (азимут) и SG90 (высота). Питание 5В, управление PWM.
Алгоритм автоматического режима
- Считывает 4 LDR.
- Считает средние: верх, низ, лево, право.
- Разница азимута = право - лево. Если |diff| > 10: поворачивает серво азимута.
- Разница высоты = верх - низ. Если |diff| > 10: поворачивает серво высоты.
- Если средняя освещённость < 8 (ночь): возвращает панель в позицию восхода (0° азимут, 30° высота).
Виртуальная приборная панель (PLX-DAQ)
PLX-DAQ — Excel-макрос для приёма данных по Serial. Установите, откройте «PLX-DAQ Spreadsheet», настройте порт/baud rate, нажмите Connect. Данные логгируются в реальном времени.
Прототип
Конструкция из дерева, все компоненты смонтированы. Тестировалось под искусственной лампой. Стенд компактный, гибкий, подходит для обучения и прототипирования алгоритмов перед крупным внедрением.
Программный код
#include <Servo.h>
int mode = 0; // 0=Manual, 1=Auto
int axe = 0; // 0=Left-Right, 1=Up-Down
int buttonState1 = 0, buttonState2 = 0;
int prevButtonState1 = 0, prevButtonState2 = 0;
int ldrtopr = 0, ldrtopl = 1, ldrbotr = 2, ldrbotl = 3;
int topl=0, topr=0, botl=0, botr=0;
Servo servo_updown;
Servo servo_rightleft;
int threshold_value = 10;
void setup() {
Serial.begin(9600);
Serial.println("CLEARDATA");
Serial.println("LABEL,t,voltage,current,power,Mode");
pinMode(12, INPUT); // Mode button
pinMode(11, INPUT); // Axis button
pinMode(A4, INPUT); // Potentiometer
servo_updown.attach(5);
servo_rightleft.attach(6);
}
void loop() {
// Чтение напряжения панели (делитель 1:1 на A5)
float volt = analogRead(A5) * 5.0 / 1023.0;
float voltage = 2 * volt;
float current = voltage / 20.0;
float power = voltage * current;
Serial.print("DATA,TIME,");
Serial.print(voltage); Serial.print(",");
Serial.print(current); Serial.print(",");
Serial.print(power); Serial.print(",");
// Кнопка режима (D12)
buttonState1 = digitalRead(12);
if (buttonState1 != prevButtonState1) {
if (buttonState1 == HIGH) mode = (mode == 1) ? 0 : 1;
}
prevButtonState1 = buttonState1;
delay(50);
if (mode == 0) {
Serial.println('M');
manualsolartracker();
} else {
Serial.println('A');
automaticsolartracker();
}
}
void automaticsolartracker() {
topr = analogRead(ldrtopr);
topl = analogRead(ldrtopl);
botr = analogRead(ldrbotr);
botl = analogRead(ldrbotl);
int avgtop = (topr + topl) / 2;
int avgbot = (botr + botl) / 2;
int avgleft = (topl + botl) / 2;
int avgright = (topr + botr) / 2;
int diffelev = avgtop - avgbot;
int diffazi = avgright - avgleft;
// Азимут (лево-право)
if (abs(diffazi) >= threshold_value) {
if (diffazi > 0) {
if (servo_rightleft.read() < 180)
servo_rightleft.write(servo_rightleft.read() + 2);
} else {
if (servo_rightleft.read() > 0)
servo_rightleft.write(servo_rightleft.read() - 2);
}
}
// Высота (вверх-вниз)
if (abs(diffelev) >= threshold_value) {
if (diffelev > 0) {
if (servo_updown.read() < 180)
servo_updown.write(servo_updown.read() - 2);
} else {
if (servo_updown.read() > 0)
servo_updown.write(servo_updown.read() + 2);
}
}
}
void manualsolartracker() {
buttonState2 = digitalRead(11); // Примечание: в оригинале D13, но схема — D11
if (buttonState2 != prevButtonState2) {
if (buttonState2 == HIGH) axe = (axe == 1) ? 0 : 1;
}
prevButtonState2 = buttonState2;
delay(50);
if (axe == 0) {
servo_rightleft.write(map(analogRead(A4), 0, 1023, 0, 180));
} else {
servo_updown.write(map(analogRead(A4), 0, 1023, 0, 180));
}
}
Схемы
Полная схема в разделе Schematics (ZIP-архив). Основные соединения:
- LDR: A0–A3 через делители 330Ом
- Серво Up-Down: D5, Серво Left-Right: D6
- Кнопка режима: D12, Кнопка оси: D11
- Потенциометр: A4
- Солнечная панель: A5 (делитель 10к/10к или 1:1)
Производственный процесс
- Цифровые кости на Arduino: генератор случайных чисел с LCD-дисплеем и кнопкой
- DIY USB-геймпад на Arduino: собственный высокопроизводительный контроллер
- Солнечный трекер v2.0 — продвинутая DIY система слежения за солнцем
- Pixel Chaser: игра на один тап с NeoPixel Ring и Arduino Nano
- IoT-солнечный трекер на Arduino: умное управление энергией с мониторингом через Cayenne
- Магнитная левитация на отталкивании с Arduino: Простая схема и DIY-руководство
- Arduino Home Controller с Alexa: умный дом голосовым управлением
- NeoPixel Matrix Pong на Arduino Nano: неоновая игра Pong на матрице 15×10
- Измерение солнечной радиации на Arduino UNO с Ethernet Shield
- DIY LED-рулетка — собираем одноигровой аркадный автомат на Arduino Nano