W dzisiejszym artykule zajmiemy się kontynuacją rozbudowy naszej zdalnej stacji pogodowej. Stworzymy istotny element naszego projektu jakim jest komunikacja moduły Nodemcu z bazą danych oraz wyświetlimy otrzymane wyniki na stworzonym poprzednio emulatorze.
Jako przykład wykorzystamy ultradźwiękowy czujnik odległości HC-SR04. Prześlemy wartości otrzymane z czujnika za pomocą komunikacji WiFi z wykorzystaniem modułu Nodemcu V3, który zawiera wbudowany moduł esp8266. Do połączenia modułu z bazą posłużymy się dedykowaną dla arduino biblioteką Firebase.
W pierwszej kolejności podłączymy nasz układ. Schemat podłączenia prezentuje się następująco :

Po podłączeniu układu możemy przejść do odpowiedniego zaprogramowania naszego modułu mcu. W tym celu uruchamiamy naszą bazę danych. Stworzenie bazy danych krok po kroku zostało opisane w poprzednim artykule. Wchodzimy w zakładkę RealTime Database i kopiujemy widoczny tam link do naszej bazy.

Następnie wchodzimy w settings->project settings i kopiujemy znajdujący się tam Web API Key.

Po skopiowaniu obu linków przechodzimy do programowania naszego modułu. Po uruchomieniu arduino przechodzimy do menadżera bibliotek, wpisujemy frazę „Firebase” i instalujemy następującą bibliotekę:

Tworzymy nowy plik i wpisujemy kod naszego programu.
#include <Arduino.h>
#if defined(ESP32)
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
#include <Firebase_ESP_Client.h>
#include "addons/TokenHelper.h"
#include "addons/RTDBHelper.h"
#define WIFI_SSID "Nazwa wifi do którego podłączony jest komputer"
#define WIFI_PASSWORD "Hasło do wifi"
#define trigPin D0
#define echoPin D1
#define API_KEY "Tu wklej skopiowany wcześniej WEB API KEY"
#define DATABASE_URL "Tu wklej link do bazy"
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
unsigned long sendDataPrevMillis = 0;
int count = 0;
bool signupOK = false;
long czas, dystans;
void setup(){
Serial.begin(9600);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(300);
}
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
config.api_key = API_KEY;
config.database_url = DATABASE_URL;
if (Firebase.signUp(&config, &auth, "", "")){
Serial.println("ok");
signupOK = true;
}
else{
Serial.printf("%s\n", config.signer.signupError.message.c_str());
}
config.token_status_callback = tokenStatusCallback;
Firebase.begin(&config, &auth);
Firebase.reconnectWiFi(true);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop(){
if (Firebase.ready() && signupOK && (millis() - sendDataPrevMillis > 3000 || sendDataPrevMillis == 0)){
sendDataPrevMillis = millis();
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
czas = pulseIn(echoPin, HIGH);
dystans = czas / 58;
Firebase.RTDB.setInt(&fbdo, "Pomiar/int", dystans);
}
}Jeżeli wszystko wykonaliśmy poprawnie, po wgraniu programu do naszego modułu i podłączeniu czujnika do źródła zasilania w naszej bazie danych powinny pojawiać się wartości mierzonej przez czujnik odległości.

Możemy przejść do napisania aplikacji mobilnej wyświetlającej w czasie rzeczywistym uzyskaną przez bazę danych wartość . Przerabiamy nieco naszą aplikację z poprzedniego artykułu usuwając przycisk oraz modyfikując pola tekstowe. Gotowy plik activity_main.xml wygląda następująco:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="371dp"
android:layout_height="112dp"
android:text="StacjaPogodowaAjmaker"
android:textAlignment="center"
android:textSize="80px"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.111" />
<TextView
android:id="@+id/describe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="176dp"
android:layout_marginTop="201dp"
android:layout_marginEnd="177dp"
android:layout_marginBottom="511dp"
android:text="Aktualna wartość odległości w cm : "
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="176dp"
android:layout_marginTop="235dp"
android:layout_marginEnd="177dp"
android:layout_marginBottom="477dp"
android:text=" "
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Przechodzimy do najważniejszego, czyli pliku MainActivity.java który odpowiada za działanie naszej aplikacji. Wklejamy odpowiedni kod uzyskując tym samym gotową do uruchomienia aplikację.
package com.example.stacjapogodowaajmaker;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
public class MainActivity extends AppCompatActivity {
TextView currentDistance;
DatabaseReference firebaseDatabase;
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
currentDistance = findViewById(R.id.distance);
firebaseDatabase = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = firebaseDatabase.child("Pomiar/int");
usersRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
Long test = snapshot.getValue(Long.class);
currentDistance.setText(Long.toString(test));
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
super.onCreate(savedInstanceState);
}
}Odpalamy stworzony wcześniej emulator i obserwujemy zmieniającą się wartość odległości.

Podsumowując dotychczasowe artykuły, udało nam się zrealizować funkcję zapisywania danych do bazy z poziomu aplikacji mobilnej, modułu esp8266 oraz odczyt danych. W kolejnym artykule zajmiemy się rozbudową naszego projektu o nowy wygląd, stworzymy szkielet aplikacji wykorzystując programowanie obiektowe oraz uporządkujemy naszą bazę danych tak aby była przejrzysta i prosta w obsłudze.







