Kontynuując temat rozpoczęty parę wpisów temu, gdzie to głównie testowaliśmy inwerter i czysto teoretycznie obliczaliśmy czas podtrzymania na baterii, nadszedł w końcu czas na testy w praktyce.
Udało mi się w końcu zaopatrzyć w panel fotowoltaiczny o mocy 100W, a także w regulator ładowania (ten poprzedni to PWM, a teraz mam MPPT, który działa lepiej przy kiepskim nasłonecznieniu) i przełącznik ATS (czyli urządzenie, które automatycznie przełącza się między dwoma źródłami zasilania, w zależności od tego, które w danym momencie jest dostępne). Mogłoby się wydawać, że jesteśmy już ustawieni i nie musimy martwić się o napięcie w sieci. Sytuacja jednak nie wygląda tak różowo. Po testach praktycznych już wiem, że może w lecie przy dobrej pogodzie będę w stanie całkowicie uniezależnić się od sieci miejskiej, ale przy gorszej pogodzie sytuacja zmienia się diametralnie. Aby zapewnić ciągłość zasilania będę musiał monitorować stan zasilania po inwerterze i w razie konieczności przełączyć się na sieć. W tym celu potrzebny mi właśnie ATS, który powinien automatycznie wykonać te czynności. Tutaj jednak napotkałem kolejne problemy.

Sam proces przełączania napięcia jest bardzo głośny (prawie tak jak zwarcie w sieci), a w samym module ATS widać niepokojące iskrzenie na stykach, mimo niewielkiego natężenia prądu. Wymyśliłem więc nieco okrężne i druciarskie rozwiązanie.
Mógłbym za pomocą najlepszej platformy do profesjonalnego migania diodą (zwanej też Arduino) monitorować stan napięcia na panelu PV i baterii, z tych informacji wywnioskować czy jest wystarczające zasilanie aby ładować baterię poprzez energię słoneczną, a jeśli nie i sama bateria jest bliska rozładowaniu – to włączyć przekaźnik który załączy zasilacz 12V do akumulatora aby dostarczyć nam brakujące wolty 😁. Za pomocą takiego rozwiązania eliminujemy twarde przełączanie pomiędzy inwerterem a siecią. Niestety, będzie się to też wiązało ze stratami mocy z uwagi, że będziemy dostarczać napięcie dla inwertera dość okrężną drogą. Niemniej jednak pomyślałem, że warto spróbować. W tym celu zbudowałem układ prototypowo-pająkowy, zamknąłem go w obudowie przystosowanej do montażu na szynie DIN i rozpocząłem testy, na razie symulując różne sytuacje na zasilaczu.

Pora na nieco kodu, korzystając z pomocy ChatGPT (no co, dlaczego by sobie nie pomóc?) udało mi się stworzyć podstawę programu. Po drobnych przeróbkach udało mi się stworzyć coś, co działa zgodnie z założeniami. Tutaj całość programu:
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
// TFT setup
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// Przekaźnik
#define RELAY_PIN 3
// Pomiar napięcia
#define BATT_PIN A0
#define PV_PIN A2
// Dzielnik napięcia: R1 = 100k, R2 = 22k → mnożnik ≈ 5.545
const float VOLTAGE_MULTIPLIER = 5.638;
// Progi
const float BATT_LOW = 12.0; // Próg przełączenia na zasilacz
const float PV_GOOD = 13.0; // PV musi mieć tyle, by wrócić z zasilacza na PV
bool usingBackup = false;
bool blink = false;
void setup() {
tft.initR(INITR_BLACKTAB); // dla ST7735 160x128
tft.setRotation(1);
tft.fillScreen(ST77XX_BLACK);
tft.setTextSize(1);
tft.setTextColor(ST77XX_WHITE);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH);
}
void loop() {
// Pomiar napięć
float batt = analogRead(BATT_PIN) * (5.0 / 1023.0) * VOLTAGE_MULTIPLIER;
float pv = analogRead(PV_PIN) * (5.0 / 1023.0) * VOLTAGE_MULTIPLIER;
// Logika przekaźnika
if (!usingBackup && batt < BATT_LOW) {
digitalWrite(RELAY_PIN, LOW);
usingBackup = true;
} else if (usingBackup && pv >= PV_GOOD) {
digitalWrite(RELAY_PIN, HIGH);
usingBackup = false;
}
// Wyświetlanie
tft.fillScreen(ST77XX_BLACK);
tft.setCursor(5, 5);
tft.print("Batt: "); tft.print(batt, 2); tft.println(" V");
tft.setCursor(5, 25);
tft.print("PV : "); tft.print(pv, 2); tft.println(" V");
tft.setCursor(5, 85);
tft.print("Status: ");
tft.setTextColor(ST7735_GREEN);
if(usingBackup) tft.setTextColor(ST7735_RED);
tft.println(usingBackup ? "AC" : "PV");
tft.setTextColor(ST7735_WHITE);
// Migająca kropka aby wiedzieć, że nic się nie zacięło
blink = !blink;
if (blink) {
tft.setCursor(150, 5);
tft.print("*");
}
delay(3000);
}
Czas na testy. Po symulacjach różnych sytuacji napięciowych stwierdziłem, że mój układ działa poprawnie. Zamontowałem go więc w miejscu docelowym i odpaliłem „produkcyjnie” (choć na razie zasila mniej krytyczne urządzenia sieciowe).

Podsumowując – na ten moment układ działa zgodnie z oczekiwaniami, choć jak wiadomo – prawdziwy test to dopiero codzienne użytkowanie w warunkach produkcyjnych. W najbliższych tygodniach planuję monitorować jego stabilność, skuteczność i wpływ na ogólną ciągłość zasilania. Jeśli rozwiązanie się sprawdzi – być może zostanie rozszerzone o jakieś dodatkowe funkcje. Wrócę do tematu z aktualizacją i wnioskami po dłuższym okresie działania – wtedy też ocenię, czy to rozwiązanie warte było zachodu.
