week__11 (Firebase) - JINEEH/SmartDevice_JinHee GitHub Wiki
1-1. Firebase๋ฅผ ์ด์ฉํ์ฌ ๋ฐ์ดํฐ ์ ์ฅ ๋ฐ ํ์ฉ
2-1. ์น ์ดํ๋ฆฌ์ผ์ด์
์ ๋น ๋ฅด๊ณ ์ฝ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅํ๋ฉฐ ๋ค์ํ ๊ธฐ๋์ ํ์ฉํ ์ ์์
- ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ฌด๋ฃ๋ก ์ฌ์ฉ ๊ฐ๋ฅ
- ๋ฐ์ดํฐ ๋ณด์๊ณผ ๊ด๋ จ๋ ์ธ์ฆ๊ธฐ๋ฅ(ex: ์ด๋ฉ์ผ, SNS ๋ก๊ทธ์ธ)๊ณผ ์ค์๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํด๋ผ์ฐ๋ ๋ฐฉ์ ์ฌ์ฉ ๊ฐ๋ฅ
- ์ฌ์ฉ์ or ๋๋ฐ์ด์ค์์ ์
๋ ฅ๋ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ (ํ์ผ ์
๋ก๋ ๊ณต์ ๊ธฐ๋ฅ) ๊ฐ๋ฅ
- ๋ฐ์ดํฐ ์๋ ๋ถ์ ๊ธฐ๋ฅ
- ๋ฉ์์ง ๊ธฐ๋ฅ๊ณผ ๋ฐฑ์
๊ณผ ๊ด๋ จ๋ ์คํ ๋ฆฌ์ง ๊ธฐ๋ฅ
- ๋ฐ์ดํฐ ์ ์ฅ/๊ณต์ /๋ถ์/๋ณด์/๋ฐฑ์
-
๊ตฌ๊ธ ์์ด๋๋ก ๋ก๊ทธ์ธ ํ ํ๋ก์ ํธ ๋ง๋ค๊ธฐ ์คํ
-
ํ๋ก์ ํธ ์ด๋ฆ ์ ๋ ฅ ํ ๋น๋->Realtime Database->๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง๋ค๊ธฐ




- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ์ ์์น(๋ฏธ๊ตญ) ๋ฐ ํ ์คํธ ๋ชจ๋ ์ค์ ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค URL ๋ณต์ฌ ๋ฐ ์ฝ๊ธฐ, ์ฐ๊ธฐ ๊ท์น ์ค์
- ๋น๋->AUthentication ์ด๋ ํ ์์ํ๊ธฐ
- ์ต๋ช ๋ฐฉ์ ์ ํ ํ ์ฌ์ฉ ์ค์ On
- <ํ๋ก์ ํธ ์ค์ >์์ ์น API ํค ํ์ธ ๋ฐ ๋ณต์ฌ
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
- ์คํ ์ฝ๋
#include <WiFi.h>
#include <FirebaseESP32.h>
//Provide the token generation process info.
#include "addons/TokenHelper.h"
//Provide the RTDB payload printing info and other helper functions.
#include "addons/RTDBHelper.h"
// Firebase ์ค์
#define FIREBASE_HOST "your_firebase_host"
#define FIREBASE_AUTH "your_firebase_auth"
#define WIFI_SSID "your_wifi_ssid"
#define WIFI_PASSWORD "your_wifi_password"
// ๋ด์ฅ LED ํ ์ค์
#define LED_PIN 2
// Firebase ๊ฐ์ฒด ์์ฑ
FirebaseData firebaseData;
FirebaseAuth auth;
FirebaseConfig config;
bool signupOK = false;
unsigned long sendDataPrevMillis = 0;
void setup_wifi() {
delay(10);
// Wi-Fi ๋คํธ์ํฌ์ ์ฐ๊ฒฐ ์์
Serial.println();
Serial.print("์ฐ๊ฒฐ ์ค์ธ Wi-Fi: ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Wi-Fi ์ฐ๊ฒฐ๋จ");
Serial.println("IP ์ฃผ์: ");
Serial.println(WiFi.localIP());
}
void setup() {
// ์๋ฆฌ์ผ ํต์ ์ด๊ธฐํ
Serial.begin(115200);
// WiFi ์ฐ๊ฒฐ
setup_wifi();
// API ํค๋ฅผ ํ ๋นํฉ๋๋ค.(ํ์)
config.api_key = FIREBASE_AUTH;
//RTDB URL์ ํ ๋นํฉ๋๋ค.(ํ์)
config.database_url = FIREBASE_HOST;
/* Sign up */
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);
// ๋ด์ฅ LED ํ ์ค์
pinMode(LED_PIN, OUTPUT);
// "/ledState" ๊ฒฝ๋ก๋ฅผ 0์ผ๋ก ์ด๊ธฐํ
if (Firebase.ready() && signupOK)
{
if (Firebase.RTDB.setInt(&firebaseData, "/ledState", 0)){
Serial.println("PASSED");
Serial.println("PATH: " + firebaseData.dataPath());
Serial.println("TYPE: " + firebaseData.dataType());
}
else {
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData.errorReason());
}
}
}
void loop() {
// Firebase.ready() ํจ์๋ ์ธ์ฆ ์์
์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๋ฐ๋ณต์ ์ผ๋ก ํธ์ถ๋์ด์ผ ํฉ๋๋ค.
if (Firebase.ready() && signupOK && \
(millis() - sendDataPrevMillis > 2000 || sendDataPrevMillis == 0))
{
sendDataPrevMillis = millis();
// Firebase์์ LED ์ํ ๊ฐ์ ธ์ค๊ธฐ
int ledState = 0;
if (Firebase.RTDB.getInt(&firebaseData, "/ledState")) {
if (firebaseData.dataType() == "int") {
ledState = firebaseData.intData();
Serial.println(ledState);
if (ledState == 1) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
}
}
else {
Serial.println(firebaseData.errorReason());
}
}
}
- ์ค์ต ๊ฒฐ๊ณผ
11.7-1.2.mp4
- ์ค๋น๋ฌผ: ESP32, ESP32 ํ์ฅ ์ค๋, ์ด์ํ ์ผ์, ์ ํผ์ผ์ด๋ธ 3๊ฐ
- ์คํ ์ฝ๋
int sensorPin = 34;
int value = 0;
void setup() {
Serial.begin(115200);
}
void loop() {
value = analogRead(sensorPin);
Serial.println(value);
delay(500);
}
- ์ค์ต ๊ฒฐ๊ณผ
- 4์ด์ ๋น ์ฆ๊ฐ, 14์ด์ ๋น ๊ฐ์๋ก ์ธํ ๋ณํ ํ์ธ
11.7-2.mp4
- ESP32์ ํ์์คํฌํ๋ฅผ ์ฌ์ฉํ์ฌ Firebase ์ค์๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ ๋ก๊น ํ๊ธฐ
- ์คํ ์ฝ๋
#include <WiFi.h>
#include <FirebaseESP32.h>
// ํ ํฐ ์์ฑ ํ๋ก์ธ์ค ์ ๋ณด ์ ๊ณต
#include "addons/TokenHelper.h"
// RTDB ํ์ด๋ก๋ ์ถ๋ ฅ ์ ๋ณด ๋ฐ ๊ธฐํ ๋์ ํจ์ ์ ๊ณต
#include "addons/RTDBHelper.h"
// Firebase ์ค์
#define FIREBASE_HOST "https://esp32-led-6265e-default-rtdb.firebaseio.com/" //"https://esp32-light-sensor-49d0d-default-rtdb.firebaseio.com/"
#define FIREBASE_AUTH "AIzaSyDv0Uh_reGxqHVqVVLm8kGGaP1KFIkC0io" //"AIzaSyDpwhvYS26vq2UowbTusA502vJucotAPMI"
#define WIFI_SSID "zineeh"
#define WIFI_PASSWORD "SMARTDEVICE0516"
// Firebase ๊ฐ์ฒด ์ ์
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
bool signupOK = false;
// ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฃผ ๊ฒฝ๋ก
String databasePath = "/room1";
String sensorPath = "/lightsensor";
String timePath = "/timestamp";
/// ๋ถ๋ชจ ๋
ธ๋ (ํ์ฌ ์๊ฐ ์ ๋ณด๋ก ๋งค ๋ฃจํ๋ง๋ค ์
๋ฐ์ดํธ)
String parentPath;
int timestamp;
FirebaseJson json;
const char* ntpServer = "pool.ntp.org";
// ๋น ์ผ์ ํ
int sensorPin = 34;
// ํ์ด๋จธ ๋ณ์ (์๋ก์ด ์ธก์ ๊ฐ์ 20์ด๋ง๋ค ์ ์ก)
unsigned long sendDataPrevMillis = 0;
unsigned long timerDelay = 60000; //1 minutes
// WiFi ์ด๊ธฐํ
void setup_wifi() {
delay(10);
// Wi-Fi ๋คํธ์ํฌ์ ์ฐ๊ฒฐ ์์
Serial.println();
Serial.print("์ฐ๊ฒฐ ์ค์ธ Wi-Fi: ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Wi-Fi ์ฐ๊ฒฐ๋จ");
Serial.println("IP ์ฃผ์: ");
Serial.println(WiFi.localIP());
}
// ํ์ฌ epoch ์๊ฐ์ ๊ฐ์ ธ์ค๋ ํจ์
unsigned long getTime() {
time_t now;
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
//Serial.println("Failed to obtain time");
return (0);
}
time(&now);
return now;
}
void setup() {
Serial.begin(115200);
// WiFi ์ฐ๊ฒฐ
setup_wifi();
configTime(0, 0, ntpServer);
// API ํค ํ ๋น (ํ์)
config.api_key = "AIzaSyDv0Uh_reGxqHVqVVLm8kGGaP1KFIkC0io";
// RTDB URL ํ ๋น (ํ์)
config.database_url = "https://esp32-led-6265e-default-rtdb.firebaseio.com/";
Firebase.reconnectWiFi(true);
fbdo.setResponseSize(4096);
/* ํ์ ๊ฐ์
*/
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;
// ํ ํฐ ์์ฑ ์ต๋ ์ฌ์๋ ํ์ ํ ๋น
config.max_token_generation_retry = 5;
// Firebase ์ธ์ฆ ๋ฐ ์ค์ ๊ณผ ํจ๊ป ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๊ธฐํ
Firebase.begin(&config, &auth);
}
void loop() {
// Send new readings to database
if (Firebase.ready() && signupOK
&& (millis() - sendDataPrevMillis > timerDelay
|| sendDataPrevMillis == 0)) {
sendDataPrevMillis = millis();
// ํ์ฌ ํ์์คํฌํ ๊ฐ์ ธ์ค๊ธฐ
timestamp = getTime();
Serial.print("time: ");
Serial.println(timestamp);
parentPath = databasePath + "/" + String(timestamp);
json.set(sensorPath.c_str(), String(analogRead(sensorPin)));
json.set(timePath, String(timestamp));
Serial.println("Set json... ");
if (Firebase.setJSON(fbdo, parentPath.c_str(), json))
Serial.println("ok");
else
Serial.println(fbdo.errorReason());
}
}
- ์ค์ต ๊ฒฐ๊ณผ

- ํ๋ก์ ํธ ์์ฑ ํ ์ฑ(Light-Sensor-Web-App) ๋ฑ๋ก ๋ฐ script ๋ณต์ฌ
- ์คํ ์ฝ๋
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<title>ESP ๋ฐ์ดํฐ ๊ธฐ๋ก Firebase ์ฑ</title>
<style>
#chart_div {
width: 1200px;
height: 500px;
}
#gauge_div {
height: 300px;
}
div {
display: table;
margin-right: auto;
margin-left: auto;
}
</style>
<!-- Firebase SDK ํฌํจ -->
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js"></script>
<!-- ํ์ํ Firebase ๊ธฐ๋ฅ๋ง ํฌํจ -->
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-database.js"></script>
<script>
// ์น ์ฑ์ Firebase ๊ตฌ์ฑ
const firebaseConfig = {
apiKey: "AIzaSyDv0Uh_reGxqHVqVVLm8kGGaP1KFIkC0io",
authDomain: "esp32-led-6265e.firebaseapp.com",
databaseURL: "https://esp32-led-6265e-default-rtdb.firebaseio.com/",
projectId: "esp32-led-6265e",
storageBucket: "esp32-led-6265e.appspot.com",
messagingSenderId: "442137904366",
appId: "1:442137904366:web:f185f9518c565f4d261fff"
};
// Firebase ์ด๊ธฐํ
firebase.initializeApp(firebaseConfig);
// ์ธ์ฆ๊ณผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐธ์กฐ ์์ฑ
const auth = firebase.auth();
const db = firebase.database();
</script>
</head>
<body>
<!-- ์ฐจํธ๋ฅผ ์ํ ์ปจํ
์ด๋ -->
<div>
<div id="chart_div"></div>
</div>
<div>
<div id="gauge_div"></div>
</div>
<script type="text/javascript"
src="https://www.gstatic.com/charts/loader.js"></script>
<script>
// ํ์ฌ ์ฐจํธ ํจํค์ง ๋ก๋
google.charts.load('current', {
packages: ['corechart', 'line', 'gauge'],
});
// API๊ฐ ๋ก๋๋์์ ๋ ์ฝ๋ฐฑ ํจ์ ์ค์
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
// ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ๋ฐ์ดํฐ ๊ฐ์ฒด ์์ฑ
let data = google.visualization.arrayToDataTable([
['Time', 'Light Sensor'],
["00:00", 0],
]);
let gauge_data = google.visualization.arrayToDataTable([
['Light Sensor'],
[0],
]);
// ์ ๋ชฉ, ์์ ๋ฑ์ด ํฌํจ๋ ์ต์
๊ฐ์ฒด ์์ฑ
let options = {
max: 2048, //4096,
hAxis: {
//textPosition: 'none',
},
vAxis: {
},
};
// ์ฐจํธ ๊ทธ๋ฆฌ๊ธฐ
let chart = new google.visualization.LineChart(
document.getElementById('chart_div')
);
chart.draw(data, options);
let gauge_chart = new google.visualization.Gauge(
document.getElementById('gauge_div')
);
gauge_chart.draw(gauge_data, options);
// ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฒฝ๋ก
var dbPath = 'room1';
// ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐธ์กฐ
var dbRef = firebase.database().ref(dbPath);
// ํ์ํ ์ต๋ ๋ฐ์ดํฐ ํ ์
let maxDatas = 50;
// ์ต์ ์ธก์ ๊ฐ ๊ฐ์ ธ์์ ์ฐจํธ์ ํ์ (ํ์๋๋ ์ธก์ ๊ฐ ์๋ chartRange ๊ฐ์ ํด๋น)
dbRef.orderByKey().limitToLast(maxDatas).on('child_added', snapshot =>{
var jsonData = snapshot.toJSON(); // ์: {lightsensor: 2502, timestamp:1641317355}
// ๊ฐ ์ ์ฅ
var lightsensor = Number(jsonData.lightsensor);
var timestamp = epochToDateTime(jsonData.timestamp);
// ์ฐจํธ์ ๊ฐ ํ์
if (data.getNumberOfRows() > maxDatas) {
data.removeRows(0, data.getNumberOfRows() - maxDatas);
}
data.addRow([timestamp, lightsensor]);
chart.draw(data, options);
gauge_data.setValue(0, 0, lightsensor);
gauge_chart.draw(gauge_data, options);
});
}
// ์ํฌํฌ Time์ JavaScript Date ๊ฐ์ฒด๋ก ๋ณํ
function epochToJsDate(epochTime){
return new Date(epochTime*1000);
}
// Time์ ์ฌ๋์ด ์ฝ์ ์ ์๋ ํ์ (HH:MM)์ผ๋ก ๋ณํ
function epochToDateTime(epochTime) {
var epochDate = new Date(epochToJsDate(epochTime));
var dateTime =
("00" + epochDate.getHours()).slice(-2) +
":" +
("00" + epochDate.getMinutes()).slice(-2);
return dateTime;
}
</script>
</body>
</html>
- ์ค์ต ๊ฒฐ๊ณผ
- ์ค์๊ฐ์ผ๋ก ๋ณํํ๋ ๋ฐ์ดํฐ ๊ทธ๋ํ(๋ฐ์ดํฐ ๋ถ์ ๊ธฐ๋ฅ ๊ตฌํ)
- ๋น์ ์ ๋๊ฐ ๊ฐ์ฅ ๋์๋ ์๊ฐ๊ณผ ์์น๊ฐ ํ์ธ ๊ฐ๋ฅ
- Firebase ์น ์ฑ์ url์ ํตํด ์กฐํ ๊ฐ๋ฅ
- https://firebase.google.com/docs/cli?hl=ko ์์ CLI ์ค์น ๋ฐ ํ๋กฌํํธ ์ฌ์ฉ
-
๋ช ๋ น์ด ์คํ ํ ํ๋ก์ ํธ ๋ฆฌ์คํธ ํ์ธ
-
๋ช ๋ น์ด ์คํ ํ ํ๋ก์ ํธ ๋ฐ hosting ์ค์
- ๋ช ๋ น์ด ์คํ ํ ์น ์ฑ ํธ์คํ ์์
- ์ค์ต ๊ฒฐ๊ณผ
- ๋ณต์ฌํ url์ ๋ธ๋ผ์ฐ์ ์ ์ ๋ ฅํ๋ฉด ์ค์๊ฐ์ผ๋ก ๋น ์ผ์ ๊ฐ์ ๋ชจ๋ํฐ๋ง ๊ฐ๋ฅ
- ์ ํ์ safari์์๋ ํ์ธ ๊ฐ๋ฅ
5-1. ํฌํ TR: ํฌํ ๋ค์ด์ค๋์ PN ์ ํฉ์ ๋ฒ ์ด์ค-์ด๋ฏธํฐ ์ ํฉ์ ์ด์ฉํ ํธ๋์ง์คํฐ๋ก ๋น์๋์ง๋ฅผ ์ ๊ธฐ์๋์ง๋ก ๋ณํ
- ๋น์ ์ธ๊ธฐ์ ๋ฐ๋ผ ํ๋ฅด๋ ์ ๋ฅ๊ฐ ๋ณํํ๋ ๊ด๊ธฐ์ ๋ ฅ ํจ๊ณผ๋ฅผ ์ด์ฉํจ
- ๊ด์ ๋ฅ๋ฅผ ํธ๋์ง์คํฐ๋ฅผ ์ด์ฉํ์ฌ ์ฆํญ์ํด
- pnpํ(๊ฒ๋ฅด๋ง๋ ์ฌ์ฉ), npnํ(์ค๋ฆฌ์ฝ ์ฌ์ฉ)
- ํฌํ TR์ ํฌํ ๋ค์ด์ค๋๋ณด๋ค ๋น์ ๋ ๋ฏผ๊ฐํ์ง๋ง ๋ฐ์ ์๋๋ ๋ ๋๋ฆผ
5-2. ํฌํ ๋ค์ด์ค๋: ๊ด๊ธฐ์ ๋ ฅ ํจ๊ณผํ ๋ค์ด์ค๋์ ์ธ๋ถํ๋ก๋ฅผ ์ ์ํ์ฌ ๋น์ ๋น์ถฐ ๊ด์ ๋ฅ๋ฅผ ๊บผ๋ด๋ ์ผ์
- ๊ด์ ํธ๋ฅผ ์ ๊ธฐ์ ํธ๋ก ๋ณํ
5-3. CDS: ์กฐ๋ ์ผ์(ํฉํ ์นด๋๋ฎด ๊ด์ผ์)์ด๋ฉฐ ๋น์ ์์ ๋ฐ๋ผ ์ ํญ๊ฐ์ด ๋ณํ(๋น์ ์ธ๊ธฐ๊ฐ ์
์๋ก ์ ํญ์ด ์์์ง)ํ๋ ๊ด ๊ฐ๋ณ์ ํญ
- ๊ด์ผ์ ์ค ๊ฐ์ฅ ๊ฐ๋จํ๊ณ ์ ๋ ดํ์ฌ ์ผ์์ํ์ ๋ง์ด ์ฐ์