in below code, it update gps location to firebase RTDB and alertStatus. and recorded audio is uploading to firebase storage.
im using
ESP32 devkitV1 board
NEO6M MODULE
INMP441 MIC
BUTTON
I have connected neo 6m, INMP441 and the button to esp32 board. I have seperately checked each one and those are working fine. then i merge all code together
code is working fine there is no errors in this code. but when i press button to start recording and after finish recording, upload to firebase,, while it recording it say no more free storage.
so what i did is format SPIFFS and LITTLEFS and again upload my full code. then it showing failed to mount LIttleFS .. so how i can fix this issue. im not using SD card for keep audio files. note- im using .raw type to store audio data. then my android app, im convert it to .wav and play in my app. and after file upload to firebase, i clear the SPIFFS also.
how i can fix this issue
Connecting to Wi-Fi...
Connected to Wi-Fi!
E (406) esp_littlefs: ./managed_components/joltwallet__littlefs/src/littlefs/lfs.c:1369:error: Corrupted dir pair at {0x0, 0x1}
E (410) esp_littlefs: mount failed, (-84)
E (414) esp_littlefs: Failed to initialize LittleFS
LittleFS initialization failed!
#include <driver/i2s.h>
#include <WiFi.h>
#include <Firebase_ESP_Client.h>
#include <WiFiClientSecure.h>
#include <LittleFS.h> // Include LittleFS instead of SPIFFS
#include <Preferences.h> // Include Preferences library
#include <Arduino.h>
#include <TinyGPS++.h>
// Firebase configuration
#include "addons/TokenHelper.h"
#include "addons/RTDBHelper.h"
// I2S configuration for recording
#define I2S_WS 25
#define I2S_SD 33
#define I2S_SCK 32
#define I2S_PORT I2S_NUM_0
#define I2S_SAMPLE_RATE (16000)
#define I2S_SAMPLE_BITS (16)
#define I2S_READ_LEN (16 * 1024)
#define RECORD_TIME (20) // Seconds
#define I2S_CHANNEL_NUM (1)
#define FLASH_RECORD_SIZE (I2S_CHANNEL_NUM * I2S_SAMPLE_RATE * I2S_SAMPLE_BITS / 8 * RECORD_TIME)
// Wi-Fi and Firebase configurations
#define WIFI_SSID "Chamika"
#define WIFI_PASSWORD "24682468"
#define API_KEY "*******"
#define USER_EMAIL "*******"
#define USER_PASSWORD "*******"
#define STORAGE_BUCKET_ID "*******"
#define DATABASE_URL "*******"
// Define the push button pin
#define BUTTON_PIN 23
File file;
char filename[50]; // To store dynamically generated filename
// Create object for HardwareSerial and GPS
HardwareSerial GPS_Serial(2); // (Rx, Tx)
TinyGPSPlus gps;
// Firebase objects
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
Preferences preferences; // Create Preferences object
// File counter
int fileCounter; // Declare fileCounter
// Task flags
bool recordingComplete = false;
bool taskCompleted = false;
unsigned long sendDataPrevMillis = 0;
bool signupOK = false;
int buttonState = 0;
// Function prototypes
void LittleFSInit();
void i2sInit();
void i2s_adc(void* arg);
void uploadToFirebase();
bool fileExists(const char* path);
void generateNewFileName();
void clearLittleFS();
void setup() {
Serial.begin(115200);
GPS_Serial.begin(9600, SERIAL_8N1, 16, 17); // Use pins 16 and 17 for RX and TX
// Set up the push button pin
pinMode(BUTTON_PIN, INPUT_PULLUP);
preferences.begin("counter", false); // Open preferences with the namespace "counter"
// Retrieve the counter from preferences (default to 1 if not set)
fileCounter = preferences.getInt("fileCounter", 1);
Serial.printf("Starting with fileCounter: %d\n", fileCounter);
// Initialize Wi-Fi connection
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(300);
Serial.println("Connecting to Wi-Fi...");
}
Serial.println("Connected to Wi-Fi!");
// Initialize LittleFS
LittleFSInit();
// Initialize Firebase
config.api_key = API_KEY;
config.database_url = DATABASE_URL;
// Sign up for Firebase
if (Firebase.signUp(&config, &auth, "", "")) {
Serial.println("Firebase signup successful");
signupOK = true;
} else {
Serial.printf("Firebase signup failed: %s\n", config.signer.signupError.message.c_str());
}
// Token status callback function
config.token_status_callback = tokenStatusCallback;
Firebase.begin(&config, &auth);
Firebase.reconnectWiFi(true);
}
void loop() {
smartDelay(1000); // Handle GPS communication
if (Firebase.ready() && signupOK && (millis() - sendDataPrevMillis > 5000 || sendDataPrevMillis == 0)) {
sendDataPrevMillis = millis();
if (gps.location.isValid()) {
double latitude = gps.location.lat();
double longitude = gps.location.lng();
double altitude = gps.altitude.meters();
// Send latitude to Firebase
if (Firebase.RTDB.setFloat(&fbdo, "/gps/latitude", latitude)) {
} else {
Serial.println("Failed to update latitude.");
Serial.println(fbdo.errorReason());
}
// Send longitude to Firebase
if (Firebase.RTDB.setFloat(&fbdo, "/gps/longitude", longitude)) {
} else {
Serial.println("Failed to update longitude.");
Serial.println(fbdo.errorReason());
}
// Send altitude to Firebase
if (Firebase.RTDB.setFloat(&fbdo, "/gps/altitude", altitude)) {
} else {
Serial.println("Failed to update altitude.");
Serial.println(fbdo.errorReason());
}
} else {
Serial.println("Invalid GPS data");
}
}
// Handle push button state and update Firebase
if (Firebase.ready() && signupOK) {
buttonState = digitalRead(BUTTON_PIN);
if (buttonState == LOW) { // Button pressed
if (Firebase.RTDB.setInt(&fbdo, "/alertStatus", 1)) {
Serial.println("Button pressed! Alert sent to Firebase.");
// Initialize I2S and start recording task
i2sInit();
xTaskCreate(i2s_adc, "i2s_adc", 1024 * 4, NULL, 1, NULL);
if (Firebase.ready() && recordingComplete && !taskCompleted) {
taskCompleted = true;
if (fileExists(filename)) {
uploadToFirebase();
} else {
Serial.println("File not found, cannot upload.");
}
}
} else {
Serial.println("Failed to write to Firebase");
Serial.println(fbdo.errorReason());
}
} else { // Button not pressed
if (Firebase.RTDB.setInt(&fbdo, "/alertStatus", 0)) {
// Serial.println("No alert. Button not pressed.");
} else {
Serial.println("Failed to write to Firebase");
Serial.println(fbdo.errorReason());
}
}
// Small delay to avoid flooding Firebase
delay(500);
}
}
static void smartDelay(unsigned long ms) {
unsigned long start = millis();
do {
while (GPS_Serial.available()) {
gps.encode(GPS_Serial.read());
}
} while (millis() - start < ms);
}
void LittleFSInit() {
if (!LittleFS.begin()) { // Initialize LittleFS
Serial.println("LittleFS initialization failed!");
while (1) yield();
}
// Generate a new filename for the current recording
generateNewFileName();
file = LittleFS.open(filename, FILE_WRITE);
if (!file) {
Serial.println("File creation failed!");
while (1) yield();
}
Serial.println("LittleFS initialized and file opened.");
}
void generateNewFileName() {
int fileNumber = 1;
// Check if the counter file exists in LittleFS
if (LittleFS.exists("/fileCounter.txt")) {
File counterFile = LittleFS.open("/fileCounter.txt", FILE_READ);
fileNumber = counterFile.parseInt();
counterFile.close();
}
// Create a new filename using the file number
sprintf(filename, "/guardianRecord%d.raw", fileNumber);
// Increment and save the new file number back to LittleFS
File counterFile = LittleFS.open("/fileCounter.txt", FILE_WRITE);
counterFile.printf("%d", fileNumber + 1);
counterFile.close();
Serial.printf("New file name generated: %s\n", filename);
}
void i2sInit() {
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = I2S_SAMPLE_RATE,
.bits_per_sample = i2s_bits_per_sample_t(I2S_SAMPLE_BITS),
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = 0,
.dma_buf_count = 16,
.dma_buf_len = 1024,
.use_apll = 1
};
i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
const i2s_pin_config_t pin_config = {
.bck_io_num = I2S_SCK,
.ws_io_num = I2S_WS,
.data_out_num = -1,
.data_in_num = I2S_SD
};
i2s_set_pin(I2S_PORT, &pin_config);
}
void i2s_adc(void* arg) {
int i2s_read_len = I2S_READ_LEN;
int flash_wr_size = 0;
size_t bytes_read;
char* i2s_read_buff = (char*)calloc(i2s_read_len, sizeof(char));
while (flash_wr_size < FLASH_RECORD_SIZE) {
i2s_read(I2S_PORT, (void*)i2s_read_buff, i2s_read_len, &bytes_read, portMAX_DELAY);
file.write((const unsigned char*)i2s_read_buff, bytes_read);
flash_wr_size += bytes_read;
Serial.printf("Recording %d%%\n", flash_wr_size * 100 / FLASH_RECORD_SIZE);
}
file.close();
free(i2s_read_buff);
Serial.println("Recording complete");
recordingComplete = true;
i2s_driver_uninstall(I2S_PORT);
vTaskDelete(NULL);
}
void uploadToFirebase() {
String uploadPath = "/audio/guardianRecord" + String(fileCounter) + ".raw";
Firebase.Storage.upload(&fbdo, STORAGE_BUCKET_ID, filename, mem_storage_type_flash, uploadPath.c_str(), "audio/raw");
if (fbdo.httpCode() == FIREBASE_ERROR_HTTP_CODE_OK) {
Serial.println("Upload successful!");
// Increment file counter and save to preferences
fileCounter++;
preferences.putInt("fileCounter", fileCounter);
// Clear LittleFS after successful upload
clearLittleFS();
} else {
Serial.printf("Failed to upload file, reason: %s\n", fbdo.errorReason().c_str());
}
}
bool fileExists(const char* path) {
return LittleFS.exists(path);
}
void clearLittleFS() {
LittleFS.remove(filename);
Serial.println("LittleFS cleared.");
}