Стационарная солнечная панель ловит прямые лучи час-два в сутки: солнце уходит по дуге на 180 градусов, а панель смотрит в одну точку неба. Поворотная платформа с серво добавляет, по замерам сборщиков трекеров, до 30-40 процентов съёмной энергии в ясный день — это разница между «батарея дожила до вечера» и «батарея легла в полдень». Механика при этом смехотворна: одна SG90 из урока про подключение, кусок фанеры и два фоторезистора по бокам картонной перегородки.
Трекер — самый честный прибор из трёх уроков кластера: здесь серво показывает не чужое число с датчика, а собственное положение относительно света. Два глаза смотрят в одно небо, перегородка между ними бросает тень на того, кто отвернулся, и разность показаний подсказывает, куда крутиться. Это уже не индикатор, а замкнутая система слежения — и в ней впервые появляются пороги, мёртвая зона и заслуженный отдых серво.
Разберём механику глаз, посчитаем мёртвую зону и шаг, соберём скетч на millis с detach-отдыхом в покое и посмотрим на трекер в симуляторе, где солнце заменяют два ползунка. Вторую ось наклона здесь не трогаем: конструкция пан-тилт с двумя серво разобрана в отдельном уроке, а по одной оси трекер собирается из того, что уже лежит на столе.
Два глаза и перегородка
Глаза — два одинаковых фоторезистора с делителями, развёрнутые в стороны на 30-60 градусов, между ними перегородка высотой сантиметр-полтора. Пока источник света прямо по курсу, перегородка тени не бросает и показания близки. Свет ушёл влево — тень легла на правый глаз, левый ловит больше, разность выросла. Направление трекеру даёт именно перегородка, а не сами датчики: без неё два LDR стоят рядом и видят почти одно и то же небо. Подключение фоторезистора с делителем разобрано в уроке про ночной светильник — здесь оно повторяется дважды.
Разность в покое не ноль: датчики не идентичны, свет мерцает, рука отбрасывает тень. Типичная мёртвая зона трекера — 20-50 единиц АЦП из 1023; я ставлю 30. Зона меньше двадцати превращает платформу в трещотку — та же болезнь, что разобрана в уроке про дрожь и помехи: серво постоянно щёлкает то влево, то вправо, редуктор греется, батарея тает. Зона больше полусотни — платформа точна до плюс-минус пары градусов и теряет доли процента энергии, зато живёт спокойно. Это осознанный размен: чуть меньше съёма в обмен на тишину и ресурс механики.
Шаг — один градус за тик 50 мс, то есть двадцать градусов в секунду. Медленнее — трекер не успеет за солнцем, которое уходит примерно на градус за четыре минуты; быстрее — платформа наезжает на мёртвую зону с другой стороны, проскакивает и качается. Пределы 30-150° — страховка механики: у крайних положений провода панели перекручиваются, а качалка упирается в основание; в средней трети хода трекер живёт годами. Свет ушёл за предел — платформа просто стоит и ждёт.
#include <Servo.h> Servo srv; const int LDR_L = A0; // левый глазconst int LDR_R = A1; // правый глазconst int DEAD = 30; // мёртвая зона, единиц АЦПconst int STEP_MS = 50; // тик: один градус за 50 мсconst int MIN_A = 30; // нижний пределconst int MAX_A = 150; // верхний пределconst unsigned long REST_MS = 2000; // тишина до detach int angle = 90;unsigned long tPrev = 0;unsigned long tMoved = 0;bool onDuty = true; void setup() { Serial.begin(9600); srv.attach(11); srv.write(angle); Serial.println("Treker: l / r / ugol");} void loop() { if (millis() - tPrev >= STEP_MS) { tPrev = millis(); int l = analogRead(LDR_L); int r = analogRead(LDR_R); int diff = l - r; if (diff > DEAD && angle > MIN_A) { // светлее слева if (!onDuty) { srv.attach(11); onDuty = true; } angle = angle - 1; srv.write(angle); tMoved = millis(); Serial.print("l="); Serial.print(l); Serial.print(" r="); Serial.print(r); Serial.print(" ugol="); Serial.println(angle); } else if (diff < -DEAD && angle < MAX_A) { // светлее справа if (!onDuty) { srv.attach(11); onDuty = true; } angle = angle + 1; srv.write(angle); tMoved = millis(); Serial.print("l="); Serial.print(l); Serial.print(" r="); Serial.print(r); Serial.print(" ugol="); Serial.println(angle); } if (onDuty && millis() - tMoved > REST_MS) { srv.detach(); // покой: импульсы сняты onDuty = false; Serial.println("pokoj=detach: val obestochen"); } }}Detach-строка — экономика прибора. SG90 на удержании ест около 10 мА круглосуточно; за сутки набегает четверть ампер-часа, и пара АА-банок улетает за пару вечеров наблюдений. После detach() импульсы кончаются, мотор обесточен, потребление падает почти до нуля — механика из урока про ток удержания здесь работает на трекер, а лёгкую платформу от положения самопроизвольно не уводит. Возврат зеркальный: перед первым же шагом attach(11) возвращает импульсы, и серво снова держит позицию. Порог тишины 2 с подобран под облачный день: короткие вспышки света не будят мотор каждые полминуты.
Каркас скетча — тик на millis() из урока про millis вместо delay: опрос глаз каждые 50 мс, шаг не больше градуса за тик, всё остальное время loop() свободен. Именно свободный loop() делает трекер расширяемым: добавьте Serial-команду «домой» на 90°, кнопку ручного режима или лог в CSV — тик переварит всё это, не сдвинув ни строчки в слежении. Блокирующий delay(50) не сломал бы трекер сразу, но закрыл бы обе эти двери.
| Параметр | Моё значение | Меньше — что будет | Больше — что будет |
|---|---|---|---|
| Мёртвая зона | ±30 единиц АЦП | трещотка на шуме, редуктор греется | пролёт до пары градусов, тише |
| Шаг за тик | 1° | ход растягивается на минуты | проскок мёртвой зоны и качание |
| Тик | 50 мс | реакция живее, шум чаще | лениво: солнце уходит градус за 4 минуты |
| Пауза до detach | 2 с | мотор будят каждую вспышку | дольше держит 10 мА удержания |
Погода, тени и дрожь
Облачный день — экзамен, на котором мой первый трекер провалился. Оба глаза видят одно серое небо, показания падают вместе, а разность живёт на шуме: платформа ползала туда-сюда весь день, было слышно, как щёлкает редуктор. Лечение без замены железа — поднять мёртвую зону до 50 и растянуть тик до 100 мс: в пасмурность точность и не нужна, всё равно прямой луч не ловится. Продвинутый вариант — следить за абсолютным уровнем: когда оба канала ниже 150 единиц, серво отдаётся detach и будит раз в минуту.
Вторая ловушка — тень самой панели: если панель шире расстояния между глазами, на низком солнце она накрывает один из LDR, и трекер уводится в сторону от солнца. Перегородка должна быть выше датчиков, а глаза — вынесены за край панели. Третья — насыщение: в прямой луч оба модуля выдают под тысячу, дельта сжимается до десятков единиц, и прибор слепнет ровно там, где должен быть самым точным. Спасает то, что это пиковое положение: платформа уже смотрит на солнце, и слепота в центре мёртвой зоны безвредна.
В симуляторе у трекера нет солнца — его играют два ползунка фоторезисторов: в симе они садятся на A0 и A1, на живой плате подойдёт любая пара аналоговых входов. Отдых изображён условно: движок симулятора не рисует обесточенный вал, поэтому о нём докладывает строка pokoj=detach в мониторе — на живой плате в этот момент мотор реально молчит и вал можно повернуть рукой. Пробуйте три сценария: плавный уход света (ползунки по одному), облачность (оба вниз) и резкая вспышка сбоку — поведение во всех трёх должно совпасть с разобранным выше.
Куда расти дальше. Вторая ось удваивает глаза и серво — той самой пан-тилт платформой, и разность считают уже по двум парам каналов; каркас тика и мёртвой зоны переносится без изменений. Батарейный вариант просит разбудить апгрейд сна: помимо detach, плату укладывают в глубокий сон с пробуждением по свету — на Uno это делается прерыванием, и трекер превращается в устройство, которое живёт месяц на трёх батарейках. А для уличной версии я добавляю датчик дождя: пошёл дождь — платформа уходит в парковочное положение 90° и ждёт.
И про честность цифры 30-40 процентов, с которой урок начался: она справедлива для ясного дня и одноосного доворота за солнцем по азимуту. В пасмурную неделю трекер не добавляет ничего — диффузный свет ловится в любом положении, и вся его работа сводится к паузам в мёртвой зоне. Поэтому трекер ставят там, где ясных дней много, а панель одна: дешёвая SG90 окупается быстрее, чем второй квадрат метра кремния.
- Направление подсказывает разность двух LDR с перегородкой: тень на отвернувшемся глазе — сигнал к повороту
- Мёртвая зона ±30 единиц АЦП (типично 20-50) — плата за тишину: меньше трещотка, больше потерянные градусы
- Шаг 1° за тик 50 мс — двадцать градусов в секунду: солнце уходит примерно градус за четыре минуты, запас есть
- Пределы 30-150° берегут провода и механику; за краем трекер стоит и ждёт
- detach после 2 с покоя снимает 10 мА удержания до долей миллиампера; перед шагом — attach обратно
- 1. Зачем трекеру перегородка между фоторезисторами?
- 2. Мёртвую зону уменьшили с 30 до 5 единиц АЦП. Что произойдёт?
- 3. Солнце уходит примерно на градус за четыре минуты. Почему шаг 1° за 50 мс не отстаёт?
- 4. Сколько SG90 держит позицию и что делает detach()?
- 5. В прямой полуденный луч оба LDR выдают около 1000. Что увидит трекер?
Частые вопросы по теме урока
- Зачем трекеру перегородка между фоторезисторами?
- Без перегородки два LDR рядом видят одно небо и разность около нуля. Стенка бросает тень на датчик, от которого ушёл свет, — по знаку разности трекер понимает, куда крутиться. бросает тень на отвернувшийся от света датчик — разность даёт направление
- Мёртвую зону уменьшили с 30 до 5 единиц АЦП. Что произойдёт?
- Разность в покое дрожит на десятки единиц: зона в 5 единиц пропускает этот шум, и платформа качается туда-сюда. Типичная рабочая зона — 20-50 единиц АЦП из 1023. трекер станет трещоткой: платформа будет щёлкать на шуме разности
- Солнце уходит примерно на градус за четыре минуты. Почему шаг 1° за 50 мс не отстаёт?
- Шаг 1° за 50 мс даёт 20°/с — солнце проходит свой градус за 240 с. Запас по скорости огромен, поэтому трекер двигается лениво и экономно, оставаясь в мёртвой зоне. 20 градусов в секунду против градуса за четыре минуты — запас в тысячи раз
- Сколько SG90 держит позицию и что делает detach()?
- Удержание — примерно 10 мА круглосуточно, четверть ампер-часа за сутки. detach() прекращает импульсы, мотор обесточен и потребление падает почти до нуля, но вал держать перестаёт. около 10 мА; detach снимает импульсы и обесточивает мотор
- В прямой полуденный луч оба LDR выдают около 1000. Что увидит трекер?
- На насыщении оба канала прижаты к потолку 1023, и разность сжимается до десятков единиц — прибор слепнет. Это не страшно: платформа уже смотрит на солнце, а слепота внутри мёртвой зоны означает покой. дельту, сжатую до десятков единиц, — слепоту в центре, где она безвредна