Зарядная станция с автоматической ориентацией солнечных панелей
Зарядная станция с автоматической ориентацией солнечных панелей
Прошлым летом я приобрел небольшой солнечный модуль. В инструкции по эксплуатации указано, что его следует ориентировать на юг с углом наклона 35°, чтобы заряжать аккумулятор на 3,7 В через модуль Solar Power Manager.
Однако, чтобы днем он всегда был направлен в сторону солнца, я решил попробовать построить полностью автоматический следящий механизм с помощью датчика освещенности и двух сервоприводов.
Как всегда, я действовал постепенно. Сначала протестировал датчик освещенности, затем сервоприводы. Затем было интересно наблюдать за взаимодействием компонентов при поиске самой яркой точки.
Самое важное было задокументировано здесь, и я надеюсь, что это вдохновит кого-нибудь на создание собственной версии.
Когда версия 1 с Arduino была готова и работала, я сразу же создал вторую версию с платой ESP32, с тем чтобы при переходе в спящий режим устройство потребляло меньше энергии и, таким образом, более эффективно заряжало аккумулятор.
Но как же измерить интенсивность света?
Наиболее эффективная длина волны для наиболее распространенных солнечных батарей лежит в видимом диапазоне спектра света. Световой поток в 1 люмен, падающий на площадь 1 м², освещает ее (в среднем) с интенсивностью 1 люкс.
Интенсивность освещенности – Википедия
Итак, сначала поиск подходящего датчика освещенности.
Оборудование 1: Измерение освещенности с помощью GY-30

Плата расширения датчика освещенности GY-30 / BH1750FVI оснащена фотодиодом, способным улавливать большую часть видимого света в диапазоне примерно от 400 до 700 нм. Чем ярче свет, тем выше значение освещенности в люксах, выдаваемое 16-разрядным аналого-цифровым преобразователем. Плата может выполнять как непрерывные, так и единичные измерения. Управление осуществляется через интерфейс I2C, питание — от 3,3 до 5 В.
Технические характеристики датчика освещенности GY-30
Подключение, часть 1:

Исходный код для теста датчика освещенности:
Первое измерение освещенности в люксах.
#include "BH1750FVI.h" BH1750FVI myLux(0x23); uint32_t lastUpdate = 0; void setup() { Serial.begin(115200); Serial.println(); Serial.print(__FILE__);// liefert den Pfad zur aktuellen Datei Serial.println(); Wire.begin(); // für arduino uno // Wire.begin(23,19); // für lolin32 lite an SDA (Serial Data): Pin 23 und SCL (Serial Clock): Pin 19 myLux.powerOn(); myLux.setContHighRes(); // Für kontinuierliche Messung // myLux.setOnceHighRes();// Für einmalige Messung - Stromsparmodus } void loop() { uint16_t interval = 100; if (millis() - lastUpdate >= interval) { lastUpdate += interval; float val = myLux.getLux(); Serial.println(val, 1); } delay(1000); // myLux.setOnceHighRes();// Für einmalige Messung - Stromsparmodus }
Еще одним открытием стало то, что библиотека для датчика освещенности позволяет выполнять однократное измерение, чтобы впоследствии сэкономить энергию. Однако в таком случае при каждом новом измерении необходимо вводить myLux.setOnceHighRes();. Измерение с помощью USB-тестера напряжения не показало никаких изменений. Поэтому я пока оставил это без внимания.
Оборудование 2: Сервопривод MG996R
MG996R — это цифровой микросервопривод, известный своим применением в дистанционно управляемых роботах, вертолетах и самолетах.
Он оснащен металлической передачей для повышенной прочности и может поворачиваться в диапазоне около 180 градусов. Его положение можно регулировать с высокой точностью.
Благодаря своей низкой стоимости и простоте в обращении он пользуется популярностью у любителей-конструкторов, и, следовательно, у меня.
Технические характеристики сервопривода
Подключение, часть 2:

Исходный код
Для начала — тест с одним сервоприводом:
#include <Servo.h> //für Arduino Uno Servo servo; // Servo-Objekt erstellen für Arduino const int servoPin = 9; // servo1 gelb unten horizontal an Pin 9 void setup() { servo.attach(servoPin); // } void loop() { servo.write(0); // move MG996R's shaft to angle 0° delay(1000); // wait for one second servo.write(45); // move MG996R's shaft to angle 45° delay(1000); // wait for one second servo.write(90); // move MG996R's shaft to angle 90° delay(1000); // wait for one second servo.write(135); // move MG996R's shaft to angle 135° delay(1000); // wait for one second servo.write(180); // move MG996R's shaft to angle 180° delay(1000); // wait for one second }
Теперь тест с двумя сервоприводами:
#include <Servo.h> Servo servo1; // der MG 996R servo1 Servo servo2; // der MG 996R servo2 void setup() { servo1.attach(9); // servo1 gelb unten horizontal an Pin 9 servo2.attach(10); // orange servo2 oben vertikal an Pin 10 } void loop() { servo2.write(45); // move MG996R's shaft to angle 0° delay(1000); // wait for one second servo1.write(45); // move MG996R's shaft to angle 45° delay(1000); // wait for one second servo2.write(90); // move MG996R's shaft to angle 90° delay(1000); // wait for one second servo1.write(90); // move MG996R's shaft to angle 135° delay(1000); // wait for one second servo2.write(135); // move MG996R's shaft to angle 180° delay(1000); // wait for one second servo1.write(135); // move MG996R's shaft to angle 180° delay(1000); // wait for one second }
Третье испытание:
Датчик освещенности управляет сервоприводом, GY-30 и MG996r одновременно
Теперь датчик освещенности и оба сервопривода работают вместе для первоначального горизонтального сканирования с целью нахождения самой яркой точки.
Подключение, часть 3:

Исходный код для сканирования:
Тестовое сканирование самой яркой точки по горизонтали
#include "BH1750FVI.h" #include <Servo.h> BH1750FVI myLux(0x23); uint32_t lastUpdate = 0; Servo servo1; // der MG996R servo1 Servo servo2; // der MG996R servo2 void setup(){ Wire.begin(); myLux.powerOn(); myLux.setContHighRes(); servo1.attach(9); // servo1 gelb unten horizontal an Pin 9 servo2.attach(10); // orange servo2 oben vertikal an Pin 10 } void loop() { int maxLightIntensity = 0; // Maximal gemessene Lichtintensität int maxAngle = 0; // Winkel mit der höchsten Lichtintensität // Durchlaufe alle Winkel von 0 bis 180 Grad for(int angle = 0; angle <= 180; angle += 10){ servo1.write(angle); // Drehe den Servo auf den aktuellen Winkel delay(200); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if(lux > maxLightIntensity){ maxLightIntensity = lux; maxAngle = angle; } } // Drehe den Servo auf den Winkel mit der höchsten Lichtintensität servo1.write(maxAngle); delay(10000); // Warte einen Moment, bevor der nächste Durchlauf beginnt }
Тест сканирования самой яркой точки по горизонтали и вертикали
#include "BH1750FVI.h" #include <Servo.h> BH1750FVI myLux(0x23); Servo servo1; // der MG 996R servo1 Servo servo2; // der MG 996R servo2 void setup(){ Serial.begin(115200); Serial.println(); Serial.print(__FILE__);// liefert den Pfad zur aktuellen Datei Serial.println(); Wire.begin(); myLux.powerOn(); myLux.setContHighRes(); servo1.attach(9); // servo1 gelb unten horizontal an Pin 9 servo2.attach(10); // orange servo2 oben vertikal an Pin 10 servo1.write(90); servo2.write(90); } void loop() { int maxLightIntensity1 = 0; // Maximal gemessene Lichtintensität horizontal int maxAngle1 = 0; // Winkel mit der höchsten Lichtintensität horizontal int maxLightIntensity2 = 0; // Maximal gemessene Lichtintensität vertikal int maxAngle2 = 0; // Winkel mit der höchsten Lichtintensität vertikal // Durchlaufe alle Winkel von 0 bis 180 Grad horizontal for(int angle1 = 0; angle1 <= 180; angle1 += 10){ servo1.write(angle1); // Drehe den Servo auf den aktuellen Winkel delay(500); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if(lux > maxLightIntensity1){ maxLightIntensity1 = lux; maxAngle1 = angle1; Serial.print("MaxLux1: "); Serial.println(maxLightIntensity1, 1); Serial.print("Bester Winkel horizontal: "); Serial.println(maxAngle1, 1); } } // Durchlaufe alle Winkel von 0 bis 180 Grad vertikal for(int angle2 = 20; angle2 <= 160; angle2 += 10){ servo2.write(angle2); // Drehe den Servo auf den aktuellen Winkel delay(500); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if(lux > maxLightIntensity2){ maxLightIntensity2 = lux; maxAngle2 = angle2; Serial.print("MaxLux2: "); Serial.println(maxLightIntensity2, 1); Serial.print("Bester Winkel horizontal: "); Serial.println(maxAngle2, 1); } } // Drehe den Servo auf den Winkel mit der höchsten Lichtintensität servo1.write(maxAngle1); servo2.write(maxAngle2); Serial.print("Bester Winkel 1 und 2 : "); Serial.print(maxAngle1, 1); Serial.print(" und "); Serial.println(maxAngle2, 1); delay(10000); // Warte einen Moment, bevor der nächste Durchlauf beginnt }
Чтобы обеспечить полное сканирование на 360 градусов с помощью 180-градусных сервоприводов, необходимо выполнить 3 цикла.
1-й проход: все углы от 0 до 180 градусов по горизонтали при 35 градусах по вертикали.
2-й проход: все углы от 0 до 180 градусов по горизонтали при 145 градусах по вертикали.
3-й проход: все углы от 0 до 180 градусов по вертикали с оптимальным значением по горизонтали.
#include "BH1750FVI.h" #include <Servo.h> BH1750FVI myLux(0x23); Servo servo1; // der MG 996R servo1 Servo servo2; // der MG 996R servo2 void setup(){ Serial.begin(115200); Serial.println(); Serial.print(__FILE__); // liefert den Pfad zur aktuellen Datei Serial.println(); Wire.begin(); myLux.powerOn(); myLux.setContHighRes(); // Für kontinuierliche Messung servo1.attach(9); // servo1 gelb unten horizontal an Pin 9 servo2.attach(10); // orange servo2 oben vertikal an Pin 10 servo1.write(90); servo2.write(90); } void loop() { int maxLightIntensity1 = 0; // Maximal gemessene Lichtintensität horizontal int maxAngle1 = 0; // Winkel mit der höchsten Lichtintensität horizontal int maxLightIntensity2 = 0; // Maximal gemessene Lichtintensität vertikal int maxAngle2 = 0; // Winkel mit der höchsten Lichtintensität vertikal // Durchlauf alle Winkel von 0 bis 180 Grad horizontal bei 35 Grad servo2.write(35); for(int angle1 = 0; angle1 <= 180; angle1 += 10){ servo1.write(angle1); // Drehe den Servo auf den aktuellen Winkel delay(500); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if(lux > maxLightIntensity1){ maxLightIntensity1 = lux; maxAngle1 = angle1; Serial.print("MaxLux1: "); Serial.println(maxLightIntensity1, 1); Serial.print("Bester Winkel horizontal: "); Serial.println(maxAngle1, 1); } } // Durchlauf alle Winkel von 0 bis 180 Grad horizontal bei 145 Grad servo2.write(145); for(int angle1 = 180; angle1 >= 0; angle1 -= 10){ servo1.write(angle1); // Drehe den Servo auf den aktuellen Winkel delay(500); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if(lux > maxLightIntensity1){ maxLightIntensity1 = lux; maxAngle1 = angle1; Serial.print("MaxLux1: "); Serial.println(maxLightIntensity1, 1); Serial.print("Bester Winkel horizontal: "); Serial.println(maxAngle1, 1); } } // Durchlauf alle Winkel von 0 bis 180 Grad vertikal mit bester Wert bei horizontal servo1.write(maxAngle1); for(int angle2 = 30; angle2 <= 150; angle2 += 10){ servo2.write(angle2); // Drehe den Servo auf den aktuellen Winkel delay(500); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if(lux > maxLightIntensity2){ maxLightIntensity2 = lux; maxAngle2 = angle2; Serial.print("MaxLux2: "); Serial.println(maxLightIntensity2, 1); Serial.print("Bester Winkel horizontal: "); Serial.println(maxAngle2, 1); } } // Drehe den Servo auf den Winkel mit der höchsten Lichtintensität servo1.write(maxAngle1); servo2.write(maxAngle2); Serial.print("Bester Winkel 1 und 2 : "); Serial.print(maxAngle1, 1); Serial.print(" und "); Serial.println(maxAngle2, 1); delay(300000); // Warte 5 Minuten, bevor der nächste Durchlauf beginnt }
Попробуй ускорить процесс:
Сократи время измерения после обнаружения максимального значения. (В ходе длительного тестирования этот метод не всегда эффективен в зависимости от облачности)
#include "BH1750FVI.h" #include <Servo.h> BH1750FVI myLux(0x23); Servo servo1; // der MG 996R servo1 Servo servo2; // der MG 996R servo2 void setup(){ Serial.begin(115200); Serial.println(); Serial.print(__FILE__); // liefert den Pfad zur aktuellen Datei Serial.println(); Wire.begin(); myLux.powerOn(); myLux.setContHighRes(); servo1.attach(9); // servo1 ist am Arduino an Pin 9 servo2.attach(10); // orange servo2 oben vertikal an Pin 10 } void loop() { int maxLightIntensity1 = 0; // Maximal gemessene Lichtintensität horizontal int maxAngle1 = 0; // Winkel mit der höchsten Lichtintensität horizontal int maxLightIntensity2 = 0; // Maximal gemessene Lichtintensität vertikal int maxAngle2 = 0; // Winkel mit der höchsten Lichtintensität vertikal // Durchlaufe alle Winkel von 0 bis 180 Grad horizontal bei 35 Grad servo2.write(35); for(int angle1 = 0; angle1 <= 180; angle1 += 10){ servo1.write(angle1); // Drehe den Servo auf den aktuellen Winkel delay(500); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if(lux > maxLightIntensity1){ maxLightIntensity1 = lux; maxAngle1 = angle1; Serial.print("MaxLux1: "); Serial.println(maxLightIntensity1, 1); Serial.print("Bester Winkel horizontal: "); Serial.println(maxAngle1, 1); } else if(lux < maxLightIntensity1){ // Bei abnehmender Helligkeit, breche die Schleife ab break; } } // Durchlaufe alle Winkel von 0 bis 180 Grad horizontal bei 120 Grad servo2.write(120); for(int angle1 = 180; angle1 >= 0; angle1 -= 10){ servo1.write(angle1); // Drehe den Servo auf den aktuellen Winkel delay(500); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if(lux > maxLightIntensity1){ maxLightIntensity1 = lux; maxAngle1 = angle1; Serial.print("MaxLux1: "); Serial.println(maxLightIntensity1, 1); Serial.print("Bester Winkel horizontal: "); Serial.println(maxAngle1, 1); } else if(lux < maxLightIntensity1){ // Bei abnehmender Helligkeit, breche die Schleife ab break; } } // Durchlaufe alle Winkel von 0 bis 180 Grad vertikal servo1.write(maxAngle1); for(int angle2 = 30; angle2 <= 150; angle2 += 10){ servo2.write(angle2); // Drehe den Servo auf den aktuellen Winkel delay(500); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if(lux > maxLightIntensity2){ maxLightIntensity2 = lux; maxAngle2 = angle2; Serial.print("MaxLux2: "); Serial.println(maxLightIntensity2, 1); Serial.print("Bester Winkel horizontal: "); Serial.println(maxAngle2, 1); } else if(lux < maxLightIntensity2){ // Bei abnehmender Helligkeit, breche die Schleife ab break; } } // Drehe den Servo auf den Winkel mit der höchsten Lichtintensität servo1.write(maxAngle1); servo2.write(maxAngle2); Serial.print("Bester Winkel 1 und 2 : "); Serial.print(maxAngle1, 1); Serial.print(" und "); Serial.println(maxAngle2, 1); delay(300000); // Warte 5 Minuten, bevor der nächste Durchlauf beginnt }
Пока что почти всё работает. В качестве текущей финальной версии я использую поиск оптимального угла в 3 прогонах.
Теперь осталось подключить Servo Power Manager и аккумулятор (схема подключения показана на Lolin32) — и можно приступать к измерению потребляемого тока. Потребление Arduino составляет 0,058 А·ч.
Версия на Arduino готова.
Вторая версия с платой ESP32 Lolin32 Lite
В этой второй версии я заменил плату Arduino на Lolin32 Lite. Я хочу провести более длительное тестирование, чтобы проверить, будет ли плата без проблем работать с сервомоторами, когда она переходит в спящий режим. Первые измерения показывают, что во время «сна» потребление снижается с 0,052 Ач до 0,008 Ач.
Подключение с Lolin32 Lite:

Тест датчика освещенности:
Скетч для тестирования измерения освещенности идентичен версии для Arduino; необходимо лишь добавить в функцию setup строку wire.begin() с указанием номера вывода: SDA (последовательные данные) — на вывод 23, а SCL (последовательный такт) — на вывод 19.

Исходный код теста сервопривода на Lolin32:
Вот скетч для второго теста сервопривода с использованием библиотеки esp32servo (версия 1.1.2) и для проверки, не затянут ли где-нибудь кабели или не мешают ли они.
#include <Arduino.h> #include <ESP32Servo.h> // Die ESP32Servo-Bibliothek einbinden const int servoPin1 = 5; // gelb servo 1 unten horizontal an Pin 5 const int servoPin2 = 18; // orange servo 2 oben vertikal an Pin 18 Servo myServo1; // Servo1-Objekt erstellen Servo myServo2; // Servo2-Objekt erstellen void setup() { myServo1.attach(servoPin1); myServo2.attach(servoPin2); } void loop() { myServo2.write(90); // Servo 2 auf 90 Grad (Mittelstellung) drehen delay(5000); myServo1.write(90); // Servo1 auf 90 Grad (Mittelstellung) drehen delay(5000); // 5 Sekunde warten myServo1.write(0); delay(5000); myServo1.write(180); delay(5000); myServo2.write(30); // Servo 2 auf 30 Grad drehen delay(5000); myServo1.write(0); delay(5000); myServo1.write(90); delay(5000); myServo1.write(180); delay(5000); myServo2.write(150); // Servo 2 auf 150 Grad drehen delay(5000); myServo1.write(0); delay(5000); myServo1.write(90); delay(5000); myServo1.write(180); delay(5000); }
Исходный код финальной версии от Lolin32:
Вот мой текущий финальный скетч с отключенной возможностью сокращения времени сканирования:
#include "BH1750FVI.h" #include <Arduino.h> #include <ESP32Servo.h> // Die ESP32Servo-Bibliothek einbinden const int servoPin1 = 5; // gelb servo1 unten horizental an Pin 5 const int servoPin2 = 18; // orange servo2 oben vertikal an Pin 18 BH1750FVI myLux(0x23); Servo Servohorizontal; // Servo 1 Objekt erstellen Servo Servovertikal; // Servo 2 Objekt erstellen void setup() { Serial.begin(115200); Serial.println(); Serial.print(__FILE__); // liefert den Pfad zur aktuellen Datei Serial.println(); Wire.begin(23, 19); // für lolin32 lite an SDA (Serial Data): Pin 23 und SCL (Serial Clock): Pin 19 Servohorizontal.attach(servoPin1); Servovertikal.attach(servoPin2); myLux.powerOn(); myLux.setContHighRes(); // Für kontinuierliche Messung } void loop() { int maxLichtstaerkehoriz = 0; // Maximal gemessene Lichtintensität horizontal int maxWinkelHorizont = 0; // Winkel mit der höchsten Lichtintensität horizontal int maxLichtstaerkevert = 0; // Maximal gemessene Lichtintensität vertikal int maxWinkelvertikal = 0; // Winkel mit der höchsten Lichtintensität vertikal // Durchlaufe alle Winkel von 0 bis 180 Grad horizontal bei 35 Grad vertikal Servovertikal.write(25); for (int winkelhorizontal = 0; winkelhorizontal <= 180; winkelhorizontal += 10) { Servohorizontal.write(winkelhorizontal); // Drehe den Servo auf den aktuellen Winkel delay(100); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if (lux > maxLichtstaerkehoriz) { maxLichtstaerkehoriz = lux; maxWinkelHorizont = winkelhorizontal; Serial.print("Schleife 1: "); Serial.print("MaxLux1: "); Serial.println(maxLichtstaerkehoriz, 1); Serial.print("Bester Winkel horizontal: "); Serial.println(maxWinkelHorizont, 1); delay(1000); } // else if (lux < maxLichtstaerkehoriz) { // Bei abnehmender Helligkeit, breche die Schleife ab // Serial.println("breche die Schleife 1 ab"); // delay(1000); // break; // } } // Durchlaufe alle Winkel von 0 bis 180 Grad horizontal bei 120 Grad Servovertikal.write(140); for (int winkelhorizontal = 180; winkelhorizontal >= 0; winkelhorizontal -= 10) { Servohorizontal.write(winkelhorizontal); // Drehe den Servo auf den aktuellen Winkel delay(100); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if (lux > maxLichtstaerkehoriz) { maxLichtstaerkehoriz = lux; maxWinkelHorizont = winkelhorizontal; Serial.print("Schleife 2: "); Serial.print("MaxLux1: "); Serial.println(maxLichtstaerkehoriz, 1); Serial.print("Bester Winkel horizontal: "); Serial.println(maxWinkelHorizont, 1); delay(1000); } // else if (lux < maxLichtstaerkehoriz) { // Serial.println("breche die Schleife 2 ab"); // delay(1000); // Bei abnehmender Helligkeit, breche die Schleife ab // break; // } } // Durchlaufe alle Winkel von 0 bis 180 Grad vertikal Servohorizontal.write(maxWinkelHorizont); for (int angle2 = 30; angle2 <= 150; angle2 += 10) { Servovertikal.write(angle2); // Drehe den Servo auf den aktuellen Winkel delay(100); // Warte einen Moment, damit sich der Servo drehen kann uint16_t lux = myLux.getLux(); // Lese die Lichtintensität if (lux > maxLichtstaerkevert) { maxLichtstaerkevert = lux; maxWinkelvertikal = angle2; Serial.print("Schleife 3: "); Serial.print("MaxLux2: "); Serial.println(maxLichtstaerkevert, 1); Serial.print("Bester Winkel horizontal: "); Serial.println(maxWinkelvertikal, 1); delay(1000); } // else if (lux < maxLichtstaerkevert) { // Serial.println("breche die Schleife 3 ab"); // delay(1000); // Bei abnehmender Helligkeit, breche die Schleife ab // Bei abnehmender Helligkeit, breche die Schleife ab // break; // } } // Drehe den Servo auf den Winkel mit der höchsten Lichtintensität Servohorizontal.write(maxWinkelHorizont); Servovertikal.write(maxWinkelvertikal); Serial.print("Bester Winkel 1 und 2 : "); Serial.print(maxWinkelHorizont, 1); Serial.print(" und "); Serial.println(maxWinkelvertikal, 1); // Warte 5 Minuten, bevor der nächste Durchlauf beginnt // delay(300000); esp_sleep_enable_timer_wakeup(300 * 1000000); // Setze die Schlafdauer (5 Minuten = 300.000.000 Mikrosekunden) esp_deep_sleep_start(); // Betrete den Deep-Sleep-Modus. Manuell aufwecken mit Reset-Taste. }
Финальная зарядная станция:
Поскольку в прошлые выходные было два солнечных дня без дождя, в конце дня я смог зарядить с её помощью два смартфона через разъем USB-A (5 В / 1 А).
Что мне пока не понравилось, так это то, что аккумуляторный блок находится под воздействием солнца, и эта версия подходит только для использования в хорошую погоду.
На фотографии уже видна вторая тестовая версия опорной пластины с крышкой, к которой, вероятно, еще будут добавлены боковые стенки.

Используемые библиотеки:
Для датчика освещенности с обеими платами микроконтроллера:
GitHub – RobTillaart/BH1750FVI_RT: библиотека Arduino для датчика освещенности BH1750FVI (GY-30)
Для сервопривода MG996r:
На Arduino Uno: Servo (установлена по умолчанию)
На Lolin32 Lite: esp32servo
Дополнительное оборудование:
Солнечная панель 3,5 Вт
Модуль управления солнечной энергией без аккумулятора 14500, так как емкость составляет всего 800 мАч
Аккумулятор LiPo 10000 мАч, 3,7 В с разъемом PH2.0A
Технические характеристики производителя:
Датчик освещенности GY-30
Сервопривод MG996R
Управление солнечной энергией: http://www.waveshare.com/wiki/Solar_Power_Manager
Расположение выводов Arduino:
Схема расположения выводов Arduino Uno Rev3 – Prilchen tüftelt
Расположение выводов Lolin32:
Схема расположения выводов ESP32 LOLIN32 (Lite) – Prilchen tüftelt
3D-печать:
Всего для печати требуется 5 деталей, базовая плата доступна для Arduino Uno и Lolin32 Lite.
Базовая платформа размером 20 x 20 см предоставляет дополнительное место для Solar Panel Manager и аккумулятора на 3,7 В.
Крепление для солнечной панели рассчитано на размер 13,5 x 16,5 см.
Печать выполнялась с использованием нити PETG.
Солнечная панель и MG996R_servo1 были склеены с помощью клея для ПВХ-U от Tangit. На PETG держится надежно!
Сервоприводы были закреплены прилагающимися винтами. Остальные детали — саморезами M2x4 и M2x10.




























