Pular para o conteúdo principal

Primeiros Passos com o Módulo de Detecção de Eventos Sonoros

Introdução

Uma placa de áudio de borda compacta fornece detecção de som em tempo real com forte proteção de privacidade de dados locais. Ela detecta cinco eventos sonoros anormais — choro de bebê, quebra de vidro, disparo de arma de fogo, alarmes T3/T4 e ronco — possibilitando resposta imediata e aviso prévio confiável. Projetada para integração nativa com ESPHome, com compatibilidade perfeita com Home Assistant usando a série XIAO, é ideal para monitoramento de segurança residencial ou acionadores de automação responsivos.

pir

Especificações

RecursoDescrição
Chip PrincipalXMOS XU316-1024-QF60BC24
Eventos SuportadosChoro de bebê / Quebra de vidro / Disparo de arma de fogo / Alarme de fumaça e Alarme de CO (T3/T4) / Ronco
Microfones DigitaisMicrofones digitais de alto desempenho × 1
Sensibilidade-26 dBFS
Ponto de Sobrecarga Acústica120 dBL
SNR64 dBA
AlimentaçãoUSB 5V, 5V externo
Dimensões40 × 20 mm
Temperatura de Operação0℃ – 65℃

Visão Geral de Hardware e Dimensões

Vista Frontal

pir

Vista Traseira

pir

Uso via USB

Este dispositivo pode operar em modo autônomo e suporta comunicação plug-and-play através da interface USB usando comandos AT.

Primeiro, conecte o dispositivo ao seu computador usando um cabo USB Tipo-C para USB Tipo-A.

  • Passo 1 :Em seguida, abra o PuTTY ou qualquer outro software de terminal serial. Se você ainda não instalou um, pode baixar o PuTTY no seguinte link:

  • Passo 2 :Depois de abrir o terminal serial, selecione a porta COM correta e ajuste a taxa de transmissão para 115200. Após a conexão, você poderá interagir com o dispositivo através da interface USB.

pir

Como o dispositivo escuta continuamente eventos sonoros, você pode testá-lo gerando eventos sonoros suportados próximo ao dispositivo.

pir

Além disso, você pode ajustar os parâmetros do dispositivo usando comandos AT. Abaixo estão alguns comandos que você pode usar para interagir com o dispositivo.

ComandoDescriçãoExemplo
AT+GETDETECTObter os tipos de detecção atualmente habilitados (1–5 tipos).AT+GETDETECT+GETDETECT:baby_cry,glass_break
AT+SETDETECT=<types>Definir os tipos de eventos a serem detectados (separados por vírgula, máximo de 5).AT+SETDETECT=baby_cry,snore
AT+GETEVENTTHRESHOLD=<type>Obter o limite de confiança para um evento específico.AT+GETEVENTTHRESHOLD=baby_cry+GETEVENTTHRESHOLD:baby_cry,70
AT+SETEVENTTHRESHOLD=<type>,<val>Definir o limite de confiança para um evento específico.AT+SETEVENTTHRESHOLD=baby_cry,75
AT+GETSUPPORTEDLISTListar todos os tipos de eventos suportados pelo dispositivo.AT+GETSUPPORTEDLIST+GETSUPPORTEDLIST:doorbell,glass_break,baby_cry,...
AT+SETOUTPUTTYPE=<type>Definir o que é enviado quando um evento é detectado.AT+SETOUTPUTTYPE=highest_confidence
AT+GETINTMODEObter o modo de interrupção atual.AT+GETINTMODE+GETINTMODE:single
AT+SETINTMODE=<mode>Definir o modo de operação da interrupção.AT+SETINTMODE=continuous
AT+RESETINTRedefinir o status da interrupção e colocar o pino INT_N em nível ALTO.AT+RESETINT
AT+SAVECONFIGSalvar a configuração atual para que persista após reiniciar.AT+SAVECONFIG
AT+GETFWVERSIONObter a string da versão do firmware.AT+GETFWVERSION+GETFWVERSION:1.0.2
AT+RESETRestaurar as configurações padrão e reiniciar o dispositivo (apaga toda a configuração personalizada).AT+RESET

Quando um evento é detectado, o dispositivo envia automaticamente:

+EVENT: <event_id>,<confidence>

Exemplo: +EVENT: 1,87 → ID de evento 1 (baby_cry), 87% de confiança


AT+SETOUTPUTTYPE valores

ValorComportamento
highest_confidenceApenas o único evento com maior confiança é reportado
all_eventsTodos os eventos detectados são reportados a cada ciclo de detecção

AT+SETINTMODE valores

ValorComportamento
singleINT_N dispara uma vez, depois deve ser redefinido com AT+RESETINT
continuousINT_N dispara continuamente enquanto o evento é detectado

Uso com Arduino

Conectar o XIAO

Este dispositivo é compatível com módulos XIAO e pode ser conectado a quaisquer pinos UART disponíveis na placa. É compatível com os módulos ESP32S3, ESP32C6 e ESP32C3, portanto você só precisa modificar as definições dos pinos RX e TX no código de acordo. Conecte o dispositivo na mesma orientação mostrada nas imagens.

pir

Baixar a Biblioteca

  • Acesse o repositório no GitHub Link
  • Clique no botão verde "Code"
  • Selecione "Download ZIP"
  • Salve o arquivo (por exemplo, AudioEventSensor-main.zip) no seu computador

pir

Instalar a Biblioteca na Arduino IDE

Usando a Arduino IDE (Recomendado)

  • Abra a Arduino IDE
  • Vá em Sketch → Include Library → Add .ZIP Library...
  • Navegue até o arquivo ZIP baixado
  • Clique em "Open" para instalar

pir

Verificar a Instalação

Vá em File → Examples → AudioEventSensor para ver os exemplos de sketches

pir

Alterar os Pinos UART

De acordo com a sua placa XIAO, você deve alterar as definições dos pinos UART no código. Neste exemplo, usamos o XIAO ESP32S3.

#define UART1_TX 43
#define UART1_RX 44

Uso Básico

Depois que você fizer o upload para o ESP32, este código inicializa um Sensor de Eventos de Áudio via UART e o configura para detectar eventos sonoros específicos, como disparo de arma de fogo e quebra de vidro. Durante a configuração, ele reinicia o dispositivo, lê a versão do firmware, obtém a lista de eventos sonoros suportados e define os limites de detecção para cada evento selecionado. A configuração é então salva para que as definições persistam após reinicializar. No loop principal, o programa escuta continuamente os eventos sonoros detectados e os imprime no monitor serial em tempo real. Isso permite que o sistema atue como uma solução de monitoramento e aviso antecipado para eventos acústicos anormais.

pir

Bônus : Notificações por E-mail

  • Primeiro, você precisa criar uma Senha de App. Consulte este guia
  • Em seguida, baixe e instale as bibliotecas de suporte necessárias. Instale a biblioteca ESP Mail Client pelo Gerenciador de Bibliotecas da Arduino.

pir

Código

Email Ino
#include <WiFi.h>
#include <ESP_Mail_Client.h>
#include <AudioEventSensor.h>

// WiFi credentials
#define WIFI_SSID "WIFI-SSID"
#define WIFI_PASSWORD "PASSWORD"

// Email credentials
#define SENDER_EMAIL "[email protected]"
#define SENDER_PASSWORD "abcd efgh ijkh xvyz"
#define RECIPIENT_EMAIL "[email protected]"

#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 587

// UART pins for audio sensor
#define UART1_TX 43
#define UART1_RX 44

// Cooldown period in milliseconds (30 seconds)
#define EVENT_COOLDOWN_MS 30000

// Event tracking structure
struct EventTracker {
String eventType;
unsigned long lastTriggerTime;
int detectionCount;
};

// Track multiple event types
EventTracker events[] = {
{"baby_cry", 0, 0},
{"glass_break", 0, 0},
{"gunshot", 0, 0},
{"snore", 0, 0},
{"T3", 0, 0},
{"T4", 0, 0}
};
const int EVENT_COUNT = 6;

SMTPSession smtp;
AudioEventSensor audio(Serial1);

void setup() {
Serial.begin(115200);
delay(1000);

Serial1.begin(115200, SERIAL_8N1, UART1_RX, UART1_TX);
audio.begin(115200);

Serial.println("=================================");
Serial.println("Audio Event Email Alert System");
Serial.println("=================================\n");

// Connect to WiFi
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");

while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(300);
}

Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();

// Initialize audio sensor
Serial.println("Initializing audio sensor...");
delay(2000);

audio.resetDevice();
delay(500);

// Get firmware version
String firmwareVersion;
if (audio.getFirmwareVersion(firmwareVersion)) {
Serial.print("Firmware version: ");
Serial.println(firmwareVersion);
}

// Configure detection
Serial.println("Setting detection types...");
if (audio.setDetectTypes("gunshot,glass_break,baby_cry,snore,T3")) {
Serial.println("✓ Detection types set: gunshot, glass_break");
} else {
Serial.println("✗ Failed to set detection types");
}
delay(500);

// Set thresholds
audio.setEventThreshold("glass_break", 60);
audio.setEventThreshold("gunshot", 65);
delay(500);

// Save configuration
audio.saveConfig();
delay(500);

Serial.println("\n=================================");
Serial.println("System ready. Monitoring events...");
Serial.println("=================================\n");
}

void loop() {
// Check for audio events
if (audio.available()) {
String eventData = audio.readEvent();

if (eventData.length() > 0) {
Serial.print("[" + getTimestamp() + "] ");
Serial.println(eventData);

// Extract event type from the event string
String eventType = extractEventType(eventData);
int confidence = extractConfidence(eventData);

// Check if we should send an email for this event
if (shouldSendEmail(eventType)) {
Serial.println("\n>>> ALERT: New " + eventType + " detected!");
Serial.println(">>> Sending email notification...");

sendEventEmail(eventType, confidence);

Serial.println(">>> Email sent. Cooldown active for " +
String(EVENT_COOLDOWN_MS/1000) + " seconds.\n");
}
}
}

delay(100);
}

// Extract event type from event string (e.g., "glass_break 95% confidence")
String extractEventType(String eventData) {
int spaceIndex = eventData.indexOf(' ');
if (spaceIndex > 0) {
return eventData.substring(0, spaceIndex);
}
return eventData;
}

// Extract confidence from event string
int extractConfidence(String eventData) {
int percentIndex = eventData.indexOf('%');
if (percentIndex > 0) {
// Find the last space before %
int lastSpace = eventData.lastIndexOf(' ', percentIndex);
if (lastSpace > 0) {
String confStr = eventData.substring(lastSpace + 1, percentIndex);
return confStr.toInt();
}
}
return 0;
}

// Check if enough time has passed since last email for this event type
bool shouldSendEmail(String eventType) {
unsigned long currentTime = millis();

for (int i = 0; i < EVENT_COUNT; i++) {
if (events[i].eventType == eventType) {
// Check if cooldown period has passed
if (currentTime - events[i].lastTriggerTime >= EVENT_COOLDOWN_MS) {
// Update last trigger time
events[i].lastTriggerTime = currentTime;
events[i].detectionCount++;
return true;
} else {
// Still in cooldown period
unsigned long timeRemaining = EVENT_COOLDOWN_MS - (currentTime - events[i].lastTriggerTime);
Serial.println(" ⏳ Cooldown active. " + String(timeRemaining/1000) + "s remaining.");
return false;
}
}
}

return false; // Unknown event type
}

// Send email notification
void sendEventEmail(String eventType, int confidence) {
// Prepare email subject and body
String subject = "🚨 ALERT: " + formatEventName(eventType) + " Detected!";

String body = "SECURITY ALERT\n";
body += "═══════════════════════════════\n\n";
body += "Event Type: " + formatEventName(eventType) + "\n";
body += "Confidence: " + String(confidence) + "%\n";
body += "Time: " + getTimestamp() + "\n";
body += "Device: ESP32 Audio Sensor\n";
body += "Location: [Your Location]\n\n";
body += "═══════════════════════════════\n";
body += "This is an automated alert from your audio monitoring system.\n";

// Send the email
gmail_send(subject, body);
}

// Format event name for display
String formatEventName(String eventType) {
if (eventType == "glass_break") return "Glass Breaking";
if (eventType == "gunshot") return "Gunshot";
if (eventType == "baby_cry") return "Baby Crying";
if (eventType == "snore") return "Snoring";
return eventType;
}

// Get formatted timestamp
String getTimestamp() {
unsigned long seconds = millis() / 1000;
unsigned long minutes = seconds / 60;
unsigned long hours = minutes / 60;

seconds = seconds % 60;
minutes = minutes % 60;
hours = hours % 24;

char timestamp[12];
sprintf(timestamp, "%02lu:%02lu:%02lu", hours, minutes, seconds);
return String(timestamp);
}

// Gmail send function
void gmail_send(String subject, String textMsg) {
MailClient.networkReconnect(true);

smtp.debug(0); // Set to 1 for debug output
smtp.callback(smtpCallback);

Session_Config config;
config.server.host_name = SMTP_HOST;
config.server.port = SMTP_PORT;
config.login.email = SENDER_EMAIL;
config.login.password = SENDER_PASSWORD;
config.login.user_domain = F("127.0.0.1");
config.time.ntp_server = F("pool.ntp.org,time.nist.gov");
config.time.gmt_offset = 3;
config.time.day_light_offset = 0;

SMTP_Message message;
message.sender.name = F("ESP32 Security System");
message.sender.email = SENDER_EMAIL;
message.subject = subject;
message.addRecipient(F("Security Admin"), RECIPIENT_EMAIL);
message.text.content = textMsg;
message.text.transfer_encoding = "base64";
message.text.charSet = F("utf-8");
message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_high;
message.addHeader(F("Message-ID: <[email protected]>"));

if (!smtp.connect(&config)) {
Serial.printf("✗ Connection error, Status Code: %d, Error Code: %d, Reason: %s\n",
smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
return;
}

if (!MailClient.sendMail(&smtp, &message)) {
Serial.printf("✗ Send error, Status Code: %d, Error Code: %d, Reason: %s\n",
smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
} else {
Serial.println("✓ Email sent successfully!");
}
}

void smtpCallback(SMTP_Status status) {
Serial.println(status.info());

if (status.success()) {
Serial.println("────────────────────");
Serial.printf("✓ Message sent: %d\n", status.completedCount());
Serial.printf("✗ Message failed: %d\n", status.failedCount());
Serial.println("────────────────────\n");
smtp.sendingResult.clear();
}
}



Em seguida, substitua os seguintes parâmetros no código pelos seus próprios valores: o endereço de e-mail do remetente, os pinos UART, a App Password, o endereço de e-mail do destinatário e o SSID e a senha da sua rede Wi‑Fi.

pir

Suporte Técnico & Discussão de Produtos

Obrigado por escolher nossos produtos! Estamos aqui para oferecer diferentes tipos de suporte para garantir que sua experiência com nossos produtos seja a mais tranquila possível. Oferecemos vários canais de comunicação para atender a diferentes preferências e necessidades.

Loading Comments...