Nhận lệnh giọng nói không cần Internet trên ESP32-S3 bằng ESP_SR: Hi ESP, micro INMP441, đèn, quạt

Nhận lệnh giọng nói ngay trên ESP32-S3 bằng thư viện ESP_SR có sẵn: từ đánh thức Hi ESP, lệnh tiếng Anh tự viết, micro INMP441, cài đặt phân vùng ESP SR 16M, bật tắt đèn và quạt.

Nói "Hi ESP" rồi "turn on the light", đèn sáng: không cần Wi-Fi, không gửi âm thanh lên máy chủ nào. ESP32-S3 đủ sức tự nhận từ đánh thức và các câu lệnh giọng nói nhờ thư viện ESP_SR của Espressif, có sẵn trong gói ESP32 cho Arduino IDE. Bài này giải thích cách ESP_SR hoạt động, phần cứng cần có, cách nối micro I2S INMP441, cài đặt Arduino IDE cho đúng phân vùng bộ nhớ, chương trình bật tắt đèn, quạt bằng giọng nói và các lỗi hay gặp.

1. ESP_SR làm được gì

  • Từ đánh thức (wake word): mô hình đóng gói sẵn nghe câu "Hi ESP".
  • Lệnh giọng nói: tới vài chục câu lệnh do bạn tự viết bằng chữ (tiếng Anh), không phải thu âm huấn luyện.
  • Chạy hoàn toàn trên chip: phản hồi nhanh, không phụ thuộc mạng, không lộ âm thanh trong nhà ra ngoài.

Giới hạn: mô hình lệnh có sẵn trong gói là tiếng Anh, từ đánh thức cố định "Hi ESP". Chỉ chạy trên dòng ESP32-S3 (và P4), không chạy trên ESP32 DevKit V1 thường.

2. Phần cứng cần có

  • Bo ESP32-S3 có Flash 16 MB và PSRAM (ví dụ loại ghi N16R8). Mô hình giọng nói chiếm vài MB Flash và cần PSRAM khi chạy.
  • Micro I2S INMP441 (cách hoạt động của loại micro này có trong bài INMP441 thuộc loạt module).
  • Một LED với điện trở 330 Ω, một module relay cho quạt, breadboard, dây cắm.

3. Cách hoạt động

Năm khối nối tiếp: micro I2S INMP441 16 kHz; xử lý âm đầu vào lọc ồn; WakeNet9 nghe Hi ESP; MultiNet7 nhận lệnh tiếng Anh; hàm khiNghe bật đèn, quạt
Âm thanh đi qua các khối của ESP_SR, cuối cùng gọi hàm của bạn.

ESP_SR đọc âm thanh 16 kHz từ micro, xử lý đầu vào (lọc ồn), đưa qua mô hình WakeNet để nghe từ đánh thức. Khi nghe thấy, chương trình chuyển sang chế độ nghe lệnh: mô hình MultiNet so tiếng nói với danh sách câu lệnh. Mỗi lần nhận ra một câu, ESP_SR gọi hàm sự kiện của bạn kèm số thứ tự lệnh.

Hai trạng thái: chờ từ đánh thức SR_MODE_WAKEWORD và nghe lệnh SR_MODE_COMMAND; nghe Hi ESP thì chuyển sang nghe lệnh; nghe được lệnh thì bật tắt rồi nghe tiếp; hết thời gian chờ thì quay về chờ từ đánh thức
Các sự kiện ESP_SR gọi vào hàm khiNghe().

4. Nối dây

ESP32-S3 DevKitC N16R8: INMP441 SCK nối GPIO4, WS nối GPIO5, SD nối GPIO6, VDD 3V3, GND, chân L/R nối GND; LED qua điện trở 330 ohm ở GPIO10; module relay quạt ở GPIO11
Micro I2S 3 dây tín hiệu; LED và relay ở hai GPIO.

Chân L/R của INMP441 nối GND để micro gửi tiếng ở kênh trái. Đặt micro xa quạt, relay và mạch nguồn xung; tiếng ồn làm giảm khả năng nhận lệnh.

5. Cài đặt Arduino IDE

Bảng cài đặt: Board ESP32S3 Dev Module; Flash Size 16MB; Partition Scheme ESP SR 16M 3MB APP 6MB SPIFFS 3.9MB MODEL; PSRAM OPI PSRAM với bo N16R8; USB CDC On Boot Enabled nếu cắm cổng USB gốc của chip
Theo gói esp32 3.3.x.

Điều quan trọng nhất là chọn đúng Partition Scheme "ESP SR 16M": khi upload, Arduino IDE tự nạp thêm file mô hình vào phân vùng riêng. Bo dùng PSRAM loại khác (QSPI) thì chọn mục PSRAM tương ứng.

6. Chương trình

Chương trình chỉ dùng thư viện ESP_I2S và ESP_SR có sẵn trong gói ESP32. Danh sách lệnh là các câu tiếng Anh; một lệnh có thể có nhiều cách nói (ví dụ "Turn on the light" và "Light on" cùng là bật đèn).

// PYWORLD.VN - Nhận lệnh giọng nói không cần Internet trên ESP32-S3 bằng thư viện ESP_SR có sẵn trong gói esp32
// PYWORLD.VN - Nói "Hi ESP" để đánh thức, rồi nói lệnh tiếng Anh: "turn on the light", "turn off the fan"...
// PYWORLD.VN - Micro INMP441: SCK GPIO4, WS GPIO5, SD GPIO6, L/R nối GND; LED GPIO10, relay quạt GPIO11

#include <Arduino.h>
#include "ESP_I2S.h"
#include "ESP_SR.h"

const int CHAN_SCK = 4;
const int CHAN_WS = 5;
const int CHAN_SD = 6;
const int CHAN_DEN = 10;
const int CHAN_QUAT = 11;
const bool RELAY_KICH_MUC_THAP = true;
const uint32_t TAN_SO_MAU = 16000;       // ESP_SR cần âm thanh 16 kHz, 16 bit

I2SClass i2s;

enum { LENH_BAT_DEN, LENH_TAT_DEN, LENH_BAT_QUAT, LENH_TAT_QUAT };

// Mỗi lệnh có thể có nhiều câu nói khác nhau (tiếng Anh, theo mô hình lệnh đóng gói sẵn)
static const sr_cmd_t DANH_SACH_LENH[] = {
  {LENH_BAT_DEN, "Turn on the light"},
  {LENH_BAT_DEN, "Light on"},
  {LENH_TAT_DEN, "Turn off the light"},
  {LENH_TAT_DEN, "Light off"},
  {LENH_BAT_QUAT, "Turn on the fan"},
  {LENH_BAT_QUAT, "Start fan"},
  {LENH_TAT_QUAT, "Turn off the fan"},
  {LENH_TAT_QUAT, "Stop fan"},
};

void datQuat(bool bat) {
  digitalWrite(CHAN_QUAT, (bat != RELAY_KICH_MUC_THAP) ? HIGH : LOW);
}

void khiNghe(sr_event_t suKien, int maLenh, int maCau) {
  switch (suKien) {
    case SR_EVENT_WAKEWORD:
      Serial.println("Nghe thay 'Hi ESP': cho lenh...");
      ESP_SR.setMode(SR_MODE_COMMAND);        // micro đơn: chuyển ngay sang nghe lệnh
      break;
    case SR_EVENT_TIMEOUT:
      Serial.println("Het thoi gian cho lenh, quay ve cho tu danh thuc");
      ESP_SR.setMode(SR_MODE_WAKEWORD);
      break;
    case SR_EVENT_COMMAND:
      Serial.printf("Lenh %d, cau %d: ", maLenh, maCau);
      switch (maLenh) {
        case LENH_BAT_DEN: digitalWrite(CHAN_DEN, HIGH); Serial.println("bat den"); break;
        case LENH_TAT_DEN: digitalWrite(CHAN_DEN, LOW); Serial.println("tat den"); break;
        case LENH_BAT_QUAT: datQuat(true); Serial.println("bat quat"); break;
        case LENH_TAT_QUAT: datQuat(false); Serial.println("tat quat"); break;
        default: Serial.println("khong ro"); break;
      }
      ESP_SR.setMode(SR_MODE_COMMAND);        // cho nói tiếp lệnh khác trước khi hết thời gian chờ
      break;
    default:
      break;
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(CHAN_DEN, OUTPUT);
  digitalWrite(CHAN_DEN, LOW);
  pinMode(CHAN_QUAT, OUTPUT);
  datQuat(false);

  i2s.setTimeout(1000);
  i2s.setPins(CHAN_SCK, CHAN_WS, -1, CHAN_SD);
  // INMP441 gửi mẫu 24 bit trong khe 32 bit: nhận 32 bit rồi đổi xuống 16 bit cho ESP_SR
  i2s.begin(I2S_MODE_STD, TAN_SO_MAU, I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO, I2S_STD_SLOT_LEFT);
  i2s.configureRX(TAN_SO_MAU, I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO, I2S_RX_TRANSFORM_32_TO_16);

  ESP_SR.onEvent(khiNghe);
  ESP_SR.begin(i2s, DANH_SACH_LENH, sizeof(DANH_SACH_LENH) / sizeof(sr_cmd_t), SR_CHANNELS_MONO, SR_MODE_WAKEWORD, "M");
  Serial.println("San sang: noi 'Hi ESP'");
}

void loop() {
  delay(100);   // việc nhận dạng chạy trong tác vụ riêng của ESP_SR
}
  • INMP441 gửi mẫu 24 bit trong khe 32 bit; configureRX(…, I2S_RX_TRANSFORM_32_TO_16) đổi xuống 16 bit đúng định dạng ESP_SR cần.
  • Sau mỗi lệnh, chương trình gọi lại setMode(SR_MODE_COMMAND) để có thể nói tiếp lệnh khác mà không phải nói lại "Hi ESP"; im lặng một lúc thì quay về chờ từ đánh thức.
  • Muốn thêm lệnh: thêm một số vào enum, thêm câu vào DANH_SACH_LENH và một nhánh trong switch.
Serial Monitor: sẵn sàng nói Hi ESP; nghe thấy Hi ESP chờ lệnh; lệnh 0 câu 0 bật đèn khi nói Turn on the light; lệnh 2 câu 4 bật quạt khi nói Turn on the fan; hết thời gian chờ lệnh, quay về chờ từ đánh thức
Ví dụ một lần nói.

7. Mẹo để nhận lệnh tốt hơn

  • Nói rõ, tốc độ vừa phải, cách micro khoảng 0,5–2 m; phòng ồn thì lại gần hơn.
  • Chọn câu lệnh khác nhau rõ rệt về âm (tránh hai lệnh chỉ khác một từ ngắn).
  • Thêm vài cách nói cho cùng một lệnh để người dùng không phải nhớ đúng một câu.
  • Dùng hai micro (định dạng "MM") giúp lọc ồn tốt hơn ở nơi nhiều tạp âm.
  • Relay đóng cắt tải lớn (quạt, đèn 220 V) phải là module có cách ly và do người có chuyên môn đấu phía điện lưới.

8. Lỗi hay gặp

Hiện tượngNguyên nhân thường gặpCách xử lý
Báo không tìm thấy mô hìnhChọn sai Partition Scheme, Flash 8 MBChọn "ESP SR 16M", bo Flash 16 MB
Lỗi thiếu bộ nhớ khi khởi độngChưa bật PSRAM hoặc chọn sai loạiChọn OPI PSRAM (N16R8) hoặc QSPI tùy bo
Không bao giờ nghe "Hi ESP"Sai chân I2S, L/R không nối GND, micro lỗiKiểm tra dây; in thử mức âm thanh như bài INMP441
Nhận nhầm lệnhCâu lệnh giống nhau, phòng ồnĐổi câu khác biệt hơn, giảm ồn
Serial Monitor không hiện gìCắm cổng USB gốc mà chưa bật USB CDC On BootBật mục đó, hoặc cắm cổng USB-UART
Reset khi relay đóngNguồn yếu, nhiễu cuộn relayNguồn riêng cho relay; xem bài relay làm ESP32 bị reset

9. Xem thêm

  • Các bài cùng loạt AI trên vi điều khiển: TinyML là gì, Edge Impulse, loa trợ lý AI trên ESP32-S3; bài micro I2S INMP441 trong loạt module, bài chọn ESP32-S3, C3, C6 trong loạt ESP32 nâng cao.

Tin tức liên quan

Cảm biến quang: thu phát, phản xạ gương, khuếch tán, triệt nền – cấu tạo, nguyên lý và chế tạo
Cảm biến quang: thu phát, phản xạ gương, khuếch tán, triệt nền – cấu tạo, nguyên lý và chế tạo

Cảm biến quang hoạt động thế nào: bốn kiểu thu phát, phản xạ gương, khuếch tán, triệt nền; điều chế ánh sáng chống nhiễu, cấu tạo, cách chế tạo và làm cảm biến phản xạ có điều chế với ESP32.

HX711 với load cell và LCD 1602 bằng MicroPython
HX711 với load cell và LCD 1602 bằng MicroPython

Hướng dẫn ESP32 đọc load cell qua HX711 và hiển thị LCD 1602 bằng MicroPython, gồm đấu dây, hiệu chuẩn và xử lý lỗi.

Hiệu chuẩn load cell tại hiện trường: tải thật, mô phỏng mV/V, thế chỗ, ISO 376 và ASTM E74
Hiệu chuẩn load cell tại hiện trường: tải thật, mô phỏng mV/V, thế chỗ, ISO 376 và ASTM E74

Hiệu chuẩn hệ load cell tại hiện trường: chuỗi đo và nguồn sai số, tải thật so với mô phỏng mV/V, thế chỗ cho cân bồn, lưu ý lắp đặt, so sánh ISO 376 và ASTM E74.

ESP32 CH340 hay CP2102, cổng Type-C hay Micro USB: khác nhau gì và cài driver trên Windows 10, 11
ESP32 CH340 hay CP2102, cổng Type-C hay Micro USB: khác nhau gì và cài driver trên Windows 10, 11

Chip CH340 và CP2102 trên mạch ESP32 làm gì, khác nhau ở đâu, cách nhận biết qua Device Manager và mã VID:PID, cách cài driver trên Windows 10, 11, chọn cổng Type-C hay Micro USB.

Trò chơi robot và người lập trình trên bảng ô vuông: 3 màn chơi kèm mẫu in
Trò chơi robot và người lập trình trên bảng ô vuông: 3 màn chơi kèm mẫu in

Trò chơi lập trình không cần máy tính cho trẻ 5–8 tuổi: thẻ lệnh tiến, quay, lặp lại trên bảng ô vuông; luật chơi, ba màn có lời giải, mẫu in và biến thể nâng cao.

Điện một chiều DC, xoay chiều AC và an toàn khi làm việc gần điện 220 V
Điện một chiều DC, xoay chiều AC và an toàn khi làm việc gần điện 220 V

Điện một chiều và xoay chiều khác nhau thế nào, vì sao điện lưới 220 V có đỉnh 311 V, bộ nguồn đổi 220 V thành 5 V ra sao, vì sao điện giật nguy hiểm, CB, chống giật và quy tắc khi dùng relay 220 V.

Chuẩn rung: hiệu chuẩn gia tốc kế bằng giao thoa laser và so sánh theo ISO 16063, đáp ứng tần số
Chuẩn rung: hiệu chuẩn gia tốc kế bằng giao thoa laser và so sánh theo ISO 16063, đáp ứng tần số

Hiệu chuẩn gia tốc kế theo ISO 16063: dịch chuyển, vận tốc, gia tốc theo tần số, phương pháp giao thoa laser và so sánh lưng tựa lưng, đọc đáp ứng tần số và chuỗi liên kết chuẩn rung.

Điều khiển hồng ngoại hoạt động thế nào: sóng mang 38 kHz, giao thức NEC và ESP32
Điều khiển hồng ngoại hoạt động thế nào: sóng mang 38 kHz, giao thức NEC và ESP32

Giải thích điều khiển hồng ngoại: sóng mang 38 kHz, mắt thu và giao thức NEC với khung 32 bit, mã lặp. Hướng dẫn tự giải mã phím điều khiển và tự phát lệnh bằng ESP32, không dùng thư viện ngoài.


Bình luận
Đã thêm vào giỏ hàng