3481浏览
查看: 3481|回复: 2

[ESP8266/ESP32] FireBeetle 更大的存储空间用于播放音频

[复制链接]
前面的文章介绍了 DAC 方式播放和用更高精度的 PWM 方式直接播放音频文件,但是很明显我们遇到了的2个问题:
1.      1.存储空间有限,APP中最大只能存放2.7MB的音频;
2.      2.每次都需要手工将数据转化为 .h ,比较麻烦。

这次就介绍如何在 FireBeetle上使用更大的空间。从介绍中可以看到FireBeetleFlash 16MB,但是 APP 最大只能用到3MB,余下的空间要么分配给 SPIFFS,要么分给 FATFS
FireBeetle 更大的存储空间用于播放音频图1

SPIFFS FATFS 都是一种文件系统。其中SPIFFS是一个用于SPI NOR flash 设备的嵌入式文件系统,支持磨损均衡、文件系统一致性检查等功能【参考1】。同样的 FATFS也是一种文件系统【参考2】。很明显ESP32 上我们可以使用更大的空间,因此这里尝试使用FATSFS来存储音频文件。
对于 ESP32 来说,每次上传的 APP FATFS 是分开的。比如,编译之后生成了一个3MB APP, 那么上传时只会烧写更新3MB APP那一段的SPINOR中的内容,余下的部分不会改变(加上压缩以及快速的串口通讯,我们并不会感觉上传太慢)。因此,我们还需要一个额外的工具来完成上传 FATFS 的部分。这个工具就是Arduinoesp32fs 插件,这个插件能将文件传输到ESP32SPIFFS,LittleFS 或者FatFS分区上,项目地址如下:
下载到编译好的文件是一个 JAR文件。

FireBeetle 更大的存储空间用于播放音频图2

安装方法是在你 Arduino.exe 的目录中,Tools下创建ESP32FS/Tool 目录,然后将上面这个文件放置进去:

FireBeetle 更大的存储空间用于播放音频图3

重启 Arduino 之后在 Tools 菜单中会出现 ESP32Sketch Data Upload”的选项。

FireBeetle 更大的存储空间用于播放音频图4

为了给 FATFS 分区上传,我们还需要2个额外的工具 mklittlefs.exe mkfatfs.exe。这两个工具需要放在C:\Users\用户名\AppData\Local\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\tools目录下。
上面准备妥当之后,先编写一个测试程序。这个程序会列出当前 FATFS 上面的文件名称。

  1. #include "FS.h"
  2. #include "FFat.h"
  3. void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
  4.     Serial.printf("Listing directory: %s\r\n", dirname);
  5.     File root = fs.open(dirname);
  6.     if(!root){
  7.         Serial.println("- failed to open directory");
  8.         return;
  9.     }
  10.     if(!root.isDirectory()){
  11.         Serial.println(" - not a directory");
  12.         return;
  13.     }
  14.     File file = root.openNextFile();
  15.     while(file){
  16.         if(file.isDirectory()){
  17.             Serial.print("  DIR : ");
  18.             Serial.println(file.name());
  19.             if(levels){
  20.                 listDir(fs, file.name(), levels -1);
  21.             }
  22.         } else {
  23.             Serial.print("  FILE: ");
  24.             Serial.print(file.name());
  25.             Serial.print("\tSIZE: ");
  26.             Serial.println(file.size());
  27.         }
  28.         file = root.openNextFile();
  29.     }
  30.    
  31. }
  32. void setup() {
  33.   Serial.begin(115200);
  34.   if(!FFat.begin()){
  35.         Serial.println("FFat Mount Failed");
  36.         return;
  37.   }  
  38.     Serial.printf("Total space: %10u\n", FFat.totalBytes());
  39.     Serial.printf("Free space: %10u\n", FFat.freeBytes());  
  40.    
  41. }
  42. void loop() {
  43.     listDir(FFat, "/", 0);
  44.     delay(5000);
  45. }
复制代码
此外,我们还要在程序目录下创建一个 data 目录,然后将3支歌曲的文件放在里面。
FireBeetle 更大的存储空间用于播放音频图5

直接使用菜单上传FATFS分区。

FireBeetle 更大的存储空间用于播放音频图6

选择 FATFS
FireBeetle 更大的存储空间用于播放音频图7

看到下面的字样就表示已经成功:
FireBeetle 更大的存储空间用于播放音频图8

接下来,像普通 Arduino 代码一样上传我们的程序,打开串口就能看到结果:
FireBeetle 更大的存储空间用于播放音频图9

有了上面的代码,我们可以很容易编写出来播放代码:
  1. #include "FS.h"
  2. #include "FFat.h"
  3. #include "data\1990.h"
  4. #include "soc/sens_reg.h"  // For dacWrite() patch, TEB Sep-16-2019
  5. void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
  6.     Serial.printf("Listing directory: %s\r\n", dirname);
  7.     File root = fs.open(dirname);
  8.     if(!root){
  9.         Serial.println("- failed to open directory");
  10.         return;
  11.     }
  12.     if(!root.isDirectory()){
  13.         Serial.println(" - not a directory");
  14.         return;
  15.     }
  16.     File file = root.openNextFile();
  17.     while(file){
  18.         if(file.isDirectory()){
  19.             Serial.print("  DIR : ");
  20.             Serial.println(file.name());
  21.             if(levels){
  22.                 listDir(fs, file.name(), levels -1);
  23.             }
  24.         } else {
  25.             Serial.print("  FILE: ");
  26.             Serial.print(file.name());
  27.             Serial.print("\tSIZE: ");
  28.             Serial.println(file.size());
  29.         }
  30.         file = root.openNextFile();
  31.     }
  32.    
  33. }
  34. void playFile(fs::FS &fs, const char * path){
  35.     Serial.printf("Playing file: %s\r\n", path);
  36.     File file = fs.open(path);
  37.     if(!file){
  38.         Serial.println("- failed to open file for reading");
  39.         return;
  40.     }
  41.     uint8_t buffer[1024*4];
  42.     size_t bytessend;
  43.     while(file.available()){
  44.         bytessend=file.read(buffer, 1024*4);
  45.         for (int i=0;i<1024*4;i++) {
  46.             CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN1_M);
  47.             SET_PERI_REG_BITS(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_DAC, buffer[i], RTC_IO_PDAC1_DAC_S);
  48.             SET_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE);
  49.             ets_delay_us(125);
  50.         }
  51.     }
  52.     file.close();
  53. }
  54. void setup() {
  55.   Serial.begin(115200);
  56.   if(!FFat.begin()){
  57.         Serial.println("FFat Mount Failed");
  58.         return;
  59.   }  
  60.     Serial.printf("Total space: %10u\n", FFat.totalBytes());
  61.     Serial.printf("Free space: %10u\n", FFat.freeBytes());  
  62.    
  63.     listDir(FFat, "/", 0);
  64. }
  65. void loop() {
  66.     playFile(FFat, "/1st.wav");
  67.     playFile(FFat, "/10years.wav");
  68.     playFile(FFat, "/1990.wav");
  69. }
复制代码

参考:












pATAq  版主

发表于 2021-4-20 00:47:54

很好的帖子,学习了!
回复

使用道具 举报

zoologist  高级技匠
 楼主|

发表于 2021-6-13 17:06:40

本问题到的 mklittlefs.exe mkfatfs.exe


下载附件mkfatfs.zip

下载附件x86_64-w64-mingw32-mklittlefs-295fe9b.zip
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail