Automatyczny przełącznik PV / sieć na Arduino – niezawodny off-grid?

Automatyczny przełącznik PV / sieć na Arduino – niezawodny off-grid?

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.

Schemat połączeń w moim projekcie, stworzony w EasyEDA.

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).

Moduł przełącznika w miejscu docelowym. Tak wiem, że ekran jest krzywo ale nikt z tego strzelał nie będzie a przecież widać wszystko 😅.

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.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *