From ecbcbbeb50b0a3b77ccf08eeb8dc1ff4e87e9e38 Mon Sep 17 00:00:00 2001 From: Dooho Yi Date: Sat, 12 Jun 2021 18:56:35 +0900 Subject: [PATCH] audioooo done. w/ a debug monitoring screen. --- audioooo/platformio.ini | 2 + audioooo/src/main.cpp | 475 ++++++++++++++++++++++++++++++++++++++++ audioooo/src/main.ino | 434 ------------------------------------ 3 files changed, 477 insertions(+), 434 deletions(-) create mode 100644 audioooo/src/main.cpp delete mode 100644 audioooo/src/main.ino diff --git a/audioooo/platformio.ini b/audioooo/platformio.ini index 0d75a1c..d93d430 100644 --- a/audioooo/platformio.ini +++ b/audioooo/platformio.ini @@ -15,3 +15,5 @@ framework = arduino lib_deps = adafruit/Adafruit SSD1306@^2.4.5 adafruit/Adafruit BusIO@^1.7.3 + arkhipenko/TaskScheduler@^3.3.0 +upload_speed = 921600 ; 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 diff --git a/audioooo/src/main.cpp b/audioooo/src/main.cpp new file mode 100644 index 0000000..7e34db0 --- /dev/null +++ b/audioooo/src/main.cpp @@ -0,0 +1,475 @@ +// +// wirelessly connected cloud (based on ESP-NOW, a kind of LPWAN?) +// + +// +// 0set performance 'Georidugi'/Distancing +// @ 2021 Jun 15 ~ 17 +// + +// +// 2021 june +// +// esp32 based sampler +// + +//======================== +// +#define MY_GROUP_ID (10000) +#define MY_ID (MY_GROUP_ID + 1) +#define MY_SIGN ("AUDIOOOO") +// +//======================== + +//===================== +// +// 'HAVE_CLIENT' +// --> i have a client. enable the client task. +// +// 'DISABLE_AP' +// --> (questioning)... +// +//==================== +// +#define DISABLE_AP + +//======================== +// +#define LED_PERIOD (11111) +#define LED_ONTIME (1) +#define LED_GAPTIME (222) +// +#define SCREEN_PERIOD (200) //200ms = 5hz +// +#define WIFI_CHANNEL 5 +// +// 'MONITORING_SERIAL' +// +// --> sometimes, the 'Serial' is in use (for example, 'osc' node) +// then, use 'Serial1' - D4/GPIO2/TDX1 @ nodemcu (this is TX only.) +// +// --> otherwise, MONITORING_SERIAL == Serial. +// +#if defined(SERIAL_SWAP) +#define MONITORING_SERIAL (Serial1) +#else +#define MONITORING_SERIAL (Serial) +#endif +// +//======================= + +//======================== +#if defined(ARDUINO_FEATHER_ESP32) // featheresp32 +#define LED_PIN 13 +#elif defined(ARDUINO_ESP32_DEV) // esp32dev (MakePython ESP32 => Have NO LED) +#define LED_PIN 2 +#else +#define LED_PIN 2 +#endif +//======================= + +//arduino +#include + +//post & addresses +#include "../../post.h" + +//espnow +#include +#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_cmd = "(((..listening..)))"; +String screen_filename = "***.wav"; + +// +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, true); + +// +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; + + //line3 - rf. last msg. + display.setCursor(0, line); + display.println(screen_cmd.c_str()); + line += line_step; + // + display.display(); + // +} +Task screen_task(SCREEN_PERIOD, TASK_FOREVER, &screen, &runner, true); + +//sample # +int sample_now = 0; //0~999 + +//on 'start' +void sample_player_start() +{ + //filename buffer - 8.3 naming convension! 8+1+3+1 = 13 + // + '/' root symbol 13+1 = 14 (ESP32 specific?) + char filename[14] = "/NNN.wav"; + //search for the sound file + int note = sample_now; + int nnn = (note % 1000); // 0~999 + int nn = (note % 100); // 0~99 + filename[1] = '0' + (nnn / 100); // N__.WAV + filename[2] = '0' + (nn / 10); // _N_.WAV + filename[3] = '0' + (nn % 10); // __N.WAV + //TEST + Serial.println(filename); + screen_filename = String(filename); + bool test = SD.exists(filename); + if (!test) { + Serial.println("... does not exist."); + screen_filename = screen_filename + "_!NEXIST!"; + return; + } + //start the player! + audio.connecttoSD(filename); + delay(10); +} +Task sample_player_start_task(0, TASK_ONCE, &sample_player_start, &runner, false); + +//on 'stop' +void sample_player_stop() { + //filename buffer - 8.3 naming convension! 8+1+3+1 = 13 + // + '/' root symbol 13+1 = 14 (ESP32 specific?) + char filename[14] = "/NNN.wav"; + //search for the sound file + int note = sample_now; + int nnn = (note % 1000); // 0~999 + int nn = (note % 100); // 0~99 + filename[1] = '0' + (nnn / 100); // N__.WAV + filename[2] = '0' + (nn / 10); // _N_.WAV + filename[3] = '0' + (nn % 10); // __N.WAV + //TEST + Serial.println(filename); + screen_filename = String(filename); + bool test = SD.exists(filename); + if (!test) { + Serial.println("... does not exist."); + screen_filename = screen_filename + "_!NEXIST!"; + return; + } + //stop the player. + audio.stopSong(); +} +Task sample_player_stop_task(0, TASK_ONCE, &sample_player_stop, &runner, false); +//*-*-*-*-*-*-*-*-*-*-*-*-* + +// +extern Task hello_task; +static int hello_delay = 0; +void hello() { + // + byte mac[6]; + WiFi.macAddress(mac); + uint32_t mac32 = (((((mac[2] << 8) + mac[3]) << 8) + mac[4]) << 8) + mac[5]; + // + Hello hello(String(MY_SIGN), MY_ID, mac32); // the most basic 'hello' + // and you can append some floats + static int count = 0; + count++; + hello.h1 = (count % 1000); + hello.h2 = sample_now; + // hello.h3 = 0; + // hello.h4 = 0; + // + uint8_t frm_size = sizeof(Hello) + 2; + uint8_t frm[frm_size]; + frm[0] = '{'; + memcpy(frm + 1, (uint8_t *) &hello, sizeof(Hello)); + frm[frm_size - 1] = '}'; + // + esp_now_send(NULL, frm, frm_size); // to all peers in the list. + // + // MONITORING_SERIAL.write(frm, frm_size); + // MONITORING_SERIAL.println(" ==(esp_now_send/0)==> "); + // + if (hello_delay > 0) { + if (hello_delay < 100) hello_delay = 100; + hello_task.restartDelayed(hello_delay); + } +} +Task hello_task(0, TASK_ONCE, &hello, &runner, false); + +//task #0 : blink led +extern Task blink_task; +void blink() { + // + static int count = 0; + count++; + // + switch (count % 4) { + case 0: + digitalWrite(LED_PIN, LOW); // first ON + blink_task.delay(LED_ONTIME); + break; + case 1: + digitalWrite(LED_PIN, HIGH); // first OFF + blink_task.delay(LED_GAPTIME); + break; + case 2: + digitalWrite(LED_PIN, LOW); // second ON + blink_task.delay(LED_ONTIME); + break; + case 3: + digitalWrite(LED_PIN, HIGH); // second OFF + blink_task.delay(LED_PERIOD - 2* LED_ONTIME - LED_GAPTIME); + break; + } +} +Task blink_task(0, TASK_FOREVER, &blink, &runner, false); // makepython esp32 has NO led => disabled. + +// on 'Note' +void onNoteHandler(Note & n) { + //is it for me? + if (n.id == MY_GROUP_ID || n.id == MY_ID) { + // + screen_cmd = n.to_string(); + screen_cmd_notify_task.restart(); + // + if (n.onoff == 1) { + sample_now = n.pitch; + sample_player_start_task.restartDelayed(10); + } else if (n.onoff == 0) { + sample_now = n.pitch; + sample_player_stop_task.restartDelayed(10); + } + // + } +} + +// on 'receive' +void onDataReceive(const uint8_t * mac, const uint8_t *incomingData, int32_t len) { + + // + // MONITORING_SERIAL.write(incomingData, len); + + // +#if defined(HAVE_CLIENT) + Serial.write(incomingData, len); // we pass it over to the client. +#endif + + // open => identify => use. + if (incomingData[0] == '{' && incomingData[len - 1] == '}' && len == (sizeof(Hello) + 2)) { + Hello hello(""); + memcpy((uint8_t *) &hello, incomingData + 1, sizeof(Hello)); + // + MONITORING_SERIAL.println(hello.to_string()); + // + } + + // open => identify => use. + if (incomingData[0] == '[' && incomingData[len - 1] == ']' && len == (sizeof(Note) + 2)) { + Note note; + memcpy((uint8_t *) ¬e, incomingData + 1, sizeof(Note)); + onNoteHandler(note); + + //is it for me? + if (note.id == MY_GROUP_ID || note.id == MY_ID) { + hello_delay = note.ps; + if (hello_delay > 0 && hello_task.isEnabled() == false) { + hello_task.restart(); + } + } + + MONITORING_SERIAL.println(note.to_string()); + } +} + +// on 'sent' +void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t sendStatus) { + if (sendStatus != 0) MONITORING_SERIAL.println("Delivery failed!"); +} + +// SD TEST +void printDirectory(File dir, int numTabs) { + // char filename[256] = ""; + while(true) { + File entry = dir.openNextFile(); + if (!entry) { + // no more files + break; + } + for (uint8_t i=0; i \"" + String(MY_SIGN) + "\""); + Serial.println("- mac address: " + WiFi.macAddress() + ", channel: " + String(WIFI_CHANNEL)); +#if defined(HAVE_CLIENT) + Serial.println("- ======== 'HAVE_CLIENT' ========"); +#endif +#if defined(SERIAL_SWAP) + Serial.println("- ======== 'SERIAL_SWAP' ========"); +#endif +#if defined(DISABLE_AP) + Serial.println("- ======== 'DISABLE_AP' ========"); +#endif +#if defined(HAVE_CLIENT_I2C) + Serial.println("- ======== 'HAVE_CLIENT_I2C' ========"); +#endif + Serial.println("-"); + + //wifi + WiFiMode_t node_type = WIFI_AP_STA; +#if defined(DISABLE_AP) + // system_phy_set_max_tpw(0); + WiFi.setTxPower(WIFI_POWER_MINUS_1dBm); // Set WiFi RF power output to lowest level + node_type = WIFI_STA; +#endif + WiFi.mode(node_type); + + //esp-now + if (esp_now_init() != 0) { + Serial.println("Error initializing ESP-NOW"); + return; + } + esp_now_register_send_cb(onDataSent); + esp_now_register_recv_cb(onDataReceive); + // + Serial.println("- ! (esp_now_add_peer) ==> add a 'broadcast peer' (FF:FF:FF:FF:FF:FF)."); + uint8_t broadcastmac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + // + esp_now_peer_info_t peerInfo; + memcpy(peerInfo.peer_addr, broadcastmac, 6); + peerInfo.channel = 0; + peerInfo.encrypt = false; + esp_now_add_peer(&peerInfo); + + // + Serial.println("-"); + Serial.println("\".-.-.-. :)\""); + Serial.println(); +} + +void loop() { + // + audio.loop(); + // + runner.execute(); + // +} diff --git a/audioooo/src/main.ino b/audioooo/src/main.ino deleted file mode 100644 index 0183fba..0000000 --- a/audioooo/src/main.ino +++ /dev/null @@ -1,434 +0,0 @@ -#include "Arduino.h" -//#include "WiFiMulti.h" -#include "Audio.h" -#include "SPI.h" -#include "SD.h" -#include "FS.h" -#include -#include - -//SD Card -#define SD_CS 22 -#define SPI_MOSI 23 -#define SPI_MISO 19 -#define SPI_SCK 18 - -//Digital I/O used //Makerfabs Audio V2.0 -#define I2S_DOUT 27 -#define I2S_BCLK 26 -#define I2S_LRC 25 - -//SSD1306 -#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); - -//Button -const int Pin_vol_up = 39; -const int Pin_vol_down = 36; -const int Pin_mute = 35; - -const int Pin_previous = 15; -const int Pin_pause = 33; -const int Pin_next = 2; - -Audio audio; - -/* - WiFiMulti wifiMulti; - String ssid = "Makerfabs"; - String password = "20160704"; - */ - -struct Music_info -{ - String name; - int length; - int runtime; - int volume; - int status; - int mute_volume; -} music_info = {"", 0, 0, 0, 0, 0}; - -String file_list[20]; -int file_num = 0; -int file_index = 0; - -int get_music_list(fs::FS &fs, const char *dirname, uint8_t levels, String wavlist[30]); - -void setup() -{ - //IO mode init - pinMode(Pin_vol_up, INPUT_PULLUP); - pinMode(Pin_vol_down, INPUT_PULLUP); - pinMode(Pin_mute, INPUT_PULLUP); - pinMode(Pin_previous, INPUT_PULLUP); - pinMode(Pin_pause, INPUT_PULLUP); - pinMode(Pin_next, INPUT_PULLUP); - - //Serial - Serial.begin(115200); - - //LCD - 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(); - logoshow(); - - //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"); - 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]); - } - - //WiFi - /* - WiFi.mode(WIFI_STA); - wifiMulti.addAP(ssid.c_str(), password.c_str()); - wifiMulti.run(); - if (WiFi.status() != WL_CONNECTED) - { - WiFi.disconnect(true); - wifiMulti.run(); - } - */ - - //Audio(I2S) - audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT); - audio.setVolume(21); // 0...21 - - //audio.connecttoFS(SD, "/MoonlightBay.mp3"); //ChildhoodMemory.mp3 //MoonRiver.mp3 //320k_test.mp3 - //file_list[0] = "MoonlightBay.mp3"; - open_new_song(file_list[file_index]); - print_song_time(); -} - -uint run_time = 0; -uint button_time = 0; - -void loop() -{ - audio.loop(); - if (millis() - run_time > 1000) - { - run_time = millis(); - print_song_time(); - display_music(); - } - - if (millis() - button_time > 300) - { - //Button logic - if (digitalRead(Pin_next) == 0) - { - Serial.println("Pin_next"); - if (file_index < file_num - 1) - file_index++; - else - file_index = 0; - open_new_song(file_list[file_index]); - print_song_time(); - button_time = millis(); - } - if (digitalRead(Pin_previous) == 0) - { - Serial.println("Pin_previous"); - if (file_index > 0) - file_index--; - else - file_index = file_num - 1; - open_new_song(file_list[file_index]); - print_song_time(); - button_time = millis(); - } - if (digitalRead(Pin_vol_up) == 0) - { - Serial.println("Pin_vol_up"); - if (music_info.volume < 21) - music_info.volume++; - audio.setVolume(music_info.volume); - button_time = millis(); - } - if (digitalRead(Pin_vol_down) == 0) - { - Serial.println("Pin_vol_down"); - if (music_info.volume > 0) - music_info.volume--; - audio.setVolume(music_info.volume); - button_time = millis(); - } - if (digitalRead(Pin_mute) == 0) - { - Serial.println("Pin_mute"); - if (music_info.volume != 0) - { - music_info.mute_volume = music_info.volume; - music_info.volume = 0; - } - else - { - music_info.volume = music_info.mute_volume; - } - audio.setVolume(music_info.volume); - button_time = millis(); - } - if (digitalRead(Pin_pause) == 0) - { - Serial.println("Pin_pause"); - audio.pauseResume(); - button_time = millis(); - } - } - - //串口控制切歌,音量 - if (Serial.available()) - { - String r = Serial.readString(); - r.trim(); - if (r.length() > 5) - { - audio.stopSong(); - open_new_song(file_list[0]); - print_song_info(); - } - else - { - audio.setVolume(r.toInt()); - } - } -} - -void open_new_song(String filename) -{ - //去掉文件名的根目录"/"和文件后缀".mp3",".wav" - music_info.name = filename.substring(1, filename.indexOf(".")); - audio.connecttoFS(SD, filename.c_str()); - music_info.runtime = audio.getAudioCurrentTime(); - music_info.length = audio.getAudioFileDuration(); - music_info.volume = audio.getVolume(); - music_info.status = 1; - Serial.println("**********start a new sound************"); -} - -void display_music() -{ - int line_step = 24; - int line = 0; - char buff[20]; - ; - sprintf(buff, "%d:%d", music_info.runtime, music_info.length); - - display.clearDisplay(); - - display.setTextSize(2); // Normal 1:1 pixel scale - display.setTextColor(SSD1306_WHITE); // Draw white text - - display.setCursor(0, line); // Start at top-left corner - display.println(music_info.name); - line += line_step; - - display.setCursor(0, line); - display.println(buff); - line += line_step; - - sprintf(buff, "V:%d",music_info.volume); - - display.setCursor(0, line); - display.println(buff); - line += line_step; - - display.setCursor(0, line); - display.println(music_info.status); - line += line_step; - - display.display(); -} - -void logoshow(void) -{ - display.clearDisplay(); - - display.setTextSize(2); // Normal 1:1 pixel scale - display.setTextColor(SSD1306_WHITE); // Draw white text - display.setCursor(0, 0); // Start at top-left corner - display.println(F("MakePython")); - display.setCursor(0, 20); // Start at top-left corner - display.println(F("MUSIC")); - display.setCursor(0, 40); // Start at top-left corner - display.println(F("PLAYER V2")); - display.display(); - delay(2000); -} - -void lcd_text(String text) -{ - display.clearDisplay(); - - display.setTextSize(2); // Normal 1:1 pixel scale - display.setTextColor(SSD1306_WHITE); // Draw white text - display.setCursor(0, 0); // Start at top-left corner - display.println(text); - display.display(); - delay(500); -} - -void print_song_info() -{ - Serial.println("***********************************"); - Serial.println(audio.getFileSize()); - Serial.println(audio.getFilePos()); - Serial.println(audio.getSampleRate()); - Serial.println(audio.getBitsPerSample()); - Serial.println(audio.getChannels()); - Serial.println(audio.getVolume()); - Serial.println("***********************************"); -} - -//刷新歌曲时间 -void print_song_time() -{ - //Serial.println(audio.getAudioCurrentTime()); - //Serial.println(audio.getAudioFileDuration()); - music_info.runtime = audio.getAudioCurrentTime(); - music_info.length = audio.getAudioFileDuration(); - music_info.volume = audio.getVolume(); -} - -int get_music_list(fs::FS &fs, const char *dirname, uint8_t levels, String wavlist[30]) -{ - 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; -} - -//********************************************** -// optional -void audio_info(const char *info) -{ - Serial.print("info "); - Serial.println(info); -} -void audio_id3data(const char *info) -{ //id3 metadata - Serial.print("id3data "); - Serial.println(info); -} - -//歌曲结束逻辑 -void audio_eof_mp3(const char *info) -{ //end of file - Serial.print("eof_mp3 "); - Serial.println(info); - file_index++; - if (file_index >= file_num) - { - file_index = 0; - } - open_new_song(file_list[file_index]); -} -void audio_showstation(const char *info) -{ - Serial.print("station "); - Serial.println(info); -} -void audio_showstreaminfo(const char *info) -{ - Serial.print("streaminfo "); - Serial.println(info); -} -void audio_showstreamtitle(const char *info) -{ - Serial.print("streamtitle "); - Serial.println(info); -} -void audio_bitrate(const char *info) -{ - Serial.print("bitrate "); - Serial.println(info); -} -void audio_commercial(const char *info) -{ //duration in sec - Serial.print("commercial "); - Serial.println(info); -} -void audio_icyurl(const char *info) -{ //homepage - Serial.print("icyurl "); - Serial.println(info); -} -void audio_lasthost(const char *info) -{ //stream URL played - Serial.print("lasthost "); - Serial.println(info); -} -void audio_eof_speech(const char *info) -{ - Serial.print("eof_speech "); - Serial.println(info); -}