Ghi dữ liệu ESP32 vào database Realtime firebase

Ghi dữ liệu ESP32 vào database Realtime firebase

Tổng quan về dự án ghi dữ liệu từ ESP32 vào database Realtime Firebase 

Mục đích của dự án là ghi lại các giá trị đọc được từ cảm biến BM280 vào cơ sở dữ liệu Realtime của Firebase và cả giá trị timestamps. Realtime cụ thể sẽ được lấy từ máy chủ NTP. Trong ứng dụng ghi dữ liệu, Epoch timestamp rất hữu ích để ghi các giá trị có đánh dấu Realtime hiện. Thời gian Epoch còn được gọi là Unix epoch, Unix time, POSIX time, hoặc Unix timestamp. Ghi dữ liệu từ ESP32 vào Firebase Realtime Database

Kết nối cảm biến BME280 với ESP32

 Kết nối BME280 với bảng mạch ESP32 rất dễ dàng. Kết nối đầu cuối VCC với 3,3V, nối đất với nối đất (điểm chung), SCL của cảm biến với SCL của module và SDA của cảm biến với chân SDA của module ESP.

 Chân I2C trong ESP32 cho SDA là GPIO21 và cho SCL là GPIO22

 Linh kiện bắt buộc

 Cần các linh kiện sau để kết nối bảng mạch ESP32 với cảm biến BME280.

  • Bảng ESP32

  • Cảm biến BME280

  • Dây kết nối

  • breadboard

 Sơ đồ kết nối

 Kết nối thiết bị ESP32 với BME280 như trong sơ đồ bên dưới: 

Sơ đồ kết nối của ESP32 và BME280

 Vin được kết nối với chân 3,3V trên module và cả bảng mạch ESP32, cảm biến thường được nối đất.

 Trong một số cảm biến BME280, chân SCK có nghĩa là chân SCL và được kết nối với chân GPIO tương ứng trên bảng mạch ESP32. Tương tự như vậy, chân SDI là chân SDA và được kết nối với chân GPIO tương ứng trên bo mạch.

Thiết lập console Google Firebase

Đầu tiên, nhập https://firebase.google.com/ vào tab tìm kiếm của trình duyệt và nhấn enter. 

Thao tác này sẽ mở trang chính của Firebase. Nhấp vào ‘Go to console’ như được tô sáng trong hình chữ nhật màu đỏ. 

 Nhấp vào ‘Go to console’

Bạn sẽ được chuyển hướng đến một trang web mới với thông báo chào mừng.  Nhấp vào nút “Create a project” như hình bên dưới.

Google Firebase Getting Started no2

Trang sau mở ra.

 Bước 1: Viết tên dự án của bạn. Nhớ đánh dấu vào thỏa thuận với Firebase. Bây giờ hãy nhấp vào 'Continue'. ESP32 Firebase Realtime Data Logging Project setting up 1

Bước 2: Không cần bật 'Google Analytics cho dự án này' vì không cần. Nhấp vào “Create project” để tiếp tục. 

ESP32 and ESP8266 firebase authentication pic 2

Sau một lúc, dự án của bạn sẽ được tạo.

 Nhấp vào “Continue”

ESP32 Firebase Realtime Data Logging Project setting up 2

Đặt phương thức xác thực

 Bạn sẽ được chuyển hướng đến trang của dự án mới tạo. Chọn Build > Authentication.

 Nhấp vào “Get Started” để bắt đầu quá trình xác thực. 

ESP32 Firebase Realtime Data Logging Project setting up 3

Trang sau sẽ xuất hiện. Tại đây, sẽ chuyển sang tùy chọn 'Email/Mật khẩu' làm phương thức đăng nhập. 

ESP32 Firebase Realtime Data Log

Bật tùy chọn 'Email/Mật khẩu' bằng cách trượt thanh trượt sang phải. Sau đó lưu cài đặt. ESP32 and ESP8266 firebase authentication pic 7

Phương thức xác thực này sẽ được kích hoạt như bên dưới: 

ESP32 and ESP8266 firebase authentication pic 8

Bây giờ, bạn sẽ phải cung cấp Email/Mật khẩu của người dùng sẽ có quyền truy cập vào dự án firebase. Đầu tiên, nhấp vào “Users” trong tab, sau đó chuyển đến  ”Add user”. 

ESP32 Firebase Realtime Data Logging Project setting up 5

Chỉ định email và mật khẩu của người dùng. Sau đó nhấp vào “Add user”

ESP32 and ESP8266 firebase authentication pic 10

Sau khi thêm người dùng, bạn có thể xem email, ngày tạo và UID người dùng được liên kết với người dùng mà bạn vừa ủy quyền. Bạn có thể nhận thấy rằng phần “ Signed in” trống.  Điều này là do người dùng này chưa đăng nhập vào dự án Firebase. 

ESP32 Firebase Realtime Data Logging Project setting up 6

Lấy API key

 Chuyển đến biểu tượng cài đặt và nhấp vào “Project setting”. 

ESP32 Firebase Realtime Data Logging Project setting up 7

Trong cài đặt dự án, bạn sẽ có thể xem API key như được đánh dấu bên dưới. Key này duy nhất cho dự án của bạn. Sẽ cần nó trong khi lập trình bảng mạch ESP32.

ESP32 Firebase Realtime Data Logging Project setting up 8

Realtime Database

 Trong tab Build, hãy chuyển đến “Realtime Database”. Sau đó nhấp vào “Create Database”. 

ESP32 Firebase Realtime Data Logging Project setting up 9

Chỉ định vị trí cơ sở dữ liệu Realtime và nhấp vào “Next”. 

ESP32 Firebase Realtime Data Logging Project setting up 10

Đối với các quy tắc bảo mật, hãy bắt đầu ở chế độ thử nghiệm trong thời gian này.  Bây giờ hãy nhấp vào “Enable”. 

ESP32 Firebase Realtime Data Logging Project setting up 11

Cài đặt cơ sở dữ liệu hiện đã hoàn tất. Bạn có thể xem URL cơ sở dữ liệu như hình bên dưới. Lưu nó vì sẽ cần nó trong khi lập trình bảng mạch ESP32. 

ESP32 Firebase Realtime Data Logging Project setting up 12

Bây giờ hãy chuyển đến tab “Rules” và sau đó là “Edit rules”. Sao chép các quy tắc hiển thị bên dưới và sau đó nhấp vào nút “Pusblish”. 

ESP32 Firebase Realtime Data Logging Project setting up 13

Các quy tắc này sẽ bảo mật dữ liệu. Chúng tôi đã khai báo node 'Data' bao gồm một số nút khác sẽ là các UID của người dùng. Chỉ những người dùng được xác thực mới có quyền truy cập vào node riêng của họ. Do đó, người dùng được xác thực sẽ chỉ có thể (đọc/ghi) tới một node tương ứng với UID của nó. Người dùng có UID ‘x’ sẽ có thể đọc/ghi dữ liệu ở node: Data/x.

Thiết lập phần mềm Arduino IDE

Sử dụng Arduino IDE để lập trình bảng mạch phát triển ESP32. Bạn nên có phiên bản Arduino IDE mới nhất. Ngoài ra, cần cài đặt plugin cho bảng mạch tương ứng mà bạn sẽ sử dụng.

Cài đặt thư viện BME280

 Vì đang kết nối cảm biến BME280 với ESP32 nên sẽ phải cài đặt các thư viện hỗ trợ lập trình BME280. Sẽ yêu cầu hai thư viện cho dự án này:

  1. Thư viện Adafruit_BME280

  2. Thư viện Adafruit_Sensor 

 Sử dụng Trình quản lý thư viện trong Arduino IDE để cài đặt các phiên bản mới nhất của thư viện. Mở Arduino IDE và vào Sketch > Include Libraries > Manage Libraries. Nhập từng tên thư viện vào thanh tìm kiếm và cài đặt cả hai. 

Adafruit unified sensor library install

Cài đặt thư viện Client Google Firebase ESP

 Yêu cầu thư viện ứng dụng client firebase ESP cho dự án này. Thư viện này tương thích với cả bảng mạch phát triển ESP32 và ESP8266. Chúng tôi sẽ sử dụng Trình quản lý thư viện trong Arduino IDE để cài đặt nó.

 Mở Arduino IDE và nhấp vào Sketch > Library > Manage Libraries. Nhập 'Firebase ESP Client' trong tab tìm kiếm và cài đặt phiên bản mới nhất của Thư viện ứng dụng Client Firebase Arduino cho ESP8266 và ESP32 được hiển thị bên dưới. 

Installing Firebase ESP Client library

Sau khi cài đặt thư viện, hãy khởi động lại IDE.

 Code ESP32 ghi dữ liệu Realtime

 Mở Arduino IDE và vào File > New để mở một file mới.

 Sao chép code được cung cấp dưới đây trong tập tin đó. Cần nhập thông tin đăng nhập mạng. Bạn cũng phải khai báo khóa API web và URL cơ sở dữ liệu đã được lưu trước đó. Ngoài ra, sẽ phải chỉ định email và mật khẩu sử dụng trong xác thực Firebase để cấp quyền cho người dùng. 

#include <Arduino.h>

#include <WiFi.h>

#include <Firebase_ESP_Client.h>

#include <Wire.h>

#include <Adafruit_Sensor.h>

#include <Adafruit_BME280.h>

#include "time.h"

#include "addons/TokenHelper.h"

#include "addons/RTDBHelper.h"

 

//Enter your network credentials

const char* ssid = "YOUR_SSID";

const char* password = "YOUR_PASSWORD";

 

//Enter Firebase web API Key

#define API_KEY "AIzaSyCPU3dkKnnc--XM5vorDZroV_0NYxH****"

 

// Enter Authorized Email and Password

#define USER_EMAIL "WRITE_AUTHORIZED_EMAIL"

#define USER_PASSWORD "WRITE_AUTHORIZED_PASSWORD"

 

// Enter Realtime Database URL

#define DATABASE_URL "WRITE_YOUR_REALTIME_DATABASE_URL"

 

FirebaseData Firebase_dataObject;

FirebaseAuth authentication;

FirebaseConfig config;

 

String UID;

 

// Database main path 

String database_path;

 

String temperature_path = "/temperature";

String humidity_path = "/humidity";

String pressure_path = "/pressure";

String time_path = "/epoch_time";

 

//Updated in every loop

String parent_path;

 

int epoch_time;

FirebaseJson json;

 

const char* ntpServer = "pool.ntp.org";

 

Adafruit_BME280 bme; 

float temperature;

float humidity;

float pressure;

 

//send new readings every 5 minutes

unsigned long previous_time = 0;

unsigned long Delay = 300000;

 

//get current epoch time

unsigned long Get_Epoch_Time() {

  time_t now;

  struct tm timeinfo;

  if (!getLocalTime(&timeinfo)) {

    return(0);

  }

  time(&now);

  return now;

}

 

void setup(){

  Serial.begin(115200);

  

    if (!bme.begin(0x76)) {

    Serial.println("Could not find BME280 sensor. Check Connections!");

    while (1);

  }

  

  WiFi.begin(ssid, password);

  Serial.print("Connecting to WiFi ..");

  while (WiFi.status() != WL_CONNECTED) {

    Serial.print('.');

    delay(1000);

  }

  Serial.println(WiFi.localIP());

  Serial.println();

  

  configTime(0, 0, ntpServer);

 

  config.api_key = API_KEY;

  authentication.user.email = USER_EMAIL;

  authentication.user.password = USER_PASSWORD;

  config.database_url = DATABASE_URL;

 

  Firebase.reconnectWiFi(true);

  Firebase_dataObject.setResponseSize(4096);

 

  config.token_status_callback = tokenStatusCallback; 

  config.max_token_generation_retry = 5;

 

  Firebase.begin(&config, &authentication);

 

  Serial.println("Getting User UID...");

  while ((authentication.token.uid) == "") {

    Serial.print('.');

    delay(1000);

  }

  UID = authentication.token.uid.c_str();

  Serial.print("User UID: ");

  Serial.println(UID);

 

  database_path = "/Data/" + UID + "/BME280 Readings";

}

 

void loop(){

  if (Firebase.ready() && (millis() - previous_time > Delay || previous_time == 0))

{

    previous_time = millis();

 

    epoch_time = Get_Epoch_Time();

    Serial.print ("time: ");

    Serial.println (epoch_time);

 

    parent_path= database_path + "/" + String(epoch_time);

 

    json.set(temperature_path.c_str(), String(bme.readTemperature()));

    json.set(humidity_path.c_str(), String(bme.readHumidity()));

    json.set(pressure_path.c_str(), String(bme.readPressure()/100.0F));

    json.set(time_path, String(epoch_time));

    Serial.printf("Set json...%s\n",Firebase.RTDB.setJSON(&Firebase_dataObject, parent_path.c_str(), &json) ? "ok" : Firebase_dataObject.errorReason().c_str());

  }

}

Giải thích code

 Đầu tiên import tất cả các thư viện cần thiết cho dự án này. 

#include <Arduino.h>

#include <WiFi.h>

#include <Firebase_ESP_Client.h>

#include <Wire.h>

#include <Adafruit_Sensor.h>

#include <Adafruit_BME280.h>

#include "time.h"

#include "addons/TokenHelper.h"

#include "addons/RTDBHelper.h"

Tiếp theo, sẽ tạo hai biến toàn cục, một cho SSID và một cho mật khẩu. Chúng sẽ chứa thông tin đăng nhập mạng sử dụng để kết nối với bộ định tuyến không dây.  Thay thế cả hai bằng thông tin đăng nhập mạng của bạn để đảm bảo kết nối thành công. 

//Enter your network credentials

const char* ssid = "YOUR_SSID";

const char* password = "YOUR_PASSWORD";

Thông tin đăng nhập Firebase (Credentials)

Tiếp theo, sẽ khai báo key web API firebase của Google đã truy cập và lưu trước đó 

//Enter Firebase web API Key

#define API_KEY "AIzaSyCPU3dkKnnc--XM5vorDZroV_0NYxH****"

Bước tiếp theo là khai báo email và mật khẩu của người dùng đã sử dụng khi ủy quyền cho người dùng trong dự án. Cả hai thông tin này phải tương ứng với những thông tin bạn đã lưu khi thêm người dùng. 

// Enter Authorized Email and Password

#define USER_EMAIL "WRITE_AUTHORIZED_EMAIL"

#define USER_PASSWORD "WRITE_AUTHORIZED_PASSWORD"

Bây giờ hãy nhập URL của cơ sở dữ liệu Realtime đã có trước đó sau khi tạo cơ sở dữ liệu Realtime. Ở đây, URL cơ sở dữ liệu là “esp-data-logging-a4e40-default-rtdb.asia-southeast1.firebasedatabase.app” 

// Enter Realtime Database URL

#define DATABASE_URL "WRITE_YOUR_REALTIME_DATABASE_URL"

Tiếp theo, sẽ tạo một số biến đối tượng cho một số chức năng của firebase: dữ liệu, xác thực và cấu hình. 

FirebaseData Firebase_dataObject;

FirebaseAuth authentication;

FirebaseConfig config;

Biến lưu trữ dữ liệu

Biến chuỗi UID sẽ lưu UID của người dùng. 

String UID;

Tiếp theo, sẽ tạo một số biến chuỗi cho các path. ‘database path’ là path chính sẽ được cập nhật với UID người dùng. Tiếp theo, có các path để đọc giá trị cảm biến nhiệt độ, độ ẩm và áp suất cũng như path của thời gian epoch. ‘Parent_path’ sẽ thay đổi sau mỗi vòng lặp với timestamp mới. 

ESP32 Firebase Realtime Data Logging Project paths

 

String database_path;  //main path

String temperature_path = "/temperature";

String humidity_path = "/humidity";

String pressure_path = "/pressure";

String time_path = "/epoch_time";

 

//Updated in every loop

String parent_path;

Biến số nguyên ‘epoch_time’ sẽ lưu thời gian epoch có được từ máy chủ NTP. 

int epoch_time;

Xác định địa chỉ của máy chủ NTP trong một biến toàn cục kiểu const char sẽ là pool.ntp.org. 

const char* ntpServer = "pool.ntp.org";

Tiếp theo, sẽ tạo một object FirebaseJson có tên là 'json', sử dụng để gửi dữ liệu cảm biến cùng với thời gian epoch tới cơ sở dữ liệu Realtime một cách dễ dàng. 

FirebaseJson json;

BME280

Sau đó, khai báo biến đối tượng Adafruit_BME280 có tên bme bằng cách đặt ở các chân I2C GPIO mặc định của ESP32. Ngoài ra, sẽ khai báo các biến để gán các giá trị của cảm biến BME280 chẳng hạn như nhiệt độ, áp suất và độ ẩm. Chúng được khai báo là các kiểu dữ liệu động vì sẽ xử lý các giá trị số có thể có dấu chấm thập phân. Nói cách khác, các giá trị do cảm biến BME280 trả về là các giá trị dấu phẩy động. 

Adafruit_BME280 bme; 

float temperature;

float humidity;

float pressure;

Ở đây, khai hai biến previous_time và Delay. Bao gồm độ trễ 5 phút (300000 mili giây) trước khi gửi các giá trị cảm biến mới. Thời gian cập nhật đang được lưu trữ trong biến “Delay”. 

//send new readings every 5 minutes

unsigned long previous_time = 0;

unsigned long Delay = 300000;

Get_Epoch_Time()

Để lấy được thời gian epoch/Unix, tạo hàm Get_Epoch_Time() sẽ trả về thời gian epoch bất cứ khi nào có yêu cầu được gửi đến máy chủ.

//get current epoch time

unsigned long Get_Epoch_Time() {

  time_t now;

  struct tm timeinfo;

  if (!getLocalTime(&timeinfo)) {

    return(0);

  }

  time(&now);

  return now;

}

setup()

Trong hàm setup(), bắt đầu giao tiếp dữ liệu nối tiếp với tốc độ truyền là 115200. 

 Serial.begin(115200);

Các dòng code sau sẽ khởi tạo cảm biến BME280. Trong trường hợp không thành công, một thông báo liên quan sẽ được in trên màn hinh serial của phần mềm. 

    if (!bme.begin(0x76)) {

    Serial.println("Could not find BME280 sensor. Check Connections!");

    while (1);

  }

Phần code sau đây sẽ kết nối bo mạch ESP32 với mạng cục bộ có thông tin đăng nhập mạng mà chúng ta đã chỉ định ở trên. Sử dụng chức năng WiFi.begin(). Các đối số sẽ là SSID và mật khẩu mà chúng tôi đã xác định trước đó trong code. Sau khi kết nối được thiết lập, địa chỉ IP của bảng mạch ESP32 sẽ được in trên màn hình serial. 

WiFi.begin(ssid, password);

  Serial.print("Connecting to WiFi ..");

  while (WiFi.status() != WL_CONNECTED) {

    Serial.print('.');

    delay(1000);

  }

  Serial.println(WiFi.localIP());

  Serial.println();

Hàm configTime() được sử dụng để cấu hình thời gian. Nó có ba đối số.  Đầu tiên là thời gian bù (GMT offset) GMT sẽ đặt thành 0. Thứ hai là thời gian tiết kiệm ánh sáng ban ngày (daylight saving time) sẽ đặt là 0 vì chỉ muốn truy cập thời gian epoch và hai tham số này không cần thiết cho nó. Đối số thứ ba là biến máy chủ NTP ‘ntpServer’ chứa địa chỉ máy chủ NTP. 

 configTime(0, 0, ntpServer);

Bây giờ, sẽ sử dụng biến đối tượng dữ liệu firebase đã tạo để cấu hình và đặt key API cũng như URL cơ sở dữ liệu. Sau đó, sẽ xác định email và mật khẩu của người dùng cho một biến đối tượng xác thực firebase. 

  config.api_key = API_KEY;

  authentication.user.email = USER_EMAIL;

  authentication.user.password = USER_PASSWORD;

  config.database_url = DATABASE_URL;

 

Các dòng code sau đây sử dụng để đặt chức năng callback cho tác vụ tạo code thông báo chạy. Chúng cũng sẽ được đặt thành một biến đối tượng cấu hình Firebase. 

  config.token_status_callback = tokenStatusCallback; 

  config.max_token_generation_retry = 5;

Sử dụng Firebase.begin() trên path cấu hình và xác thực, sẽ khởi tạo kết nối thư viện firebase.

Firebase.begin(&config, &authentication);

Các dòng code sau sẽ lấy UID người dùng 

 Serial.println("Getting User UID...");

  while ((authentication.token.uid) == "") {

    Serial.print('.');

    delay(1000);

  }

  UID = authentication.token.uid.c_str();

  Serial.print("User UID: ");

  Serial.println(UID);

Hơn nữa, database_path sẽ được đặt như sau: Nó gồm Dữ liệu theo sau là UID của người dùng và "/BME280 Readings"

  database_path = "/Data/" + UID + "/BME280 Readings";

loop()

Bên trong hàm loop(),sẽ lấy thời gian epoch sau khi kết nối với Firebase và sau mỗi 5 phút. Thời gian epoch này sẽ được in trong màn hình serial của phần mềm.

 Sau đó, sẽ cập nhật parent_path với giá trị epoch_time. Sử dụng json.set() sẽ cập nhật tất cả các lần đọc giá trị cảm biến và timestamp với các giá trị hiện tại. Đối số đầu tiên là path và đối số thứ hai là giá trị.

 Hơn nữa, chúng tôi sẽ gọi Firebase.RTDB.setJSON()

void loop(){

  if (Firebase.ready() && (millis() - previous_time > Delay || previous_time == 0)){

    previous_time = millis();

 

    epoch_time = Get_Epoch_Time();

    Serial.print ("time: ");

    Serial.println (epoch_time);

 

    parent_path= database_path + "/" + String(epoch_time);

 

    json.set(temperature_path.c_str(), String(bme.readTemperature()));

    json.set(humidity_path.c_str(), String(bme.readHumidity()));

    json.set(pressure_path.c_str(), String(bme.readPressure()/100.0F));

    json.set(time_path, String(epoch_time));

    Serial.printf("Set json... %s\n", Firebase.RTDB.setJSON(&Firebase_dataObject, parent_path.c_str(), &json) ? "ok" : Firebase_dataObject.errorReason().c_str());

  }

}

Chạy mô hình

Chọn đúng bảng và cổng COM trước khi tải mã của bạn lên bảng. Chuyển đến ‘Tools > Board’ và chọn module mạch phát triển ESP32.select esp32 board

Tiếp theo, vào ‘Tools > Port’ và chọn cổng thích hợp mà bo mạch của bạn được kết nối. 

Selecting COM PORT ESP32

Nhấp vào nút tải lên để tải code lên bảng mạch phát triển ESP32.

 Sau khi đã tải code lên bảng mạch phát triển, hãy nhấn nút Enable của nó. \

ESP32 enable reset button

Trong phần mềm Arduino IDE, hãy mở màn hình serial và xem trạng thái kết nối WIFI và địa chỉ IP của module ESP32 của mình. Các giá trị đọc đầu tiên sẽ được gửi đến Cơ sở dữ liệu Realtime Firebase. Ở phần console của database realtime firebase bạn sẽ xem được tất cả các dữ liệu.

ó thể thấy dữ liệu theo sau là UID người dùng, sau đó là “BME280 Readings”.  Theo đó, timestamp hiển thị thời gian epoch. Đây là dữ liệu sau 10 phút đầu tiên, do đó có ba timestamp tại thời điểm 0, 5 phút và 10 phút. 

ESP32 Firebase Realtime Data Logging Project demo 1

Mở rộng ra xem timestamp riêng lẻ, bạn sẽ có thể xem được ba lần đọc giá trị cảm biến như sau: 

ESP32 Firebase Realtime Data Logging Project demo 2

>>> 100+ Mã Sản Phẩm Dây Rút: https://mecsu.vn/san-pham/day-rut-nhua.5op

>>> 1000+ Mã Sản Phẩm Đầu Cosse: https://mecsu.vn/san-pham/dau-cosse.Q1j

Bài viết cùng chuyên mục

NHANH

NHANH

Vì Đổi mới liên tục nên Nhanh hơn

ĐÚNG

ĐÚNG

Coi trọng và ưu tiên việc làm Đúng

ĐỦ

ĐỦ

Tìm và mua Đủ Đơn hàng hơn

KỊP THỜI

KỊP THỜI

Hiệu suất tối ưu bởi Kịp Thời hơn