Connect Hardware

Instructions and status for connecting your ESP32 sensor rig.

Connecting Your ESP32 Sensors (Authenticated)
This is the most secure and reliable method. The ESP32 signs in and sends data directly to the database.

Important First Steps

  1. Go to the Firebase Console -> Authentication -> Sign-in method, and **enable the Email/Password provider**.
  2. Go to the Users tab and **add a new user**. Use an email like `device-user@example.com` and a secure password.
  3. Update the `USER_PASSWORD` in the sketch below with the password you just created.

Arduino Library Setup

Before uploading, you must install these libraries in the Arduino IDE Library Manager.

  1. Firebase ESP Client by Mobizt
  2. SparkFun VL53L5CX by SparkFun Electronics

Wi-Fi Credentials

Update the sketch with your Wi-Fi credentials.

  • Update the `WIFI_SSID` and `WIFI_PASSWORD` in the sketch.

Complete Arduino Sketch

Copy this code into the Arduino IDE, update your Wi-Fi and user password, and upload it to your ESP32.

/*
  SensorFusion3D_ESP32_Firebase_Auth_Buzzer.ino
*/

#include <Arduino.h>
#include <WiFi.h>
#include <Wire.h>
#include "SparkFun_VL53L5CX_Library.h"

#include <Firebase_ESP_Client.h>
#include <addons/TokenHelper.h>

// ====================== WIFI ======================
#define WIFI_SSID       "YOUR_WIFI_SSID"
#define WIFI_PASSWORD   "YOUR_WIFI_PASSWORD"

// ====================== FIREBASE ======================
#define API_KEY       "AIzaSyBw7bumF5bM8LwQBBfhoaXNjBUhyk5uxxw"
#define DATABASE_URL  "https://sensorfusion3d-default-rtdb.europe-west1.firebasedatabase.app"

#define USER_EMAIL    "device-user@example.com"
#define USER_PASSWORD "YOUR_REAL_USER_PASSWORD"

// ====================== HARDWARE ======================
#define SDA_PIN 21
#define SCL_PIN 22
#define TCA_ADDR 0x70

#define BUZZER_PIN 12

// ====================== SENSORS ======================
const int NUM_SENSORS = 3;
const uint8_t SENSOR_CHANNELS[NUM_SENSORS] = {0, 1, 2};
const char* SENSOR_IDS[NUM_SENSORS] = {
  "frontSensor",
  "leftSensor",
  "rightSensor"
};

#define SENSOR_READ_INTERVAL 1000
#define TCA_SELECT_DELAY 15

// ====================== FIREBASE OBJECTS ======================
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;

// ====================== SENSOR OBJECTS ======================
SparkFun_VL53L5CX sensor0, sensor1, sensor2;
SparkFun_VL53L5CX* sensors[NUM_SENSORS] = { &sensor0, &sensor1, &sensor2 };

bool sensorOK[NUM_SENSORS] = {false};

// ====================== TCA SELECT ======================
bool safeTCASelect(uint8_t channel) {
  if (channel > 7) return false;

  Wire.beginTransmission(TCA_ADDR);
  Wire.write(1 << channel);

  if (Wire.endTransmission() != 0) {
    Serial.printf("❌ TCA select failed (ch %d)\n", channel);
    return false;
  }

  delay(TCA_SELECT_DELAY);
  return true;
}

// ====================== SENSOR INIT ======================
void initSensor(int idx) {
  if (!safeTCASelect(SENSOR_CHANNELS[idx])) return;

  if (sensors[idx]->begin()) {
    sensors[idx]->setResolution(64);
    sensors[idx]->startRanging();
    sensorOK[idx] = true;
    Serial.printf("✅ Sensor %d ready\n", idx);
  } else {
    Serial.printf("❌ Sensor %d not found\n", idx);
  }
}

// ====================== SETUP ======================
void setup() {
  Serial.begin(115200);
  delay(100);

  pinMode(BUZZER_PIN, OUTPUT);
  digitalWrite(BUZZER_PIN, LOW);

  Wire.begin(SDA_PIN, SCL_PIN);

  Serial.println("\nStarting ESP32 SensorFusion + Firebase + Buzzer");

  // ---- WIFI ----
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(300);
  }
  Serial.println("\nWiFi connected");

  // ---- FIREBASE ----
  config.api_key = API_KEY;
  config.database_url = DATABASE_URL;

  auth.user.email = USER_EMAIL;
  auth.user.password = USER_PASSWORD;

  config.token_status_callback = tokenStatusCallback;

  Firebase.reconnectWiFi(true);
  fbdo.setResponseSize(4096);

  Firebase.begin(&config, &auth);

  // ---- SENSORS ----
  for (int i = 0; i < NUM_SENSORS; i++) {
    initSensor(i);
  }

  Serial.println("✅ System ready");
}

// ====================== LOOP ======================
void loop() {
  static unsigned long lastRead = 0;

  if (!Firebase.ready()) return;

  // ===== BUZZER CONTROL =====
  if (Firebase.RTDB.getBool(&fbdo, "/control/buzzer")) {
    bool buzzerState = fbdo.boolData();
    digitalWrite(BUZZER_PIN, buzzerState ? HIGH : LOW);
  }

  // ===== SENSOR DATA =====
  if (millis() - lastRead < SENSOR_READ_INTERVAL) return;
  lastRead = millis();

  for (int i = 0; i < NUM_SENSORS; i++) {
    if (!sensorOK[i]) continue;
    if (!safeTCASelect(SENSOR_CHANNELS[i])) continue;

    VL53L5CX_ResultsData data;
    if (!sensors[i]->isDataReady()) continue;
    if (!sensors[i]->getRangingData(&data)) continue;

    FirebaseJson json;
    json.set("id", SENSOR_IDS[i]); // Add id field for compatibility with frontend
    json.set("sensorId", SENSOR_IDS[i]);
    json.set("timestamp", (unsigned long)millis());

    FirebaseJsonArray matrix;
    for (int y = 0; y < 8; y++) {
      FirebaseJsonArray row;
      for (int x = 0; x < 8; x++) {
        row.add(data.distance_mm[y * 8 + x]);
      }
      matrix.add(row);
    }
    json.set("matrix", matrix);

    String path = "/sensors/";
    path += SENSOR_IDS[i];

    if (Firebase.RTDB.setJSON(&fbdo, path.c_str(), &json)) {
      Serial.printf("📡 %s sent\n", SENSOR_IDS[i]);
    } else {
      Serial.println(fbdo.errorReason());
    }
  }
}
Sensor Status
Real-time connection status of your sensors. This card will update automatically when data is received from the database.
Front SensorLast update: N/A
Disconnected
Left SensorLast update: N/A
Disconnected
Right SensorLast update: N/A
Disconnected