# Czujnik Wilgotności Gleby


Czujnik wilgotności gleby to pierwsza rzecz, która przychodzi na myśl, jeśli chodzi o budowę inteligentnego systemu nawadniania lub automatycznego systemu nawadniania roślin. Dzięki temu czujnikowi i niewielkiej obsłudze Arduino możemy zaprojektować, np. automatyczny system nawadniania za pomocą `Arduino UNO R3`, który może podlewać rośliny, gdy jest to potrzebne, unikając nadmiernego podlewania.

Projekt obejmuje połączenie komponentów do/z Arduino, zaprogramowanie czujnika z sensorem wykorzystując
`Arduino IDE`, testy (polskich znaków diakrytycznych) oraz uruchomienie.
<!--more-->

```
TUTAJ WSTAWIĆ ASCII czujnika
```
## **Użyte oprogramowanie**

✔ Arduino IDE - Version: 2.3.4, Date: 2024-12-03T10:03:03.490Z, CLI Version: 1.1.1 –
https://www.arduino.cc/en/software

✔ IrfanView - Przeglądarka i edycja zdjęć - https://www.irfanview.com/

✔ Biblioteka LiquidCrystal_I2C.h - Wersja 1.1.4 - https://github.com/johnrickman/LiquidCrystal_I2C

✔ LaTeX - (Edytory LaTeX online) - https://www.overleaf.com/

✔ TinyPNG - (Compression for Faster Websites online) - https://tinypng.com/

✔ Canva - Popularne narzędzie online do tworzenia projektów, np. okładek - https://www.canva.com/

✔ TinkerCad - Darmową aplikacja służącą do projektowania 3D, elektroniki i programowania -
https://www.tinkercad.com/

## **Komponenty**

Komponenty potrzebne do zbudowania czujnika wilgotności gleby.

| NAZWA	| ILOŚĆ | KOMPONENT|
| ------|-------|----------|
| UA_UNO_R3	| 1	| [Arduino UNO R3]|
| ULCD	| 1	| [Niebieski wyświetlacz LCD 1602 16x2 HD44780 z konwerterem i2C]|
| SENCZ_W | 1 | 	[Czujnik LM39 wilgotności gleby z potencjometrem]|
| K_USB | 1| 	[Kabel USB do Arduino (USB-A/USB-B)]|
| K_MZ  | 7| 	[Kabelek połączeniowy (męsko/żeński)]|
| K_ZZ  | 2| 	[Kabelek połączeniowy (żeńsko/żeński)]|

> `Rysunek 1`: Arduino UNO R3

![Arduino UNO R3](arduino-uno-r3.jpg)

> `Rysunek 2`: Niebieski wyświetlacz LCD 1602 16x2 HD44780 z konwerterem i2C

![Niebieski wyświetlacz LCD 1602 16x2 HD44780 z konwerterem i2C](HD44780.jpg)

> `Rysunek 3`: Czujnik LM39 wilgotności gleby z potencjometrem

![Czujnik LM39 wilgotności gleby z potencjometrem](czujnik-lm39-wilgotnosci-gleby.jpg)

> `Rysunek 4`: Kabel USB do Arduino (USB-A/USB-B)

![Kabel USB do Arduino (USB-A/USB-B)](kabel-usb-a-usb-b-arduino.jpg)

> `Rysunek 5`: Kabelek połączeniowy (męsko/żeński)

![Kabelek połączeniowy (męsko/żeński)](kabelek-polaczeniowy-mesko-zenski.jpg)

> `Rysunek 6`: Kabelek połączeniowy (żeńsko/żeńśki)

![Kabelek połączeniowy (żeńsko/żeńśki)](kabelek-polaczeniowy-zensko-zenski.jpg)

## **Opis Projektu**

Projekt ten służy do monitorowania wilgotności gleby przy użyciu czujnika wilgotności gleby oraz wyświetlacza `LCD 16X2`. Dzięki temu można odczytywać aktualny poziom wilgotności gleby pokazany na wyświetlaczu w procentach. Wyświetlane są również polskie znaki diakrytyczne, czyli pospolite `ogonki`.

## **Rozkład pinów czujnika wilgotności gleby**

Czujnik wilgotności gleby, znany również jako `Soil Moisture Sensor`, który posiada cztery piny: `VCC`, `GND`, `Aout`, `Dout`. Piny te mogą być używane do uzyskiwania danych o wilgotności gleby z czujnika. `Rysunek 7` ukazuje rozkład tych pinów:

> `Rysunek 7`: Rozkład pinów czujnika wilgotności gleby

![Rozkład pinów czujnika wilgotności gleby)](rozklad-pinow-czujnika-wilgotnosci-gleby.jpg)

Źródło do `Rysunkek 7`:
https://circuitdigest.com/sites/default/files/inlineimages/u4/Soil-Moisture-Sensor-Pinout.png

## **Połąćzenie pinów**

✔ `VCC`- Zasilanie 5V;

✔ `GND - Masa (Ground)` - podłączenie do GND w Ardnuino (masy lub uziemienia);

✔ `AO (A_OUT)` - (Analog output pin) - wyjście analogowe dające sygnał między VCC a GND;

✔ `DO (D_OUT)`- (Digital output pin) - wyjście cyfrowe (wskazujące na wilgotność niską lub wysoką); [link](#);

## **Działanie czujnika**

Czujnik wilgotności gleby działa poprzez umieszczenie sondy z dwiema przewodzącymi płytkami w glebie.

Rezystancja sondy zmienia się w zależności od wilgotności gleby: im więcej wody, tym mniejszy opór, a im mniej wody, tym wyższy opór. Czujnik przekształca tę rezystancję w sygnał napięciowy, który pozwala określić poziom wilgotności.

## **Czujnik wilgotności gleby - części I**

## **Sonda czujnika**

Czujnik zawiera sondę w kształcie widełka z dwiema przewodzącymi podkładkami, która działa jak zmienny potencjometr, a jej wartość może być odczytana przez mikrokontroler `Arduino UNO R3`.

> `Rysunek 8`: Sonda czujnika wilgotności gleby

![Sonda czujnika wilgotności gleby)](sonda-czujnika-wilgotnosci-gleby.jpg)

Źródło do `Rysunek 8`:

https://circuitdigest.com/sites/default/files/inlineimages/u4/Soil-Moisture-Sensor-Module-Components.png

**LEGENDA:**

Opis poszczególnych elementów składowych czujnika wilgotności gleby do `Arduino UNO R3`:

- **Sensor (-):** - Jest to jeden z elektrod sondy pomiarowej, która wchodzi w kontakt z glebą. Rezystancja pomiędzy tym a drugim elektrodą zmienia się w zależności od wilgotności gleby.

- **Sensor (+):** - Jest to druga elektroda sondy pomiarowej, która wraz z `Sensor (-)` tworzy obwód pomiarowy. Razem z Sensor - tworzy mostek pomiarowy, który reaguje na zmiany wilgotności gleby.

- **Comparator op amp:** - Jest to komparator operacyjny, który porównuje sygnał z sondy
z ustalonym progiem. Umożliwia wygenerowanie sygnału cyfrowego w zależności od przekroczenia progu wilgotności.

- **Trim-pot adjust sensitivity:** - Jest to potencjometr, który pozwala na regulację czułości czujnika.
Dzięki niemu można dostosować próg zadziałania sygnału cyfrowego do indywidualnych potrzeb.

- **Signal LED:** - Jest to dioda sygnalizująca stan wyjścia cyfrowego. Świeci się, gdy wyjście cyfrowe jest w stanie wysokim lub niskim, w zależności od ustawień.

- **Power LED:** - Jest to dioda sygnalizująca zasilanie modułu. Świeci się, gdy moduł jest podłączony do zasilania.

- **Analog OUT:** - Jest to wyjście analogowe, które wysyła sygnał proporcjonalny do wilgotności gleby.
Pozwala na odczyt precyzyjnych wartości wilgotności za pomocą mikrokontrolera.

- **Digital OUT:** - Jest to wyjście cyfrowe, które generuje sygnał `0` lub `1` w zależności
od przekroczenia progu wilgotności. Może być wykorzystane do sterowania urządzeniami zewnętrznymi, takimi jak pompy.

- **GND:** - Jest to masa modułu, która musi być połączona z masą mikrokontrolera. Zapewnia prawidłowe funkcjonowanie układu.

- **VCC:** - Jest to pin zasilania modułu, który musi być podłączony do napięcia `5V`. Zapewnia zasilanie dla wszystkich elementów modułu.

- **DO (D_OUT)** - (`Digital output pin`) - wyjście cyfrowe (wskazujące na wilgotność niską lub wysoką);

## **Moduł czujnika**

Moduł czujnika wilgotności gleby konwertuje sygnał analogowy na cyfrowy i może działać bez mikrokontrolera. Składa się z dwóch pinów wejściowych dla sondy, pinów zasilania (`VCC i GND`) oraz dwóch pinów wyjściowych (cyfrowego i analogowego).

> `Rysunek 9`: Moduł czujnika wilgotności gleby

![Moduł czujnika wilgotności gleby)](modul-czujnika-wilgotnosci-gleby.jpg)

`Rysunek 9` - Źródło: `własne`

Moduł zawiera komparator `LM393` do digitalizacji sygnału z sondy oraz potencjometr (takie niebieskie pokrętło) do regulacji czułości wyjścia cyfrowego, umożliwiający ustawienie progu wilgotności, po przekroczeniu którego wyjście jest `LOW` lub `HIGH`.

**Obserwacja:**

Największą wadą, jaką zauważyłem dotyczącą czujnika `LM393`, jest to, że ulega szybkiej korozji z powodu elektrolizy, która zachodzi podczas pomiaru wilgotności. Proces ten jest spowodowany przez prąd stały płynący przez elektrody w wilgotnej glebie, co prowadzi do wydzielania gazów i przemian chemicznych na powierzchni elektrod. W efekcie, metalowa powierzchnia elektrod ulegała stopniowemu niszczeniu, co powoduje rdzewienie lub korozję objawiającą się na górnej blaszce sensora - `Rysunek 9 -> Moduł czujnika wilgotności gleby wraz z czujnikiem`.

**Zasadniczo dzieje się tak z kilku przyczyn:**

* Wilgotność gleby: - Im wilgotniejsza gleba, tym większe prawdopodobieństwo korozji. Woda w glebie działa jako elektrolit, przyspieszając proces elektrolizy.

* Rodzaj materiału elektrod: - Często elektrody są wykonane z miedzi lub innych metali, które mogą ulegać korozji w środowisku wilgotnym.

* Częstotliwość pomiarów: - Im częściej czujnik jest używany, tym większe prawdopodobieństwo korozji.

## **Obwód czujnika – schemat połączeń**

Teraz, możemy podłączyć wszystkie wymagane przewody do płytki `Arduino UNO R3`.
Aby pracować z czujnikiem, musimy najpierw zasilić czujnik, w tym celu używamy pinu `5V` i `GND` płytki `Arduino UNO`, jak na `Rysunku 10 -> Schemat obwodu czujnika wilgotności gleby w Arduino UNO R3`.

> `Rysunek 10`: Schemat obwodu czujnika wilgotności gleby w `Arduino UNO R3`

![Schemat obwodu czujnika wilgotności gleby w Arduino UNO R3)](schemat-obwodu-czujnika-wilgotnosci-gleby-w-arduino-uno-r3.jpg)


Opracowanie własne w aplikacji online https://www.tinkercad.com

Źródło:
https://www.tinkercad.com/things/j5SqFSHWvdv/editel?returnTo=\%2Fdashboard\%2Fdesigns\%2Fcircuits

**Schemat podłączenia**:

Podłączenie `LCD` i czujnika do `Arduino UNO R3`:

Whyświetlacz `LCD 16x2|5x8|I2C (LiquidCrystal_I2C)`:

* GND <—> GND
* VCC <—> 5V
* SDA <—> A4
* SCL <—> A5

Podłączamy piny `SDA` i `SCL` do odpowiednich pinów w `Arduino UNO R3 (SDA -> A4, SCL -> A5)`.

Moduł z sensorem do `Arduino UNO R3`:

* GND <—> GND
* VCC <—> 5V
* SIG <—> AU

Podłączamy wyjście analogowe do pinu `A0` do `Arduino.A`

> `Rysunek 11`: Schemat elektroniczny z widokiem na podłączenia pinów

![Schemat elektroniczny z widokiem na podłączenia pinów)](schemat-elektroniczny-z-widokiem-na-podlaczenie-pinow.jpg)

Opracowanie własne w aplikacji online https://www.tinkercad.com

Źródło:
https://www.tinkercad.com/things/j5SqFSHWvdv/editel?returnTo=\%2Fdashboard\%2Fdesigns\%2Fcircuits

## **Polskie ogonki na wyświetlaczu LCD**

Poniżej znajdują się `Rysunek 12 -> Polskie znaki na wyświetlaczu - Część I` i `Rysunek 13 -> Polskie znaki na wyświetlaczu - Część II`, na których wzorowałem opracowanie własnych zestawów polskich znaków diakrytycznych do tego projektu. Można skorzystać było z biblioteki `glcdfont.c`, tak jak zostało to opisane na stronie `Piotra Góreckiego`:  (https://piotr-gorecki.pl/ur027-kurs-arduino-polskie-litery-w-glcdfont-c/), ale postanowiłem spróbować własnych sił, czego dowodem jest `Rysunek 14 -> Matryca polskich znaków diakrytycznych (opracowanie własne) - Część I` i `Rysunek 15 -> Matryca polskich znaków diakrytycznych (opracowanie własne) - Część II`.

> `Rysunek 12`: Polskie znaki na wyświetlaczu - Część I

![Polskie znaki na wyświetlaczu - Część I)](polskie-znaki-na-wyswietlaczu-czesc-i.jpg)

> `Rysunek 13`: Polskie znaki na wyświetlaczu - Część II

![Polskie znaki na wyświetlaczu - Część II)](polskie-znaki-na-wyswietlaczu-czesc-ii.jpg)

Źródło do `Rysunku 13`:
https://piotr-gorecki.pl/ur027-kurs-arduino-polskie-litery-w-glcdfont-c/

Opracowanie własnych zestawów polskich znaków do projektu: `Czujnik wilgotności gleby`:

> `Rysunek 14`: Matryca polskich znaków diakrytycznych (opracowanie własne) - Część I

![Matryca polskich znaków diakrytycznych (opracowanie własne) - Część I)](matryca-polskich-znakow-diakrytycznych-opracowanie-wlasne-czesc-i.jpg)


> `Rysunek 15`: Matryca polskich znaków diakrytycznych (opracowanie własne) - Część II

![Matryca polskich znaków diakrytycznych (opracowanie własne) - Część II)](matryca-polskich-znakow-diakrytycznych-opracowanie-wlasne-czesc-ii.jpg)


Matryca polskich znaków diakrytycznych w `Arduino UNO R3`:

* ą = B00000, B00000, B01100, B00010, B01110, B10010, B01111, B00000; // ą
* Ą = B00100, B01010, B10001, B10001, B11111, B10001, B10001, B00010; // Ą
* ć = B00100, B01000, B11111, B10001, B10000, B10001, B11111, B00000; // ć
* Ć = B00100, B11111, B10101, B10000, B10000, B10001, B11111, B00000; // Ć
* ę = B00000, B00000, B01110, B10001, B11111, B10000, B01110, B00010; // ę
* Ę = B11111, B10000, B10000, B11111, B10000, B10000, B11111, B00010; // Ę
* ł = B01100, B00100, B00110, B00100, B01100, B00100, B01110, B00000; // ł
* Ł = B10000, B10000, B10100, B11000, B10000, B10000, B11111, B00000; // Ł
* ń = B00010, B00100, B10110, B11001, B10001, B10001, B10001, B00000; // ń
* Ń = B10101, B10101, B11001, B10101, B10011, B10001, B10001, B00000; // Ń
* ó = B00010, B00100, B01110, B10001, B10001, B10001, B01110, B00000; // ó
* Ó = B00100, B11111, B10101, B10001, B10001, B10001, B11111, B00000; // Ó
* ś = B00100, B11111, B10000, B11111, B00001, B10001, B11111, B00000; // ś
* Ś = B00010, B00100, B01111, B10000, B01110, B00001, B11110, B00000; // Ś
* ż = B00100, B00000, B11111, B00010, B00100, B01000, B11111, B00000; // ż
* Ż = B00100, B11111, B10001, B00010, B01100, B10001, B11111, B00000; // Ż
* ź = B00010, B00100, B11111, B00010, B00100, B01000, B11111, B00000; // ź
* Ź = B00100, B11111, B01001, B00010, B01100, B10001, B11111, B00000; // Ź

Przy założeniu, że 1 `zapala`, a 0 `gaśnie`.

Oczywiście testy również powinny się pojawić.

Wyświetlacz ten (Niebieski wyświetlacz `LCD 1602 16x2 HD44780` z konwerterem `i2C`) ma pewne ograniczenia, a mianowicie pozwala na wyświetlanie tylko `8` znaków `specjalnych` w jednym wierszu, dlatego podzieliłem wyświetlanie znaków na trzy ekrany, zaczynające się od T1 - `Rysunek 16 -> Test ogonków - Część I`, T2 - `Rysunek 17 -> Test ogonków - Część II` i T3 - `Rysunek 18 -> Test ogonków - Część III`.

> `Rysunek 16`: Test ogonków - Część I

![Test ogonków - Część I](test-ogonkow-czesc-i.jpg)

> `Rysunek 17`: Test ogonków - Część II

![Test ogonków - Część II](test-ogonkow-czesc-ii.jpg)

> `Rysunek 18`: Test ogonków - Część III

![Test ogonków - Część III](test-ogonkow-czesc-iii.jpg)

Kod źródłowy wykorzystany do testów polskich znaków diakrytycznych znajduje się nieco niżej.

## **Podłączenie czujnika i wyświetlacza do Arduino UNO R3**

Te proste kroki powinny wystarczyć, aby zbudować własny czujnik wilgotności gleby:

Połączenia, które należy wykonać za pomocą przewodów połączeniowych, schemat na `Rysunku 19 -> Schemat Czujnika Wilgotności Gleby - opracowanie własne`.

Połączenie wyświetlacza `LCD` do `Arduino UNO R3`: `[LCD -> A_UNO]`:

* GND <–> GND - Maska do Masy;
* SCL <–> A5 - Zegar magistrali I2C;
* SDA <–> A4 - Dane magistrali I2C;
* VCC <–> 5V - Zasilanie;

Czujnik `LM39` wilgotności gleby z potencjometrem: `[SENCZ -> A_UNO]`:

* GND <–> GND - Maska do Masy;
* VCC <–> 5V - Zasilanie;
* A0 <–> A0 - Wejście analogowe;

> `Rysunek 19`: Schemat Czujnika Wilgotności Gleby - opracowanie własne

![Schemat Czujnika Wilgotności Gleby - opracowanie własne](schemat_czujnika-wilgotnosci-gleby-opracowanie-wlasne.jpg)

## **Instalacja biblioteki i kompilacja w Arduino IDE**

## **Instalacja biblioteki LiquidCrystal_I2C**

Aby obsługiwać wyświetlacz `LCD` z interfejsem `I2C`, należy zainstalować bibliotekę `LiquidCrystal_I2C`. Biblioteka do pobrania w `Sekcji 1.2`. Można to zrobić również w `Arduino IDE`, wybierając:

`Sketch > Include Library > Manage Libraries...`

lub w polskiej wersji: `Menu główne > Narzędzia > Zarządzanie bibliotekami, Rysunek -> Zarządzanie bibliotekami w Arduino IDE`.

> `Rysunek 20`: Zarządzanie bibliotekami w Arduino IDE

![Zarządzanie bibliotekami w Arduino IDE](zarzadzanie-bibliotekami-w-arduino-ide.jpg)

wyszukując `LiquidCrystal_I2C`, jak na `Rysunku 21 -> Instalacja biblioteki LiquidCrystal_I2C w Arduino IDE`.

> `Rysunek 21`: Instalacja biblioteki LiquidCrystal_I2C w Arduino IDE

![Instalacja biblioteki LiquidCrystal_I2C w Arduino IDE](instalacja-biblioteki-liquidcrystal_i2c-w-arduino-ide.jpg)

Po dokonaniu tych czynności, powinniśmy zobaczyć przesłane biblioteki w `Arduino IDE`, jak pokazuje `Rysunek 22 -> Przesłane biblioteki w Arduino IDE`

> `Rysunek 22`: Przesłane biblioteki w Arduino IDE

![Przesłane biblioteki w Arduino IDE](przeslanie-biblioteki-w-arduino-ide.jpg)

## **Kompilacja kodu w Arduino IDE**

Kompilację w `Arduino IDE` przeprowadzimy w kilku etapach:

- **Otwarcie Projektu:** - Otwieramy `Arduino IDE` i tworzymy nowy projekt lub otwieramy istniejący - `Rysunek 23` i `Rysunek 24`;

- **Wklejenie Kodu:** - Wklejamy nasz kod z pliku `wilgotnosc_gleby_v4.1o.ino` do okna edycyjnego i
wybieramy odpowiedni model płyty Arduino (np. `Arduino Uno`) - `Rysunek 25`.;

- **Wybranie Portu:** - Wybieramy port, do którego jest podłączone Arduino - `Rysunek 26`;

- **Kompilacja i Przesłanie:** - Klikamy w menu górne i wybieramy `Weryfikuj/Kompiluj`, aby skompilować kod, a następnie `Prześlij`, aby przesłać kod na płytkę `Arduino UNO R3` - `Rysunek 27`, `Rysunek 28` i `Rysunek 29`.

AD1:

> `Rysunek 23`: Otwarcie Projektu w Arduino IDE

![Otwarcie Projektu w Arduino IDE](otwarcie-projektu-w-arduino-ide.jpg)

> `Rysunek 24`: Podgląd nowego projektu w Arduino IDE

![Podgląd nowego projektu w Arduino IDE](podglad-nowego-projektu-w-arduino-ide.jpg)

AD2:

> `Rysunek 25`: Wklejanie kodu i wybieranie płyty w Arduino IDE

![Wklejanie kodu i wybieranie płyty w Arduino IDE](wklejanie-kodu-i-wybieranie-plyty-w-arduino-ide.jpg)

AD3:

> `Rysunek 26`: Wybranie Portu w Arduino IDE

![Wybranie Portu w Arduino IDE](wybranie-portu-w-arduino-ide.jpg)

AD4:

> `Rysunek 27`: Kompilacja kodu w Arduino IDE

![Kompilacja kodu w Arduino IDE](kompilacja-kodu-w-arduino-ide.jpg)

> `Rysunek 28`: Przesyłanie kodu w Arduino IDE do Arduino UNO

![Przesyłanie kodu w Arduino IDE do Arduino UNO](przeslanie-kodu-w-arduino-ide.jpg)

> `Rysunek 29`: Wynik przesłania kodu do Arduino UNO R3

![Wynik przesłania kodu do Arduino UNO R3](wynik-przesylania-kodu-do-arduino-uno-r3.jpg)

## **Demonstracja = działanie programu**

Demonstracja została przeprowadzona w warunkach domowych z użyciem wody, natomiast docelowo będzie miał zastosowanie w kwiatku z glebą.

**Proces działania odbywa się następująco:**
- **Uruchomienie:** - Po podłączeniu `Arduino UNO R3` do komputera (standardowy port USB) i załadowaniu kodu `Rysunek 28`, program zaczyna działać - `Rysunek 29`;

- **Inicjacja:** - Wyświetlacz `LCD` jest inicjowany, a niestandardowe znaki są definiowane - (może ich być maksymalnie `8` w tym wyświetlaczu);

- **Pętla główna:** - Program wchodzi w pętlę `loop()`, gdzie odczytuje dane z czujnika, sprawdza ich poprawność, oblicza wilgotność, i wyświetla wyniki na `LCD` - `Rysunek 31`;

- **Powtarzanie:** - Pętla `loop()` jest wykonywana w nieskończonej pętli, co oznacza, że program będzie nieustannie odczytywał dane (przy założeniu, że czujnik będzie w stanie użytku) i aktualizował wyświetlacz.

> `Rysunek 30`: Demonstracja działania czujnika wilgotności gleby - brak styczności z wilgocią

![Demonstracja działania czujnika wilgotności gleby - brak styczności z wilgocią](demo-czujnika-brak-stycznosci-z-wilgocia.jpg)

> `Rysunek 31`: Demonstracja działania czujnika wilgotności gleby - czujnik ma styczności z wilgocią

![Demonstracja działania czujnika wilgotności gleby - czujnik ma styczności z wilgocią](demo-czujnika-stycznosc-z-wilgocia.jpg)

## **Kod źródłowy - Czujnik wilgotności gleby**

`Listing 1`: Kod źródłowy - Pomiar wilgotności gleby w Arduino

```c
# ]> Nazwa skryptu: wilgotnosc_gleby_v4.1o.c lub  wilgotnosc_gleby_v4.1o.ino
# ]>
# ]> Kod oryginalny:
# ]> Copyright (C) 2021 by VP Tech&Gardening-kannada
# ]> https://www.youtube.com/@vptechgardening-kannada9689
# ]>
# ]> Modyfikacja + dodatki wlasne:
# ]> Autor: Lukasz Wojcik
# ]> Data: 13-18.01.2025
# ]>
# ]> Opis: Kod odczytuje dane wejsciowe analogowe z czujnika wilgotnosci gleby,
# ]>       mapuje je na wartosc procentowa i wyswietla poziom wilgoci na ekranie LCD.
# ]>       Zawiera rowniez niestandardowe znaki polskie - ogonki
# ]>       do prawidlowego wyswietlania slow w jezyku polskim.
# ]>
# ]> Wlasciwy kod zaczyna sie od sekcji komentarza /***
# ]> Licencja MIT

/********************************************************
   Arduino - Czujnik wilgotnosci gleby
**********************************************************/

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

int sensorPin = A0;
int sensorValue = 0;
int percentValue = 0;

// Definicje niestandardowych znakow polskich, czyli "ogonkow"
byte aChar[8] = {B00000, B00000, B01100, B00010, B01110, B10010, B01111, B00000}; // a z kreseczka
byte AChar[8] = {B00100, B01010, B10001, B10001, B11111, B10001, B10001, B00010}; // A z ogonkiem
byte cChar[8] = {B00100, B01000, B11111, B10001, B10000, B10001, B11111, B00000}; // c z kreseczka
byte CChar[8] = {B00100, B11111, B10101, B10000, B10000, B10001, B11111, B00000}; // C z kreseczka
byte eChar[8] = {B00000, B00000, B01110, B10001, B11111, B10000, B01110, B00010}; // e z ogonkiem
byte EChar[8] = {B11111, B10000, B10000, B11111, B10000, B10000, B11111, B00010}; // E z ogonkiem
byte lChar[8] = {B01100, B00100, B00110, B00100, B01100, B00100, B01110, B00000}; // l z kreseczka
byte LChar[8] = {B10000, B10000, B10100, B11000, B10000, B10000, B11111, B00000}; // L z kreseczka
byte nChar[8] = {B00010, B00100, B10110, B11001, B10001, B10001, B10001, B00000}; // n z kreseczka
byte NChar[8] = {B10101, B10101, B11001, B10101, B10011, B10001, B10001, B00000}; // N z kreseczka
byte oChar[8] = {B00010, B00100, B01110, B10001, B10001, B10001, B01110, B00000}; // o z kreseczka
byte OChar[8] = {B00100, B11111, B10101, B10001, B10001, B10001, B11111, B00000}; // O z kreseczka
byte sChar[8] = {B00100, B11111, B10000, B11111, B00001, B10001, B11111, B00000}; // s z kreseczka
byte SChar[8] = {B00010, B00100, B01111, B10000, B01110, B00001, B11110, B00000}; // S z kreseczka
byte zChar[8] = {B00100, B00000, B11111, B00010, B00100, B01000, B11111, B00000}; // z z kropeczka
byte ZChar[8] = {B00100, B11111, B10001, B00010, B01100, B10001, B11111, B00000}; // Z z kropeczka
byte z2Char[8] = {B00010, B00100, B11111, B00010, B00100, B01000, B11111, B00000}; // z z kreseczka
byte Z2Char[8] = {B00100, B11111, B01001, B00010, B01100, B10001, B11111, B00000}; // Z z kreseczka

// Tablica z definicjami znakow i ich adresami
const byte* chars[] = {aChar, AChar, cChar, CChar, eChar, EChar, lChar, LChar, nChar, NChar, oChar, OChar, sChar, SChar, zChar, ZChar, z2Char, Z2Char};
const byte addresses[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};

void setup() {
  lcd.init();
  lcd.backlight();

  // Tworzenie niestandardowych znakow
  for (int i = 0; i < sizeof(chars) / sizeof(chars[0]); i++) {
    lcd.createChar(addresses[i], chars[i]);
  }

  lcd.setCursor(0, 0);
  lcd.print("Uruchamianie...");
  delay(4000);
  lcd.clear();
}

void loop() {
  sensorValue = analogRead(sensorPin);

  // Sprawdzanie, czy wartosc jest w poprawnym zakresie
  if (sensorValue < 200 || sensorValue > 1023) {
    lcd.setCursor(0, 0);
    lcd.print("Blad odczytu");
    delay(1000);
    lcd.clear();
    return;
  }

  percentValue = map(sensorValue, 1023, 200, 0, 100);

  lcd.setCursor(0, 0);
  lcd.print("Wilgotno");
  lcd.write(byte(13)); // Wyswietlanie znaku "s z kresecza"
  lcd.write(byte(2)); // Wyswietlanie znaku "c z kreseczka"
  lcd.print(" Gleby");
  lcd.setCursor(0, 1);
  lcd.print("Warto");
  lcd.write(byte(13)); // Wyswietlanie znaku "s z kresecza"
  lcd.write(byte(2)); // Wyswietlanie znaku "c z kreseczka"
  lcd.print(" ");
  lcd.print(percentValue);
  lcd.print("%");

  delay(1000);
  lcd.clear();
}
```
## **Kod źródłowy - Polskie znaki diakrytyczne**


`Listing 2`: Kod źródłowy - Testowanie polskich znaków diakrytycznych

```c
# ]>-----------------------------------------------------------------------------------<[
# ]> Nazwa skryptu: test_ogonkow.c lub test_ogonkow.ino
# ]>
# ]> Autor: Lukasz Wojcik
# ]> Data: 13-18.01.2025
# ]>
# ]> Opis: Kod testuje i wyswietla na wyswietlaczu LCD niestandardowe znaki polskie
# ]>       w trzech partiach, z krotkimi przerwami miedzy nimi, aby umozliwic odczytanie
# ]>       wyswietlanych znakow.
# ]>
# ]> Wlasciwy kod zaczyna sie od sekcji komentarza /***
# ]> Licencja MIT
# ]>
# ]>-----------------------------------------------------------------------------------<[

/***********************************************
     Test polskich znakow diakrytycznych:

     T1: aAcCeElL
        czyszczenie ekranu
     T2: nNoOSszZ
         czyszczenie ekranu
     T3: zZ

***********************************************/

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);
int sensorPin = A0;
int sensorValue = 0;
int percentValue = 0;

// Definicje niestandardowych polskich znakow
byte aChar[8] = {B00000, B00000, B01100, B00010, B01110, B10010, B01111, B00010}; // "a z kreseczka"
byte AChar[8] = {B00100, B01010, B10001, B10001, B11111, B10001, B10001, B00010}; // "A z kreseczka"
byte cChar[8] = {B00010, B00100, B01110, B10001, B10000, B10001, B01110, B00000}; // "c z kreseczka"
byte CChar[8] = {B00100, B11111, B10101, B10000, B10000, B10001, B11111, B00000}; // "C z kreseczka"
byte eChar[8] = {B00000, B00000, B01110, B10001, B11111, B10000, B01110, B00010}; // "e z ogonkiem"
byte EChar[8] = {B11111, B10000, B10000, B11111, B10000, B10000, B11111, B00010}; // "E z ogonkiem"
byte lChar[8] = {B01100, B00100, B00110, B00100, B01100, B00100, B01110, B00000}; // "l z kreseczka"
byte LChar[8] = {B10000, B10000, B10100, B11000, B10000, B10000, B11111, B00000}; // "L z kreseczka"

byte nChar[8] = {B00010, B00100, B10110, B11001, B10001, B10001, B10001, B00000}; // "n z kreseczka"
byte NChar[8] = {B10101, B10101, B11001, B10101, B10011, B10001, B10001, B00000}; // "N z kreseczka"
byte oChar[8] = {B00010, B00100, B01110, B10001, B10001, B10001, B01110, B00000}; // "o z kreseczka"
byte OChar[8] = {B00100, B11111, B10101, B10001, B10001, B10001, B11111, B00000}; // "O z kreseczka"
byte sChar[8] = {B00100, B11111, B10000, B11111, B00001, B10001, B11111, B00000}; // "s z kreseczka"
byte SChar[8] = {B00010, B00100, B01111, B10000, B01110, B00001, B11110, B00000}; // "S z kreseczka"
byte zChar[8] = {B00100, B00000, B11111, B00010, B00100, B01000, B11111, B00000}; // "z z kropeczka"
byte ZChar[8] = {B00100, B11111, B10001, B00010, B01100, B10001, B11111, B00000}; // "Z z kropeczka"
byte z2Char[8] = {B00010, B00100, B11111, B00010, B00100, B01000, B11111, B00000}; // "z z kropeczka"
byte Z2Char[8] = {B00100, B11111, B01001, B00010, B01100, B10001, B11111, B00000}; // "Z z kropeczka"

void setup() {
  lcd.init();
  lcd.backlight();

  lcd.setCursor(0, 0);
  lcd.print("Uruchamianie...");
  delay(4000);
  lcd.clear();
}

void loop() {
  sensorValue = analogRead(sensorPin);

  // Sprawdzanie, czy wartosc jest w poprawnym zakresie
  if (sensorValue < 200 || sensorValue > 1023) {
    lcd.setCursor(0, 0);
    lcd.print("Blad odczytu");
    delay(1000);
    lcd.clear();
    return;
  }

  percentValue = map(sensorValue, 1023, 200, 0, 100);

  // Wyswietlanie pierwszych 8 znakow od "a z kreseczka" do "l z kreseczka"
  lcd.createChar(0, aChar); // Tworzenie znaku "a z kreseczka"
  lcd.createChar(1, AChar); // Tworzenie znaku "A z kreseczka"
  lcd.createChar(2, cChar); // Tworzenie znaku "c z kreseczka"
  lcd.createChar(3, CChar); // Tworzenie znaku "C z kreseczka"
  lcd.createChar(4, eChar); // Tworzenie znaku "e z ogonkiem"
  lcd.createChar(5, EChar); // Tworzenie znaku "E z ogonkiem"
  lcd.createChar(6, lChar); // Tworzenie znaku "l z kreseczka"
  lcd.createChar(7, LChar); // Tworzenie znaku "L z kreseczka"

  lcd.setCursor(0, 0);
  lcd.print("T1: ");
  lcd.write(byte(0)); // "a z kreseczka"
  lcd.write(byte(1)); // "A z kreseczka"
  lcd.write(byte(2)); // "c z kreseczka"
  lcd.write(byte(3)); // "C z kreseczka"
  lcd.write(byte(4)); // "e z ogonkiem"
  lcd.write(byte(5)); // "e z ogonkiem"
  lcd.write(byte(6)); // "l z kreseczka"
  lcd.write(byte(7)); // "L z kreseczka"

  delay(2000); // Przerwa, aby umozliwic odczytanie wyswietlonych znakow
  lcd.clear();

  // Wyswietlanie kolejnych 8 znakow od "n" z kreseczka do "Z" z kreseczka
  lcd.createChar(0, nChar); // Tworzenie znaku "n z kreseczka"
  lcd.createChar(1, NChar); // Tworzenie znaku "N z kreseczka"
  lcd.createChar(2, oChar); // Tworzenie znaku "o z kreseczka"
  lcd.createChar(3, OChar); // Tworzenie znaku "O z kreseczka"
  lcd.createChar(4, sChar); // Tworzenie znaku "s z kreseczka"
  lcd.createChar(5, SChar); // Tworzenie znaku "S z kreseczka"
  lcd.createChar(6, zChar); // Tworzenie znaku "z z kropeczka"
  lcd.createChar(7, ZChar); // Tworzenie znaku "Z z kropeczka"

  lcd.setCursor(0, 0);
  lcd.print("T2: ");
  lcd.write(byte(0)); // "n z kreseczka"
  lcd.write(byte(1)); // "N z kreseczka"
  lcd.write(byte(2)); // "o z kreseczka"
  lcd.write(byte(3)); // "O z kreseczka"
  lcd.write(byte(4)); // "s z kreseczka"
  lcd.write(byte(5)); // "S z kreseczka"
  lcd.write(byte(6)); // "z z kropeczka"
  lcd.write(byte(7)); // "Z z kropeczka"

  delay(2000); // Przerwa, aby umozliwic odczytanie wyswietlonych znakow
  lcd.clear();

  // Wyswietlanie kolejnych 8 znakow od "z z kreseczka" do "Z z kreseczka"
  lcd.createChar(0, z2Char); // Tworzenie znaku "z z kreseczka"
  lcd.createChar(1, Z2Char); // Tworzenie znaku "Z z kreseczka"

  lcd.setCursor(0, 0);
  lcd.print("T3: ");
  lcd.write(byte(0)); // "z z kreseczka"
  lcd.write(byte(1)); // "Z z kreseczka"

  delay(2000); // Przerwa, aby umozliwic odczytanie wyswietlonych znakow
  lcd.clear();

  delay(1000);
}
```

## **Opis działania kodów źródłowych**

## **Czujnika wilgotności gleby**

Nagłówki i deklaracje:

```c
#include <LiquidCrystal_I2C.h> – Załącza bibliotekę do obsługi wyświetlacza LCD I2C.
```

`LiquidCrystal_I2C lcd(0x27, 16, 2)`; – Tworzy obiekt `lcd`, który komunikuje się z wyświetlaczem `LCD` przez interfejs `I2C` (adres `0x27` i wyświetlacz `16x2`).

**Zmienne:**

- **sensorPin** – Pin analogowy, do którego podłączony jest czujnik wilgotności gleby (w tym przypadku `A0`);

- **sensorValue** – Zmienna przechowująca odczytaną wartość z czujnika;

- **percentValue** – Zmienna przechowująca przeliczoną wartość wilgotności w procentach.

Tablica `chars` zawiera definicje niestandardowych znaków dla polskich liter z `ogonkami`, (np. `ą`, `ć`).

Tablica `addresses` zawiera adresy tych znaków w pamięci `LCD`.

**Definicja niestandardowych znaków:**

Dla każdej litery z `ogonkami`, (np. `ą`, `ć`, `ś`) zdefiniowane są bity w tablicach (`aChar`, `AChar`, itd.). Każdy znak jest reprezentowany jako tablica `8-bitowa`, która definiuje jego wygląd na wyświetlaczu `LCD`. Zdefiniowane są litery takie jak: `aChar`, `AChar`, `eChar`, `EChar`, `sChar`, `SChar`, itd.

Funkcja `setup()`:
```c
lcd.init(); – Inicjalizuje wyświetlacz LCD.
lcd.backlight(); – Włącza podświetlenie LCD.
```

Tworzenie niestandardowych znaków na wyświetlaczu `LCD` w pętli:

`Listing 3`: Tworzenie niestandardowych znaków na wyświetlaczu `LCD` w pętli:
```c
lcd.print("T1: ");
for (int i = 0; i < sizeof(chars) / sizeof(chars[0]); i++) {
  lcd.createChar(addresses[i], chars[i]);
}
```

Każdy znak jest przypisywany do odpowiedniego adresu w pamięci `LCD`.
Na początku na wyświetlaczu pojawia się napis `Uruchamianie...` przez `4` sekundy, a potem ekran zostaje wyczyszczony.

Funkcja `loop()`:
```c
sensorValue = analogRead(sensorPin); – Odczyt wartości analogowej z czujnika wilgotności gleby
(wartość od 0 do 1023).
```

Sprawdzanie, czy odczyt z czujnika jest w prawidłowym zakresie (`200–1023`):

Jeśli odczyt jest poza tym zakresem, na `LCD` wyświetlany jest komunikat o błędzie `Blad odczytu`. Jeśli odczyt jest prawidłowy, wartość jest mapowana z zakresu `1023–200` na zakres `0–100`, co daje wynik procentowy wilgotności gleby. Na wyświetlaczu `LCD` pojawia się:

`Wilgotno Ś Gleby` (z użyciem niestandardowych znaków dla polskich liter).
Na drugiej linii: `Wartość 67%` (przykładowa wartość wilgotności w procentach).
Całość jest odświeżana co `1` sekundę `(delay(1000))`, a po tym czasie ekran jest czyszczony i proces powtarza się.

**Podsumowanie działania kodu:**

Kod inicjalizuje wyświetlacz `LCD` i niestandardowe znaki.
Odczytuje wartość wilgotności gleby z czujnika, przelicza ją na procenty i wyświetla na `LCD`.
Sprawdza poprawność odczytu i wyświetla odpowiedni komunikat w przypadku błędu.

## **Polskie znaki diakrytyczne**

**Nagłówki i deklaracje:**

```c
#include <LiquidCrystal_I2C.h> – Załącza bibliotekę do obsługi wyświetlacza LCD I2C.
```

`LiquidCrystal_I2C lcd(0x27, 16, 2)`; – Tworzy obiekt `lcd`, który jest odpowiedzialny za komunikację z wyświetlaczem `LCD` przez interfejs `I2C` (adres `0x27` i wyświetlacz `16x2`).

**Zmienne:**

`sensorPin` – Pin analogowy, do którego podłączony jest czujnik (choć nie jest wykorzystywany w tym
przykładzie).

`sensorValue` – Zmienna przechowująca odczytaną wartość z czujnika (nie wykorzystywana w tym przypadku).

`percentValue` – Zmienna przechowująca wartość procentową (również nie używana w tym przykładzie).

**Definicje niestandardowych znaków:**

Dla każdej z polskich liter z `ogonkami`, (np. `ą`, `ć`, `ś`) i innych diakrytycznych liter zdefiniowane są bity w tablicach (`aChar`, `AChar`, itd.). Każdy znak jest reprezentowany przez tablicę `8-bitową`, która określa jego wygląd na wyświetlaczu `LCD`. Znaki są tworzone dla liter:

```
aChar, AChar (a z kreską, A z kreską),
cChar, CChar (c z kreską, C z kreską),
eChar, EChar (e z ogonkiem, E z ogonkiem),
```
itd.

funkcja `setup()`:
```
lcd.init(); – Inicjalizuje wyświetlacz LCD.
lcd.backlight(); – Włącza podświetlenie wyświetlacza.
```

Wyświetlanie tekstu `Uruchamianie...` przez `4` sekundy, a następnie czyszczenie ekranu.

Funkcja `loop()`: W tej funkcji wyświetlane są kolejne zestawy niestandardowych znaków:

**Test 1**  - Wyświetlanie liter `a` do `L` z diakrytykami:

Tworzenie znaków za pomocą `lcd.createChar()` dla liter: `a z kreską`, `A z kreską`, `c z kreską`, `C z kreską`, `e z ogonkiem`, `E z ogonkiem`, `l z kreską`, `L z kreską`.

Wyświetlanie tekstu na `LCD`:

`Listing 4`: T1: Wyświetlanie tekstu na `LCD`:

```c
lcd.print("T1: ");
lcd.write(byte(0)); // „a z kreska”
lcd.write(byte(1)); // „A z kreska”
lcd.write(byte(2)); // „c z kreska”
lcd.write(byte(3)); // „C z kreska”
lcd.write(byte(4)); // „e z ogonkiem”
lcd.write(byte(5)); // „E z ogonkiem”
lcd.write(byte(6)); // „l z kreska”
lcd.write(byte(7)); // „L z kreska”
```

Zatrzymanie na `2` sekundy `(delay(2000))`, aby umożliwić odczytanie wyświetlonych znaków.
Po upływie tego czasu, ekran zostaje wyczyszczony `(lcd.clear())`.

**Test 2** - Wyświetlanie liter `n` do `Z` z diakrytykami:

Tworzenie znaków za pomocą `lcd.createChar()` dla liter: `n z kreską`, `N z kreską`, `o z kreską`, `O z kreską`, `s z kreską`, `S z kreską`, `z z kropką`, `Z z kropką`.

**Wyświetlanie tekstu na LCD:**

`Listing 5`: T2: Wyświetlanie tekstu na `LCD`:

```c
lcd.print("T2: ");
lcd.write(byte(0)); // „n z kreska”
lcd.write(byte(1)); // „N z kreska”
lcd.write(byte(2)); // „o z kreska”
lcd.write(byte(3)); // „O z kreska”
lcd.write(byte(4)); // „s z kreska”
lcd.write(byte(5)); // „S z kreska”
lcd.write(byte(6)); // „z z kreska”
lcd.write(byte(7)); // „Z z kreska”
```

Zatrzymanie na `2` sekundy `(delay(2000))`, aby umożliwić odczytanie wyświetlonych znaków.
Po upływie tego czasu, ekran zostaje wyczyszczony.

**Test 3** - Wyświetlanie liter `z` i `Z` z diakrytykami: Tworzenie znaków za pomocą `lcd.createChar()` dla liter: `z z kreską` oraz `Z z kreską`.

**Wyświetlanie tekstu na LCD:**

`Listing 6`: T3: Wyświetlanie tekstu na `LCD`:

```c
lcd.print("T3: ");
lcd.write(byte(0)); // „z z kreska”
lcd.write(byte(1)); // „Z z kreska”
```

Zatrzymanie na `2` sekundy `(delay(2000))`, aby umożliwić odczytanie wyświetlonych znaków.
Po upływie tego czasu, ekran zostaje wyczyszczony.

Po każdym z testów, wyświetlacz zostaje wyczyszczony, a następnie kod przechodzi do kolejnej sekwencji znaków.

**Podsumowanie działania:**

Kod służy do testowania wyświetlania liter z polskimi znakami diakrytycznymi na wyświetlaczu `LCD`. Każda litera jest reprezentowana jako niestandardowy znak (tworzony za pomocą funkcji `lcd.createChar())`. Na wyświetlaczu pojawiają się trzy różne zestawy znaków, a po każdej sekwencji wyświetlania ekran jest czyszczony i następuje kolejna prezentacja.

## **Co dalej ? - Propozycja rozbudowy**

## **Podłączenie pamięci EEPROM**

Pamięć `EEPROM 24C256N` to układ pamięci o pojemności `256 Kbit (32 KB)`, która może przechowywać
dane na stałe, nawet po wyłączeniu zasilania. Jest to pamięć typu `I2C`, co oznacza, że do komunikacji z mikrokontrolerem (np. `Arduino`) wykorzystuje tylko dwa piny: `SDA (data)` i `SCL (clock)` + zasilanie `5V`, co znacznie upraszcza połączenia. Pamięć ta może być używana do przechowywania ustawień, danych użytkownika, czy innych informacji, które muszą być zachowane między restartami urządzenia.

> `Rysunek 32`: Pamięć EEPROM 32kb

![Pamięć EEPROM 32kb](pamiec-eeprom.jpg)

## **Dodatkowe zasilanie do pamięci EEPROM**

W tym przypadku użyjemy baterii stosowanych w starych `BIOS-ach` komputerów PC - `CR2032`. Ta bateria
pozwoli zasilić pamięć, gdy główne zasilanie `Arduino UNO R3` będzie wyłączone, co pozwala na przechowywanie danych przez dłuższy czas. Baterię można zamówić np. na `Allegro` (https://allegro.pl/oferta/nowa-bateria-cmos-cr2032-3v-bios-laptop-hp-lenovo-dell-zlacze-2pin-14277038189).

> `Rysunek 33`: Bateria CR2032 (BIOS)

![Bateria CR2032 (BIOS)](bateria-cr2032-bios.jpg)

## **Podłączenie AT24C256 do Arduino UNO R3 z dodatkowym zasilaniem bateryjnym**

Bateria `CR2032 (3V)` może być podłączona do pinu `VCC AT24C256`, ale należy pamiętać, że `AT24C256` działa w zakresie `2,7V` do `5,5V`. Dla bezpieczeństwa można dodać rezystor (`opornik`) podciągający na pinie `SDA` i `SCL`, aby uniknąć uszkodzenia.

* Pin 1-3 - GND lub VCC (dla adresowania)
* Pin 4 (GND) - GND Arduino i baterii
* Pin 5 (SDA) - Pin A4 (SDA) Arduino
* Pin 6 (SCL) - Pin A5 (SCL) Arduino
* Pin 7 (WP) - GND
* Pin 8 (VCC) - Bateria CR2032 (3V)


## **Konfiguracja z rezystorem**

* Rezystory na SDA i SCL - 10 k (lub wyższe, jeśli nie ma problemów z szybkością transmisji).
* Połączenie zasilania: - Bateria CR2032 (3V) do pinu VCC AT24C256.
* Połączenie masy: - GND Arduino i baterii do pinu GND AT24C256.


## **Podłączenie do Arduino z LCD, czujnikiem wilgotności gleby i wyświetlaczem**

`LC` na `I2C`

Aby połączyć `EEPROM 24C256N` z zestawem `Arduino Uno R3`, który obejmuje wyświetlacz `LCD` z konwerterem `I2C` oraz czujnik wilgotności gleby, należy wykonać następujące połączenia:

`LCD` z `I2C`:

* VCC -> 5V Arduino
* GND -> GND Arduino
* SDA -> A4 Arduino (ta sama linia co EEPROM)
* SCL -> A5 Arduino (ta sama linia co EEPROM)

**Czujnik wilgotności gleby:**

* VCC -> 5V Arduino
* GND -> GND Arduino
* A0 -> A0 Arduino (analogowe wejście dla odczytu danych)

**Pamięć EEPROM 24C256N:**

* VCC -> 5V Arduino (można również zasilić ją z baterii CR2032)
* GND -> GND Arduino
* SDA -> A4 Arduino (wspólna linia I2C z LCD i EEPROM)
* SCL -> A5 Arduino (wspólna linia I2C z LCD i EEPROM)

Wszystkie urządzenia `I2C (LCD, EEPROM)` dzielą te same linie `SD`A i `SCL` (tzn. mogą działać równolegle), co upraszcza połączenie i pozwala na łatwe komunikowanie się z nimi za pomocą biblioteki `I2C`.

## **Podsumowanie**

Taki układ pozwala na wygodne odczytywanie danych z czujnika wilgotności gleby, wyświetlanie wyników na `LCD` i jednoczesne przechowywanie danych w pamięci `EEPROM`, które będą zachowane między restartami urządzenia.

## **Podziękowanie**

I hope this article has entertained and informed you, and helped you learn a little more about the Go language. Feel free to experiment with the program and customize it to your liking.

See you in the next article!

## **Pobranie i instalacja**

Repository >> [GitHub](https://github.com/lukaszwojcikdev/czujnik-wilgotnosci-gleby)


