From 247cad3d78110ec9fb985c8463e8e06ff8564a3c Mon Sep 17 00:00:00 2001 From: Dooho Yi Date: Wed, 29 Sep 2021 17:21:13 +0900 Subject: [PATCH] init --- .gitignore | 42 +++++++++ .gitmodules | 3 + include/README | 39 +++++++++ lib/ESP32-audioI2S | 1 + lib/README | 46 ++++++++++ platformio.ini | 27 ++++++ src/main.cpp | 208 +++++++++++++++++++++++++++++++++++++++++++++ test/README | 11 +++ 8 files changed, 377 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 include/README create mode 160000 lib/ESP32-audioI2S create mode 100644 lib/README create mode 100644 platformio.ini create mode 100644 src/main.cpp create mode 100644 test/README diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b9ba671 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# esp-idf / CMake +# build/* + +# platformio +.DS_Store +*/.DS_Store +.travis.yml +.pio/ +.pio/* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..2383666 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/ESP32-audioI2S"] + path = lib/ESP32-audioI2S + url = https://github.com/schreibfaul1/ESP32-audioI2S.git diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/ESP32-audioI2S b/lib/ESP32-audioI2S new file mode 160000 index 0000000..e294ca0 --- /dev/null +++ b/lib/ESP32-audioI2S @@ -0,0 +1 @@ +Subproject commit e294ca0e1e030bffbd247a99b9828c0734245040 diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..47b90a5 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,27 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp32dev] +platform = espressif32 +board = esp32dev +framework = arduino +board_build.f_flash = 80000000L +board_build.flash_mode = dio +upload_speed = 921600 + +; to enable PSRAM +;build_flags = +; -DBOARD_HAS_PSRAM +; -mfix-esp32-psram-cache-issue + +lib_deps = + adafruit/Adafruit SSD1306@^2.4.5 + adafruit/Adafruit BusIO@^1.7.3 + arkhipenko/TaskScheduler@^3.3.0 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c5084bf --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,208 @@ +// simple player for all + +//======================== +#define GAIN_MAX 1.0 // if 1.0 is too loud, give max. limit here. +//======================== + +//======================== +#define SCREEN_PERIOD (200) //200ms = 5hz +#define MONITORING_SERIAL (Serial) +//======================= + +//arduino +#include + +//task +#include +Scheduler runner; + +//screen +#include +#include +#define MAKEPYTHON_ESP32_SDA 4 +#define MAKEPYTHON_ESP32_SCL 5 +#define SCREEN_WIDTH 128 // OLED display width, in pixels +#define SCREEN_HEIGHT 64 // OLED display height, in pixels +#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) +Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); + +//-*-*-*-*-*-*-*-*-*-*-*-*- +// my tasks +// audio & sd & filesystem +#include "Audio.h" +#include "SPI.h" +#include "SD.h" +#include "FS.h" +//sdcard +#define SD_CS 22 +#define SPI_MOSI 23 +#define SPI_MISO 19 +#define SPI_SCK 18 +//digital i/o used (for) makerfabs audio v2.0 +#define I2S_DOUT 27 +#define I2S_BCLK 26 +#define I2S_LRC 25 +Audio audio; + +//screen task +String screen_filename = "/___.mp3"; + +// +extern Task screen_cmd_notify_task; +bool cmd_notify = false; +void screen_cmd_notify() { + if (screen_cmd_notify_task.isFirstIteration()) cmd_notify = true; + else if (screen_cmd_notify_task.isLastIteration()) cmd_notify = false; + else cmd_notify = !cmd_notify; +} +Task screen_cmd_notify_task(500, 10, &screen_cmd_notify, &runner, false); + +// +extern Task screen_task; +void screen() { + //clear screen + a + int line_step = 12; + int line = 0; + display.clearDisplay(); + display.setTextColor(SSD1306_WHITE); + display.setTextSize(1); + + //line1 - mode line (playing / stopped) + notify mark + display.setCursor(0, line); + if (audio.isRunning()) display.println("= playing ==="); + else display.println("* stopped !:."); + if (cmd_notify) { + display.setCursor(120, line); + display.println("*"); + } + line += line_step; + + //line2 - filename + display.setCursor(0, line); + display.println(screen_filename.c_str()); + line += line_step; + + // + display.display(); + // +} +Task screen_task(SCREEN_PERIOD, TASK_FOREVER, &screen, &runner, true); + +//audio files (wav & mp3) +String file_list[100]; //<-- later change this to be a vector (variable length) +int file_num = 0; +int file_index = 0; +int get_music_list(fs::FS &fs, const char *dirname, uint8_t levels, String wavlist[100]) +{ + Serial.printf("Listing directory: %s\n", dirname); + int i = 0; + + File root = fs.open(dirname); + if (!root) { + Serial.println("Failed to open directory"); + return i; + } + if (!root.isDirectory()) { + Serial.println("Not a directory"); + return i; + } + + File file = root.openNextFile(); + while (file) { + if (file.isDirectory()) { } + else { + String temp = file.name(); + if (temp.endsWith(".wav")) { + wavlist[i] = temp; + i++; + } else if (temp.endsWith(".mp3")) { + wavlist[i] = temp; + i++; + } + } + file = root.openNextFile(); + } + return i; +} + +//on 'audio_eof' (automatically called by I2Saudio library at certain events) +void audio_eof_mp3(const char *info) +{ + //get next + file_index++; + if (file_index >= file_num) file_index = 0; + + // + audio.connecttoSD(file_list[file_index].c_str()); + screen_filename = file_list[file_index]; +} + +void lcd_text(String str) { + display.clearDisplay(); + display.setTextColor(SSD1306_WHITE); + display.setTextSize(1); + display.setCursor(0, 0); + display.println(str.c_str()); + display.display(); +} + +// +File root; +void setup() { + + //serial + Serial.begin(115200); + delay(100); + + //screen + Wire.begin(MAKEPYTHON_ESP32_SDA, MAKEPYTHON_ESP32_SCL); + // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally + if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32 + Serial.println(F("SSD1306 allocation failed")); + for (;;) + ; // Don't proceed, loop forever + } + display.clearDisplay(); + + //SD(SPI) + pinMode(SD_CS, OUTPUT); + digitalWrite(SD_CS, HIGH); + SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI); + SPI.setFrequency(1000000); + if (!SD.begin(SD_CS, SPI)) { + Serial.println("Card Mount Failed"); + lcd_text("SD ERR!\nCard Mount Failed!"); + while (1) + ; + } else { + // lcd_text("SD OK"); + } + + //read SD + file_num = get_music_list(SD, "/", 0, file_list); + Serial.print("Music file count:"); + Serial.println(file_num); + Serial.println("All music:"); + for (int i = 0; i < file_num; i++) { + Serial.println(file_list[i]); + } + + //audio(I2S) + audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT); + audio.setVolume(21); // 0...21 + + //start playing.. + file_index = 0; + audio.connecttoSD(file_list[file_index].c_str()); + + // + display.display(); +} + +void loop() { + // + audio.loop(); + // + // runner.execute(); + // +} diff --git a/test/README b/test/README new file mode 100644 index 0000000..b94d089 --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html