#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include "driver/i2s.h"
#include "Base64.h"
// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Databricks workspace URL
const char* databricksEndpoint = "https://dbc-.cloud.databricks.com";
const char* databricksToken = "dapi";
// I2S Microphone Configuration
#define I2S_MIC_CHANNEL I2S_CHANNEL_FMT_ONLY_LEFT
#define SAMPLE_RATE 16000
#define I2S_MIC_PIN_BCK 26
#define I2S_MIC_PIN_WS 25
#define I2S_MIC_PIN_DATA 27
#define BUFFER_SIZE 1024
// LCD display
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Function prototypes
void initI2SMicrophone();
String recordAudio();
String createDirectoryIfNotExists(String path);
String sendAudioToDatabricks(String audioData);
void setup() {
Serial.begin(115200);
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Motor Monitor");
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
lcd.setCursor(0, 1);
lcd.print("Connecting WiFi...");
}
Serial.println("Connected to WiFi");
lcd.setCursor(0, 1);
lcd.print("WiFi Connected ");
// Initialize I2S
initI2SMicrophone();
lcd.setCursor(0, 2);
lcd.print("Mic Initialized");
}
void loop() {
lcd.setCursor(0, 3);
lcd.print("Recording...");
String audioData = recordAudio();
lcd.setCursor(0, 3);
lcd.print("Sending to Databricks...");
String response = sendAudioToDatabricks(audioData);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Status:");
lcd.setCursor(0, 1);
lcd.print(response);
delay(10000); // Wait 10 seconds before the next recording
}
void initI2SMicrophone() {
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 8,
.dma_buf_len = 512,
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0
};
i2s_pin_config_t pin_config = {
.bck_io_num = I2S_MIC_PIN_BCK,
.ws_io_num = I2S_MIC_PIN_WS,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = I2S_MIC_PIN_DATA
};
// Install I2S driver
esp_err_t err = i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
if (err != ESP_OK) {
Serial.println("Failed to install I2S driver: " + String(err));
}
// Set I2S pins
err = i2s_set_pin(I2S_NUM_0, &pin_config);
if (err != ESP_OK) {
Serial.println("Failed to set I2S pins: " + String(err));
}
// Set clock
err = i2s_set_clk(I2S_NUM_0, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_32BIT, I2S_CHANNEL_MONO);
if (err != ESP_OK) {
Serial.println("Failed to set I2S clock: " + String(err));
}
i2s_zero_dma_buffer(I2S_NUM_0);
delay(500);
}
String recordAudio() {
int32_t samples[BUFFER_SIZE];
size_t bytesRead;
String audioData = "";
Serial.println("Start Recording...");
unsigned long startTime = millis();
while (millis() - startTime < 2000) { // Record for 2 seconds
esp_err_t res = i2s_read(I2S_NUM_0, &samples, BUFFER_SIZE * sizeof(int32_t), &bytesRead, pdMS_TO_TICKS(1000));
if (res == ESP_OK && bytesRead > 0) {
Serial.println("Bytes read: " + String(bytesRead));
int samplesRead = bytesRead / sizeof(int32_t);
for (int i = 0; i < samplesRead; i++) {
// Convert to 16-bit by shifting right 16 bits
int16_t sample = samples[i] >> 16;
audioData += String(sample) + ",";
}
} else if (res == ESP_ERR_TIMEOUT) {
Serial.println("I2S Read timeout.");
} else {
Serial.println("I2S Read failed: " + String(res));
}
}
Serial.println("Recording Completed.");
return audioData;
}
String createDirectoryIfNotExists(String path) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String endpoint = String(databricksEndpoint) + "/api/2.0/dbfs/create";
http.begin(endpoint);
http.addHeader("Authorization", "Bearer " + String(databricksToken));
http.addHeader("Content-Type", "application/json");
String payload = "{\"path\": \"" + path + "\"}";
int httpResponseCode = http.POST(payload);
if (httpResponseCode == 200) {
String response = http.getString();
Serial.println("Directory created or already exists: " + response);
} else {
String errorResponse = http.getString();
Serial.println("Error creating directory: " + String(httpResponseCode));
Serial.println("Error response: " + errorResponse);
}
http.end();
}
}
String sendAudioToDatabricks(String audioData) {
// Create directory if it doesn't exist
createDirectoryIfNotExists("/databricks-datasets/motor_monitoring");
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String endpoint = String(databricksEndpoint) + "/api/2.0/dbfs/put";
http.begin(endpoint);
http.addHeader("Authorization", "Bearer " + String(databricksToken));
http.addHeader("Content-Type", "application/json");
String path = "/databricks-datasets/motor_monitoring/motor_" + String(millis()) + ".txt";
String payload = "{\"path\": \"" + path + "\", \"contents\": \"" + audioData + "\", \"overwrite\": true}";
Serial.println("Sending to Databricks...");
int httpResponseCode = http.POST(payload);
if (httpResponseCode == 200) {
String response = http.getString();
Serial.println("Response: " + response);
return "File uploaded to: " + path;
} else {
String errorResponse = http.getString();
Serial.println("Error code: " + String(httpResponseCode));
Serial.println("Error response: " + errorResponse);
return "Error: " + String(httpResponseCode);
}
http.end();
} else {
Serial.println("WiFi not connected");
return "WiFi Error";
}
}