W tym artykule zostaną dodane nowe moduły do wcześniej prezentowanej już doniczki, dodatkowo zrobimy menu które ułatwi nam przemieszczanie się pomiędzy wilgotnością, ustawianiem wilgotności, włączaniem lub wyłączeniem bluetooth’a, oraz ustawianiem stacji w radiu.
Spis treści
- Podłącznie modułu radia i bluetooth
- Zaprogramowanie doniczki
- Pliki do pobrania
Podłączenie modułu radia i bluetooth
Zaczniemy od podłączenia modułu radia do doniczki, oczywiście podłączenie radia jak i modułu bluetooth jest zgodne z artykułem https://ajmaker.pl/2021/12/11/podlaczenie-i-zaprogramowanie-automatycznej-doniczki-z-arduino/ , oznacza to, że wykorzystamy wolne piny które nam zostały. Zmianie ulegnie jedynie podłączenie zasilania i uziemienia ekranu LCD.
Podłączamy najpierw moduł bluetooth ponieważ jest najprostszy, pin GND podpinamy pod GND nad pinem 5, a VCC do pinu 5. Teraz będziemy musieli przepiąć piny zasilania ekranu LCD do pinów VCC i GND nad pinem A4 lub A5 i teraz podpinamy zasilanie jak i uziemienie modułu radia, a przy okazji wpinamy piny SCL i SDA w znajdujące się niżej piny od arduino. Gotowy schemat znajduje się poniżej (nowo podłączone lub zmienione połączenia są kolorowe).
Zaprogramowanie doniczki
Omówię tutaj tylko zmiany jakie zaszły względem poprzedniego artykułu na temat podłączenia i zaprogramowania doniczki, możecie je znaleźć tutaj.
Doszły dwie nowe biblioteki
#include <SoftwareSerial.h> #include <TEA5767.h>
Nowy obiekt do obsługi radia
TEA5767 FMRadio;
Zmienne do obsługi radia
unsigned char buff[5]; float frequency; int stereo; int signal_level; int search_MODE; int S_direction; double current_frq; int lung = 500; unsigned long current_mills = millis(); int difference; long beforeF = -6; long currentF = beforeF; int bluetooth = 0; int ostatni_bt = 0; bool zmiana_bt = true;
W funkcji setup doszło kilka nowych ustawień
pinMode(BT, OUTPUT);//ustawienie pinu BT jako wyjście digitalWrite(BT, LOW);//ustawienie BT na stan niski FMRadio.init(); FMRadio.set_frequency(104.9); SPI.begin();
W głównej funkcji loop zaszło najwięcej zmian, ponieważ zostało wprowadzone menu na warunku wielokrotnego wyboru switch case i wygląda ono następująco.
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ść która została ustawiona enkoderowi switch (menu) { case 0: ZrobOdczytWilgotnosci(); WyswietlWilgotnosc(); 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, nazwa oznacza nazwę naszego kodu obrazka, a 128 i 64 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); } 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); } if (obecny_czas - ostatni_czas > 30000) { ostatni_czas = obecny_czas; uspiony = true; } else { obecny_czas = millis(); } break; case 1: while (menu == 1) { 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ść delay(50); } break; case 2: myEnc.write(ostatni_bt); while (menu == 2) { bluetooth = myEnc.read(); if (bluetooth != ostatni_bt) { zmiana_bt = !zmiana_bt; } if (zmiana_bt) { display.clearDisplay(); 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("BLUETOOTH");//piszemy tekst który ma się ukazać display.setTextSize(3);// ustawiamy rozmiar czcionki display.setCursor(50, 22);//ustawiamy kursor na daną pozycję display.print("ON");//wyświetlamy wcześniej ustawioną wilgotność display.display();//wyświetlamy digitalWrite(BT, HIGH); } else { display.clearDisplay(); 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("BLUETOOTH");//piszemy tekst który ma się ukazać display.setTextSize(3);// ustawiamy rozmiar czcionki display.setCursor(50, 22);//ustawiamy kursor na daną pozycję display.print("OFF");//wyświetlamy wcześniej ustawioną wilgotność digitalWrite(BT, LOW); display.display();//wyświetlamy } ostatni_bt = bluetooth; delay(50); } break; case 3: while (menu == 3) { display.clearDisplay(); if (FMRadio.read_status(buff) == 1) { current_frq = floor(FMRadio.frequency_available(buff) / 100000 + 0.5) / 10; stereo = FMRadio.stereo(buff); signal_level = FMRadio.signal_level(buff); display.clearDisplay(); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(5, 1); display.print("FRQ:"); display.print(current_frq); if (stereo) { display.setCursor(5, 15); display.print("Stereo"); } else { display.setCursor(5, 15); display.print("Mono"); } display.setCursor(7, 29); display.print("SigLv:"); display.println(signal_level); display.println("/15"); display.display(); delay(500); } delay(200); if (search_MODE == 1) { if (FMRadio.process_search(buff, S_direction) == 1) { search_MODE = 0; } } currentF = myEnc.read(); if (currentF > beforeF) { beforeF = currentF; search_MODE = 1; S_direction = TEA5767_SEARCH_DIR_UP; FMRadio.search_up(buff); display.clearDisplay(); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(7, 1); display.print("FRQ UP"); delay(200); } if (currentF < beforeF) { beforeF = currentF; search_MODE = 1; S_direction = TEA5767_SEARCH_DIR_DOWN; FMRadio.search_down(buff); display.clearDisplay(); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(7, 1); display.print("FRQ DOWN"); delay(200); } } break; }
W samym kodzie dużo się nie zmieniło, wcześniejszy kod został przerobiony i dodany do switcha. Nowoścą jest kod od radia który omówiony dokładniej jest w tym artykule https://ajmaker.pl/2021/12/10/tuner-fm-radio-stereo-tea5767-antena-arduino/. Oczywiście zostało dodane włączanie i wyłączanie modułu bluetooth, które jak można zauważyć jest proste, opiera się tylko na ustawieniu stanu niskiego lub wysokiego.
Ostatnią zmianą jest lekka modyfikacja funkcji wybudź która teraz odpowiada również za zmianę opcji w menu.
void Wybudz() { static unsigned long lastTime; unsigned long timeNow = millis(); if (timeNow - lastTime < 20 0) return; menu++; lastTime = timeNow; if (uspiony == true) { menu = 0; } uspiony = false; if (menu > 3) { menu = 0; } }
To było by na tyle ze zmian, gotowy kod możecie pobrać poniżej, a potrzebne biblioteki do obsługi radia z tego artykułu https://ajmaker.pl/2021/12/10/tuner-fm-radio-stereo-tea5767-antena-arduino/.