Kỹ thuật điện tử & Điện lạnh

Lập trình ESP-IDF giao tiếp với file âm thanh sử dụng giao thức I2S (P1) kiến thức mới năm 2023

Lập trình ESP-IDF giao tiếp với file âm thanh sử dụng giao thức I2S (P1) – Cập nhật kiến thức mới nhất năm 2023

Giới thiệu

Inter-IC Sound (I²S) là một loại giao tiếp dữ liệu khác nhưng dành cho âm thanh.  I2S đã được phát hành sau I2C và trong khi I2C là giao tiếp chung, I2S được thiết kế để vận chuyển dữ liệu âm thanh. I2S được tạo ra vào những năm 1980, khi kỹ thuật số bắt đầu chinh phục thị trường âm thanh tiêu dùng.Mục đích đã nêu của I2S là tạo điều kiện phát triển thiết bị điện tử âm thanh bằng giao diện được tiêu chuẩn hóa để truyền dữ liệu số giữa các ADC, DAC, bộ lọc kỹ thuật số, bộ xử lý tín hiệu số và các loại IC khác được sử dụng trong các hệ thống âm thanh.Nó vốn dĩ là một giao thức hai kênh, bởi vì nó được thiết kế cho âm thanh nổi.

Sơ đồ sau mô tả ba cấu hình được I2S hỗ trợ.

 

Về cơ bản, nó có ba dòng cho những điều sau:
• Dữ liệu, Dữ liệu vào (DIN) hoặc Dữ liệu ra (DOUT) (SD)
• Đồng hồ hoặc đồng hồ bit (SCK)
• Chọn kênh, chọn từ (WS) 
 Đường dữ liệu mang dữ liệu âm thanh nổi cho cả kênh trái (kênh 0) và kênh phải (kênh 1). Tín hiệu chọn kênh cho biết dữ liệu kênh nào hiện đang được truyền: đây là mức thấp cho kênh bên trái và mức cao cho kênh bên phải. Cuối cùng, SCK là đồng hồ chung cho cả hai đầu được cung cấp bởi chủ, thường là bên gửi trong kiểu giao tiếp này. ESP32 cung cấp hai thiết bị ngoại vi I2S có thể được cấu hình làm đầu vào hoặc đầu ra. Khi được định cấu hình làm đầu vào, micrô có thể được sử dụng để lấy mẫu dữ liệu âm thanh và lưu trữ trên đèn flash để sử dụng sau này. Nếu nó được định cấu hình làm đầu ra, thì một loa có thể được kết nối để tạo ra âm thanh. Trong ví dụ này, chúng ta sẽ sử dụng MAX98357 từ Maxim Integrated làm bộ khuếch đại âm thanh I2S giữa ESP32 và loa.

Hình ảnh về module MAX98357:

Lập trình ESP-IDF giao tiếp với file âm thanh sử dụng giao thức I2S (P1) 17

Mô-đun này là một bộ khuếch đại chi phí thấp, hiệu quả cao có thể được sử dụng với đầu ra 3,3 V từ mô-đun ESP32 mà không cần bất kỳ nguồn điện bên ngoài nào. Nó có thể tạo ra công suất 3.2W cho loa 4Ω, quá đủ cho các mục đích của chúng ta. Để biết thêm thông tin, bạn có thể xem biểu dữ liệu của nó trên trang web Maxim Integrated
tại Ví dụ của chúng ta sẽ được chia thành hai phần để giúp mọi thứ dễ theo dõi hơn.

  • Trong phần đầu tiên, chúng ta sẽ xác định các phân vùng trên bộ nhớ flash ESP32 và tải tệp WAV lên phân vùng dữ liệu dưới dạng dữ liệu âm thanh.
  • Phần thứ hai chứa ứng dụng thực, nơi chúng ta phát tệp âm thanh trên loa. Hãy bắt đầu bằng cách tải lên một tệp.

Tải tệp âm thanh vào bộ nhớ Flash của ESP32

Tuy không khó nhưng việc tải lên một tập tin cũng cần một số chú ý. Vì vậy, chúng ta hãy làm theo nó từng bước:
1. Sau khi tạo dự án PlatformIO, hãy thêm tệp định nghĩa phân vùng, partition.csv, trong thư mục gốc của dự án:

 

 

# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, , 0x6000,
phy_init, data, phy, , 0x1000,
factory, app, factory, , 1M,
spiffs, data, spiffs, 0x210000, 1M,

Đây là tệp mà chúng ta có thể xác định các phân vùng của bộ nhớ flash. Bộ nạp khởi động (bootloader) luôn tìm kiếm phân vùng xuất xưởng nơi ứng dụng đã được lưu trữ. Tệp âm thanh sẽ nằm trong phân vùng dữ liệu spiffs. partition.csv cũng chứa các thông tin khác như độ lệch từ lúc bắt đầu flash và kích thước của một phân vùng. Nếu không cung cấp độ lệch, thì ESP-IDF sẽ tính toán nó dựa trên thông tin đến từ sdkconfig và các kích thước, như được cung cấp trong phân vùng.csv. Ở đây, chúng ta phải cung cấp tất cả các kích thước. Trong ví dụ này, phân vùng spiffs bắt đầu từ 0x210000 và kích thước của nó là 1 MB. Vì chúng ta muốn tùy chỉnh các phân vùng flash, chúng ta cần chỉ định tệp định nghĩa, partition.csv, trong cả platformio.inisdkconfig.

2. Chỉnh sửa platformio.ini để chỉ định tệp phân vùng:

 

monitor_speed = 115200
board_build.partitions = partitions.csv

3. Start a command line và kích hoạt môi trường ảo Python cho công cụ dòng lệnh pio:

$ source ~/.platformio/penv/bin/activate
(penv)$ pio --version
PlatformIO, version 5.1.0

4. Chỉnh sửa sdkconfig bằng công cụ pio. Như đã thảo luận trước đó, sdkconfig chứa tất cả các cài đặt ứng dụng cho dự án ESP32. Trong trường hợp này, chúng tôi sẽ đặt tệp phân vùng tùy chỉnh trong sdkconfig:

 

(penv)$ pio run -t menuconfig

ở đây các bạn có thể dùng ESP-IDF PowerShell để thực hiện thay đổi trong sdkconfig bằng việc gõ lệnh idf.py menuconfig

Và cho ta kết quả tương tự :

Lập trình ESP-IDF giao tiếp với file âm thanh sử dụng giao thức I2S (P1) 18

5. Đặt tên của partition file trong sdkconfig bằng cách chọn Partition Table | Partition Table | Custom partition table CSV:

Lập trình ESP-IDF giao tiếp với file âm thanh sử dụng giao thức I2S (P1) 19

Nhập tên của tệp dưới dạng phân vùng.csv vào hộp văn bản.

Hãy quay lại cấp cao nhất và điều hướng đếnComponent Config | SPIFFS. Cấu hình để đặt số lượng phân vùng tối đa là 5. Điều này sẽ hỗ trợ số lượng phân vùng mà chúng tôi đã xác định trong tệp phân vùng tùy chỉnh:

Lập trình ESP-IDF giao tiếp với file âm thanh sử dụng giao thức I2S (P1) 20

Ta lưu rồi ấn Q để thoát.

6. Bây giờ chúng ta đã sẵn sàng để kiểm tra xem phân vùng spiffs có được tạo hay không. Để thực hiện việc này, hãy chạy một ứng dụng đơn giản, như sau:

 

#include <stdio.h>
#include <sys/stat.h>
#include "esp_spiffs.h"
#include "esp_err.h"
void app_main(void)
{
printf("Initializing SPIFFSn");
esp_vfs_spiffs_conf_t conf = {
.base_path = "/spiffs",
.partition_label = NULL,
.max_files = 5,
.format_if_mount_failed = true};
esp_err_t ret = esp_vfs_spiffs_register(&conf);
if (ret != ESP_OK)
{
printf("Failed to initialize SPIFFS (%s)n", esp_
err_to_name(ret));
return;
}
size_t total = 0, used = 0;
ret = esp_spiffs_info(conf.partition_label, &total,
&used);
if (ret == ESP_OK)
{
printf("Partition size: total: %d, used: %dn",
total, used);
}
else
{
printf("Failed to get SPIFFS partition
information (%s)n", esp_err_to_name(ret));
}
}

Trong app_main, trước tiên chúng ta tạo một biến cấu hình để đăng ký phân vùng spiffs. Sau đó, chúng ta gọi esp_vfs_spiffs_register với biến đó. Khi mã lần chạy đầu tiên, hàm đăng ký sẽ định dạng phân vùng spiffs.

Tại đây, esp_spiffs_info sẽ đọc thông tin phân vùng. Và nếu mọi thứ suôn sẻ, chúng ta sẽ thấy kích thước phân vùng được in trên màn hình nối tiếp.

7. Khi thấy rằng phân vùng spiffs đã sẵn sàng, hãy tạo thư mục dữ liệu trong thư mục gốc của dự án và sao chép tệp âm thanh, rooster.wav. Tệp này được cung cấp trong kho mã, nhưng bạn có thể sử dụng bất kỳ tệp WAV nào có các tham số được hỗ trợ bởi mô-đun âm thanh. Các bạn có thể tạo file âm thanh bất kì rồi chuyển đổi dưới dạng file.wav tùy thích.

 

(penv)$ mkdir data && cp ~/Downloads/rooster.wav data/

8. Tạo hình ảnh SPIFFS bằng cách sử dụng công cụ pio. Công cụ pio yêu cầu thư mục dữ liệu và sử dụng các tệp bên trong thư mục này để tạo hình ảnh phân vùng:

 

(penv)$ pio run -t buildfs

9. Tải lại hình ảnh lên phân vùng spiffs bằng cách sử dụng pio:

 

(penv)$ pio run -t uploadfs

10. Hãy cập nhật lại code, main.c. Thêm đoạn mã sau vào cuối hàm app_main để kiểm tra xem tệp có nằm trong phân vùng hay không. Sau đó, chạy lại ứng dụng:

struct stat st;
if (stat("/spiffs/rooster.wav", &st) == 0)
{
printf(">> rooster.wav found. %ldn", st.st_size);
}
else
{
printf(">> rooster.wav NOT foundn");
}

Kết nối với màn hình nối tiếp để xem liệu tệp âm thanh có tồn tại trên bộ nhớ flash hay không:

 

Initializing SPIFFS
Partition size: total: 956561, used: 100400
>> rooster.wav found. 99286

pio sử dụng mkspiffs esptool.py từ Espressif đằng sau màn hình để tạo và tải lên tệp hình ảnh SPIFFS. Nếu bạn muốn tùy chỉnh quá trình tải tệp lên, bạn có thể sử dụng các công cụ này. Công cụ mkspiffs mới nhất hiện có tại esptool.py nằm trong thư mục $ HOME / .platformio của bạn.

11. Cuối cùng, chúng ta đã sẵn sàng phát tệp WAV này trên loa. Hãy thảo luận điều này vào bài tiếp theo.

Series Navigation

<< Giao tiếp UART với ESP-IDFLập trình ESP-IDF giao tiếp với file âm thanh sử dụng giao thức I2S (P2) >>

Kết thúc
Ngoài các bài viết tin tức, bài báo hàng ngày của https://www.kythuatcodienlanh.com/, nguồn nội dung cũng bao gồm các bài viết từ các cộng tác viên chuyên gia đầu ngành về chuỗi kiến thức kỹ thuật điện, điện lạnh, điện tử, cơ khí,…,.. được chia sẽ chủ yếu từ nhiều khía cạnh liên quan chuỗi kiến thức này.
Bạn có thể dành thời gian để xem thêm các chuyên mục nội dung chính với các bài viết tư vấn, chia sẻ mới nhất, các tin tức gần đây từ chuyên gia và đối tác của Chúng tôi. Cuối cùng, với các kiến thức chia sẻ của bài viết, hy vọng góp phần nào kiến thức hỗ trợ cho độc giả tốt hơn trong hoạt động nghề nghiệp cá nhân!
* Ý kiến được trình bày trong bài viết này là của tác giả khách mời và không nhất thiết phải là SEMTEK. Nhân viên tác giả, cộng tác viên biên tập sẽ được liệt kê bên cuối bài viết.
Trân trọng,
Các chuyên mục nội dung liên quan

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Back to top button