Connections
Sensor connections to the board can be made with a I2C quick connection. One connection from the ESP32 Feather board to the BME 680 sensor. The I2C connection is passed through the BME 680 at which point connect the other I2C connector to the SI1145.

Arduino Sketch
/*
Ryan Kurasaki
Communciation with a Firebase database in this software was adapted from example code from Random Nerd Tutorials. See below.
Rui Santos
Complete project details at our blog: https://RandomNerdTutorials.com/esp32-data-logging-firebase-realtime-database/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <Adafruit_BME680.h>
#include <bme68x.h>
#include <bme68x_defs.h>
#include <Arduino.h>
#include <WiFi.h>
#include <Firebase_ESP_Client.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_SI1145.h"
#include "time.h"
Adafruit_SI1145 uv = Adafruit_SI1145();
byte Hawaii_day;
byte Hawaii_month;
int Hawaii_year;
int Hawaii_min;
int Hawaii_sec;
int Hawaii_hour;
const long gmtOffset_sec = -36000; //Hawaii is 10 hour behind on GMT
const int daylightOffset_sec = 0; // Hawaii DST offset is zero between spring and winter
// Provide the token generation process info.
#include "addons/TokenHelper.h"
// Provide the RTDB payload printing info and other helper functions.
#include "addons/RTDBHelper.h"
//// Insert your network credentials
#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "PASSWORD"
// Insert Firebase project API Key
#define API_KEY "AIzaSyDTSq0beE3OilNvo3OxioCsNhXvI1Cv99s"
// Insert Authorized Email and Corresponding Password
#define USER_EMAIL "EMAIL"
#define USER_PASSWORD "PASSWORD"
// Insert RTDB URLefine the RTDB URL
#define DATABASE_URL "https://indoor-environment-39280-default-rtdb.firebaseio.com"
// Define Firebase objects
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
// Variable to save USER UID
String uid;
// Database main path (to be updated in setup with the user UID)
String databasePath;
// Database child nodes
String locPath = "/area";
String tempPath = "/temperature";
String humPath = "/humidity";
String presPath = "/pressure";
String visPath = "/visible";
String irPath = "/infrared";
String uviPath = "/ultraviolet";
String timePath = "/timestamp";
// Parent Node (to be updated in every loop)
String parentPath;
int timestamp;
FirebaseJson json;
const char* ntpServer = "ntp.hawaii.edu";
// BME280 sensor
Adafruit_BME680 bme; // I2C
float temperature;
float humidity;
float pressure;
// Timer variables (send new readings every three minutes)
unsigned long sendDataPrevMillis = 0;
unsigned long timerDelay = 3600000;
// Initialize BME680
void initBME() {
if (!bme.begin()) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
// Initialize WiFi
void initWiFi() {
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
Serial.println();
}
// Function that gets current epoch time
unsigned long getTime() {
time_t now;
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
//Serial.println("Failed to obtain time");
return (0);
}
time(&now);
return now;
}
//Time Function to GET LOCAL TIME FROM NTP SERVER
struct tm LocalTime(int &Hawaii_hour)
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
}
//Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
Hawaii_day = timeinfo.tm_mday;
Hawaii_month = timeinfo.tm_mon + 1;
Hawaii_year = timeinfo.tm_year + 1900;
Hawaii_hour = timeinfo.tm_hour;
Hawaii_min = timeinfo.tm_min;
Hawaii_sec = timeinfo.tm_sec;
// Serial.println(Hawaii_day);
// Serial.println(Hawaii_month);
// Serial.println(Hawaii_year);
// Serial.println(Hawaii_hour);
// Serial.println(Hawaii_min);
// Serial.println(Hawaii_sec);
return timeinfo;
}
void setup() {
Serial.begin(115200);
// Initialize BME280 sensor
initBME();
if (! uv.begin()) {
Serial.println("Didn't find Si1145");
while (1);
}
initWiFi();
configTime(0, 0, ntpServer);
// Assign the api key (required)
config.api_key = API_KEY;
// Assign the user sign in credentials
auth.user.email = USER_EMAIL;
auth.user.password = USER_PASSWORD;
// Assign the RTDB URL (required)
config.database_url = DATABASE_URL;
Firebase.reconnectWiFi(true);
fbdo.setResponseSize(4096);
// Assign the callback function for the long running token generation task */
config.token_status_callback = tokenStatusCallback; //see addons/TokenHelper.h
// Assign the maximum retry of token generation
config.max_token_generation_retry = 5;
// Initialize the library with the Firebase authen and config
Firebase.begin(&config, &auth);
// Getting the user UID might take a few seconds
Serial.println("Getting User UID");
while ((auth.token.uid) == "") {
Serial.print('.');
delay(1000);
}
// Print user UID
uid = auth.token.uid.c_str();
Serial.print("User UID: ");
Serial.println(uid);
// Update database path
databasePath = "/UsersData/" + uid + "/readings 113";
}
void loop() {
// Send new readings to database
if (Firebase.ready() && (millis() - sendDataPrevMillis > timerDelay || sendDataPrevMillis == 0)) {
Serial.println (millis() - sendDataPrevMillis);
sendDataPrevMillis = millis();
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
}
//Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
Hawaii_day = timeinfo.tm_mday;
Hawaii_month = timeinfo.tm_mon + 1;
Hawaii_year = timeinfo.tm_year + 1900;
Hawaii_hour = timeinfo.tm_hour;
Hawaii_min = timeinfo.tm_min;
Hawaii_sec = timeinfo.tm_sec;
int z = 0;
float temp = 0;
float humidity = 0;
float pressure = 0;
float vis = 0;
float ir = 0;
float uvi = 0;
while (z < 100)
{
temp = temp + bme.readTemperature();
humidity = humidity + bme.readHumidity();
pressure = pressure + bme.readPressure() / 100.0F;
vis = vis + uv.readVisible();
ir = ir + uv.readIR();
uvi = uvi + uv.readUV();
z = z + 1;
}
temp = temp / 100;
humidity = humidity / 100;
pressure = pressure / 100;
vis = vis /100;
ir = ir / 100;
uvi = uvi / 100 /100;
timestamp=getTime();
parentPath = databasePath + "/" + String(timestamp);
json.set(locPath.c_str(), String(113));
json.set(timePath, String(timestamp));
json.set(tempPath.c_str(), String(temp));
json.set(humPath.c_str(), String(humidity));
json.set(presPath.c_str(), String(pressure));
json.set(visPath.c_str(), String(vis));
json.set(irPath.c_str(), String(ir));
json.set(uviPath.c_str(), String(uvi));
Serial.printf("Set json... %s\n", Firebase.RTDB.setJSON(&fbdo, parentPath.c_str(), &json) ? "ok" : fbdo.errorReason().c_str());
}
}