W tym artykule kontynuujemy rozbudowę naszej zdalnej stacji pogodowej. Przebudujemy kod aplikacji do pracy z większą ilością czujników, podłączymy pierwszy czujnik oraz odpowiednio przechowamy dane w naszej bazie.

W pierwszej kolejności zajmiemy się podłączeniem naszego czujnika do modułu Nodemcu. Czujnik gazu wyposażony jest w dwa wyjścia służące do odczytu danych: D0 oraz A0. W pierwszym przypadku możemy za pomocą potencjometru ustawić wartość progową po przekroczeniu której czujnik będzie wysyłał nam sygnał o zbyt dużym stężeniu gazu. W przypadku wyjścia A0 odczytujemy wartości z zakresu od 0 do 1023 na wejściu przetwornika analogowo-cyfrowego. W naszej stacji pogodowej wykorzystamy wyjście A0.
Podłączenie czujnika jest niezwykle proste i sprowadza się jedynie do podłączenia dowolnego źródła zasilania 5 V do czujnika oraz wyjścia A0 czujnika do wejścia A0 modułu Nodemcu.

Jeżeli mamy prawidłowo podpięty czujnik, to możemy przejść do pisania kodu naszej aplikacji. W tym artykule zmienimy trochę koncepcję naszego projektu i zmienimy bibliotekę z której będziemy korzystać na FirebaseESP8266. Link do pobrania biblioteki znajdziecie w załączniku na końcu artykułu. Dodatkowo wprowadzimy do naszej bazy funkcjonalność pobierania aktualnej daty, którą wykorzystamy w późniejszym czasie do wyświetlania naszych pomiarów na wykresach. Bibliotekę do tego służącą pobieramy z menadżera bibliotek wpisując frazę „ESPDateTime”.

Pierwszą istotną zmianą w kodzie jest odejście od korzystania z klucza API na rzecz sekretnego tokenu. Pokażę teraz jak znaleźć taki token w kilku krokach.
- Wchodzimy w nasz projekt na platformie Firebase.
- Wchodzimy w zakładkę Project Settings.

- Wybieramy zakładkę Service accounts, a następnie klikamy w Database secrets.

- Najeżdżamy kursorem w pole Secret i za pomocą przycisku Show, ujawniamy nasz ciąg znaków. Całość kopiujemy i zapisujemy.
Drugim z istotnych elementów jest modyfikacja adresu naszej bazy. W poprzednim kodzie kopiowaliśmy cały adres łącznie z przedrostkiem https://, natomiast w tym przypadku wykorzystamy ten sam adres, ale bez przedrostka.
#include <FirebaseESP8266.h>
#include <ESPDateTime.h>
#include<sstream>
#include <Arduino.h>
#if defined(ESP32)
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
#define WIFI_SSID "" // Nazwa naszej sieci wi-fi
#define WIFI_PASSWORD "" // Hasło do naszej sieci
#define HOST "" // Ciąg znaków z pola secrets.
#define DATABASE_URL "" // Adres naszej bazy bez przedrostka https://
FirebaseData firebaseData; // Stworzenie objektu klasy FirebaseData
void setup() {
Serial.begin(9600);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) { // Oczekujemy na połączenie z WiFi
Serial.print(".");
delay(300);
}
Firebase.begin(DATABASE_URL, HOST); // Łączymy się z bazą za pomocą adresu bazy i sekretnego ciągu znaków
Firebase.reconnectWiFi(true); // Przeładowanie wiFi
setupDateTime(); // Ustawiamy odpowiednie parametry do przechwycenia obecnej daty
}
void setupDateTime() {
DateTime.setServer("time.pool.aliyun.com"); // Wybieramy serwer z którego będziemy pobierali datę
DateTime.setTimeZone("GMT-2"); // Ustawiamy strefę czasową dla Polski
DateTime.begin(); // Uruchamiamy nasze przechwytywanie daty
DateTime.toISOString().c_str(); // Konwertujemy datę do typu String
DateTime.now(); // Pobieramy czas w s jaki upłynął od daty bazowej : 01.01.1970
delay(1000);
}
template <typename T> // Ta funkcja służy do zniwelowania błędu który się pojawiał podczas próby użycia metody to_string.
std::string to_string(T value)
{
std::ostringstream os ;
os << value ;
return os.str() ;
}
void pomiarDymu(int ilosc, int pomiar, String data) // Funkcja realizująca pomiar dymu
{
std::string sciezka = "Dym/Pomiar_" + to_string(ilosc); // Ustawiamy odpowiednią ścieżkę bazując na zmiennej ilosc
String czujnikDymu = String(sciezka.c_str()); // Konwertujemy naszą ścieżkę na typ String
String wskazanieCzujnikaDymu = czujnikDymu + "/Wskazanie"; // Ustawiamy ścieżkę dla wskazania czujnika
String dataCzujnikaDymu = czujnikDymu + "/Data"; // Ustawiamy ścieżkę dla daty
Firebase.setInt(firebaseData, wskazanieCzujnikaDymu, pomiar); // Przesyłamy wartość wskazania do bazy
Firebase.setString(firebaseData, dataCzujnikaDymu, data); // Przesyłamy wartość daty do bazy
}
int iloscPomiarowDym() { // Funkcja sprawdzająca aktualną ilość pomiarów
int iloscPomiarow;
Firebase.getInt(firebaseData, "Dym/IloscPomiarow", &iloscPomiarow); // Pobieramy numer ostatniego pomiaru
iloscPomiarow++; // Zwiększamy numer o 1
Firebase.setInt(firebaseData, "Dym/IloscPomiarow", iloscPomiarow); // Przesyłamy do bazy następny numer
return iloscPomiarow; // Zwracamy numer
}
void loop() {
delay(5000); // Czekamy 5s przed każdym pomiarem
int pomiarCzujnikaDymu = analogRead(A0); // Pobieramy wartość wskazania czujnika z konwertera A/C dla pinu A0
String currentTime = DateTime.format(DateFormatter::SIMPLE).c_str(); // Ustawiamy format czasu na YYYY/MM/DD HH:MM:SS
pomiarDymu(iloscPomiarowDym(), pomiarCzujnikaDymu, currentTime); // Realizujemy funkcję pomiaru zawartości dymu
}Na początku programu łączymy się z naszą bazą danych poprzez obiekt klasy FirebaseDatabase, następnie oczekujemy na połączenie się z siecią WiFi. Następnie konfigurujemy klasę DataTime, aby poprawnie wyświetlała wartość aktualnej daty dla czasu polskiego. Po przeprowadzeniu wstępnej konfiguracji w nieskończonej pętli wykonujemy następujące kroki:
- Odczekujemy 5s
- Odczytujemy wartość wskazania czujnika
- Ustawiamy format czasu na YYYY/MM/DD HH:MM:SS
- Wywołujemy funkcję pomiarDymu() z argumentami : iloscPomiarowDymu() jako zwracana obecna ilość pomiarów powiększona o 1, odczyt wartości jakości powietrza z konwertera oraz obecna data.
Po przepisaniu powyższego kodu możemy przejść do przygotowania naszej bazy do pierwszego pomiaru, później nie będzie to już konieczne. Tworzymy tabelę Dym, a następnie pod tą tabelą tworzymy zmienną IloscPomiarow o wartości 0.

Jeżeli kod poprawnie nam się skompilował powinniśmy uzyskać następujący rezultat:




