W artykule zostanie omówione po kolei podłączenie wszystkich potrzebnych urządzeń do doniczki oraz zaprogramowanie arduino. Taka doniczka może być dobrym rozwiązaniem dla osób które lubią zrobić coś samemu, oraz gdy nie mają czasu lub zapominają o podlewaniu kwiatków, wystarczy ustawić wilgotność i nasza doniczka jest gotowa do pracy.
Spis treści
- Krótki opis
- Podłączenie czujnika wilgotności
- Podłączenie przełącznika
- Podłączenie czujnika poziomu wody*
- Podłączenie wyświetlacza LCD
- Podłączenie enkodera
- Podłączenie zasilania
- Podłączenie zasilania do złączek zaciskowych
- Podłączenie wtyczki zasilającej do arduino
- Podłączenie zasilania do przełącznika
- Podłączenie pompki do zasilania
- Gotowe podłączenie
- Zaprogramowanie arduino
- Pliki do pobrania
Krótki opis
Po podłączeniu, oraz zaprogramowaniu naszej doniczki powinna ona podlewać roślinkę, gdy wilgotność będzie mniejsza od tej której wcześniej ustawiliśmy . W doniczce istnieje możliwość ustawienia po jakim czasie ekran ma przejść w tryb uśpienia, aby zaoszczędzić energię.
Podłączenie czujnika wilgotności
Jako pierwszy zostanie podłączony czujnik wilgotności, VCC podłączamy do pinu V, GDN do pinu G i AOUT do pinu A0.
Kiedy połączenie jest gotowe, zachęcam do zapoznania się z tym artykułem, aby dowiedzieć się jak skonfigurować nasz czujnik, aby poprawnie wskazywał wartości, następnie kiedy odpowiednio ustawimy czujnik, przechodzimy do kolejnego połączenia.
Podłączenie przełącznika
W przełączniku na razie będą interesować nas piny z ledami po dwóch stronach, zaczniemy od IN1 które wpinamy do pinu A1, następnie GND do G i VCC do V.
Kiedy połącznie jest gotowe, przechodzimy dalej.
Podłączenie czujnika poziomu wody
Podłącznie czujnika wody jest bardzo proste,wystarczy jeden z kabli podłączyć do pinu A2, a drugi do G.
Po gotowym podłączeniu, przechodzimy do wyświetlacza LCD.
Podłącznie wyświetlacza LCD
Wyświetlacz LCD podłączamy pod piny A4 który odpowiada za SDA i A5 który odpowiada za SCL, następnie zasilanie podłączamy pod 5V i GDN do GND.
Po zakończeniu podłączenia przechodzimy do enkodera.
Podłączenie enkodera
Podłączenie enkodera zaczniemy od VCC i GND, VCC podpinamy do 5V, a GND do GND, teraz zajmiemy się SW, CLK, DT. CLK wpinamy do pinu 2, SW do 3 i DT do 4.
Po podłączeniu już wszystkich potrzebnych urządzeń, możemy zabrać się za podłączenie zasilania.
Podłączanie zasilania
Do podłączenia zasilania będziemy potrzebowali dwóch złączek zaciskowych na 3 wejścia, jeden kabel na zasilający (+), a drugi na uziemienie (-) .
Podłączenie zasilania do złączek zaciskowych
Do jednej z naszych złączek wpinamy kabel zasilający odpowiadający za plusa, następnie to samo robimy z drugą złączką, tyle, że będzie ona odpowiadać za minusa.
Podłączenie wtyczki zasilającej do arduino
Z złączek wyprowadzamy po jednym kablu, jeden z minusa, drugi z plusa, następnie wpinamy je zgodnie z schematem przedstawionym na wtyczce. Jeden kabel wprowadzamy do minusa, przykręcamy i robimy to samo z plusem.
Podłączenie zasilania do przełącznika
Wyprowadzamy kolejny kabel ze złączki, tym razem tylko plusa i wpinamy go do wejścia oznaczonym NO, wykonamy teraz połączenie pompki.
Podłączenie pompki do zasilania
Odpowiedzialny za zasilanie naszej pompki będzie odpowiadał przełącznik, który za pomocą arduino będzie przełączał się i dawał dopływ prądu kiedy będzie to potrzebne. Kabel czerwony z pompki wprowadzamy do wejścia COM w przełączniku, za to czarny, czyli uziemienie, wpinamy do złączki odpowiedzialnej za minusa.
Gotowe podłączenie
Gdy już wykonamy podłączenie, powinno wyglądać ono następująco, tak jak na poniższym zdjęciu.
Gdy zgadza się ono z twoim połączeniem, możemy przejść dalej i zaprogramować nasze arduino.
Zaprogramowanie arduino
Programowanie zaczniemy od zdefiniowania wszystkich potrzebnych pinów, zaimportowania odpowiednich bibliotek, stworzenia obiektów, zadeklarowania zmiennych oraz wgrania grafiki której użyjemy przy wyświetlaniu braku wody, więcej o niej możecie dowiedzieć się w tym artykule.
//definicje #define CLK 2//enkoder #define DT 4//enkoder #define AOUT A0//czujnik wilgotnosci #define WODA A7//czujnik poziomu wody #define IN1 A1//przełącznik #define SW 3//przycisk //biblioteki #include <Encoder.h> #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> //obiekty Adafruit_SSD1306 display(0); Encoder myEnc(CLK, DT); //zmienne const int mokry = 805; //wartość suchego czujnika wilgotności const int suchy = 390; //wartość mokrego czujnika wilgotności int odczyt = analogRead(AOUT);//odczyt z czujnika poziomu cieczy int wilgotnosc = 0;//odczyt z czujnika wilgotności long ustaw_wilgotnosc = 0;//odczytujemy wartość z enkodera long poprzednia_wartosc = 0;//zmienna pomocnicza do enkodera bool zmiana = true;//czy jest zmieniana wilgotność int ilosc_wody = 0;//poziom wody volatile bool uspiony = false;//zmienna odpowiadająca za tryb uśpienia unsigned long obecny_czas = 0;//zmienna do mierzenia obecnego czasu unsigned long ostatni_czas = 0;//ostatni mierzony czas volatile bool wcisniety = false;//zmienna odpowiedzialna za wchodzenie do menu //grafika const unsigned char kropla_wody [] PROGMEM = { 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x1c, 0xe0, 0x00, 0x00, 0x3c, 0xf0, 0x00, 0x00, 0x78, 0x70, 0x00, 0x00, 0x70, 0x78, 0x00, 0x00, 0xf0, 0x3c, 0x00, 0x00, 0xe0, 0x1e, 0x00, 0x01, 0xe0, 0x1e, 0x00, 0x01, 0xc0, 0x0f, 0x00, 0x03, 0xc0, 0x07, 0x80, 0x03, 0xd0, 0x07, 0x80, 0x03, 0x90, 0x03, 0xc0, 0x03, 0xb0, 0x01, 0xc0, 0x07, 0xb0, 0x01, 0xe0, 0x07, 0xb0, 0x01, 0xe0, 0x07, 0x30, 0x00, 0xe0, 0x07, 0xb0, 0x01, 0xe0, 0x03, 0xb8, 0x01, 0xc0, 0x03, 0x98, 0x01, 0xc0, 0x03, 0xcc, 0x03, 0xc0, 0x01, 0xc7, 0x03, 0x80, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x0f, 0xf0, 0x00 };
Następnie ustawiamy wszystkie potrzebne ustawienia w funkcji setup
void setup() { Serial.begin(9600);//rozpoczęcie transmisji na porcie szeregowym display.begin(SSD1306_SWITCHCAPVCC, 0x3C);//definiujemy rodzaj użytego wyświetlacza oraz adres I2C display.clearDisplay();//czyścimy ekran display.setTextSize(3);//ustawiamy rozmiar czcionki display.setTextColor(WHITE);//ustawiamy kolor biały pinMode(IN1, OUTPUT);//ustawienie pinu IN1 jako wyjście pinMode(SW, INPUT_PULLUP);//ustawienie pinu SW jako przycisk attachInterrupt(digitalPinToInterrupt(SW), Wybudz , FALLING);//ustawiamy przerwanie na przycisk ktore ma wykonac funkcje wybudz }
Przechodzimy do głównej funkcji loop w której będzie wykonywany cały kod. Całość będzie się opierała na dwóch pętlach, gdzie jedna odpowiada za stan gdzie arduino jest uśpione, a druga gdy jest wybudzone. Będziemy przemieszczać się pomiędzy nimi, za pomocą przerwań, co pozwoli na wybudzanie ekranu, oraz wchodzenia do menu ustawiania wilgotności.
Zaczniemy od pętli w której arduino nie jest uśpione, włączamy ekran, gdyby była taka potrzeba i ustawiamy na enkoderze poprzednią wcześniej ustawioną wartość, aby się ona nie wyzerowała.
while (!uspiony) { display.ssd1306_command(SSD1306_DISPLAYON);//włączenie wyświetlacza lcd jeżeli był wcześniej wyłączony myEnc.write(poprzednia_wartosc);//ustaw poprzednią wartość enkoderowi, aby się nie wyzerowała
Tworzymy pętlę która będzie odpowiadała za menu ustawiania wilgotności. Będzie ona załączana przy pomocy przerwania o którym dowiecie się pod koniec. W pętli wykorzystujemy wczytywanie wartości z enkodera, oraz gdy będzie ona przekraczała zakres od 0 do 100 powinna zostać ustawiona prawidłowo, następnie wartość z enkodera zostaje wczytana do zmiennej która odpowiada za ustawienie wilgotności, na końcu zostaje wyświetlona na wyświetlaczu LCD i wartość zostaje przypisana do poprzedniej wartości.
while (wcisniety) { long ustaw_wilgotnosc = myEnc.read();//odczytujemy wartość z enkodera if (ustaw_wilgotnosc < 0) { //jeżeli wartość z enkodera jest mniejsza od 0 ustaw ją na 0 myEnc.write(0);//ustawiamy pozycję enkodera na 0 } else if (ustaw_wilgotnosc > 100) {//w przeciwnym wypadku jeżeli wartość jest większa od 100 ustaw ją na 100 myEnc.write(100);//ustawiamy pozycję enkodera na 100 } //Ponownie wczytujemy wartości z enkodera ustaw_wilgotnosc = myEnc.read();//wczytaj ponownie wartość enkodera w razie gdyby uległa ona zmianie przez instrukcje warunkowe //Wyświetlamy pobraną wartość na wyświetlaczu display.clearDisplay();//czyścimy ekran display.setCursor(4, 0);//ustawiamy kursor na daną pozycję display.setTextSize(2);// ustawiamy rozmiar czcionki display.writeFastHLine(0, 16, 128, WHITE);//rysujemy białą linię, dwa pierwsze parametry odpowiadają za szerokość i wysokość, pozostałe dwa za szerokość lini oraz kolor display.println("USTAW WIL.");//piszemy tekst który ma się ukazać display.setTextSize(3);// ustawiamy rozmiar czcionki display.setCursor(50, 22);//ustawiamy kursor na daną pozycję display.print(ustaw_wilgotnosc);//wyświetlamy wcześniej ustawioną wilgotność display.print("%");//piszemy tekst który ma się ukazać display.display();//wyświetlamy poprzednia_wartosc = ustaw_wilgotnosc;//przypisujemy obecną ustawioną wilgotność, aby później delay(50); }
Teraz zrobimy sprawdzenie czy jest woda w zbiorniku, na początku robimy odczyt, a później sprawdzamy czy wartość nie jest mniejsza od 50 i do póki jest mniejsza, oznacza, że w pojemniku nie ma wody. Gdy wartość wzrośnie powinna się wykonać dalsza część kodu.
ilosc_wody = analogRead(WODA); while (ilosc_wody < 50) { display.clearDisplay();//czyścimy ekran display.drawBitmap(5, 18, kropla_wody, 32, 32, WHITE);//pierwsze dwa parametry odpowiadają za ustawienie kursora, kropla_wody oznacza nazwę naszego kodu obrazka, a 32 i 32 to rozmiar obrazka, na końcu ustawiamy kolor WHITE czyli biały display.setTextSize(2);// ustawiamy rozmiar czcionki display.setCursor(42, 18);//ustawiamy kursor na daną pozycję display.print("NALEJ");//piszemy tekst który ma się ukazać display.setCursor(42, 35);//ustawiamy kursor na daną pozycję display.print("WODY");//piszemy tekst który ma się ukazać display.display();//wyświetlamy na ekranie, bez tego nie zadziała delay(100); ilosc_wody = analogRead(WODA);//robimy pomiar czy jest wystarczająca ilość wody }
Zaprogramujemy sprawdzanie poziomu wilgotności i jeżeli będzie mniejsza niż ustawiona zostanie uruchomiona pompka która doleje wody i uzupełni wilgotność. Następnie wywołujemy funkcje które zrobią odczyt wilgotności i wyświetlą ją na ekranie.
if (wilgotnosc < ustaw_wilgotnosc) { digitalWrite(IN1, LOW); delay(2000); digitalWrite(IN1, HIGH); delay(5000); } else { digitalWrite(IN1, HIGH); } ZrobOdczytWilgotnosci(); WyswietlWilgotnosc();
Ustawiamy czas jaki ma minąć do wygaśnięcia ekranu, ja ustawiłem 30000 milisekund, czyli 30 sekund, jeżeli potrzebujemy więcej lub mniej czasu, można to zmienić.
if (obecny_czas - ostatni_czas > 30000) { ostatni_czas = obecny_czas; uspiony = true; } else { obecny_czas = millis(); }
Zajmiemy się teraz drugą pętlą odpowiedzialną za działanie, kiedy wyświetlacz LCD jest w stanie uśpienia. Na początku wyłączamy wyświetlacz i robimy odczyt wilgotności by sprawdzić czy nasza roślinka nie usycha, jeżeli nie, to wyłącz pompkę w razie gdyby była włączona. Jednak gdy wilgotność jest zbyt niska, to włącz pompkę, odczekaj 2 sekundy, wyłącz pompkę i odczekaj 5 sekund, aby woda zdążyła wsiąknąć.
while (uspiony) { display.ssd1306_command(SSD1306_DISPLAYOFF);//wyłączenie wyświetlacza lcd ZrobOdczytWilgotnosci(); if (wilgotnosc < ustaw_wilgotnosc) { digitalWrite(IN1, LOW);//włączenie przełącznika delay(2000); digitalWrite(IN1, HIGH);//wyłączenie przełącznika delay(5000); } else { digitalWrite(IN1, HIGH);//wyłączenie przełącznika } delay(1000); } }
Nasz program jest już prawie gotowy, wystarczy tylko dodać funkcję pod koniec kodu i możemy się cieszyć jego działaniem.
Pierwsza funkcja odpowiada za zmianę stanu uśpienia, nie jest ona zbyt skomplikowana.
void Uspij() { uspiony = true;//ustawienie zmiennej uspiony na true }
Drugą funkcją oczywiście jest wybudzenie która dodatkowo działa jako wejście do menu.
void Wybudz() { uspiony = false;//ustawienie zmiennej uspiony na false wcisniety = !wcisniety;//zmienia stan zmiennej wcisniety na przeciwny który jest }
Kolejną funkcją będzie pomiar wilgotności, więcej o czujnikach możecie dowiedzieć się w tym artykule.
void ZrobOdczytWilgotnosci() { int odczyt = analogRead(AOUT);//zadeklarowanie i wczytanie do zmiennej wartości z czujnika wilgotnosc = map(odczyt, suchy, mokry, 100, 0);//zmapowanie odczytywanych wartości na procenty }
Ostatnia funkcja będzie odpowiedzialna, za wyświetlanie wilgotności na wyświetlaczu, więcej o nich znajduje się tutaj.
void WyswietlWilgotnosc() { display.clearDisplay();//czyścimy ekran display.setCursor(4, 0);//ustawiamy kursor na daną pozycję display.setTextSize(2);// ustawiamy rozmiar czcionki display.writeFastHLine(0, 16, 128, WHITE);//rysujemy białą linię, dwa pierwsze parametry odpowiadają za szerokość i wysokość, pozostałe dwa za szerokość lini oraz kolor display.println("WILGOTNOSC");//piszemy tekst który ma się ukazać display.setTextSize(3);// ustawiamy rozmiar czcionki display.setCursor(50, 22);//ustawiamy kursor na daną pozycję display.print(wilgotnosc);//piszemy tekst który ma się ukazać display.print("%");//piszemy tekst który ma się ukazać display.display();//wyświetlamy delay(10); }
To by było na tyle w tym artykule, mam nadzieję, że wszystko działa i możecie się cieszyć własną automatyczną doniczką. Oczywiście poniżej znajduje się cały kod i potrzebne biblioteki które możecie pobrać.