niedziela, 11 marca 2018

Moduły PV


Moduły PV były założone z myślą o wspomaganiu urządzeń niskonapięciowych (te zasilić najprościej, bez przetwornicy na napięcie 220V). Również w celu rozpoznania ile tak naprawdę można w ciągu roku tej energii wyprodukować.

Wybrałem najtańszy wariant - panele amorficzne (150zł / 85W). Najniższa cena za 1W, ale i największa powierzchnia na 1W. Nie chcąc dziurawić dachu są zamontowane na domku gospodarczym, skierowane na stronę zachodnią (niestety nie było możliwości skierowania na południe).

(podczas montażu)
Panele nieobciążone dają napięcie dochodzące do ~76V. Są połączone równolegle. Za dostosowanie napięcia do 24V (napięcie robocze akumulatorów, 3 pary 12V akku) posłużył kontroler ładowania (bez MPPT). Większość urządzeń podłączonych podłączonych pod obwód (wspomagany PV) jest na 12V (zamiana napięć poprzez przetwornice).

Jak opisałem wcześniej za kontrolę całości odpowiada sterownik (co i kiedy na co przełączyć, co robić z nadwyżką energii). Dla niego PV jest kolejnym modułem, którego działanie jest opisane skryptem. Moduł ten (jak i zresztą wszystkie pozostałe) jest oparty na Arduino Nano (Atmega 328). Za pomiar napięć/prądów odpowiada w nim:

  • wewnętrzny przetwornik A/C (tam gdzie dokładność nie jest tak kluczowa)
  • zewnętrzny przetwornik 16-bitowy ADS1115 (głównie do pomiaru prądu z wykorzystaniem przetworników prąd-napięcie ACS712)


schemat modułu do PV

oraz płytka do niego

W skrócie schemat działania sterownika (w zakresie PV) jest taki:

  • w przypadku nadwyżki energii (względem energii aktualnie pobieranej) przełącz kolejne urządzenia na PV
  • w przypadku gdy więcej energii idzie z akku, a nie z PV - przełączaj kolejne urządzenia na sieć
Aby nie następowało zbyt częste (i zbyt pochopne) przełączanie wykorzystany jest tutaj bufor akumulatorów. Chwilowe zaciemnienie powoduje, że część energii idzie z akumulatorów, które później są doładowywane. Dzięki pomiarom napięcia oraz prądu (i jego kierunku) na buforze można procentowo określić jak mocno akku ma być wykorzystane. Obecnie przyjąłem bezpieczne 30% nominalnej pojemności użytych akku. 

I ile energii z tego jest (?)
Od maja zeszłego roku do chwili obecnej (I połowa marca) 4 (po 85W) panele dostarczyły i zostało użyte ok 95kWh. Rok do roku wyjdzie nieco ponad 100 kWh. Ale panele są niestety na stronie zachodniej, nie mam też układu MPPT.

Tak wygląda dzienna produkcja z 3 dni zeszłego roku.

(wykres zrobiony równolegle pracującym domoticzem)


piątek, 9 marca 2018

W działaniu


A jak całość działa i w gdzie jest przydatna(?)

Te urządzenia w domu które dało się podłączyć są wpięte w sterownik: oświetlenia zewnętrzne i wewnętrzne, akwarium, alarm, siłowniki bramy, sygnalizacje, itd. Tam gdzie przewodów wcześniej nie przewidziałem użyta jest transmisja 2.4GHz i dostęp przez mysensors.

Możliwość kontrolowania całości skryptem pozwala na sporą elastyczność... według potrzeb. Przykładowo oświetlenie zewnętrzne działa wg:

  • włączone zawsze między 23 a  5 rano
  • oraz dodatkowo jeżeli poziom oświetlenia spadnie poniżej 20% (czujnik natężenia światła na fotorezystorze jest wyskalowany od 0-100%) również jest zapalone

Bardziej złożona jest np. kontrola zasilania. Pod sterownik podłączony jest kontroler obsługi paneli fotowoltaicznych (PV - 4x85W) z niedużym buforem w postaci akumulatorów żelowych (6 x 7.2Ah 12V). Kontroler oprócz odczytu prądów (ładowania, poboru, PV) i napięć ma również:
  • przełączać urządzenia z sieci elektrycznej na PV w zależności od naładowania bufora i ew. nadwyżki z PV
  • odłączać kolejne urządzenia (zaczynając od tych z najmniejszym priorytetem) w chwili sytuacji braku prądu w sieci (tak by te najważniejsze mogły pracować na podtrzymaniu)
  • wykorzystać maksymalnie prąd z PV - w sytuacji, gdy wszystkie urządzenia są podłączone pod PV i jest nadwyżka energii, załączane są kolejne LEDy w akwarium
(kontroler PV pomimo, że jest blisko komunikuje się za pomocą NRF24 i mysensors)

Do części urządzeń jest dostęp za pomocą SMS'ów, w skrypcie jest to zrealizowane w taki sposób:


# Polecenie GSM
sms_polecenie = gsmreceive(1)
sms_telefon = gsmgetnr(1)
# (...)
if (wej_alarm_uzbr) 
{
   if (wyj_alarm_ster)
     wyj_alarm_ster = wyj_alarm_ster ^ sms_polecenie == "alarm" 
   else
   {
# (...)

A wysyłanie sms'ów dla konkretnych zdarzeń w sposób następujący:

# (...)
if (czy_godzina_9_dnia_powszedniego_licznik == 0)
{
  czy_godzina_9_dnia_powszedniego_licznik = 1
  gsmsend("Przypomnienie - alarm nie jest uzbrojony", "")
}
# (...)

I tak za pomocą telefonu jest dostęp do sterownika:



SMSy nie są zbyt wygodne przy wysyłaniu długich raportów i do nich użyłem maila. Każdy mail oprócz opisu zdarzenia przekazuje statystykę:
  •  z wejść analogowych za dzień bieżący oraz poprzedni
  • "zrzut" wszystkich zmiennych skryptu (zarówno "pamięciowe" jak i fizyczne)
  • dla każdego fizycznego wejścia/wyjścia 10 ostatnich wartości wraz z czasem 






Statystyka SQL jest tak zrealizowana by można było dokładać kolejne tabelki bez konieczności restartu sterownika. Każde wysłanie maila weryfikuje czy w katalogu aplikacji jest plik SQL o odpowiedniej budowie:
  • w pierwszej linii ma komentarz /*STAT*/
  • w drugiej linii jest tytuł, który pojawi się w mailu
  • od drugiej linii jest zapytanie SQL

I tak dla statystyki dziennej plik ma taką zawartość:

/*STAT*/
/*Minimalne i maksymalne wartości portów analogowych - dzień bieżący*/
select dt.*
      ,(select time(min(wmin.czas)) from Wartosc wmin {...} minczas
      ,(select time(max(wmax.czas)) from Wartosc wmax {...} maxczas
  from
(  
select p.nazwa
  ,p.PortId
      ,min(w.wartosc) minwart
      ,max(w.wartosc) maxwart
  ,round(avg(w.wartosc), 2) srwart
  from Wartosc w 
 inner join Port p
    on p.PortId = w.PortId 
 where p.typ = 'AN'
   and w.czas between date('now') and date('now', '1 days', '-1 seconds')
 group by p.nazwa, p.PortId
) dt


czwartek, 8 marca 2018

Interpreter języka skryptowego


Przyznaję, że ta część całego sterownika najbardziej mi się podoba i stanowiła dla mnie pewien walor edukacyjny - napisanie swojego języka skryptowego. Oczywiście nie jest on specjalnie skomplikowany. Są obsługiwane stałe i zmienne tylko typów (string, int, decimal), kontrola programu pozwala na użycie (if, while) oraz zagnieżdżonych podprogramów (dla if oraz while). Ale... to i tak jest fajne :-)

Źródła z krótką aplikacją konsolową oraz przykładowymi UnitTestami umieściłem pod (link).

Jak to działa.


Parser na wstępie interpretuje czy w danej linii mamy wyrażenie czy instrukcję... albo instrukcję z wyrażeniem. Trzeba też obsłużyć przypadek, gdzie w wyrażeniu znajduję się również instrukcja. Parser w znacznej mierze korzysta z wyrażeń regularnych i tak dla rozpoznania wyrażenia mamy takie dłuższe "krzaki":

^\s*(\d+\.\d+|\w+|""[^""]*"")\s*(\([^)]*\))?\s*([\^+\-*\/%\|\&><]|={2}|!=)?\s*(.*)$

Po sparsowaniu tekstu skryptu otrzymujemy jedną złączoną instrukcję, przykładowo (dla skryptu):

int x = 5
while (x < 5)
{
x = x - 1
print x
}
x = 2
print x

złączenie wygląda tak:

Jak już jest "własny język" to przyszły pomysły na nowe instrukcje. I tak wymieniony wcześniej whiletime() - to taka odmiana while'a. While ze spełnionym zawsze warunkiem (while(true) - czyli nadaje się tylko do głównej, nieskończonej pętli) a w parametrze przyjmuje minimalny czas trwania pętli. Można oczywiście to wykonać zwykłym while'em ale już potrzebne są dodatkowe polecenia pomiaru czasu i użycie przynajmniej jednej zmiennej.


środa, 7 marca 2018

Kontroler


Po rezygnacji z domoticz'a postanowiłem zrobić swój kontroler, współpracujący z mysensors. Jakie przyjąłem założenia:

  • miał być napisany w .NET (najszybciej powstanie, poza tym lubię VisualStudio)
  • logika pracy kontrolera może być zmieniana bez konieczności kompilacji kodu - czyli program "sterownika domowego" musi być w postaci skryptu ew. jakiego pliku konfiguracyjnego
  • skrypt będzie napisany we własnym, dedykowanym języku
  • archiwizacja danych w bazie SQL - wymagań dużych co do motoru nie ma, zatem wybór padł na SQLLite
  • konsola "administracyjna", pozwalająca na dostęp do aplikacji i jej kontrolę na "niskim poziomie" napisana z wykorzystanie .Net Remoting
  • wielowątkowa (obsługa archiwizacji danych czy komunikacji z mysensors nie powinna blokować głównego procesu - logiki sterownika)
  • dostęp do sterownika poprzez WWW (już taki użytkowy, nie administracyjny) - aplikacja w Angularze + webAPI hostowane przez Owin


Najciekawszy oczywiście, bo wykonujący całą logikę sterownika, jest główny proces. Jego zadaniem jest wczytanie skryptu (programu "inteligentnego domu"), jego "kompilacja" i wykonanie. Przyjąłem, że nie skorzystam z gotowych rozwiązań (można użyć chociażby język Lua) tylko napiszę swój interpreter języka skryptowego. 


Sam interpreter opiszę nieco później (zasadę działania z kodem). A jak taki skrypt wygląda...


Wycięty fragment skryptu to sterowanie pompą obiegową ciepłej wody. W głównej pętli (takie dedykowane polecenie whiletime, przyjmujące w parametrze liczbę milisekund ile ma trwać minimalnie), którego czas trwania wynosi 10ms mamy:
  • przygotowanie zmiennej pomocniczej div_5, która posłuży do odmierzania czasu 50ms
  • sprawdzenie czy bieżący czas jest między 5'tą rano, a minutę przed północą
  • a jeżeli powyższy warunek jest spełniony oraz dodatkowo alarm nie jest uzbrojony i nie ma przerwy w zasilaniu - włączana jest pompa obiegowa
Są tutaj wymienione wcześniej dwa rodzaje zmiennych - "fizyczne" (sprzężone z urządzeniami, zarówno podłączonymi przewodowo jak i bezprzewodowo) i "zwykłe" (pamięciowe). Za sprzężenie zmiennych fizycznych odpowiada osobny proces.

Funkcjonalnie ten fragment odpowiada po prostu za odłączenie pompy obiegu ciepłej wody w czasie kiedy nie jest ona potrzebna.


wtorek, 6 marca 2018

Od strony sprzętowej


Sterownik jest postawiony na Raspberry Pi 2, na którym działa Raspbian. Miałem wówczas możliwość wykorzystania (tak porównując do poprzednich swoich 2 rozwiązań na mikrokontrolerach AVR i Stm32):

  • łatwego dostępu do systemu poprzez Ethernet (wraz z narzędziami pomagającymi w utrzymaniu - konsola, lista i kontrola procesów, itd..)
  • innych języków niż C/C++ - tu zależało mi na .NET (aplikacja sterownika pracuje pod Mono), który jest dla mnie najwygodniejszy

Z RPi wykorzystane zostały porty:
  • GPIO - na obsługę przewodowych urządzeń, czujników
  • SPI - do transciver'a NRF24
  • UART - modem GSM


Porty wejścia/wyjścia do obsługi przewodowych urządzeń są dostosowane do logiki 5V. I tak urządzeniami wykonawczymi są przekaźniki oraz 2 buzzery - wszystkie pracują na tym napięciu. Aby zapewnić separację galwaniczną (przewody mają do ok. 15m i są nieekranowane - wręcz gwarantowane zakłócenia) wykorzystałem:
  • PC817 - optoizolator
  • ULN2803 - zespół 8 darlingtonów jako bufor prądowy

Pierwszy darlington ma odciążyć port RPi (maks. pobór prądu 0,3mA, przy wymaganym dla optoizolatora ok 15-20mA), drugi natomiast to bufor zasilający już urządzenie docelowe. Zastosowane przekaźniki pobierają maksymalnie 50mA. Oba zespoły darlingtonów mają własne, odfiltrowane zasilanie - również celem eliminacji zakłóceń. 

Sama realizacja wygląda tak:



Strona wejściowa (wejścia cyfrowe, również logika 5V i zastosowana izolacja) jest zrealizowana z wykorzystaniem tylko optoizolatora PC817 oraz filtrem RC na jego wejściu:


NRF24 oraz moduł GSM są bezpośrednio podpięte pod RPi. Sam NRF również pobiera z niego zasilanie (3.3V). Moduł GSM ma oddzielne zasilanie, z wstawionymi kondensatorami LowESR (łączna pojemność 5000uF) - taki bufor jest z uwagi na chwilowy, możliwy pobór prądu - w pikach może dochodzić do 2A.

Sterownik ma podtrzymanie zasilanie w postaci akumulatora żelowego 12V (1.2Ah), a jedno z wejść GPIO RPi monitoruje obecność napięcia sieciowego.



A całość, już zamontowana we "wnęce z drzwiczkami" wygląda tak:


poniedziałek, 5 marca 2018

domoticz - mysensors - arduino


Pierwsze zainstalowane i używane to połączenie:
  • domoticz'a (strona projektu) - jako kontroler
  • mysensors (link) - rozwiązanie wspierające komunikację bezprzewodową oraz dające "szkielet" aplikacji dla node'ów
Sam domoticz jest bardzo wygodnym rozwiązaniem. Ma przyjazny interfejs ze wsparciem urządzeń mobilnych, możliwość tworzenia wykresów na podstawie zapamiętanych danych. Dostępne są również widgety na Androida. Bardziej rozbudowaną logikę można tworzyć za pomocą skryptów Lua bądź "programowania drabinkowego".


Ale domoticz jako kontroler nie spełnił wszystkich oczekiwań:
  • nie współpracował (być może już uległo zmianie) z GSM (dwukierunkowo)
  • przewodowe urządzenia były podpięte pod Raspberry PI (poprzez optoizolację do GPIO) - domoticz miał problemy z szybkim odczytem tych portów (zwłoka w czasie była niekiedy rzędu 5-10 sekund)

Co potrzebowałem, czego szukałem


Zaczynając.... w tym blogu postaram się przybliżyć Wam przyjęte przeze mnie rozwiązanie w temacie tzw. inteligentnego domu. 

Wyszukując rozwiązania dla siebie czego szukałem:
  • możliwość obsługi urządzeń podłączonych przewodem jak i bezprzewodowych; wynikało to z faktu, że na etapie budowy o niektórych urządzeniach wiedziałem, a niektóre nie przyszły mi wtedy do głowy :-)
  • bezpieczna separacja między siecią bezprzewodową a przewodową (wykluczenie ingerencji, "włamania" poprzez sieć bezprzewodową); w sieci przewodowej jest np. alarm włamaniowy
  • autonomiczne działanie części urządzeń (w przypadku przerwania komunikacji z kontrolerem) - np. brama ma się zamknąć niezależnie od działania systemu
  • wsparcie GSM (wysyłanie powiadomień, możliwość sterowania sms'ami)
  • wsparcie e-mail (szczegółowe raporty)
  • względnie krótki czas reakcji (od czasu zdarzenia przekazanego do kontrolera, do "wydania" polecenia przez kontroler); czas liczony w milisekundach (do 100-200[ms])
  • możliwość archiwizacji odczytanych danych z sensorów

Ogólnie (na dużych klockach) całość powinna wyglądać tak (i tak też jest przedstawiana na wielu stronach):