PRACA DYPLOMOWA INŻYNIERSKA™ga_… · Zajmuje się pełnym cyklem tworzenia aplikacji mobilnych...
Transcript of PRACA DYPLOMOWA INŻYNIERSKA™ga_… · Zajmuje się pełnym cyklem tworzenia aplikacji mobilnych...
Rok akademicki 2012/2013
Politechnika WarszawskaWydział Elektroniki i Technik Informacyjnych
Instytut Informatyki
PRACA DYPLOMOWA INŻYNIERSKA
Maciej Ciemięga
Beerduino – system wspomagania procesu warzenia piwa z wykorzystaniem platform Arduino (ADK) oraz
Android.
Opiekun pracydr hab. inż. Piotr Gawrysiak
Ocena: .....................................................
.................................................................Podpis Przewodniczącego
Komisji Egzaminu Dyplomowego
Kierunek: Informatyka
Specjalność: Inżynieria Systemów Informatycznych
Data urodzenia: 1989.05.02
Data rozpoczęcia studiów: 2008.10.01
ŻYCIORYS
Urodziłem się 5 maja 1989 roku w Warszawie. W latach 2005-2008 uczęszczałem do LXX Liceum Ogólnokształcącego imienia Aleksandra Kamińskiego w Warszawie o profilu mat-fiz-geo, z warsztatami grafiki komputerowej. Maturę zdałem w 2008 roku, uzyskując wynik 94% z matematyki na poziomie rozszerzonym oraz 75% z fizyki, również na poziomie rozszerzonym. Od 2008 roku studiuję na wydziale Elektroniki i Technik Informacyjnych (studia I stopnia) na Politechnice Warszawskiej, kierunek Informatyka. Na początku semestru zimowego 2010/2011 wybrałem specjalizację Inżynieria Systemów Informatycznych. W czerwcu 2011 roku rozpocząłem pracę na 3/4 etatu w firmie Mobo Studio S.C, aby w lutym 2012 roku przejść na pełny etat. Zajmuje się pełnym cyklem tworzenia aplikacji mobilnych na platformę Android w językach Java, XML oraz SQLite.
Platformą Android interesuję się już 4 lata. W lipcu 2009 roku, widząc potencjał systemu, kupiłem telefon Era G1 (HTC Dream). Od tego momentu nieprzerwanie rozwijałem swoje umiejętności programowania na Androida, zarówno hobbistycznie, jak i zawodowo w pracy. Od września 2009 roku osobiście tworzę aplikację popularnego słownika internetowego Ling.pl na platformę Android. Pod koniec tego samego roku współtworzyłem aplikację ContactSign dla Start-upu o takiej samej nazwie. Na początku roku 2010 rozpocząłem pisanie dwuosobowej gry internetowej Mobnetic Soccer. Gra uzyskała wyniki ponad 120 000 pobrań i ocenę 4/5 gwiazdek w sklepie Android Market (dzisiejszy sklep Google Play Store). Jako twórca tej aplikacji zostałem nagrodzony telefonem Google Nexus One w programie „Device Seeding Program for Top Android Market Developers”.
Moimi zainteresowaniami, obok tematyki urządzeń mobilnych, są pływanie (basen), siłownia, piwowarstwo amatorskie, snowboard oraz żeglarstwo śródlądowe (patent żeglarza jachtowego).
....................................................... Podpis studenta
EGZAMIN DYPLOMOWY
Złożył egzamin dyplomowy w dniu ..................................................................................2013 r
z wynikiem ...................................................................................................................................
Ogólny wynik studiów: ................................................................................................................
Dodatkowe wnioski i uwagi Komisji: ..........................................................................................
.......................................................................................................................................................
.......................................................................................................................................................
STRESZCZENIE
Proces zacierania i chmielenia piwa pochłania duże ilości czasu – rozpoczęty w okolicach południa potrafi trwać do późnego wieczora. Korzystając z posiadanej wiedzy, postanowiłem ułatwić sobie życie poprzez częściową automatyzacje problemu. Tak właśnie powstał system Beerduino, którego tworzenie pozwoliło mi na ciekawe rozpoczęcie przygody z mikrokontrolerem Arduino oraz jego komunikacją z urządzeniami działającym pod kontrolą systemu Android.
System posiada funkcje odliczania czasu dzięki wykorzystaniu timerów mikrokontrolera. Poprzez dołączenie do niego czujnika temperatury potrafi on na bieżąco zbierać informacje o przyrządzanym piwie i podejmować w związku z tym odpowiednie akcje. Aby system zyskał możliwości oddziaływania na przebieg procesu, dołączone zostały grzałka oraz silnik mieszadła. Dodatkowo zaimplementowany kontroler PID pozwala na samodzielny nadzór fazy podgrzewania brzeczki, co znacząco odciąża piwowara w tak prostych czynnościach.
System prezentuje przepis zdekomponowany na poszczególne kroki, co pomaga pilnować wykonania każdego z nich, a śledzenie aktualnie wykonywanego kroku ułatwia zorientowanie się w stopniu zaawansowania procesu. Każdy krok posiada wypisany tytuł, jasno definiujący jego znaczenie. Wszystko to zaprezentowane jest w przyjaznej użytkownikowi formie graficznej na ekranie jego urządzenia z systemem Android. W przypadku, gdy nastąpi zmiana kroku i wymagana jest interakcja użytkownika, system poinformuje o tym fakcie powiadomieniem dźwiękowym.
Słowa kluczowe: piwo, brzeczka, słody, mikrokontroler, Arduino, Android, Java, temperatura, kontroler, PID, podgrzewanie, warzenie, chmielenie, mieszadło.
BEERDUINO – BREWING PROCESS SUPPORT SYSTEM WITH THE USE OF ARDUINO (ADK) AND ANDROID PLATFORMS.
The process of mashing and hopping beer is highly time-consuming – it can last until late evening hours when started around noon. With the use of possessed knowledge I decided to make my life easier by partial automation of the process. This is how Beerduino system was created, whose development enabled me to commence my adventure with Arduino microcontroller and its communication with other devices operating on the Android system.
The system is equipped with the function of time countdown thanks to the use of timers of the microcontroller. Thanks to attachment of a temperature sensor it can gather up-to-date information on the prepared beer and undertake appropriate actions. In order for the system to gain the possibility to influence on the course of the process, it was equipped with a heater and an engine of a stirrer. Moreover, a PID controller implemented makes it possible to personally supervise the heating phases of the wort, which significantly reduces the amount of work of the brewer with so simple actions.
The system presents the recipe decomposed into particular steps, which is helpful in supervising the execution of each of them, and monitoring of currently executed step makes it easier to inspect the advancement of the process. Each step has an assigned title, clearly defining its role. All of it is presented in a user-friendly graphic form on a screen of the user’s device with Android system. In the event that a change of step occurs and the user’s interaction is required, the system will indicate such fact with a sound signal.
Keywords: beer, wort, malts, microcontroller, Arduino, Android, Java, temperature, controller, PID, heating, brewing, hopping, stirrer.
Spis treściObjaśnienia używanych nazw i skrótów.....................................................................................9
Wstęp........................................................................................................................................10
Motywacja oraz cel pracy.....................................................................................................10
Struktura pracy.....................................................................................................................11
1. Informacje podstawowe........................................................................................................12
1.1. Przykładowy przepis.....................................................................................................12
1.2. Poglądowy opis przebiegu procesu zacierania i chmielenia.........................................13
2. Przegląd podobnych rozwiązań............................................................................................16
2.1. BrewPi...........................................................................................................................16
2.2. BrewTroller...................................................................................................................18
3. Rozwiązanie sprzętowe.........................................................................................................20
3.1. Spis użytego sprzętu......................................................................................................20
3.2. Opis podłączeń..............................................................................................................21
4. Program na platformę Arduino.............................................................................................24
4.1. Wstępny opis.................................................................................................................24
4.2. Opis klas używanych w procesie...................................................................................25
4.3. Typy kroków TimeStep.................................................................................................27
4.4. Timer i operacje związane z czasem.............................................................................29
4.5. Komunikaty wejściowe.................................................................................................33
4.5.1. Wgranie przepisu i rozpoczęcie procesu...............................................................33
4.5.2. Poinformowanie o wykonaniu kroku manualnego................................................33
4.6. Komunikaty wyjściowe.................................................................................................34
4.6.1. Wysyłanie pełnego stanu procesu..........................................................................34
4.6.2. Wysyłanie odczytów temperatur............................................................................35
4.7. Kontrola i sterowanie temperaturą................................................................................37
4.7.1. Tryby kontrolera PID.............................................................................................39
5. Aplikacja na platformę Android............................................................................................40
5.1. Informacje ogólne..........................................................................................................40
5.2. Zachowanie aplikacji.....................................................................................................41
5.3. Ekran przy braku połączenia.........................................................................................42
5.4. Ekran wprowadzania nowego przepisu.........................................................................43
5.5. Ekran procesu................................................................................................................45
5.6. Ekran podglądu aktualnego przepisu............................................................................51
6. Testy działania aplikacji........................................................................................................52
6.1. Wprowadzanie przepisu i generowanie kroków............................................................52
6.2. Sterowanie temperaturą.................................................................................................54
6.2.1. Podgrzewanie pomiędzy przerwami......................................................................54
6.2.2. Utrzymywanie temperatury w ramach pojedynczej przerwy................................55
6.2.3. Podgrzewanie do chmielenia oraz chmielenie.......................................................56
7. Możliwości i plany rozwoju..................................................................................................58
7.1. Wysładzanie i podgrzewanie do chmielenia..................................................................58
7.2. Procesy długoterminowe...............................................................................................59
7.3. Końcowy przegląd możliwości.....................................................................................61
Podsumowanie..........................................................................................................................62
Bibliografia...............................................................................................................................63
8
OBJAŚNIENIA UŻYWANYCH NAZW I SKRÓTÓW
Android – system Google Android, także w odniesieniu do samego urządzenia z tym
systemem. Programy na tę platformę piszę się w języku Java
Arduino – płytka oparta o otwartą platformę Arduino, programowana w języku C++
Beerduino – wymyślona nazwa systemu, odnosi się do płytki Arduino z wgranym programem
Beerduino
AOA – protokół Android Open Accessory
ADK – Accessory Development Kit (referencyjna implementacja AOA)
IDE – Integrated Development Environment (zintegrowane środowisko programistyczne)
SDK – Software development kit – oprogramowanie i narzędzia służące do tworzenia
aplikacji
API – Application programming interface, zbiór klas i bibliotek dostępnych do użytku
programisty w danej wersji systemu
ADB – Android Debug Bridge, narzędzie pakietu Android SDK służące do komunikacji z
urządzeniem z systemem Android
USB – Universal Serial Bus
Holo – nazwa interfejsu użytkownika wprowadzona pierwszy raz w Androidzie 3.0,
udoskonalona w wersji 4.0
ActionBarCompat – biblioteka pozwalająca osiągnąć pasek ActionBar na urządzeniach
poniżej Androida 3.0
Chmielenie – proces gotowania brzeczki z chmielem
Przerwa – definiuje czas oraz temperaturę, w której należy pozostawić zacier
Zacieranie – proces podgrzewania słodów. Jego skutkiem jest wydzielanie (zależnych od
temperatury przerwy) enzymów, które rozkładają skrobię zawartą w słodzie na różnego
rodzaju cukry proste
Zacier – zawiesina powstała z podgrzewanych w wodzie sodów
Brzeczka – półprodukt przy produkcji piwa, klarowna ciesz pozostała z przefiltrowania
zacieru
Młóto – wszystko to, co zostało z zacieru po odfiltrowaniu brzeczki
9
WSTĘP
MOTYWACJA ORAZ CEL PRACY
W trakcie realizacji jednego z moich hobby, którym jest piwowarstwo domowe, w końcu
pojawił się problem – czas jaki cały ten proces pochłania. Naturalnym stanem rzeczy jest chęć
zautomatyzowania mało interesujących fragmentów produkcji, szczególnie, gdy można
wykorzystać w praktyce wiedzę pozyskaną przez kilka ostatnich lat – zarówno na studiach jak
i uzyskaną we własnym zakresie. W realizacji omawianego problemu posłużyłem się wiedzą
zdobytą z zakresu następujących przedmiotów na kierunku Informatyki wydziału Elektroniki
i Technik Informacyjnych:
– Podstawy programowania (PRI), dr inż. Henryk Dobrowolski:
nauka programowania w języku C
– Programowanie obiektowe (PROI), dr inż. Andrzej Pająk:
nauka programowania obiektowego w języku C++
– Programowanie zdarzeniowe (PROZ), doc. dr inż. Roman Podraza:
programowanie obiektowe w języku Java, używanym do tworzenia aplikacji na
platformę Android
– Technika mikroprocesorowa (TM), dr inż. Jerzy Chrząszcz:
nauka programowania mikrokontrolerów, obsługa przerwań i timerów
– Podstawy automatyki (PODA), prof. dr hab. Piotr Tatjewski:
sterowanie kontrolerami PID
– Systemy rozmyte (SYROZ), prof. nzw. dr hab. inż. Bohdan Butkiewicz:
systemy decyzyjne oparte na regułach.
Informacje i doświadczenia uzyskane na wyżej wymienionych przedmiotach
połączyłem z moimi zainteresowaniami:
– Programowanie aplikacji na platformę Android
– Zamiłowanie do majsterkowania
– Piwowarstwo domowe
Tak narodził się pomysł systemu, który, asystując przy procesie, pozwoli
zautomatyzować niektóre długotrwałe (a proste) czynności. System otrzymał nazwę
10
Beerduino, wywodzącą się od słów beer (piwo) oraz Arduino.
W ogólnym zarysie system składa się z mikrokontrolera Arduino, urządzenia z
Androidem, garnka, grzałki, czujnika temperatury oraz mieszadła. Program po stronie
Arduino został napisany w języku C++, w środowisku Eclipse IDE CDT (C/C++
Development Tooling). Jako mikrokontrolera użyłem płytki Seeeduino ADK Main Board [5]
(klon Arduino Mega z obsługą AOA). Aplikacja na platformę Android stworzona jest w
technologii Java przy użyciu środowiska Eclipse IDE z wtyczką ADT Plugin. Aplikacja jest
kompatybilna ze wszystkimi urządzeniami posiadającymi system Android w wersji
przynajmniej 2.3.4 (poziom API 10), obsługującymi protokół AOA. Przy testowaniu aplikacji
korzystałem z urządzeń Google Nexus One oraz Samsung Galaxy Nexus. Interfejs graficzny
projektowałem pod większy ekran telefonu Galaxy Nexus, więc to właśnie na nim aplikacja
prezentuje się najlepiej.
Wybór platformy Android wynika z moich zainteresowań oraz ogromnych możliwości
tej platformy. Decyzja odnośnie platformy Arduino także nie jest przypadkowa. Na
konferencji Google I/O w 2011 roku [14], firma Google zaprezentowała referencyjną płytkę
ADK (Accessory Development Kit) zaimplementowaną na platformie Arduino. Przedstawiła
także protokół AOA (Android Open Accessory) do komunikacji płytki ADK z urządzeniami
działającymi na systemie Android (w wersji opisanej w poprzednim akapicie). Wtedy to
system Android zyskał oficjalną możliwość interakcji z zewnętrznymi akcesoriami.
STRUKTURA PRACY
Niniejsza praca składa się z siedmiu rozdziałów. W pierwszym zawarte są podstawowe
wiadomości z zakresu natury problemu. Drugi rozdział zawiera krótki opis podobnych
rozwiązań. Kolejne rozdziały opisują moje rozwiązanie i jego implementacje. Tak więc w
rozdziale trzecim opisane są wszystkie elementy sprzętowe, którymi posłużyłem się do
rozwiązania problemu. Rozdziały czwarty i piąty opisują implementację aplikacji na
poszczególne platformy – najpierw Arduino, potem Android. W rozdziale szóstym zawarte są
testy aplikacji, a ostatni zawiera pomysły na rozwój projektu w przyszłości.
11
1. INFORMACJE PODSTAWOWE
1.1. PRZYKŁADOWY PRZEPIS
Projektowanie takiego systemu należy rozpocząć od zapoznania się z przepisami na różne
rodzaje piw. Wnioski co do tego, które informacje są istotne oraz jakie szczególne przypadki
należy obsłużyć w systemie, można wyciągnąć dopiero po przejrzeniu wielu typów
przepisów. W ten sposób projektowany system będzie kompatybilny z jak największą ich
ilością. Najwięcej informacji odnośnie przepisów znalazłem na polskich forach
internetowych, poświęconych domowemu piwowarstwu [1]. Poniżej znajduje się fragment
przepisu (odpowiedzialny za etapy zacierania i chmielenia) na piwo Irish Red Ale. Wybrałem
ten przepis, ponieważ jest prosty, ale zawiera takie szczególne przypadki jak przerwy bez
podanej długości oraz opóźnienie w chmieleniu.
Przepis na piwo Irish Red Ale:
• Słody: Lista i wartości wagowe słodów użytych w przepisie. Liczba słodów w
najprostszych piwach to 2, zazwyczaj jest ich 3 lub 4, ale zdarza się także więcej –
około 6. System nie odróżnia poszczególnych słodów i liczy się dla niego tylko
sumaryczna waga zasypu.Przykład:słód Pale Ale 2,7kgsłód Monachijski 0,8kgsłód Carared 0,5kgpalony jęczmień 0,05kgsuma 4,05kg
• Chmiele: Lista użytych w przepisie chmieli oraz ich wartości wagowe. Ta część nie
jest istotna z punktu widzenia systemu Beerduino, ponieważ waga chmieli nie ma
żadnego wpływu na przebieg procesu. Nazwa również nie jest ważna – w systemie
możemy posługiwać się wyłącznie indeksami chmieli (zgodnymi z kolejnością
wprowadzenia). Znaczenie dla projektowania systemu ma ilość chmieli używana w
przepisach – zazwyczaj są to dwie pozycje i liczba ta rzadko jest przekraczana.Przykład:Marynka 20gLubelski 30g
12
• Chmielenie: Ogólny czas gotowania oraz zestawienia czasów gotowania
poszczególnych chmieli. Można się spotkać także z informacją, w której podano
dokładną minutę wrzucenia danego chmielu. Zapisy te są tożsame – z jednego zapisu
można wyliczyć drugi.Przykład:Chmielenie: 60 minutMarynka w 5. minucie (czyli 55 minut gotowania) Lubelski w 30. minucie (czyli 30 minut gotowania)
• Zacieranie: Spis przerw, jakich należy przestrzegać. Każda przerwa definiowana jest
jako odczekanie określonego czasu w podanej temperaturze. Można spotkać się z
dwoma typami przerw. Pierwszy typ ma z góry narzucony czas, drugi zaś określany
jest jako „do skutku”. Oznacza to ręczne sprawdzanie, czy cała skrobia zawarta w
słodzie została rozłożona przez enzymy na cukry proste. Stałym elementem przepisów
jest także tak zwany mash out. Jest to przerwa trwająca około 15 minut, a poprzez
osiągnięcie temperatury w okolicach 76-78°C ma na celu zakończenie pracy
enzymów, które w tym zakresie temperatur zostają dezaktywowane. Ułatwia ona także
późniejsza filtrację, ponieważ dzięki niej brzeczka staje się mniej lepka.Przykład:67°C - 60 minut72°C – do skutku76°C - mash out
1.2. POGLĄDOWY OPIS PRZEBIEGU PROCESU ZACIERANIA I CHMIELENIA
Po wybraniu przepisu na piwo, które chcemy uwarzyć, pierwszym krokiem jest wlanie wody.
Ilość wody w litrach, którą trzeba wlać na początku, powinna być od 3 do 4 razy większa niż
liczba kilogramów użytych słodów. Należy rozpocząć podgrzewanie wody, aby ta osiągnęła
temperaturę pierwszej przerwy (tej o najmniejszej temperaturze). W czasie podgrzewania
wody do pierwszej przerwy należy osiągnąć temperaturę wyższą o około 2°C, a wynika to z
faktu, że po wrzuceniu kilka kilogramów chłodniejszych od niej słodów, temperatura się
lekko zmniejszy. Po osiągnięciu temperatury danej przerwy należy rozpocząć pomiar czasu
i utrzymywać stałą temperaturę (z dokładnością do około 1°C) przez określony w parametrze
przerwy czas. Pod wpływem danej temperatury wydziela się konkretny enzym, rozkładający
13
skrobię zawartą w słodzie na cukry proste, którymi w późniejszym etapie pożywią się
drożdże. Po ukończeniu jednej przerwy należy pogrzać wodę do następnej, lecz tym razem
bez nadwyżki temperatury, a następnie utrzymać temperaturę nowej przerwy. Po obsłużeniu
wszystkich przerw zacier należy podgrzać do temperatury 78°C aby zakończyć działania
enzymów i sprawić, że brzeczka będzie mniej lepka i rzadsza, co ułatwi jej filtrację.
Następny etap to filtracja, czyli spuszczanie brzeczki przez kranik z podłączonym do
niego filtratorem. Przed rozpoczęciem filtracji należy odczekać ok. 15 minut, aż młóto
(produkt uboczny procesu, wszystko co zostanie odfiltrowane, w tym wygotowane słody)
osiądzie na dnie i utworzy się złoże filtracyjne nad filtratorem. Po odczekaniu zalecanego
czasu należy kranik odkręcić i, przelewając brzeczkę do osobnego zbiornika, czekać aż
poziom płynu w garnku zrówna się z poziomem młóta. W tym momencie należy zakręcić
kranik, aby nie doszło do jego napowietrzenia. Po spuszczeniu brzeczki dużo ważnych
składników zostanie w młócie, dlatego następnym krokiem jest tak zwane wysładzanie.
Polega ona na dolewaniu wody i wydobywaniu z młóta resztek wartościowych cukrów.
Wysładzanie należy przeprowadzić 3 do 4 razy, a po każdym dolaniu wody odczekać 5 minut
aż młóto osiądzie, dopiero wtedy odkręcić kranik i po raz kolejny pilnować poziomu brzeczki
w garnku. Ilość wody użytej do pojedynczego wysładzanie określona jest wzorem:
obj. wody do wysładzania =(obj. końcowa −obj. początkowa) + obj. początkowa4
+ 2
Pierwszym składnikiem jest ilość wody, jaką należy dolać do początkowej objętości
wody, aby uzyskać objętość docelową. Drugi składnik opisuje przybliżoną stratę wody która
zostanie w młocie. Trzeci składnik to standardowa ilość wody, jaka ulegnie odparowaniu
podczas gotowania brzeczki przy chmieleniu.
W momencie zakończenia wysładzania brzeczka znajdzie się w osobnym pojemniku, a
jej objętość powinna być o około 2 litry większa niż objętość docelowa przepisu. W tym
czasie garnek należy umyć i wyciągnąć z niego całe zaległe tam młóto pozostałe po filtracji.
Po wykonaniu tych czynności należy wlać brzeczkę z powrotem do garnka i rozpocząć
jej podgrzewanie do temperatury powyżej 90°C, w celu rozpoczęcia chmielenia. Chmielenie
polega na wrzuceniu chmielu do gotującej się brzeczki i pozostawienie go tam przez
określony czas. W przepisie może być użytych kilka chmieli, o niezależnych czasach
gotowania, dlatego powinno to zostać uwzględnione w projektowanym systemie.
Z przedstawionego opisu procesu widać, że jego znaczną część stanowi oczekiwanie,
14
podgrzewanie oraz kontrola temperatury. Przy objętości brzeczki ok. 20 litrów samo jej
podgrzewanie trwa długo. Podniesienie temperatury o jeden stopień trwa około 2 minut, ale
wraz ze wzrostem temperatury trudność podgrzewania wzrasta. Dla przykładu: podgrzanie
brzeczki do temperatury chmielenia może potrwać ponad godzinę. Podczas wszystkich
podgrzewań należy zacier mieszać, aby nie doszło do przypalenia słodów na dnie. Trzeba o
tym pamiętać także podczas przerw.
W sumie jest to kilka godzin podgrzewania, prostego mieszania oraz oczekiwania, a
użytkownik w tym czasie musi wykonać kilka nieskomplikowanych czynności manualnych.
Dlatego właśnie powstał pomysł na stworzenie systemu Beerduino, który pomógł by
zautomatyzować ten problem. W kolejnych rozdziałach opiszę funkcjonalność systemu oraz
przybliżę rzeczy, którymi kierowałem się podczas jego projektowania.
15
2. PRZEGLĄD PODOBNYCH ROZWIĄZAŃ
2.1. BREWPI
BrewPi jest systemem o otwartym kodzie
źródłowym, którego głównymi elementami
są: mikrokontroler Arduino oraz komputer
Raspberry Pi. Podobnie jak w przypadku
systemu Beerduino, płytka Arduino jest
samodzielnym układem sterującym
przebiegiem całego procesu. System BrewPi
oraz sam komputer Raspberry Pi są dość
nowe i nie istniały jeszcze w momencie, gdy
narodził się pomysł stworzenia systemu Beerduino.
Raspberry Pi to mały komputer, o wielkości
zbliżonej do karty kredytowej, którego parametry
odpowiadają komponentom stosowanym w
smartphone'ach kilka lat temu. Podobnie jak
urządzenie z systemem Android (w przypadku
Beerduino) pozwala on rozszerzyć funkcjonalność
systemu poprzez łatwiejsze wprowadzanie oraz
prezentacje danych.
Zgodnie z dokumentacją [2], aby uruchomić
system BrewPi wymagana jest instalacja systemu operacyjnego Raspbian (jest to specjalna
wersja Debiana) na komputerze Raspberry. W tym celu należy pobrać jego obraz, a następnie
przekopiować go na kartę pamięci i włączyć skrypt instalacyjny. Kolejnymi krokami są
zainstalowanie Apache2, serwera PHP oraz MySQL oraz kilku dodatkowych modułów
Pythona (służących do komunikacji z płytką Arduino). Dzięki takiej konfiguracji, BrewPi
pozwala na wyprowadzenie interfejsu obsługiwanego z poziomu przeglądarki internetowej.
To właśnie tutaj użytkownik może dokonać konfiguracji sprzętowej, czyli zidentyfikowania
i przypisania podłączonych czujników temperatury oraz przekaźników SSR. Wszystkie
konfigurowalne elementy sprzętowe podłączane są do tarczy BrewPi nałożonej na płytkę
Arduino. Instrukcja wykonania tarczy znajduje się w trzecim odnośniku pozycji [3]. W
oficjalnym sklepie jest możliwość kupienia wszystkich części do samodzielnego wykonania
16
Rysunek 2.1: Logo projektu BrewPi,
powstałe poprzez dodanie szyszek chmielu
do loga Raspberry Pi
Rysunek 2.2: Komputer Raspberry
Pi, w porównaniu do karty SD
tarczy, bądź też zamówienia już zmontowanej.
Wg strony projektu BrewPi potrafi kontrolować temperaturę z dokładnością do 0.1°C, a
sam system przeznaczony jest do kontroli temperatury piwa podczas fermentacji oraz jego
schładzania do niższych temperatur. Widać, że pomimo dużego podobieństwa do projektu
Beerduino, są to systemy pokrywające zupełnie inne partie procesu produkcji piwa. BrewPi
zaprojektowane jest z myślą o obserwacji i prowadzeniu obszernego archiwum zapisów
temperatur. Zgromadzone w ten sposób dane zapisywane są na karcie SD, a prezentowanie
ich odbywa się poprzez interfejs wystawiony na przeglądarkę internetową. Dostęp do danych
z poziomu przeglądarki internetowej pozwala na sprawdzanie zebranych danych także przez
Internet, nawet znajdując się poza domem. Sposób ten jest bardzo wygodny dla użytkownika,
ale sprawdza się tylko w wypadku długotrwałego obserwowania zbieranych danych bez
potrzeby fizycznego ingerowania w proces co jakiś czas. W przypadku systemu opisywanego
w tej pracy, użytkownik jest częścią procesu i co jakiś czas musi wykonać konkretną
czynność, aby proces mógł przejść przez kolejne etapy produkcji.
Ponadto na stronie (oraz na forum) projektu można przeczytać, że występują liczne
problemy ze stabilną pracą komponenta Raspberry Pi – „[...] The Arduino can even run
standalone, so if your Pi crashes your beer is still safe. [...]”
(http://wiki.brewpi.com/index.php/What_is_BrewPi%3F). Jak zapewnia twórca, system jest
jednak odporny na losowe zawieszenia komputera Raspberry Pi i nie wywiera to
negatywnych efektów na kontrolę temperatury piwa.
17
Rysunek 2.3: Fragment przeglądarkowego interfejsu systemu BrewPi
2.2. BREWTROLLER
BrewTroller [4] to oprogramowanie działające na kontrolerze OpenTroller, wydane przez
firmę Open Source Control Systems. Wszelkie kody źródłowe programu BrewTroller są
dostępne w Internecie. Firma ta udostępnia także kompletne schematy sprzętowe kontrolerów
OpenTroller, występujących w wersjach BX1, EX1 oraz DX1, które różnią się ilością
obsługiwanych wejść i wyjść.
System nastawiony jest na pełną automatyzację warzenia piwa i jest kompatybilny z
podejściem HERMS, charakteryzującym się zastosowaniem trzech oddzielnych kadzi,
odgrywających w procesie różne rolę. Pierwsza z nich to kadź do przetrzymywania gorącej
wody, czyli tak zwana kadź HLT (Hot Liquor Tank), przechowująca wodę używaną w
późniejszy etapie do wysładzania. Druga to kadź MLT (Malt Liquor Tank) służący do
przeprowadzania zacierania (czyli do obsługi przerw w danej temperaturze). Ostatnią z nich
jest kocioł służący do intensywnego gotowania, używany podczas chmielenia. Wszystkie
kadzie są połączone, aby system mógł samodzielnie przepompowywać płyn z jednej do
drugiej. Dzięki temu całość procesu może być wykonana bez żadnej ingerencji operatora. Z
tego właśnie powodu system jest bardzo skomplikowany, bo oprócz trzech garnków musi
posiadać także więcej czujników temperatury, pompy do przetaczania płynów oraz
elektrozawory, pozwalające cieczy odpływać z garnków.
Firma odpowiedzialna za rozwój programu BrewTroller prowadzi własny sklep
internetowy, sprzedając nie tylko kontrolery OpenTroller, ale także wszelkiego rodzaju
moduły oraz części potrzebne do stworzenia oraz rozbudowy systemu. Tak więc do mierzenia
temperatury w systemie można nabyć czujniki DS18B20 pracujące w technologii OneWire,
dostępne w odpowiednio przygotowanych sondach (dodatkowo przystosowanych aby radzić
sobie z zakłóceniami na szynie OneWire). Do kontroli przepływu wybrać możemy jeden z
kilku zaworów kulowych sterowanych elektronicznie. Poza różnymi przełącznikami,
zestawami przekaźników, czy zasilaczami, nabyć możemy także czujniki ciśnieniowe
poziomu cieczy. Oczywiście wszystkie te części są kompatybilne z systemem BrewTroller
i pozwalają na łatwe ich dodanie do aplikacji.
18
Konfiguracja systemu odbywa się poprzez
mały wyświetlacz, udostępniający 4 linie po 20
znaków każda. Do przemieszczania się po menu
służy pokrętło na obudowie sterownika,
pozwalające na obroty w lewo i prawo oraz
wciskanie. Z racji wielkości projektu, menu
kontrolera jest rozległe i skomplikowane, więc
poruszanie się po nim nie należy do najwygodniejszych. Po zakupienia dodatkowego modułu
Ethernet i podłączeniu kontrolera do Internetu, dostajemy możliwość monitorowania jego
stanu z poziomu przeglądarki internetowej. Nie łączymy się jednak bezpośrednio z
posiadanym przez nas kontrolerem – możemy go zobaczyć dopiero z poziomu strony
producenta (drugi odnośnik w punkcie [4]), która to przetwarza dane z naszego kontrolera.
System nie posiada, niestety, dedykowanej aplikacji na urządzenia z systemem Android.
19
Rysunek 2.4: Wyświetlacz kontrolera
OpenTroller
3. ROZWIĄZANIE SPRZĘTOWE
3.1. SPIS UŻYTEGO SPRZĘTU
Poza częścią programową, która zostanie opisana w następnych rozdziałach, na system
Beerduino składa się wiele urządzeń, których lista oraz sposób podłączenia opisane zostały
poniżej.
Urządzeniami istotnymi, bezpośrednio związanymi z zakresem pracy są:
1. Płytka Seeeduino ADK Mega
2. Urządzenie z systemem Android, system w wersji 2.3+ obsługujący protokół AOA
3. Czujnik temperatury DALLAS 18B20
4. Garnek elektryczny Silvercrest 27l, z grzałką elektryczną o mocy 1800W
5. Przekaźnik SSR, 24-240V 20A – dwie sztuki
6. Opornik 4,7kΩ
7. Zasilacz uniwersalny do laptopów, 12V
8. Silnik wycieraczek przednich z Poloneza Caro, wersja 6-pinowa
9. Kabel USB – microUSB, do podłączenia płytki Arduino do urządzenia z Androidem
10. Ładowarka microUSB, do zasilania płytki Arduino.
W projekcie używam też rzeczy mniej związanych z tematem pracy. Niemniej jednak są
one niezbędne do skonstruowania działającego systemu – ich lista prezentuje się następująco:
• Zawór kulowy czerpalny, służący jako kranik do garnka
• Filtrator, podłączony do kranika od środka garnka
• Łopaty mieszadła
• Stelaż mocujący mieszadło
• Osłona sondy czujnika temperatury
• Inne kable potrzebne do połączeń.
20
3.2. OPIS PODŁĄCZEŃ
Do rozwiązania problemu użyłem układu Seeeduino ADK Main Board [5], który jest
klonem płytki referencyjnej Google ADK. W czasie jej kupowania płytka Seeeduino była
zdecydowanie łatwiej dostępna i tańsza od oficjalnej płytki Google. Płytka ADK jest
kompatybilna z każdym urządzeniem działającym pod kontrolą systemu Android w wersji co
najmniej 2.3.4, obsługującym tryb akcesoriów. Osobiście używam tu telefonów Google
Nexus One oraz Samsung Galaxy Nexus.
Garnek elektryczny, którego użyłem w procesie, wymagał lekkich modyfikacji, aby
można nim było sterować przy pomocy mikrokontrolera Arduino. Po rozkręceniu usunąłem z
jego wnętrza prymitywny układ wyłączający grzałkę, gdy zostanie osiągnięta zadana przez
pokrętło temperatura. Układ ten wykonany był całkowicie analogowo, a odcięcie grzałki
spowodowane było przez rozszerzenie się kawałka blaszki pod wpływem temperatury.
Odległość, na jaką ów kawałek miał się rozszerzyć, definiowana była poprzez odpowiednie
wykręcenie pokrętła, co powodowało zwiększenie odległości, a sama blaszka musiała
rozszerzyć się na większą długość. System regulacji temperatury zrealizowany w ten sposób
miał dokładność do +/- 5-10°C, co dyskwalifikuje jego użycie w opisywanym problemie.
Używałem tego garnka zanim rozpocząłem pracę nad systemem Beerduino, ale już wtedy nie
polegałem na zintegrowanej kontroli temperatury, a pokrętło służyło mi jedynie jako
przełącznik do włączania (ustawione w pozycji pełnego odkręcenia) i wyłączania
(maksymalnie zakręcone) grzałki. Temperaturę monitorowałem za pomocą osobnego
termometru. Teraz jego rolę przejmie czujnik temperatury DS18B20, osadzony w metalowej
rurce zabezpieczającej go przed kontaktem z cieczą. Zostanie on podłączony do płytki
Arduino poprzez rezystor o wartości 4,7kΩ. Czujnik temperatury w parze z grzałką (o mocy
1800W) będą odpowiadały za podgrzewanie zacieru.
Ponieważ grzałka operuje prądem zmiennym, nie można bezpośrednio połączyć jej z
układem Arduino, pracującym na prądzie stałym o napięciu 5V. W tym celu użyłem
przekaźnika półprzewodnikowego (SSR – Solid State Relay) o wartościach wejściowych w
granicach 3-32V prądu stałego. Jego parametry wyjściowe wynoszą odpowiednio od 24V do
240V prądu zmiennego, o natężeniu do 20A. Pomimo mojej skromnej wiedzy w zakresie
elektryki udało mi się ustalić, że wyżej wspomniany przekaźnik dobrze sprawdzi się przy
sterowaniu posiadaną przeze mnie grzałką, znajdującą się w garnku. Przekaźnik
półprzewodnikowy pozwala jednemu układowi sterować przepływem prądu w drugim
układzie, bez galwanicznego ich połączenia. Dzięki temu, wystawiając stan wysoki napięcia
21
na wybranym pinie Arduino, możliwe będzie włączanie i wyłączanie grzałki programowo.
Po podłączeniu czujnika temperatury i grzałki pozostaje obsłużyć system mieszania,
który zapobiegnie przypaleniu się słodów na dnie. Do tego celu zakupiłem wolnoobrotowy
silnik od przednich wycieraczek Poloneza Caro (wersja 6-pinowa), jest on dość tani i łatwo
dostępny. W odróżnieniu od silnika wycieraczek tylnych, ma wystarczającą moc, aby mieszać
około 20-litrowy zacier, ale jego oś obraca się tylko w jedna stronę. W związku z tym idealnie
nadaje się do obracania mieszadła. Silnik ten pracuje w 12V oraz posiada dwa biegi. Do
mieszania dużej ilości płynu potrzeba dużej mocy, ale prędkość obrotu nie musi być duża –
używać będę zatem biegu niższego. Do osi silnika przyczepione będzie mieszadło składające
się z pręta zakończonego łopatami mieszającymi. Zasilaniem silnika zajmować się będzie
uniwersalny zasilacz do laptopów, również podłączony przez przekaźnik SSR. Silnik
mieszadła umiejscowiony zostanie na specjalnym stelażu, tuż nad pokrywą garnka, a jego oś,
przechodząc przez dziurę w pokrywie, skierowana będzie w stronę dna garnka.
Mieszadło nie może być zawieszone zbyt blisko dna, ponieważ na dnie znajdować się
będzie filtrator. Jest to konstrukcja w kształcie prostokątnej ramki złożona z miedzianych
rurek, ponacinanych od strony dna. Ujście filtratora podłączone jest do kranika od
wewnętrznej strony garnka. Jego zadaniem jest pozostawienie słodu w garnku, gdy brzeczka
będzie odprowadzana przez kranik.
Sam mikrokontroler Arduino zasilany będzie przy pomocy typowej ładowarki
zakończonej złączem microUSB. Z gniazda USB na płytce wychodził będzie drugi kabel,
który utworzy połączenie z urządzeniem pracującym pod kontrolą systemu Android. To
właśnie po tym kablu odbywać się będzie transmisja danych wymienianych przez oba
urządzenia. Ponadto urządzenie z Androidem będzie ładowane podczas całego okresu
podłączenia, co niewątpliwie jest plusem i zapobiegnie wyczerpaniu jego baterii.
Na chwilę obecną cały system wymagać będzie trzech wolnych gniazdek do zasilenia
wszystkich jego komponentów: układu Arduino, grzałki oraz mieszadła. Pełen schemat
podłączeń sprzętowych znajduje się poniżej – na rysunku 3.1.
22
23
Rysunek 3.1: Schemat połączeń sprzętowych w systemie Beerduino. Numeracja elementów
jest zgodna z listą umieszczoną w rozdziale 3.1
4. PROGRAM NA PLATFORMĘ ARDUINO
Programy po stronie Arduino oraz Androida zawierają wiele części wspólnych, ponieważ
muszą rozumieć się wzajemnie. Klasy opisujące przepis, stan procesu oraz kod
odpowiedzialny za odbierania i wysyłania komunikatów są względem siebie symetryczne.
Postanowiłem jednak opisać je w rozdziale o Arduino, ponieważ to właśnie ono przetwarza te
dane procesu, a w rozdziale o aplikacji na urządzenie z systemem Android skupić się na
funkcjach wejścia-wyjścia oraz interfejsie użytkownika.
4.1. WSTĘPNY OPIS
Przy projektowaniu aplikacji po stronie Arduino postanowiłem skorzystać z alokacji
statycznej, tzn. wszelkie tablice przechowujące dane są zaalokowane w momencie startu
programu i do końca jego działania nie zmieniają swojej wielkości. Do tego celu konieczne
było założenie pewnych maksymalnych liczb elementów, jakie system będzie musiał w
tablicach tych przechowywać. Starałem się dobrać wielkości tablic z lekkim zapasem, aby
zminimalizować ryzyko ich przepełnienia. Zaalokowana w ten sposób przestrzeń pamięci nie
zwiększa swoich rozmiarów, niezależnie od etapu procesu i czasu jego trwania. Alokacja
statyczna jest zazwyczaj mało optymalna jeżeli chodzi o gospodarowanie pamięcią, ale
projektowana przeze mnie aplikacja jest jedynym programem działającym na
mikrokontrolerze, więc pozostałe zasoby są i tak nieużywane. Drugim powodem, dla którego
uważam, że warto z niej skorzystać, jest fakt znacznego uproszczenia programu oraz
minimalizacja ryzyka wystąpienia błędu.
Opisywany system zaprojektowałem tak, aby Arduino cały czas nadzorowało proces –
jest samodzielnym układem z pełną logiką problemu. Urządzenie z systemem Android pełni
funkcję urządzenia wejścia-wyjścia. Pozwala ono wprowadzić nowy przepis i rozpocząć jego
proces, aby następnie wyświetlać jego stan i potwierdzać wykonywanie konkretnych kroków.
Struktura programu składa się zasadniczo z trzech głównych metod: setup(), loop() oraz
ISR(TIMER1_COMPA_vect). Pierwsza z nich odpowiada za jednorazową konfigurację
urządzenia. Poza konfiguracją wszystkich pinów wejściowych i wyjściowych, ma tu miejsce
opisany wcześniej statyczny przydział pamięci na poszczególne tablice danych. Tutaj także
inicjowany jest tryb Android Accessory oraz ustawiane są wszystkie rejestry odpowiedzialne
za włączenie przerwań Timera1. Funkcja loop() implementuje wszelkiego typu wysyłania
i odbierania danych. Następuje w niej także przetwarzanie danych związanych z zawartością
24
kroków oraz ich zmianą na następny. Ostatnia z opisywanych funkcji zajmuje się
wykonaniem przerwania zgłoszonego przez przepełnienie licznika Timera1, odliczającego
okres jednej sekundy. To właśnie dzięki tej metodzie dochodzi do wysyłania pełnego stanu
procesu w odstępie jednej sekundy. Nie dzieje się to jednak bezpośrednio wewnątrz niej, ale
za sprawą ustawienia flagi informującej o potrzebie wysłania komunikatu stanu przy
następnym obiegu funkcji loop(). Nie wolno tutaj zawierać instrukcji odpowiedzialnych za
wysyłanie stanu, ponieważ wysyłanie na porcie szeregowym również zaimplementowane jest
przy pomocy przerwań. Doprowadziłoby to do sytuacji zgłoszenia nowego przerwania, a
przecież w trakcie przetwarzania poprzedniego obsługa przerwań jest wyłączona. Dodatkowo,
z powodu gwarancji stałych odstępów czasu pomiędzy wywołaniami tej metody, jest tu także
zaimplementowane podliczanie czasu aktualnie wykonywanego kroku.
4.2. OPIS KLAS UŻYWANYCH W PROCESIE
Aby zrozumieć możliwości i ograniczenia systemu należy poznać klasy i typy danych, które
będą używane do przechowywania informacji w systemie. Na wstępie zamierzam opisać w
jaki sposób system przechowuje podstawowe wartości:
Zmienna: Czas Temperatura Waga ObjętośćTyp pola: uint16_t uint16_t uint16_t uint16_tRozmiar w bajtach: 2 2 2 2Zakres wartości zmiennej: 0–65535 0–65535 0–65535 0–65535Jednostka: 1s 0.01°C 1g 1mlMaksymalna
reprezentowana wartość
65535sok. 18h
655.35°C 65535gok. 65kg
65535mlok. 65l
Tabela 4.1: Reprezentacja podstawowych typów danych używanych w aplikacji
Do reprezentowania każdego rodzaju danych wybrałem najmniejszą ilość bajtów, ale
taką, aby nie było mowy o przekroczeniu jej zakresu w trakcie wykonywania procesu. Jeżeli
chodzi o czas, to cały proces może trwać w okolicach 8 godzin. System nigdzie jednak nie
operuje czasem trwania całego procesu, zapisuje zaś czasy trwania poszczególnych kroków.
Ich długość może trwać do 2 godzin, w związku z tym 18 godzin uważam za wartość z dużym
zapasem. O ile nie istnieje możliwość przekroczenia maksymalnej temperatury, to waga
i objętość jednoznacznie definiują ograniczenia systemu. W chwili obecnej system
projektowany jest pod objętość 20 litrów, ale w przyszłości można go rozszerzyć do 40 litrów.
W piwowarstwie domowym nie stosuje się większych objętości niż 50 litrów, dlatego 65
litrów jest także wartością na wyrost.
25
Poniżej znajduje się wypis podstawowych klas, których obiekty będą przechowywały
wartości definiujące przebieg całego procesu.:
Klasa Rest: reprezentuje przerwę, czyli wartość temperatury, w jakiej proces powinien
się zatrzymać oraz określa czas trwania postoju. Podczas trwania przerwy bardzo istotne jest
utrzymywanie zadanej temperatury.
Typ Rozm. w bajtach Nazwa Opisuint16_t 2 time Czas jaki ma trwać dana przerwauint16_t 2 temp Temperatura, przy której powinno zacząć się
liczenie czasu przerwySuma 4
Tabela 4.2: Wykaz i znaczenie pól klasy Rest
Klasa Hop: opisuje czas gotowania konkretnego chmielu
Typ Rozm. w bajtach Nazwa Opisuint16_t 2 time Czas przez jaki dany chmiel ma być gotowanySuma 2
Tabela 4.3: Wykaz i znaczenie pól klasy Hop
Obiekty klas Rest oraz Hop nie posiadają pola indeksu, ponieważ ich indeks jest
definiowany poprzez numer pozycji w statycznej tablicy, w której są zapisane. Numeracje
obiektów Rest oraz Hop są rozłączne i każdy typ jest osobną tablica.
Klasa TimeStep: reprezentuje jeden krok w procesie. Każdy krok posiada pole
określające czas, jaki minął od momentu jego rozpoczęcia.
Każdy krok może zostać wykonany, ale informacja ta nie jest przechowywana w
obiekcie kroku, lecz jako zmienna w procesie, wskazująca numer aktualnego kroku.
Wszystkie kroki o indeksach mniejszych niż aktualny uznane są za wykonane, a wyższe kroki
czekają na wykonanie ich w przyszłości.
26
Typ Rozm. w bajtach Nazwa Opisuint8_t 1 type Typ danego kroku, spis typów oraz ich znaczenie
dostępne są w rozdziale 4.3.uint16_t 2 time Czas, który upłynął od momentu rozpoczęcia
danego kroku.uint8_t 1 firstArg Pierwszy argument, jego znaczenie określane jest
przez typ kroku i jest opisane w rozdziale 4.3.uint16_t 2 secondArg Drugi argument, jego znaczenie określane jest
przez typ kroku i jest opisane w rozdziale 4.3.Suma 6
Tabela 4.4: Wykaz pól klasy TimeStep
Znaczenie kroku jest definiowane przez jego typ oraz wartości argumentów zgodne z
danym typem. Spis i znaczenie typów kroków zamieszczone jest w następnym rozdziale.
4.3. TYPY KROKÓW TIMESTEP
W tym rozdziale wypisane są wszystkie obsługiwane przez system typy kroków. Starałem się
zdefiniować minimalną ilość typów, która w prosty sposób będzie pozwalała opisać w
systemie dowolny wymyślony krok. Jeżeli w przyszłości zajdzie potrzeba dodania nowych
kroków do procesu, powinno to wymagać tylko dodania nowego komunikatu tekstowego w
aplikacji po stronie platformy Android, a po stronie Arduino zdefiniowania nowego numeru
komunikatu tekstowego.
Nazwa: TYPE_MANUAL_STEPOpis: Podstawowy krok manualny zawierający jedynie komunikat tekstowy.Pierwszy argument: Drugi argument:Numer komunikatu tekstowego (liczony od 0) Brak
Nazwa: TYPE_MANUAL_LIQUID_STEPOpis: Krok manualny, informujący o potrzebie wykonania czynności związanej z
cieczą o danej objętości.
Np. Wlej X litrów wody.Pierwszy argument: Drugi argument:Numer komunikatu tekstowego (liczony od 0) Wartość objętości
27
Nazwa: TYPE_MANUAL_WEIGHT_STEPOpis: Krok manualny, informujący o potrzebie wykonania czynności związanej ze
składnikiem o danej wadze.
Np. Wsyp X kg słodu.Pierwszy argument: Drugi argument:Numer komunikatu tekstowego (liczony od 0) Wartość wagi
Nazwa: TYPE_HEATING_TO_REST_STEPOpis: Krok informujący o podgrzewaniu do wskazanej przerwy.Pierwszy argument: Drugi argument:Numer przerwy (np. 1) Brak
Nazwa: TYPE_HEATING_TO_TEMP_STEPOpis: Krok informujący o podgrzewaniu do wskazanej temperatury.
Np. Podgrzewanie do X°C w celu ułatwienia filtracji.Pierwszy argument: Drugi argument:Numer komunikatu tekstowego (liczony od 0) Wartość temperatury
Nazwa: TYPE_REST_STEPOpis: Krok informujący o trwaniu wskazanej przerwy, zostanie on automatycznie
wykonany po upływie czasu przypisanego do danej przerwy.Pierwszy argument: Drugi argument:Numer przerwy (np. 1) Brak
Nazwa: TYPE_MANUAL_REST_STEPOpis: Podobny do TYPE_REST_STEP, z tą różnicą, że jest to krok manualny, czyli
przerwa trwa do momentu kliknięcia przycisku przez użytkownika. Przerwy bez
limitu czasu pilnowane są przez piwowara i mają na celu odczekanie aż cała
skrobia w brzeczce zostanie rozłożona. Odbywa się to poprzez wkropienie
kropli płynu Lugola (albo jodyny) do próbki brzeczki. Brak zmiany koloru
oznacza brak skrobi w brzeczce i możliwość przejścia do następnego kroku.Pierwszy argument: Drugi argument:Numer przerwy (np. 1) Brak
28
Nazwa: TYPE_TIME_PERIOD_STEPOpis: Krok informujący wybranym tekstem o potrzebie odczekania określonego
przedziału czasu. Np. Odczekaj X minut, aż młóto osiądzie na dnie.Pierwszy argument: Drugi argument:Numer komunikatu tekstowego (liczony od 0) Wartość czasu
Nazwa: TYPE_MANUAL_INSERT_HOP_STEPOpis: Krok informujący o potrzebie wrzucenia chmielu (lub kilku – system obsługuje
ich maksymalnie 8). Np. Wrzuć chmiele: 1, 2, 5.Pierwszy argument: Drugi argument:Maska bitowa określająca wybór chmielu. Waga bitu określa
numer chmielu, a stan bitu określa, czy dany chmiel jest wybrany
Brak
Nazwa: TYPE_HOPPING_STEPOpis: Krok informujący o czasie gotowania wskazanych chmieli.
Np. Chmiele 1, 2, 5 gotuj przez X minut.Pierwszy argument: Drugi argument:Maska bitowa określająca wybrane chmiele. W przypadku, gdy
wartość maski wynosi 0, krok ten jest po prostu pustym
gotowaniem - daje to możliwość zaimplementowania opóźnienia
w gotowaniu pierwszego chmielu.
Wartość czasu, jaką
wybrane chmiele mają
się gotować.
Tabela 4.5: Wykaz obsługiwanych typów obiektów TimeStep
4.4. TIMER I OPERACJE ZWIĄZANE Z CZASEM
Bazowym taktowaniem procesu miała być częstotliwość jednej sekundy, to właśnie co
sekundę nowy stan miał być wysyłany na urządzenie z Androidem. Aby to osiągnąć musiałem
przystąpić do wyboru właściwego Timera oraz odpowiednio go skonfigurować. W dalszej
części tego rozdziału będę posługiwał się danymi oraz tabelami pochodzącymi z oficjalnej
dokumentacji producenta mikrokontrolerów ATmega (wchodzacych w skład płytki Arduino),
dostępnej pod pozycją [6].
Zegar Arduino taktowany jest z częstotliwością 16MHz. Aby osiągnąć efekt przerwania
co jedną sekundę należy znaleźć odpowiedni prescaler oraz wartość rejestru porównania
licznika, po osiągnięciu której (po przepełnieniu licznika) zostanie zgłoszone przerwanie.
29
Do dyspozycji mamy 5 ustawień prescalera (odpowiednio 1, 8, 64, 256 oraz 1024,
zgodnie z tabelą 4.6). Zadaniem prescalera jest zmniejszenie częstotliwości z jaką wartość
licznika Timera będzie wzrastała względem taktowania głównego zegara Arduino (16MHz).
Ponieważ potrzebujemy osiągnąć częstotliwość przerwań na poziomie 1Hz, należy wybrać
największy wariant prescalera – zmniejszy on taktowanie naszego Timera 1024 razy. Jest to
dopiero początek, ponieważ sam wybór prescalera nie pozwoli nam na ustawienia taktowania
Timera z częstotliwością 1Hz – trzeba dodatkowo znaleźć wartość limitu licznika. Aby to
zrobić należy zapisać równanie na częstotliwość przerwań:
Częstotliwość przerwań (Hz ) = 16MHzprescaler ∗(Wartość limitu licznika+1)
W powyższym wzorze dodanie 1 do wartości limitu licznika jest konieczne, ponieważ
wartość ta liczona jest od zera, dlatego liczba poziomów licznika będzie w rzeczywistości o
jeden większa. Po wyznaczeniu wzoru na wartość limitu licznika, wzór wygląda w sposób
następujący:
Wartość limitu licznika = 16MHzCzęstotliwość przerwań( Hz) ∗ prescaler
−1
Co po podstawieniu wcześniej dobranych wartości daje:
Wartość limitu licznika = 16MHz1Hz ∗ 1024
−1 = 15625 −1 = 15624
Gdybyśmy przy tym kroku nie uzyskali wartości całkowitej, należałoby zmniejszyć
prescaler i wyliczyć większą wartość limitu licznika.
30
Tabela 4.6: Wykaz dozwolonych wartości prescalera
Zgodnie z dokumentacją producenta oraz odnośnikiem [7], mniejsze płytki Arduino (np.
Arduino Uno) posiadają 3 Timery: Timer0, Timer1 oraz Timer2. Pierwszy oraz trzeci z nich
są timerami 8-bitowymi (256 wartości), Timer1 posiada zaś licznik 16-bitowy (65536
wartości). Większe płytki, np. Arduino Mega (z której korzystam) posiadają jeszcze
dodatkowe timery: Timer3, Timer4 oraz Timer5 – wszystkie 16-bitowe. Ponieważ wartość
15624 jest większa niż 255, nie możemy użyć żadnego z liczników 8-bitowych (Timer0 oraz
Timer2) – należy zatem wybrać jeden z liczników 16-bitowych. Należy także mieć
świadomość, że z Timera1 (lub Timera5 na Arduino Mega) korzystają biblioteki Servo,
których nie używam w moim projekcie, więc jest on wolny i można go zaadoptować na
potrzeby przerwań.
Zgodnie z powyższą tabelą, w celu uzyskania efektu przerwań co jedną sekundę, a
następnie wyzerowania licznika i odliczania od nowa, należy ustawić tryb Timera na CTC
(Clear Timer on Compare Match). Można tego dokonać włączając bit WGM12 w rejestrze
TCCR1B oraz wyłączając bity WGM11 i WGM10 w rejestrze TCCR1A.
Następnie należy ustawić prescaler. Z tabeli 4.6 wynika, że w celu ustawienia prescalera
na wartość 1024, w rejestrze TCCR1B należy ustawić bity CS12 oraz CS10 na wartość 1.
31
Tabela 4.7: Wykaz i krótka charakterystyka trybów Timera
TCCR1A – Timer/Counter 1 Control Register A:
TCCR1B – Timer/Counter 1 Control Register B:
OCR1A – Output Compare Register 1 A: do tego rejestru należy wpisać obliczoną
wcześniej wartość limitu licznika równą 15624.
TCNT1 – Timer/Counter 1: jest to wartość licznika Timera1, która w momencie
przepełnienia (osiągnięcia wartości zadanej w rejestrze OCR1A) spowoduje zgłoszenie
przerwania. Warto zresetować ją (ustawić na 0) na początku, zaraz przed włączeniem
przerwań.
TIMSK1 – Timer/Counter 1 Interrupt Mask Register: po ustawieniu wartości OCR1A
(Output Compare Register 1 A) należy włączyć bit OCIE1A (Output Compare Interrupts
Enabled 1 A), aby uaktywnić wywoływanie przerwania w momencie przepełnienia licznika.
Ostatecznie konfiguracja Timera wygląda w następujący sposób:TCCR1A = 0; // wyzerowanie całego rejestru TCCR1ATCCR1B = 0; // wyzerowanie całego rejestru TCCR1BTCNT1 = 0; // ustaw wartość początkową licznika na 0OCR1A = 15624; // ustaw rejestr porównania aby osiągnąć 1HzTCCR1B |= (1 << WGM12); // włącz tryb CTC
32
TCCR1B |= (1 << CS12) | (1 << CS10); // ustaw bity CS10 i CS12 // dla prescalera 1024
TIMSK1 |= (1 << OCIE1A); // włącz przerwania Timera
4.5. KOMUNIKATY WEJŚCIOWE
Program płytki Beerduino obsługuje obecnie dwa rodzaje komunikatów przychodzących.
Każdy z nich został opisany w dedykowanym mu podpunkcie poniżej.
4.5.1. Wgranie przepisu i rozpoczęcie procesu
Zaraz po włączeniu, Arduino znajduje się w stanie przed rozpoczęciem jakiegokolwiek
procesu. Jedyna akcja na tym etapie, która zmusi Arduino do zmiany swojego stanu to
przyjście komunikatu zadającego nowy przepis. Ponieważ jest to jedyny komunikat, na który
nasłuchuje wtedy Arduino, nie wymaga on dodatkowego pola określającego jego typ.
Opis pola Rozmiar w bajtachObjętość docelowa 2Waga zasypu 2Liczba przerw zawartych w przepisie 1Tablica przerw (Liczba przerw) * 4Liczba chmieli zawartych w przepisie 1Tablica chmieli (Liczba chmieli) * 2
Tabela 4.8: Opis położenia i znaczenia pól w komunikacie zadającym nowy przepis.
4.5.2. Poinformowanie o wykonaniu kroku manualnego
W procesie występują kroki typu manualnego, które nie wykonają się same, a wymagają za to
interakcji użytkownika. Po wykonaniu jakiejś czynności użytkownik musi potwierdzić
wykonanie danego polecenia, aby proces program mógł przejść do następnego kroku
i kontynuować pracę. System obecnie nie oferuje dodatkowych czujników, które mogłoby
same stwierdzać wykonanie danego kroku, ale temat ten został podjęty w rozdziale 7.
(Możliwości i pomysły rozwoju). Wykonanie kroku musi być więc zasygnalizowane poprzez
naciśnięcie przez użytkownika przycisku „Zrobione, dalej!” wyświetlanego, gdy aktualnie
wykonywany krok jest typu manualnego. Po jego naciśnięciu na Arduino wysyłany jest
komunikat zawierający numer kroku, który został przez użytkownika oznaczony jako
33
dokonany. Wysłany numer kroku jest sprawdzany przez program na płytce Beerduino pod
kątem tego, czy rzeczywiście aktualnie wykonywany jest krok o takim numerze. Taka
kontrola pozwoli uniknąć błędów, które mogłoby wyniknąć z desynchronizacji, w sytuacji
gdy użytkownik myśli, że wykonał dany krok, a w rzeczywistości to inny krok został
oznaczony jako wykonany. Kolejny potencjalny błąd, który może zaistnieć, jeżeli takiej
kontroli by nie było, jest dużo prostszy. Wystarczyłoby, aby użytkownik nacisnął bardzo
szybko, kilka razy przycisk wykonania kroku, zanim doszłaby do urządzenia informacja
zwrotna o tym, że dokonana została już zmiana kroku na Arduino. Użytkownik mógłby wtedy
niezamierzenie przeskoczyć kilka kroków, co miałoby swoje konsekwencje, zważywszy na to,
że raz zgłoszonego wykonania kroku nie można już cofnąć.
Struktura komunikatu prezentuje się w sposób następujący:
Opis pola Rozmiar w bajtachTyp wiadomości 1Numer wykonanego kroku 1Drugi argument, aktualnie nieużywany 1
Tabela 4.9: Opis położenia i znaczenia pól w komunikacie wykonania danego kroku
4.6. KOMUNIKATY WYJŚCIOWE
W rozdziale tym zostaną opisane komunikaty wysyłane z płytki Arduino do urządzenia z
systemem Android. Aktualnie występują dwa rodzaje komunikatów wychodzących z Arduino
– zostały one opisane w osobnych podpunktach poniżej.
4.6.1. Wysyłanie pełnego stanu procesu
Komunikat pełnego stanu procesu wysyłany jest co okres jednej sekundy. Zawiera on
wszystkie dane odnośnie przepisu i wygenerowanych z niego kroków, a także wiele
zmiennych opisujących aktualny postęp procesu. Niektóre dane nie zmieniają się (np. przepis,
który od momentu jego rozpoczęcia jest stały), ale z powodów uproszczenia struktury obu
programów zdecydowałem się przesyłać go za każdym razem.
34
Opis pola Rozmiar w bajtachTyp komunikatu 1Aktualna temperatura 2Aktualna zadana temperatura 2Temperatura początku danego kroku 2Numer aktualnego kroku 1Objętość docelowa 2Waga zasypu 2Opóźnienie wrzucenia pierwszego chmielu 2Liczba przerw zawartych w przepisie 1Tablica przerw (Liczba przerw) * 4Liczba chmieli zawartych w przepisie 1Tablica chmieli (Liczba chmieli) * 2Liczba kroków w aktualnym procesie 1Tablica kroków w procesie (Liczba kroków) * 6
Tabela 4.10: Opis położenia i znaczenia pól w komunikacie zawierającym pełny stan procesu
4.6.2. Wysyłanie odczytów temperatur
Opis pola Rozmiar w bajtachTyp komunikatu 1Indeks pierwszej temperatury z wysłanej tablicy 2Liczba przesłanych temperatur 2Tablica przesłanych temperatur (Liczba temperatur) * 2
Tabela 4.11: Opis położenia i znaczenia pól w komunikacie zawierającym odczyty temperatur
Podczas trwania procesu dokonywane są odczyty temperatury w odstępach jednej
minuty i są one gromadzone od startu procesu (czyli od wgrania nowego przepisu na
Arduino). Dane te należy przesłać na urządzenie z Androidem, aby była na nim możliwość
przeglądania całego wykresu temperatury. Jeden odczyt temperatury na minutę to bardzo
niewiele, wysyłając je na bieżąco nie napotkamy żadnych problemów. Jednak system jest
zaprojektowany tak, aby niezależnie od stanu zaawansowania procesu można było rozłączać
i ponownie łączyć oba urządzenia, a urządzenie z Androidem powinno pobrać wszelkie
informacje odnośnie procesu.
O ile sprawa ze stanem procesu jest prosta (wielkość komunikatu o stanie procesu nie
35
zwiększa się z czasem), to tablica temperatur, która gromadzi ciągle nowe dane, może się z
czasem rozrosnąć, przez co wysyłanie jej na raz mogłoby zawiesić pracę programu na pewien
czas. Dlatego też wysyłanie temperatur odbywa się w paczkach, których maksymalna
wielkości zdefiniowana jest po stronie Arduino. Przy każdym obiegu pętli głównej program
bierze zmienną wskazującą za ostatnio wysłaną temperaturę i sprawdza, czy w tablicy
zapisanych temperatur występują temperatury leżące we wskazanym miejscu lub za nim.
Jeżeli taka sytuacja nastąpi, program przystępuje do wysłania paczki temperatur i zwiększenia
wskaźnika na ostatnio wysłaną temperaturę. Jeżeli temperatury nie zmieściły się w danej
paczce, zostaną rozpatrzone przy kolejnym obiegu pętli głównej. Numer wskazujący za
ostatnio wysłaną temperaturę jest resetowany w momencie startu programu oraz w momencie
zerwania połączenia z urządzeniem, tak aby po ponownym jego podłączeniu rozpocząć
wysyłanie temperatur od nowa, niezależnie od tego, jaki stan tablicy temperatur posiadało
ostatnio urządzenie z Androidem. Jest to prymitywne rozwiązanie, ale skuteczne i pozwala
znacznie uprościć logikę aplikacji oraz połączenia pomiędzy urządzeniami.
Rozważmy sytuacje chwilowego braku połączenia obu urządzeń. Wynika z niej, że
urządzenie z Androidem posiada jakiś stan tablicy temperatur (było już podłączone), ale
nastąpił pewien okres braku połączenia. W momencie ponownego podłączenia urządzenie z
Androidem mogłoby pamiętać ostatni znany mu stan temperatur i poprosić tylko o
temperatury spod indeksów wyższych niż te, które posiada. Jednak takie podejście znacząco
komplikuje sprawę:
– Urządzenie z Androidem musi wysyłać dodatkowy komunikat proszący o temperatury
późniejsze niż ta które posiada.
– Arduino nie mogłoby rozpocząć wysyłania temperatur, ponieważ musi czekać na
komunikat z telefonu, o tym, jakie temperatury ma wysłać.
– Istnieje także potrzeba rozpatrzenie sytuacji, gdy telefon był podłączony do innego
Arduino, działającego w innym procesie. Wtedy temperatury, które posiada telefon, są
zupełnie nieadekwatne do stanu procesu na innym Arduino. W związku z tym
należałoby wysyłać także unikalny identyfikator procesu, aby Arduino mogło wysłać
go na telefon, a telefon zweryfikować, czy dane, które posiada, należą do tego procesu
– Jeżeli w tablicy temperatur, jaką posiada telefon, doszłoby do jakichkolwiek
przekłamań, nie zostałyby one naprawione, chyba że telefon przy podłączeniu, oprócz
indeksu ostatniej posiadanej temperatury, wysyłałby także skrót tablicy temperatur.
Dopiero w ten sposób Arduino mogłoby porównać, czy dane obecne na telefonie są
36
zgodne ze stanem faktycznym.
Jak widać wprowadza to dużo komplikacji w obu programach, a moim założeniem było,
aby urządzenie z Androidem nie przechowywało żadnych danych, lecz pracowało jako
wyświetlacz, będąc zawsze w synchronizacji z Arduino.
4.7. KONTROLA I STEROWANIE TEMPERATURĄ
Sterowanie temperaturą należy do głównym zadań systemu Beerduino. W przeciwieństwie do
np. kontroli czasu, jest to temat dużo bardziej skomplikowany, a każdy przypadek jego
implementacji jest inny.
Do sterowania temperaturą wykorzystałem kontroler PID, zaimplementowany na
bibliotece PIDLibrary, do której adres znajduje się w bibliografii na pozycji [9]. Pierwszym
problemem jest, co zrobić z wartością wyjściową kontrolera? Przecież na wyjściu
otrzymujemy jakąś wartość, którą powinniśmy wpłynąć na grzałkę. Grzałka sterowana jest
przekaźnikiem SSR i może być tylko włączana bądź wyłączana, bez stanów pośrednich.
Skoro nie możemy regulować bezpośrednio stopnia grzania grzałki, trzeba problem ten
rozwiązać inaczej. Skorzystałem więc ze sposobu opisanego w [10], a mianowicie okna
czasowego, ustawionego na długość 5 sekund. W ten sposób możemy sterować grzałką w
czasie, symulując stany częściowego jej włączenia. Wartość wyjściową kontrolera PID
ograniczyłem w zakresie od 0 do 5000 i reprezentuje ona czas w milisekundach, jaki w
5-sekundowym oknie grzałka będzie włączona.
Wartość temperatury wejściowej oraz wartość zadana wyrażone są zgodnie z
prezentacją podstawowych typów danych w systemie (przedstawioną w tabeli 4.1). Pozostaje
tylko dobrać odpowiednie wartości nastawów kontrolera PID. Niestety, podczas testowania
różnych parametrów, uzyskane wyniki były niezadowalające. Powodem takiego stanu rzeczy
jest duża ilość ciepła, jakie grzałka potrafi oddać już po jej wyłączeniu, a także opóźniona
reakcja systemu na jakiekolwiek akcje. Warto zauważyć, że system posiada tylko element
grzewczy, nie posiada natomiast żadnej chłodnicy. Jeżeli zatem temperatura zostanie
przestrzelona, nie jesteśmy w stanie zaradzić temu w żaden sposób, bo na jakiekolwiek akcje
jest już za późno. Dlatego właśnie należy nie dopuścić do przekroczenia zadanej temperatury.
Projektując zachowanie systemu grzewczego, przeprowadzałem testy na objętości około
8 litrów wody. Pozwoliło to znacząco skrócić czasy podgrzewania, dlatego wszystkie
pisywane wartości będą podawane pod taką objętość. Należy mieć na uwadze, że trzeba
37
będzie dostroić parametry kontrolera do docelowej objętości. Nie jest to jednak takie proste,
bo każda warka będzie miała lekko inną objętość – trzeba będzie użyć jej jako parametru przy
ostatecznym wybraniu wartości nastawów.
Po wyłączeniu w pełni pracującej grzałki, potrafi ona podnieść temperaturę wody o
nieco ponad 5°C na objętości około 8 litrów (oraz o około 2°C na objętości zbliżonej do 16
litrów). Istnieją zasadniczo dwa sposoby, aby nie dopuścić do przestrzelenia zadanej
temperatury. Pierwszy to delikatne dawkowanie mocy grzałki oraz oczekiwanie, co z
pewnością pozwoli osiągnąć temperaturę zadaną, ale także znacząco wydłuży czas
podgrzewania. Postanowiłem jednak skorzystać z innego podejścia, przypominającego trochę
reguły w systemach logiki rozmytej. Logika rozmyta świetnie radzi sobie z modelowaniem
procesów, które do tej pory obsługiwane były przez ludzi. Operatorzy znając reguły panujące
w systemie mogą łatwo przenieść je do modelu logiki rozmytej. Do tej pory przy produkcji
piwa sterowałem temperaturą ręcznie i wiedziałem właśnie, że 2°C (przy objętości docelowej)
przed osiągnięciem zadanej temperatury grzałkę wyłączyć. Zacznie działać wtedy inercja
cieplna ze stygnącej grzałki, która podniesie temperaturę w okolice wartości zadanej, ale
trzeba w tym momencie lekko ją asekurować. Przy uwzględnieniu tej reguły stworzyłem
adaptacyjny kontroler, który do pewnej temperatury podgrzewa na pełnej mocy, a po
przekroczeniu odpowiedniej temperatury przełącza się w tryb jedynie asekuracyjny. Jako
doświadczony operator wyznaczyłem taki zbiór reguł:
1. Jeżeli trzeba dużo podgrzać, wyłącz grzanie dużo przed zadaną temperaturą.
2. Jeżeli trzeba średnio podgrzać, wyłącz grzanie średnio przed zadaną temperaturą.
3. Jeżeli trzeba mało podgrzać, wyłącz grzanie mało przed zadaną temperaturą.
W powyższych regułach należy zastanowić się co znaczą pojęcia „dużo/średnio/mało
podgrzać”. Dla mnie, jako operatora, znaczyło to, że im dłużej grzałka będzie włączona, tym
więcej ciepła odda w kilka minut po jej wyłączeniu. Korzystając z faktu, że podgrzewanie jest
praktycznie stałe w czasie, możemy wartości te oprzeć na różnicy temperatur i zapisać to
wzorem:różnica temperatur = temperatura zadana − temperatura startu podgrzewania
Pojęcia „wyłączyć dużo/średnio/mało przed” oznaczają ile stopni przed osiągnięciem
zadanej temperatury, należy wyłączyć grzałkę. Jak już wspomniałem wyżej, w pełni
rozgrzana grzałka odda jeszcze 5°C. Należy zadać sobie pytanie jak długo grzałka musi być
włączona, aby była w pełni rozgrzana. Podczas prób na 8 litrach wody zauważyłem, że chcąc
podgrzać wodę o 10°C, już 5°C przed zadaną temperaturą należy wyłączyć grzanie. Wartości
38
powyżej 10°C nie mają znaczenia, ponieważ już wtedy grzałka jest w pełni rozgrzana i nie
zmagazynuje już więcej ciepła. Wyznaczyłem zatem następujący wzór na próg wyłączenia
grzania, który pokrywa wyżej opisane reguły:próg wyłączenia = min (5° C , (różnica temperatur)/ 2)
To właśnie dzięki takiemu wyliczeniu progu wyłączenia, możliwe jest sensowne
przełączanie trybu kontrolera PID z agresywnego na konserwatywny. Jak pokazują testy w
podrozdziale 6.2, system ten sprawdza się bardzo dobrze.
System wspiera jeszcze jedną drobną regułę, która odnosi się do chmielenia. Na tym
etapie należy brzeczkę intensywnie gotować, bez ograniczania się do wybranej temperatury.
Nie ma sensu używać tu obliczeń kontrolera PID i można przejąć od niego kontrolę. Dlatego
też, gdy temperatura docelowa ustawiona jest na temperaturę równą, bądź wyższą od
temperatury zainicjowania chmielenia (aktualnie 90°C), system przestaje korzystać z
kontrolera i włącza grzanie pełną mocą.
4.7.1. Tryby kontrolera PID
Poniżej prezentuję wartości parametrów kontrolera PID dla poszczególnych trybów:
I. Tryb agresywny:
Kp = 15.0; Ki = 0.01; Kd = 0.0;
Jest to tryb intensywnego podgrzewania. Człon całkujący zabezpieczy na wydłużony
czas, ale nie wpłynie znacząco na moc grzania. Człon różniczkowy wyłączony.
II. Tryb konserwatywny:
Kp = 0.7; Ki = 0.1; Kd = 80.0;
W trybie tym występuje delikatne podgrzewanie. Parametr członu całkującego ma
większą wartość, aby lepiej radzić sobie z uchybem ustalonym. Duża wartość członu
różniczkowego służy do hamowania zbyt szybkiego wzrostu temperatury.
Warto zaznaczyć także, że, w momencie przejścia kontrolera PID na tryb
konserwatywny, zakumulowana wartość członu całkującego zostaje wyzerowana.
Robię to w celu pozbycia się „historii” błędu z poprzedniego etapu intensywnego
podgrzewania (oraz analogicznie przy przełączeniu na tryb agresywny).
39
5. APLIKACJA NA PLATFORMĘ ANDROID
5.1. INFORMACJE OGÓLNE
System Beerduino nie jest aplikacją napisaną jedynie na zaliczenie. Zaprojektowałem go pod
swoje konkretne potrzeby i będzie przeze mnie używany w przyszłości. Dlatego też przy
projektowaniu interfejsu graficznego położyłem duży nacisk na jego prostotę, czytelność
(poprzez wyświetlanie tylko istotnych rzeczy i odpowiednią ich prezentacje) oraz łatwość w
obsłudze.
Aplikacja na platformę Android napisana jest w języku Java, w środowisku Eclipse IDE
z wykorzystaniem wtyczki ADT Plugin. Pomimo faktu, że jest to specyficzna aplikacja i nie
zostanie ona udostępniona szerszej grupie klientów (np. w sklepie Google Play Store), przy
jej tworzeniu zastosowałem się do wszystkich wytycznych, które zaleca stosować firma
Google do tworzeniu dobrych aplikacji na system Android. Jest ona w pełni kompatybilna z
wytycznymi nowoczesnego stylu Holo. Z kolei dzięki zastosowaniu biblioteki Android-
Support-v4 [12] (Fragments API, LocalBroadcastManager) oraz Android-Support-v7
(ActionBarCompat), aplikacja cechuje się kompatybilnością wsteczną do wersji Androida
2.3.4 (poziom API 10 – próg ten wynika z potrzeby obsługi protokołu AOA). Dodatkowo
działa w każdej orientacji ekranu, czyli nie zmusza użytkownika do trzymania urządzenia
tylko wertykalnie, bądź tylko horyzontalnie. Aplikacja nie posiada ograniczeń w postaci
obsługiwanego dpi oraz wielkości ekranu, działa zarówno na telefonach jak i na tabletach (np.
Acer Iconia A500 lub Asus Nexus 7). Postanowiłem spełnić te zalecenia dla celów
edukacyjnych.
Na początku pisania aplikacji bardzo odczuwalny staje się brak możliwości
debugowania kodu. Przy podłączeniu urządzenia z Androidem do płytki Arduino, jedyny port
microUSB w telefonie zostaje zajęty. Klasyczne debugowanie po kablu jest więc niemożliwe.
Dodając do tego fakt, że po stronie mikrokontrolera także nie posiadam możliwości włączenia
debugowania, proces inspekcji przesyłanych w bajtach wiadomości staje się bardzo uciążliwy.
Na szczęście system Android (co prawda po „zrootowaniu”) ma możliwość debugowania po
sieci WiFi. To właśnie dzięki programowi typu WiFi ADB udało mi się rozwiązać wiele
problemów w wykonywaniu programu.
40
5.2. ZACHOWANIE APLIKACJI
Aplikacja na Androida odzwierciedla stan płytki Beerduino – działa jako urządzenie wejścia-
wyjścia. Tuż po odczytaniu aktualnego stanu płytki, aplikacja decyduje, jaki ekran powinien
zostać wyświetlony użytkownikowi. Następuje potem wyświetlenie wszystkich wartości
(powiązanych z aktualnym etapem płytki) w wygodnej i interaktywnej formie graficznej. W
odpowiednich momentach użytkownik ma możliwość oddziaływania na proces poprzez
wysyłanie komunikatów na Arduino. Ponieważ cała logika procesu jest zawarta na
mikrokontrolerze, urządzenie z Androidem można dowolnie odłączać i znowu podłączać bez
wywierania żadnego efektu na trwający proces. Warto też wspomnieć, że aplikacja na
urządzeniu z Androidem włącza się automatycznie, gdy tylko użytkownik podłączy płytkę
Beerduino i od razu rozpoczyna wyświetlanie danych
odebranych z płytki Arduino.
Moduł utrzymujący połączenie z Arduino
i odpowiadający za wymianę danych z płytką
zaimplementowany jest podobnie do przykładu [16] –
w oparciu o komponent serwisu (Service), więc
komunikacja odbywa się niezależnie od istnienia okna
aplikacji. Dzięki takiemu zaprojektowaniu,
użytkownik może aplikację zminimalizować, bądź
całkowicie ją zamknąć i normalnie używać urządzenie,
a informacje opisujące stan Arduino będą w dalszym
ciągu odbierane i przetwarzane przez telefon. W
związku z tym postanowiłem wyświetlać
powiadomienie, które będzie informowało
użytkownika, że Beerduino działa w tle. Będzie ono
widoczne przez cały czas połączenia z płytką, nawet
gdy okno aplikacji nie jest wyświetlane. Pozwoli to
użytkownikowi w łatwy sposób powrócić do aplikacji
po wyjściu z niej.
Dodatkowym ułatwieniem jest dodanie powiadomień dźwiękowych. Są one przydatne
nie tylko, gdy użytkownik ma zminimalizowaną aplikację, bądź wyłączony ekran urządzenia,
ale także w sytuacji, gdy po prostu odszedł wykonywać inne czynności i nie może zobaczyć
41
Rysunek 5.1: Powiadomienie
informujące o pracy w tle
wyświetlonego okna aplikacji. Powiadomienie zostanie odtwarzane w sytuacji, gdy doszło do
zmiany kroku, z czasowego bądź temperaturowego na krok manualny. Oznacza to, że
użytkownik czekał na wykonanie pewnej czynności (odliczanie czasu lub podgrzewanie do
temperatury), a teraz przyszła kolej na jego interakcję. Krótki dźwięk wydany przez telefon
powiadomi go o konieczności ingerencji w procesie. Powiadomienie dźwiękowe nie odtworzy
się jednak w momencie zmiany z kroku manualnego na inny krok manualny (jeżeli jest kilka
kroków manualnych występujących po sobie), ponieważ użytkownik jest przy tej zmianie
obecny, więc sygnalizowanie tego dźwiękiem jest nie tylko niepotrzebne, ale także (z moich
doświadczeń) irytujące.
Wygląd aplikacji jest zgodny z dobrymi praktykami programowania na platformę
Android, a aplikacja używa standardowych komponentów. Na górnym pasku aplikacji
(ActionBar) wyświetlany jest tytuł aplikacji, czyli „Beerduino”. Poniżej, jako podtytuł okna,
wyświetlany jest stan aplikacji, bądź etap na którym się znajduje. Z prawej strony paska akcji
znajduje się wskaźnik połączenia z płytką. Dokładniejszy opis ekranów, kontrolek oraz ich
umiejscowienia opiszę w poniższych podrozdziałach.
5.3. EKRAN PRZY BRAKU POŁĄCZENIA
Jeżeli płytka Arduino jest odłączona od urządzenia z
systemem Android, ekran braku połączenia zostanie
wyświetlony użytkownikowi zaraz po włączeniu przez
niego aplikacji na telefonie. Pokaże się on także w
momencie, gdy podczas normalnej pracy programu, z
podłączonym Arduino, odłączymy od siebie oba
urządzenia. Wyświetlane dotychczas informacje
i kontrolki zostaną ukryte, ponieważ ich stan jest
nieaktualny, a interakcja z nimi nie ma sensu.
W tym stanie na ekranie wyświetlany jest tytuł
aplikacji wraz z podtytułem „Rozłączono”. Kontrolka
stanu połączenia, wyświetlana zawsze w prawym górnym
rogu, pokazuje kolor czerwony (oznaczający brak
połączenia). Jeżeli na ekranie były wyświetlane jakieś
informacje, to zostają one ukryte, a w ich miejscu pojawia
się duży napis o treści „Brak połączenia z Beerduino”.
Podczas wyświetlania tego ekranu użytkownik nie jest w stanie nic zrobić, a aplikacja
42
Rysunek 5.2: Komunikat o
braku połączenia
zareaguje dopiero po podłączeniu płytki Beerduino.
5.4. EKRAN WPROWADZANIA NOWEGO PRZEPISU
W momencie wykrycia przez aplikację podłączenia płytki Beerduino, wygląd okna ulega
zmianie. Jeżeli mikrokontroler nie przetwarza aktualnie żadnego przepisu, użytkownikowi
wyświetlony zostanie ekran wprowadzania nowego przepisu.
Kolor wskaźnika połączenia zmieni się na zielony, a podtytuł okna poinformuje o braku
działającego przepisu na Arduino („Brak aktywnego
przepisu”), zachęcając użytkownika do dodania
nowego przepisu. Dodatkową funkcjonalnością jest
akcja, która ma miejsce po wciśnięciu zielonego
wskaźnika połączenia. Po jego naciśnięciu pojawi
się okno dialogowe z przyciskiem umożliwiającym
awaryjne rozłączenie obu urządzeń, bez
konieczności fizycznego wypinania łączącego je
kabla. Treść komunikatu brzmi: „Połączony. Czy na
pewno chcesz wymusić rozłączenie z Beerduino?”.
Obecnie opcja ta używana jest do celów deweloperskich
– aby wgrać nową wersję programu na płytkę Arduino,
bądź na telefon, należy urządzenia najpierw rozłączyć,
aby połączenie między nimi mogło być w sposób
właściwy zakończone. Opcja ta pozwala na rozłączenie
urządzeń przy pomocy zwykłego kliknięcia, co
zapobiega niszczeniu portów USB w obu urządzeniach.
W przyszłości będzie to także miejsce dodania nowych
akcji do zarządzania połączeniem oraz pozwoli na
wejście w tryb sterowania awaryjnego (manualnego).
Z głównej części ekranu zniknie komunikat o
braku połączenia, a pojawi się formularz wprowadzania
nowego przepisu. Pozwala on na wprowadzenie
wszelkich potrzebnych do rozpoczęcia procesu
informacji. Formularz ten posiada wygodne do
43
Rysunek 5.3: Okno dialogowe
wyświetlane po naciśnięciu
wskaźnika połączenia
Rysunek 5.4: Domyślne
wartości na ekranie
wprowadzania nowego przepisu
kliknięcia przyciski oraz składa się z trzech sekcji:
I. Wartości ogólne
• Objętość docelowa piwa:
docelowa objętość brzeczki po zakończonym procesie zacierania i warzenia.
• Waga zasypu:
należy podać tutaj sumaryczną wagę wszystkich słodów użytych w danym przepisie.
To właśnie na podstawie wagi zasypu obliczana będzie ilość wody, którą użytkownik
ma wlać na samym początku procesu, aby zachować odpowiednie proporcje słodu do
wody.
• Opóźnienie przed dodaniem pierwszego chmielu:
jest istotna wartość, jeżeli przepis wymaga wrzucenia pierwszego chmielu nie od razu,
ale dopiero w wyznaczonej minucie (np. w 5.). W przepisach przypadek ten jest dość
często spotykany, warto więc mieć możliwość wybrania tej wartości.
II. Przerwy
Sekcja ta składa się z listy przerw,
opisanych temperaturą oraz czasem trwania.
Użytkownik może dodawać je i usuwać,
jednak aplikacja udostępnia ograniczenia,
aby nie dopuścić do sytuacji wprowadzenia
niedozwolonych danych. Sytuacją taką jest
przypadek, w którym użytkownik usunie
wszystkie przerwy. Podobną sytuacja
nastąpi, gdy użytkownik podejmie próbę
wprowadzenia więcej niż 8 przerw. Większa
liczba jest niedozwolona i nieobsługiwana
przez Arduino. W celu zachowania
symetryczności obu programów dodane
zostało takie zabezpieczenie. Nie zmienia to
faktu, że program na Arduino także takie
zabezpieczenie posiada i nie wczyta więcej niż 8 przerw – resztę zignoruje.
Domyślnie dodana jest jedna przerwa w temperaturze 67°C, ponieważ z moich
doświadczeń wynika, że jest to najpopularniejsza temperatura rozpoczynania
przepisów. Domyślny czas każdej przerwy wynosi 30 minut.
44
Rysunek 5.5: Okno dialogowe służące
do wpisywania wartości przy
wprowadzaniu przepisu (tutaj
wartości czasowych)
W momencie kliknięcia na znak plusa w celu dodania kolejnej przerwy, jej
temperatura zostanie pobrana z ostatniej, poprzedzającej ją przerwy i zwiększona o
5°C. Jest to nie tylko skok często występujący w temperaturach przerw, ale także
pozwoli on zasygnalizować użytkownikowi tendencję wzrostową temperatur w
kolejnych przerwach (aczkolwiek wprowadzane tu przerwy nie muszą mieć rosnącego
układu temperatur).
III. Chmiele
Podobnie jak w przypadku przerw, tutaj także zaimplementowane jest ograniczenie,
które nie pozwoli na wprowadzenie mniej niż jednego oraz więcej niż ośmiu chmieli.
To również wynika z założeń ustalonych po stronie płytki Beerduino.
Każdy dodany chmiel pozwala na zdefiniowanie czasu jego gotowania – wartość ta
domyślnie wynosi 60 minut.
Gdy użytkownik uzna wprowadzanie przepisu za ukończone, może przystąpić do jego
wgrania na płytkę Beerduino. Aby to uczynić, musi nacisnąć znajdujący się na samym dole
ekranu przycisk, zatytułowany „Wgraj przepis”. Zdefiniowany przepis zostaje przesłany do
Arduino, które od tej chwili zacznie dołączać go do wysyłanych komunikatów o swoim
stanie. Jednocześnie program Beerduino zmienia wskaźnik aktualnego kroku z wartości -1 na
wartość 0. Oznacza to, że płytka posiada wgrany przepis i jego stan jest aktywny. Gdy tylko
urządzenie z systemem Android odbierze pierwszy taki komunikat, wyświetlony zostanie
następny ekran – ekran procesu.
5.5. EKRAN PROCESU
Jest to główny ekran aplikacji, na którym użytkownik spędza praktycznie cały czas trwania
procesu. Przy poziomym ułożeniu urządzenia standardowo rozmieszczone kontrolki nie
zmieściłyby się na ekranie i wymagane byłoby przewijanie ekranu w pionie. Z tego właśnie
powodu ekran posiada dedykowany rozkład kontrolek dla poziomej orientacji ekranu
(rysunek 5.7).
45
Zielony wskaźnik stanu połączenia zachowuje się jak opisano na poprzednim
podrozdziale. Podtytuł okna zaczyna informować użytkownika o postępie procesu,
wyświetlając stan w formie komunikatu słownego (Np. „Krok 1 z 26”), który zmienia się wraz
z aktualny krokiem. Gdy proces dobiegnie końca, podtytuł aplikacji zostanie zmieniony na
„Zakończono”, a wszystkie kroki będą oznaczona jako wykonane.
Ogólny opis kontrolek znajdujących się na tym ekranie przedstawia się następująco:
I. Interaktywna lista kroków
Na samej górze zasadniczej części okna aplikacji wyświetlana jest lista kroków
wygenerowanych dla aktualnego procesu. Każdy krok wyświetlany jest na osobnej
„karcie” (ramce), z wypisaną nazwą czynności jaką obejmuje.
Przy długotrwałym procesie bardzo ważne jest czytelne oznakowanie stanu wykonania
46
Rysunek 5.8: Pasek akcji na ekranie procesu. Po prawej
ikonki podglądu przepisu oraz wskaźnik stanu połączenia
Rysunek 5.6: Ekran procesu w
orientacji pionowej
Rysunek 5.7: Dedykowany układ dla orientacji poziomej
kroków. Z tego powodu, na górnej krawędzi kart, dodałem pasek postępu, który
informuje o stopniu wykonania kroku. Kroki mogą znajdować się w jednym z trzech
stanów, a ich wygląd w konkretnych stanach opisany jest poniżej:
• Kroki przeszłe (wykonane):
Oprócz tekstu i ikonki, kroki te posiadają także
dopisek informujący o czasie, jaki zajęło ich
wykonywanie (np: „Krok trwał X minut”).
Wypełniony w całości pasek postępu informuje o
ich ukończeniu. Nieprzezroczystość kroków
ustawiona jest na 40% z racji ich małej ważności
w dalszym procesie.
• Kroki przyszłe:
Posiadają tytuł kroku oraz ikonkę, pasek postępu
jest pusty, a nieprzezroczystość karty ustawiona
jest na poziomie 65%. Czynności, które piwowar
będzie wykonywał w przyszłości, są dużo
ważniejsze niż kroki już dokonane, dlatego też ich
widoczność jest wyższa.
• Aktualny krok:
W ramce aktualnie wyświetlanego kroku
pokazywana jest standardowo jego nazwa oraz
ikonka. Wygląd paska postępu zależy tutaj od
typu wykonywanego kroku.
Jeżeli mamy do czynienia z krokiem czasowym,
czyli takim, który automatycznie wykona się po
upływie określonego czasu, postęp paska jest proporcjonalny do aktualnego czasu
trwania tego kroku.
długość paska w kroku czasowym = aktualny czas trwania krokudocelowy czas trwania kroku
Jeżeli wyznacznikiem wykonania jest osiągnięcie danej temperatury, długość paska
wyraża się wzorem:
długość paska w kroku temp = aktualna temp − temp zaczęcia krokudocelowa temp kroku
47
Rysunek 5.9: Wygląd kroku
przeszłego
Rysunek 5.11: Wygląd aktualnie
trwającego kroku
Rysunek 5.10: Wygląd kroku
przyszłego
W przypadku kroku manualnego niestety nie da się w żaden sposób przewidzieć czasu
jego trwania. Jest on w takim samym stopniu niewykonany, aż do momentu jego
wykonania – procent jego zaawansowania przed wykonaniem zawsze będzie równy 0.
Nie warto jednak pokazywać pustego paska postępu, gdyż wtedy wygląd aktualnego
kroku manualnego byłby zbyt podobny do przyszłych kroków. Postanowiłem zatem
pokazywać pasek postępu połowicznie zapełniony, daje to lepszy obraz kroku „w
trakcie realizacji” i pozwala łatwiej zorientować się w procesie. Kierowałem się
założeniem, że aplikacja ma być przejrzysta dla użytkownika już na pierwszy rzut oka,
bez zbędnego przyglądania się i zastanawiania.
Dodatkowo, ponieważ czas każdego kroku jest zliczany i zapisywany, aktualnie
wykonywany krok posiada dopisek „Trwa już X minut”. Pomaga to monitorować
upływ czasu na poszczególnych etapach (zwłaszcza przy krokach manualnych
i podgrzewaniu).
Kroki ułożone są w liście przewijanej horyzontalnie, a w jej centrum wyświetla się
aktualnie wykonywany krok. Krok poprzedni i następny wystają tylko lekko z boków
ekranu, ale użytkownik ma możliwość przewijania listy i podejrzenia wszystkich
kroków, zarówno przeszłych jak i przyszłych. Obecnie wykonywany krok powinien
mieć jednak swojego rodzaju priorytet, bo jest on aktualnie najważniejszy. Dlatego
też, gdy przewiniemy listę na krok inny niż aktualny, na górnym pasku aplikacji
pojawi się ikonka „przypięcia”. Kliknięcie na nią spowoduje szybkie przewinięcie
listy i wycentrowanie jej na aktualnym kroku. Powrót do aktualnego kroku następuje
również samoistnie, w momencie zmiany kroku (gdy poprzednio przetwarzany krok
został wykonany). Pomaga to nie zgubić się na liście kroków i na bieżąco mieć wgląd
w to co się dzieje.
48
Rysunek 5.12: Ikonka "przypięcia" pozwalająca łatwo wrócić do
aktualnie wykonywanego kroku
II. Przycisk wykonania manualnego kroku:
Bezpośrednio pod listą znajduje się duży
i dobrze widoczny przycisk, którego stan zależy
od typu obecnie przetwarzanego kroku. Jeżeli
krok jest typu manualnego, przycisk staje się
aktywny, a wyświetlany na nim tekst to:
„Zrobione, dalej!”. Naciśnięcie go wyśle
komunikat do płytki Arduino informując, że
użytkownik zadeklarował wykonanie tego kroku
i proces będzie mógł przejść dalej. Z kolei, gdy
krok nie jest typu manualnego (tylko np.
temperaturowy albo czasowy), przycisk jest
nieaktywny i widnieje na nim napis „Czekaj...”,
informujący użytkownika, że w danym
momencie wykonuje się czynność niezależna od niego i jedyne co może zrobić to
cierpliwie oczekiwać.
III. Wskaźnik aktualnej temperatury:
Tuż pod wyżej opisanym przyciskiem znajduje
się aktualna temperatura zacieru. Użyłem dużej
czcionki i dodatkowo z lewej strony umieściłem
wyraźną ikonę termometru. Wartość ta jest także
przesyłana z komunikatem pełnego stanu
Beerduino, więc okres jej odświeżania wynosi
jedną sekundę.
IV. Wykres temperatur:
Do wyświetlania wykresów użyłem darmowej biblioteki AchartEngine [17], która
posiada duże możliwości konfiguracji. Wykres zajmuje dolną część ekranu i agreguje
wszystkie odczyty temperatur na przestrzeni całego procesu Beerduino (od momentu
rozpoczęcie danego przepisu). Zaznaczone są na nim dwie serie wartości. Seria
zielona oznacza zbiór pomiarów temperatur zacieru na przestrzeni czasu. Czerwona
zaś jest funkcją jednowartościową i wskazuje aktualnie zadaną temperaturę, czyli taką,
do której dąży temperatura zacieru w czasie trwania podgrzewania. Oś pionowa
49
Rysunek 5.15: Kontrolka
wskazująca wartość aktualnej
temperatury
Rysunek 5.13: Aktywny przycisk
potwierdzenia wykonania kroku
manualnego
Rysunek 5.14: Wygląd przycisku
w przypadku kroku
niemanualnego
wykresu opisana jest w stopniach Celsjusza, a jej zakres wartości (zgodny ze
specyfiką problemu) zawiera liczby z przedziału od 30 do 100 stopni (włącznie). Oś
pozioma natomiast reprezentuje czas (wyrażony w minutach). Zakres osi poziomej
wynosi 150 minut (dwie i pół godziny) i udostępnia funkcje przewijania palcem w
celu przejrzenia temperaturowej historii procesu.
Aby użytkownik był na bieżąco z najnowszymi odczytami temperatur, wykres posiada
funkcje automatycznego przewijania. W momencie nadejścia nowego odczytu
temperatury wykres jest przewijany automatycznie tak, aby najnowsze wartości były
zawsze pokazane na ekranie (z prawej strony). Funkcja automatycznego przewijania
byłaby denerwująca, gdyby użytkownik chciał przejrzeć stare temperatury, a wykres
samoczynnie przeskakiwałby na koniec. Dodałem więc zabezpieczenie, które wyłącza
automatyczne przewijanie wtedy, gdy użytkownik sam przewinie wykres o daną
odległość. Może wtedy spokojnie przeglądać przeszłe odczyty, a tryb przewijania
manualnego zasygnalizowany jest zmianą koloru osi wykresu z czarnego na czerwony
(rysunek 5.16). Alarmuje to użytkownika, że wykres sam nie będzie się przesuwał
i nowe temperatury nie będą automatycznie widoczne. Gdyby takiego powiadomienia
nie było, można by odnieść wrażenie, że wczytywanie nowych wartości do wykresu
i przesuwanie go przestało po prostu działać. Aby powrócić do trybu automatycznego
przewijania, należy przesunąć wykres do końca, tak aby dojść do kilku ostatnich
wartości – osie odzyskają swój domyślny czarny kolor, a nowe temperatury znów
będą automatycznie pokazywane na ekranie.
V. Przycisk podglądu przepisu:
Ostatnim elementem widocznym na ekranie jest ikona w obszarze akcji (prawy górny
50
Rysunek 5.16: Wykres temperatur, a) w trybie automatycznego przewijania,
b) przewijanie zablokowane na żądanie użytkownika
róg ekranu), symbolizująca kartkę przepis. Po jej kliknięciu użytkownik zostanie
przekierowany na osobny ekran podglądu przepisu, który opisany jest w następnym
podrozdziale.
5.6. EKRAN PODGLĄDU AKTUALNEGO PRZEPISU
Ekran ten zatytułowany jest „Aktualny przepis”
i pozwala na podejrzenie aktualnie wykonywanego
przez płytkę Beerduino przepisu. Oprócz
możliwości przypomnienia sobie przepisu, pozwala
także sprawdzić, czy na pewno przepis został
prawidłowo wgrany do programu mikrokontrolera
Beerduino. Informacje tam zawarte są identyczne
jak te wprowadzane przez użytkownika na ekranie
dodawania nowego przepisu. Jedyną różnicą jest
fakt, że ekran ten jest wyświetlany w trybie tylko do
odczytu i nie ma możliwości wprowadzania tu
zmian – jedynym sposobem na zmodyfikowanie
przepisu jest reset płytki Beerduino i wgranie innego
przepisu na nowo.
51
Rysunek 5.17: Ekran podglądu
aktualnego przepisu
6. TESTY DZIAŁANIA APLIKACJI
6.1. WPROWADZANIE PRZEPISU I GENEROWANIE KROKÓW
Moment generowania kroków dla danego przepisu jest najważniejszy, ponieważ jeżeli błąd
wystąpi już na tym etapie, cały proces będzie przeprowadzony błędnie. Wybrałem zatem
jeden przepis na piwo, który wykorzystuje wszystkie parametry dostępne przy wprowadzaniu
przepisu. Dla utrudnienia podałem przerwy oraz chmiele w odwrotnej kolejności.
Oto wartości podane w poszczególnych sekcjach
formularza:
Wartości ogólne:
• Objętość docelowa: 20,0l
• Waga zasypu: 4,05kg
• Opóźnienie chmielenia: 5min
Przerwy:
• Przerwa #1 w 72°C: brak limitu czasu
• Przerwa #2 w 67°C: 60min
•
Chmiele:
• Chmiel #1: 30min
• Chmiel #2: 50min
Z wprowadzonego przepisu wygenerowanych zostało 26 kroków. Ich treść oraz rodzaj
prezentuje się następująco:
Lp. Nazwa Rodzaj kroku1 Gotowy do startu? Manualny2 Wlej wodę – 14,18l. Manualny3 Podgrzewanie do 67°C. Temperaturowy4 Wsyp słody – 4,05kg. Manualny5 Przerwa w 67°C (60min). Czasowy
52
Rysunek 6.1: Testowany przepis
6 Podgrzewanie do 72°C. Temperaturowy7 Przerwa w 72°C. Manualny8 Podgrzewanie do filtracji (78°C). Temperaturowy9 Odczekaj 15min przed filtracją. Czasowy10 Odkręć kranik i czekaj, aż woda spłynie. Manualny11 Zakręć kranik i wlej 3,12l wody. Manualny12 Odczekaj 5min, aż młóto osiądzie na dnie. Czasowy13 Odkręć kranik i czekaj, aż woda spłynie. Manualny14 Zakręć kranik i wlej 3,12l wody. Manualny15 Odczekaj 5min, aż młóto osiądzie na dnie. Czasowy16 Odkręć kranik i czekaj, aż woda spłynie. Manualny17 Zakręć kranik i wlej 3,12l wody. Manualny18 Odczekaj 5min, aż młóto osiądzie na dnie. Czasowy19 Odkręć kranik i czekaj, aż woda spłynie. Manualny20 Podgrzewanie do chmielenia (90°C). Temperaturowy21 Chmielenie 5min – opóźnienie Czasowy22 Wrzuć chmiel #2 Manualny23 Chmielenie 25min – #2 Czasowy24 Wrzuć chmiel #1 Manualny25 Chmielenie 30min – #1 Czasowy26 Filtracja końcowa – odkręć kranik. Manualny
Pomimo, że wprowadzone przerwy oraz chmiele znajdowały się w odwrotnej
kolejności, system sam przeprowadził sortowanie i wykrył, która przerwa zaczyna się w
niższej temperaturze. To samo stało się z czasami gotowania poszczególnych chmieli. Warto
zauważyć, że system nie zamienił ich indeksów, dzięki temu numery na liście kroków
pozostają zgodne z kolejnością wprowadzenia ich w przepisie.
Warto zwrócić także uwagę na krok numer 7. Jest to krok reprezentujący przerwę bez
podanego limitu czasu. System wygenerował dla niej krok manualny, więc nie czas, tylko
użytkownik będzie decydował, kiedy przerwa zostanie wykonana.
Gdy przerwy oraz chmiele zostaną wprowadzone w normalnej kolejności (przerwy –
rosnąco wg temperatur, chmiele – malejąco względem czasu), lista uzyskanych kroków jest
identyczna, za wyjątkiem indeksów wskazujących na konkretne przerwy/chmiele.
53
6.2. STEROWANIE TEMPERATURĄ
Test podgrzewania oraz utrzymywania temperatury wykonywałem na połowie ilości wody
(około 8 litrów) przewidzianej na przepis. W związku z tym wartości nastawów kontrolera
PID zostały dostosowane do takiej właśnie objętości wody. Niestety nie udało mi się do tej
pory wykonać łopat mieszadła (a muszą być wykonane porządnie), dlatego też testy
wykonywane były bez niego. Testy podzieliłem na trzy punkty, każdy z nich opisuje inny
przypadek, z którym musi zmierzyć się system podgrzewania.
6.2.1. Podgrzewanie pomiędzy przerwami
Testy opisane w tym punkcie skupiają się wokół podgrzewania brzeczki od jednej
temperatury do drugiej, czyli dokładnie tego co dzieje się pomiędzy przerwami.
Wykorzystane tu przerwy są podobne do tych opisanych w poprzednim podrozdziale, ale z
mniejszymi czasami, ponieważ samo utrzymywanie temperatury w obrębie przerwy opisane
zostanie w następnym punkcie. Wprowadzone przerwy to:
– przerwa w 67°C, 30 minut
– przerwa w 72°C, 20 minut
Test ten sprawdza wartości spadku temperatury po wrzuceniu słodów oraz wartość
przestrzelenia temperatury tuż po podgrzewaniu (spowodowanego inercją cieplną). W
projektowanym systemie odstępstwa te nie powinny przekraczać wartości +/- 1°C.
Poniżej (na rysunku 6.2) znajduje się wykres zmian temperatury w czasie.
Prezentowane są na nim dwie serie danych: zielona – obrazująca wartości aktualnej
temperatury oraz czerwona – ilustrująca zadaną wartość temperatury dla danej chwili. Białe
tło wykresu oznacza etap podgrzewania do zadanej temperatury. Jasnoszary kolor
podpowiada, kiedy się zaczynają oraz jak długo trwają poszczególne przerwy. Pomimo, że
ostatnia przerwa nie jest normalną przerwą, a jedynie odczekaniem do filtracji, została
zawarta na wykresie, ponieważ zachowuje się bardzo podobnie.
Wg danych składających się na wykres, maksymalne odchylenie od wartości zadanej w
dół wynosi 0.94°C. Pojawia się ono w 24. minucie, a wpływ na nie ma obniżenie temperatury
po wrzuceniu sodów. Natomiast największe przestrzelenie temperatury wynosi 0.75°C
i występuje w 80. minucie. Dodatkowo kolorem niebieskim zaznaczone są momenty zmian
parametrów kontrolera PID z podejścia agresywnego na konserwatywne. Wyraźnie widać, że
pomimo przejścia kontrolera PID w tryb zachowawczy, przez około 3°C tendencja wzrostowa
temperatury nie ulega zmianie – jest to spowodowane dużą inercją cieplną grzałki.
54
Założenie o błędzie +/- 1°C zostało osiągnięte, lecz warto zaznaczyć, że jest to test na
dużo mniejszej zawartości płynu oraz, że przeprowadzany został on bez obecności mieszadła.
Mam jednak nadzieję, że po doborze odpowiednich wartości nastawów system poradzi sobie
porównywalnie dobrze na docelowej objętości zacieru. Niestety będzie wymagało to
kolejnych żmudnych testów parametrów kontrolera PID.
6.2.2. Utrzymywanie temperatury w ramach pojedynczej przerwy
Po testach prezentujących jak system radzi sobie ze zmianą temperatury, przyszła kolej na
sprawdzenie, jak sprawnie system potrafi utrzymywać stałą temperaturę przez dłuższy okres
(około półtorej godziny). Rysunek 6.3 ukazuje wykres temperaturowy, przedstawiony w
55
Rysunek 6.2: Wykres kontroli temperatur pomiędzy przerwami
1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 8130
35
40
45
50
55
60
65
70
75
80
Zadana temperaturaAktualna temperaturaCzas w minutach
Tem
pera
tura
w °C Przerwa w 67°C Przerwa w 72°C 78°C
Wrzuceniesłodów
identycznej formie jak wykres z rysunku 6.2, dlatego też dłuższy opis prezentacji danych jest
zbędny. Znaczącą różnicą jest natomiast zakres osi Y, mieszczący się w przedziale od 50°C do
60°C. Dzięki takiemu zawężeniu zakresu osi łatwiej można zaobserwować poszczególne
wychylenia.
Najwyższe zanotowane odchylenia od temperatury zadanej to 0.48°C w dół oraz 0.25°C
w górę. Występują one odpowiednio w 33. oraz w 114. minucie. Podobnie jak w przypadku
poprzedniego testu, systemowi udało się utrzymać odchylenia o wartościach mniejszych niż
1°C. Porównując z wynikami uzyskanymi w poprzednim punkcie, widzimy, że utrzymywanie
stałej temperatury działa bardzo sprawnie, a większe odchylenia spowodowane są
przestrzeleniem temperatury przy podgrzewaniu z niższej temperatury albo spadkiem
temperatury tuż po wrzuceniu słodów.
6.2.3. Podgrzewanie do chmielenia oraz chmielenie
Aby kroki chmielenia zostały rozpoczęte, temperatura musi osiągnąć pewien założony
poziom. Idealnie, im wyższa temperatura chmielenia tym lepiej, ponieważ brzeczkę należy
intensywnie gotować. Nie zawsze da się osiągnąć temperaturę 100°C za pomocą
zastosowanej grzałki, szczególnie na dużych objętościach brzeczki. Dlatego też przy
podgrzewaniu do chmielenia system ustawia temperaturę 90°C, aby po jej przekroczeniu móc
56
Rysunek 6.3: Wykres kontroli temperatury w obrębie przerwy
1 579 17 25 33 41 49 65 73 81 89 97 105
113
121
129
137
54
54,5
55
55,5
56
Zadana temperaturaAktualna temperaturaCzas w minutach
Tem
pera
tura
w °C
przejść do następnych kroków, ale jednocześnie próbuje podgrzewać dalej. Warto
przypomnieć, że system już na początku podgrzewania (w 78°C) wie, że jest na etapie
chmielenia i odłącza kontroler PID, rozpoczynając maksymalne podgrzewanie.
Powyższy wykres pokazuje podgrzewanie do chmielenia oraz sam etap intensywnego
gotowania. Pierwsza część podgrzewania została przeprowadzona z zamkniętą pokrywą
garnka. Tutaj temperatura 100°C jest osiągana bez problemu, lecz w momencie zdjęcia
pokrywy spada ona poniżej 100°C. Te dwa przypadki pokazane zostały tylko dla porównania,
ponieważ normalnie chmielenie należy przeprowadzać ze zdjęta pokrywą.
Z testów systemu wynika, że kontroler PID jest prawidłowo odłączany, gdy tylko
temperatura zadana zostanie ustawiona na poziomie co najmniej 90°C (zdefiniowane w
programie po stronie płytki Arduino). Grzałka włączana jest wtedy na stałę, zapewniając
maksymalną moc gotowania.
57
Rysunek 6.4: Kontrola temperatury podczas chmielenia
1 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61 64 6775
80
85
90
95
100
105
Zadana temperaturaAktualna temperaturaCzas w minutach
Tem
pera
tura
w °C
Zdjęcie pokrywy garnka
7. MOŻLIWOŚCI I PLANY ROZWOJU
Od momentu rozpoczęcia pracy nad projektem systemu Beerduino, bardzo ważne były dla
mnie możliwości jego rozwoju. Głównie dlatego, że nie obsługuje on wszystkich znanych mi
czynności związanych z procesem warzenia piwa. Co więcej, brałem pod uwagę również
czynności, które mogą pojawić się w przyszłości, ponieważ im piwowar jest bardziej
doświadczony, tym bardziej skomplikowane przepisy podejmuje. Niektóre mogą wymagać
dodania pewnych funkcji i obsłużenia nowych przypadków. Kilka pomysłów na rozwój
zostało przedstawionych w rozdziałach poświęconych omawianym zagadnieniom (np. zmiana
implementacji kontroli temperatury na logikę rozmytą), więc opiszę te jeszcze nieomówione.
W pierwszym podrozdziale skupiłem się na rozbudowaniu obecnego zakresu działań
systemu Beerduino, czyli na dalszym usprawnieniu procesu zacierania i chmielenia. Staram
się tam pokazać, jak w łatwy sposób można skrócić czas wykonywania całego procesu o
okres około dwóch godzin. Drugi podrozdział traktuje o możliwościach rozwoju aplikacji
napisanej po stronie systemu Android. To właśnie ta część systemu jest najbardziej elastyczna
i pozwala swoim zasięgiem wykroczyć daleko poza zakres działań opisywany w niniejszej
pracy.
7.1. WYSŁADZANIE I PODGRZEWANIE DO CHMIELENIA
Jest to etap, na którym zauważalne są ogromne straty czasu. Mam tu na myśli kroki od
momentu odkręcenia kranika (poprzedzone odczekaniem 10 minut od podgrzania zacieru do
osiągnięcia temperatury 78°C) do wrzucenia pierwszego chmielu. Podczas filtracji młóto
osiada na dnie, tworząc pokaźne złoże filtracyjne. Otwory filtratora zastają częściowo przez
nie zatkane, co powoduje, że sama filtracja trwa długo (około 15 minut). Dodajmy do tego
fakt, że takich filtracji należy wykonać aż 4, a pomiędzy wysładzaniami wymagane jest
odczekanie po 5 minut. Same te czynności łącznie przekraczają czas jednej godziny. Należy
nie zapomnieć także o tym, że podgrzewanie do chmielenia możemy rozpocząć dopiero po
zakończeniu wysładzania i wyrzuceniu z garnka zalegającego młóta. Na umycie garnka
należy przeznaczyć kolejne 15 minut. Następnie, do czystego już garnka, należy przelać
brzeczkę znajdującą się chwilowo w osobnym zbiorniku, aby móc w końcu rozpocząć
podgrzewanie do chmielenia. Brzeczka, podczas oczekiwania na zakończenie filtracji
i umycie garnka oraz podczas jej przelewania z powrotem do garnka, wystudza się.
Podgrzewanie wystudzonej brzeczki do wysokich temperatur również trwa długo.
Wymyślonym przeze mnie rozwiązaniem jest zastosowanie systemu dwóch garnków.
58
Garnek pierwszy, w którym wykonywanie będzie zacieranie, trzeba będzie ustawić wyżej,
tak, aby podczas wysładzania brzeczka spływała do garnka drugiego – zastąpi on pojemnik,
do którego tymczasowo przelewa się brzeczkę. Plusami tego rozwiązania są: możliwość
rozpoczęcia podgrzewania brzeczki do chmielenia od razu po pierwszym odkręceniu kranika
oraz brak wychładzania się brzeczki w oczekiwaniu na zakończenie procesu wysładzania.
Modyfikację tę opisuję jako pierwszą, ponieważ pozwala zaoszczędzić około 2 godzin
czasu przy niewielkich zmianach systemu. Po stronie Arduino jedyną modyfikacją jaką należy
wykonać jest dołączenie nowego garnka (a dokładniej grzałki) do systemu. Nie ma potrzeby
dodawania nowego czujnika temperatury, ponieważ w starym garnku nie jest on już potrzebny
na etapie wysładzania. Można go zatem po prostu przełożyć do drugiego garnka. Nie potrzeba
także dodatkowego gniazdka, bo garnek pierwszy można z powodzeniem odłączyć. Po stronie
sprzętowej jest to tylko przepięcie garnka i przełożenie sondy z czujnikiem temperatury.
Najwięcej zmian należałoby wprowadzić w aplikacji na urządzenie z systemem
Android, ale dzięki zastosowaniu go jako urządzenia wejścia-wyjścia, jego interfejs możemy
zmieniać w sposób bardzo elastyczny, bez ponoszenia kosztów dodatkowych części (nowe
diody, wyświetlacze, przyciski). Ponieważ dochodzi tutaj do zrównoleglenia wykonywania
procesu, należy zaprezentować to w czytelnej dla użytkownika formie. Nie opracowałem
jeszcze dokładnie modyfikacji interfejsu, ale będzie to pierwsza rzecz, którą się zajmę po
zakończeniu prac nad obecnym etapem tworzenia systemu Beerduino.
7.2. PROCESY DŁUGOTERMINOWE
Po zacieraniu i chmieleniu jest jeszcze fermentacja (dzieląca się na dwie fazy: burzliwą
oraz cichą). Fermentacja burzliwa jest bardzo kapryśna i czasami drobna rzecz może ją
zatrzymać albo wypaczyć Wymagana jest wtedy ingerencja piwowara i wykazanie się
doświadczeniem w sytuacji, gdy przebiega ona nie tak jak było to zaplanowane. Zazwyczaj
fermentacja ta nie trwa długo, bo tylko około tygodnia, ale jest bardzo wrażliwa – temperatura
o kilka stopni wyższa może ją przyspieszyć dwukrotnie, a w niektórych przypadkach może
zwolnić, a nawet ustać. Następnym etapem jest fermentacja cicha, tutaj już mało się dzieje
(większość tego co miało się stać, zdarzyło się podczas fermentacji burzliwej). Trwa ona
zazwyczaj około dwóch tygodni. Oczywiście wartości mogą się znacząco różnić dla różnych
gatunków piwa – przedstawiłem najczęstsze wartości dla piw fermentowanych drożdżami
górnej fermentacji. Po zakończeniu fermentacji, przelane do butelek piwo, powinno
leżakować przez co najmniej miesiąc (czasami kilka miesięcy). Jak widać, ani fermentacja
burzliwa, ani fermentacja cicha, czy leżakowanie nie są dobrym obiektem do nadzoru czasu
59
rzeczywistego ze strony płytki Beerduino. Ważne są natomiast terminy przelań piwa na inną
fermentację, czy termin jego rozlewania do butelek.
Dzięki unikalnemu połączeniu Arduino oraz urządzenia z systemem Android, można
inaczej wspomagać te długoterminowe procesy. Po stronie systemu Android można zapisywać
daty początku procesu i ustawiać przypomnienia na planowane daty końca fermentacji. Daje
to możliwość utworzenia czegoś w rodzaju kalendarza z zapisanymi oczekiwanymi datami
końca fermentacji burzliwej, fermentacji cichej oraz leżakowania piwa. Oczywiście, w
przypadku zaimplementowania takiej funkcjonalności, użytkownik będzie musiał mieć
możliwość ręcznego zaznaczenia fermentacji burzliwej jako zakończonej przed czasem, bądź
przedłużenia jej o daną liczbę dni. Data końca fermentacji cichej byłaby wtedy skorygowana
i aktualizowana – tak samo data końca leżakowania. Dałoby to piwowarowi podgląd na
wszystkie procesy.
Idąc dalej tym tropem, każdy wykonany przepis mógłby tworzyć osobny wpis w bazie
danych telefonu. Dałoby to możliwość dodawania do systemu przepisów (zapisywanych w
pamięci telefonu) i w odpowiednim momencie po prostu wgrywania ich na płytkę Beerduino
w celu przeprowadzenia zacierania i chmielenia. Po zakończeniu tego procesu odpowiednie
wpisy zostałyby dodane do kalendarza, wraz z przypomnieniami o momentach przelania
piwa na fermentacje cichą oraz rozlania do butelek. Ostatnim zdarzeniem byłoby, oczywiście,
przypomnienie o gotowości piwa do spożycia.
Kiedy dodamy obsługę zapisywania zrobionych piw w pamięci telefonu, każde z nich
będzie miało swój osobny wpis w bazie danych. Warto dla każdego piwa dodać także
odpowiedni formularz, który w trakcie produkcji będzie wypełniany przez piwowara.
Powinien on zawierać następujące pola:
• Zawartość ekstraktu początkowego (przed fermentacją)
• Temperatury w jakich piwo fermentowało
• Pomiary stopnia odfermentowania (po fermentacji burzliwej oraz po cichej)
• Ilość cukru jaka została dodana przed rozlaniem i zabutelkowaniem piwa
• Daty zakończeń fermentacji burzliwej i cichej, a także data rozlania do butelek
• Objętość piwa na poszczególnych etapach (zmienia się ona podczas późniejszych
przelewań do nowych fermentatorów)
• Ilości butelek, do których piwo zostało rozlane
• Obliczona końcowa zawartość alkoholu
60
• Inne notatki i uwagi z produkcji (opisy dziwnych sytuacji i jak sobie z nimi
poradzono) – rady na przyszłość.
Do tej pory notatki takie prowadziłem w arkuszu kalkulacyjnym, a równolegle z nim
musiałem aktualizować kalendarz swoich piw. Teraz pojawi się możliwość posiadania tych
danych w jednej aplikacji, która będzie pilnowała wszystkich ważnych momentów
(np. rozlanie konkretnej warki do butelek) i sama będzie odpowiednio aktualizowała dane w
kalendarzu. Dodatkowo należy uświadomić sobie fakt, że w trakcie produkcji może
jednocześnie znajdować się wiele warek, na różnych etapach. Jedna na fermentacji burzliwej,
druga na cichej i jeszcze dwie warki leżakujące w butelkach, każda z innymi długościami
poszczególnych etapów. Pilnowanie wszystkiego w dedykowanym kalendarzu z
przypomnieniami byłoby nieocenioną pomocą.
7.3. KOŃCOWY PRZEGLĄD MOŻLIWOŚCI
Jak wynika z poprzednich podrozdziałów, możliwości rozwoju systemu są ogromne, a
obecnie pokrywa on tylko wycinek z pracy piwowara (co prawda najważniejszy). Aplikację
po stronie systemu Android można bardzo prosto rozwinąć i dostosować do własnych
potrzeb. Poniżej prezentuje skrócone podsumowanie pomysłów na dalszy rozwój projektu:
• Dodanie obsługi drugiego garnka do chmielenia oraz prezentacja graficzna
zrównleglenia procesu.
• Dodawanie nowych kontrolek – przycisków lub pól z wartościami – nie wymaga
dokupowania nowych urządzeń wejścia-wyjścia.
• Bardziej zaawansowane sposoby prezentacji danych.
• Ulepszenie systemu powiadomień dźwiękowych, np. ponawianie alarmu co kilka
minut w sytuacji, gdy użytkownik nie wykonał jeszcze danego kroku manualnego.
• Zapisywanie przeprowadzonych warek w pamięci telefonu.
• Prowadzenie dziennika i notatek do konkretnej warki.
• Utworzenie kalendarza z przypomnieniami o różnych wydarzeniach z życia browaru.
• Gromadzenie przepisów, tak aby możliwe było rozpoczęcie produkcji nowego piwa
przy użyciu istniejącego już przepisu.
61
PODSUMOWANIE
Efektem pracy jest zrealizowanie systemu Beerduino, składającego się z płytki Arduino,
urządzenia z systemem Android oraz części sprzętowej. Nie jest on tylko asystentem
piwowara, który pomaga pilnować wykonania kolejnych kroków rozbijając przepis na listę
prostych do zrozumienia kroków. Idzie on o krok dalej i stara się wyręczyć użytkownika w
prostych czynnościach takich jak kontrola temperatury lub mieszanie.
Pomimo, że powstał on wyłącznie na moje potrzeby, nie jest on trudno do złożenia
i dopasowania do potrzeb innych użytkowników. Algorytm przesyłania danych pomiędzy
urządzeniami nie jest zoptymalizowany, ale za to prosty i przygotowany pod dalszy rozwój.
Dzięki zastosowaniu urządzenia z systemem Android jako panelu wprowadzania
i wyświetlania danych, system wykazuje duże możliwości interakcji z użytkownikiem oraz
możliwości rozwoju. Opisane zostały one w odpowiednim rozdziale. System, pomimo
zastosowania prostego interfejsu graficznego, nie nadaje się dla ludzi zupełnie nieznających
się na procesie produkcji piwa. Aby dostosować go do takich użytkowników, należałoby
dodać więcej opisów, ale i one nie są w stanie zastąpić prawdziwej wiedzy teoretycznej z
zakresu tego skomplikowanego procesu.
Do realizacji systemu starałem się użyć w miarę podstawowych komponentów
sprzętowych. Telefony z systemem Android są obecnie bardzo popularne, a jedynym
specyficznym urządzeniem, które należy nabyć jest płytka Arduino (kompatybilna z ADK).
Elektryczny garnek nie jest obowiązkowy – można z powodzeniem użyć zwykłego dużego
garnka i osobno dołączyć grzałkę elektryczną. Co więcej, nawet w przypadku braku
mieszadła i grzałki, program będzie funkcjonował bez zarzutu. Jedyną różnicą będzie to, że
czynności podgrzewania oraz mieszania należy wtedy wykonywać manualnie. W przypadku
braku czujnika temperatury należałoby zmienić kroki temperaturowe (których system bez
czujnika nigdy nie uzna za wykonane) na kroki manualne.
62
BIBLIOGRAFIA
[1] Fora piwowarskie:
http://www.piwo.org/index/, 31 lipca 2013
http://www.browar.biz/forum/, 31 lipca 2013
[2] Strona projektu Raspberry Pi:
http://www.raspberrypi.org, 12 sierpnia 2013
[3] Strona BrewPi oraz projekt płytki RevA:
http://docs.brewpi.com/, 12 sierpnia 2013
https://github.com/BrewPi/brewpi-avr/, 31 lipca 2013
http://brewpi.com/brewpi-arduino-shield-soldering-guide-for-reva/, 12 sierpnia 2013
[4] Strona projektu BrewTroller, Open Source Control Systems:
https://www.oscsys.com/projects/brewtroller/system-design, 20 sierpnia 2013
http://live.brewtroller.com/, 20 sierpnia 2013
[5] Dokumentacja płytki Seeeduino, Seeed Studio, 2011:
http://www.seeedstudio.com/wiki/Seeeduino_ADK_Main_Board, 31 lipca 2013
[6] Dokumentacja mikrokontrolerów Atmega, Atmel, fragmenty rozdziałów 17.9 oraz 17.11:
http://www.atmel.com/Images/doc2549.pdf, 31 lipca 2013
[7] RobotFreak: Arduino 101: Timers and Interrupts, Let's make robots!, 7 sierpnia 2011:
http://letsmakerobots.com/node/28278, 31 lipca 2013
[8] Amandaghassaei: Arduino Timer Interrupts, Instructables, 8 lipca 2012:
http://www.instructables.com/id/Arduino-Timer-Interrupts/, 31 lipca 2013
[9] Brett Beauregard: PIDLibrary, zasób Arduino Playground:
http://playground.arduino.cc/Code/PIDLibrary, 12 sierpnia 2013
http://playground.arduino.cc/Code/PIDLibaryBasicExample, 12 sierpnia 2013
[10] Brett Beauregard: PIDLibrary Relay Output Example, zasób Arduino Playground:
http://playground.arduino.cc/Code/PIDLibraryRelayOutputExample, 12 sierpnia 2013
[11] Robert Lacoste: PID Control Without Math, miesięcznik Circuit Cellar, numer 221,
grudzień 2008, strony 54-56, 58-61:
http://itech.fgcu.edu/faculty/zalewski/CDA4170/files/PIDcontrol.pdf, 12 sierpnia 2013
[12] Dokumentacja Android Support Library:
http://developer.android.com/tools/support-library/features.html, 31 lipca 2013
63
[13] Wskazówki obsługi urządzeń USB: USB Accessory:
http://developer.android.com/guide/topics/connectivity/usb/accessory.html, 31 lipca
2013
[14] Mike Lockwood, Erik Gilling, Jeff Brown: Android Open Accessory API and
Development Kit (ADK), z konferencji Google I/O 2011, 11 maja 2011:
http://www.youtube.com/watch?v=s7szcpXf2rE, 31 lipca 2013
[15] Dokumentacja współpracy z płytką ADK: Accessory Development Kit 2011 Guide:
http://developer.android.com/tools/adk/adk.html, 31 lipca 2013
[16] Obsługa połączenia z ADK. RobotGrrl: ServiceADK, 28 listopada 2011:
https://github.com/RobotGrrl/ServiceADK/tree/master/ServiceADK, 31 lipca 2013
[17] AChartEngine – biblioteka do rysowania wykresów dla systemu Android:
https://code.google.com/p/achartengine/, 31 lipca 2013
64