diff --git a/voice_assistant.ino b/voice_assistant.ino index 521dded..270bcbc 100644 --- a/voice_assistant.ino +++ b/voice_assistant.ino @@ -7,7 +7,6 @@ const char* WIFI_SSID = "Aussie Broadband 8729"; const char* WIFI_PASS = "WIFI_PASS_REDACTED"; -// POINT TO VOICE SERVER (Not Home Assistant) const char* MQTT_BROKER = "192.168.20.13"; const int MQTT_PORT = 1883; const char* MQTT_USER = "MQTT_USER_REDACTED"; @@ -21,17 +20,15 @@ const char* TOPIC_ACK = "voice/status"; #define I2S_WS 5 #define I2S_SD 6 #define I2S_PORT I2S_NUM_0 - -#define LED_PIN 5 +#define LED_PIN 48 #define NUM_LEDS 12 -// --- AUDIO TUNING --- -// Increased to 2000 to ignore footsteps/typing (Range is 0-32768) +// --- TUNING --- #define VAD_THRESHOLD 1000 const int BLOCK_SIZE = 512; int16_t sBuffer[BLOCK_SIZE]; -// ... (Rest of Objects/Config remains standard) ... +// --- OBJECTS --- WiFiClient espClient; PubSubClient mqtt(espClient); Freenove_ESP32_WS2812 strip(NUM_LEDS, LED_PIN, 0, TYPE_GRB); @@ -49,7 +46,7 @@ const i2s_config_t i2s_config = { .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, .dma_buf_count = 8, .dma_buf_len = 64, - .use_apll =true + .use_apll = true }; const i2s_pin_config_t pin_config = { @@ -59,19 +56,17 @@ const i2s_pin_config_t pin_config = { .data_in_num = I2S_SD }; -// ... (LED Helpers remain the same) ... void setRingColor(uint8_t r, uint8_t g, uint8_t b) { strip.setAllLedsColor(r, g, b); strip.show(); } + void updateLEDs() { if (currentState == STATE_ACK_RECEIVED) { - for (int j = 0; j < 255; j += 10) { + for (int j = 0; j < 255; j += 20) { for (int i = 0; i < NUM_LEDS; i++) { byte pos = (i * 256 / NUM_LEDS + j) & 255; - if(pos < 85) { strip.setLedColorData(i, pos * 3, 255 - pos * 3, 0); } - else if(pos < 170) { pos -= 85; strip.setLedColorData(i, 255 - pos * 3, 0, pos * 3); } - else { pos -= 170; strip.setLedColorData(i, 0, pos * 3, 255 - pos * 3); } + strip.setLedColorData(i, pos, 255-pos, 0); // Simple fast rainbow } strip.show(); delay(5); @@ -80,41 +75,72 @@ void updateLEDs() { setRingColor(0,0,0); } } + void mqttCallback(char* topic, byte* payload, unsigned int length) { - // If Bridge sends a "WAKE" or "OK" message + Serial.print("MSG Recv: "); Serial.println(topic); currentState = STATE_ACK_RECEIVED; } void setup() { - delay(2000); + delay(3000); // Wait for Serial Serial.begin(115200); + Serial.println("\n\n=== BOOTING DEBUG MODE ==="); - // High Buffer for Audio - mqtt.setBufferSize(2048); - + // 1. LEDs strip.begin(); strip.setBrightness(30); - setRingColor(50, 50, 50); + setRingColor(50, 50, 50); // White + Serial.println("1. LEDs Ready"); - i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL); - i2s_set_pin(I2S_PORT, &pin_config); - - WiFi.begin(WIFI_SSID, WIFI_PASS); - while (WiFi.status() != WL_CONNECTED) { - delay(500); - setRingColor(0, 0, 255); delay(100); setRingColor(0,0,0); + // 2. I2S + if (i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL) != ESP_OK) { + Serial.println("ERR: I2S Driver Fail"); + } else { + i2s_set_pin(I2S_PORT, &pin_config); + Serial.println("2. I2S Ready"); } + // 3. WiFi + Serial.print("3. WiFi Connecting: "); + Serial.println(WIFI_SSID); + WiFi.begin(WIFI_SSID, WIFI_PASS); + + int wifi_timeout = 0; + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + setRingColor(0, 0, 255); delay(100); setRingColor(0,0,0); + wifi_timeout++; + if(wifi_timeout > 20) { + Serial.println("\nERR: WiFi Timeout! Checking Creds..."); + wifi_timeout = 0; // Keep trying or reset? + } + } + Serial.print("\n WiFi Connected! IP: "); + Serial.println(WiFi.localIP()); + + // 4. MQTT mqtt.setServer(MQTT_BROKER, MQTT_PORT); mqtt.setCallback(mqttCallback); + mqtt.setBufferSize(2048); // Vital for audio + Serial.println("4. MQTT Configured"); setRingColor(0,0,0); + Serial.println("=== SYSTEM READY ==="); } void loop() { + // MQTT Reconnect Handler if (!mqtt.connected()) { + Serial.print("MQTT Connecting to "); Serial.print(MQTT_BROKER); Serial.print(" ... "); if (mqtt.connect("ESP32Mic", MQTT_USER, MQTT_PASS)) { + Serial.println("CONNECTED"); mqtt.subscribe(TOPIC_ACK); + setRingColor(0, 255, 0); delay(500); setRingColor(0,0,0); // Flash Green on Connect + } else { + Serial.print("FAIL rc="); Serial.println(mqtt.state()); + delay(2000); + return; } } mqtt.loop(); @@ -123,7 +149,7 @@ void loop() { size_t bytesRead; i2s_read(I2S_PORT, &sBuffer, sizeof(sBuffer), &bytesRead, portMAX_DELAY); - // --- GAIN BOOST (x8) --- + // Gain Boost (x6) for (int i = 0; i < bytesRead / 2; i++) { int32_t boosted = sBuffer[i] * 6; if (boosted > 32767) boosted = 32767; @@ -137,13 +163,17 @@ void loop() { } int avg = sum / (bytesRead / 2); - // Debug (View this to tune threshold) + // Uncomment to debug sensitivity // Serial.printf("Vol: %d\n", avg); + // Trigger Logic if (currentState == STATE_IDLE && avg > VAD_THRESHOLD) { + Serial.println("TRIGGERED"); currentState = STATE_RECORDING; stateTimer = millis(); setRingColor(0, 255, 0); // Green + + // START OF SENTENCE FIX: Send the trigger buffer immediately mqtt.publish(TOPIC_AUDIO, (const uint8_t*)sBuffer, bytesRead); } @@ -152,16 +182,16 @@ void loop() { if (avg > VAD_THRESHOLD) stateTimer = millis(); - // Silence Timeout (1.5s) if (millis() - stateTimer > 1500) { + Serial.println("SILENCE DETECTED"); currentState = STATE_TRANSMITTING; - // Send marker to Voice Server mqtt.publish("voice/status", "processing"); setRingColor(0, 0, 255); // Blue } } if (currentState == STATE_TRANSMITTING && millis() - stateTimer > 4000) { + Serial.println("TIMEOUT WAIT"); currentState = STATE_IDLE; setRingColor(0,0,0); }