diff --git a/README.md b/README.md index f6bbadd..df343cb 100644 --- a/README.md +++ b/README.md @@ -60,9 +60,9 @@ A lot of wiring is necessary to get Tonuino working. After my first experients I | GND | Rotary encoder | GND | | | 4 | Button (next) | | | | GND | Button (next) | | | -| 35 | Button (previous) | | | +| 33 | Button (previous) | | | | GND | Button (previous) | | | -| 32 | Button (pause/play) | | | +| 5 | Button (pause/play) | | | | GND | Button (pause/play) | | | | 5 V | Neopixel | 5 V | Connect to p-channel MOSFET for power-saving when uC is off | | GND | Neopixel | GND | | diff --git a/src/main.cpp b/src/main.cpp index 1ca37bb..f3a5357 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -148,7 +148,6 @@ TaskHandle_t LED; WebServer server(80); // LED-brightness-configuration -const uint8_t maxLedBrightness = 255; // Maximum brightness that is used for LEDs (PWM-dimmed) uint8_t initialLedBrightness = 16; uint8_t ledBrightness = initialLedBrightness; uint8_t nightLedBrightness = 2; @@ -225,10 +224,6 @@ int32_t lastEncoderValue; int32_t currentEncoderValue; int32_t lastVolume = -1; // Don't change -1 as initial-value! uint8_t currentVolume = initVolume; -bool lastStateButtonRotary; -bool currentStateButtonRotary; -bool isPressedButtonRotary = false; -unsigned long lastPressedTimestampButtonRotary; // Sleep-configuration uint16_t maxInactivityTime = 10; // Time in minutes, after uC is put to deep sleep because of inactivity @@ -236,7 +231,6 @@ unsigned long sleepTimer = 30; // Sleep timer in minute // Sleep-helper unsigned long lastTimeActiveTimestamp = 0; // Timestamp of last user-interaction -bool gotoSleepDueToButton = false; unsigned long sleepTimerStartTimestamp = 0; // Flag if sleep-timer is active bool gotoSleep = false; // Flag for turning uC immediately into deepsleep @@ -351,6 +345,53 @@ void printDirectory(File dir, int numTabs) { } +int countChars(const char* string, char ch) +{ + int count = 0; + int length = strlen(string); + + for (uint8_t i = 0; i < length; i++) { + if (string[i] == ch) { + count++; + } + } + + return count; +} + + +void printSdContent(File dir, uint16_t allocSize, uint8_t allocCount, char *sdContent, uint8_t depth) { + while (true) { + File entry = dir.openNextFile(); + if (!entry) { + dir.rewindDirectory(); + break; + } + + if (countChars(entry.name(), '/') > depth+1) { + continue; + } + + Serial.println(entry.name()); + + if ((strlen(sdContent) + strlen(entry.name()) + 2) >= allocCount * allocSize) { + sdContent = (char*) realloc(sdContent, ++allocCount * allocSize); + Serial.printf("Free heap: %u", ESP.getFreeHeap()); + Serial.printf("realloc! -%d-\n", allocCount); + if (sdContent == NULL) { + return; + } + } + strcat(sdContent, "#"); + strcat(sdContent, entry.name()); + + if (entry.isDirectory()) { + printSdContent(entry, allocSize, allocCount, sdContent, depth); + } + entry.close(); + } +} + void IRAM_ATTR onTimer() { xSemaphoreGiveFromISR(timerSemaphore, NULL); } @@ -862,8 +903,8 @@ char ** returnPlaylistFromSD(File _fileOrDirectory) { } // Directory-mode - uint32_t allocCount = 1; - uint32_t allocSize = 512; + uint16_t allocCount = 1; + uint16_t allocSize = 512; char *serializedPlaylist = (char*) calloc(allocSize, sizeof(char)); while (true) { @@ -1325,6 +1366,7 @@ void rfidScanner(void *parameter) { } +// This task handles everything for Neopixel-visualisation void showLed(void *parameter) { static uint8_t hlastVolume = currentVolume; static uint8_t lastPos = playProperties.currentRelPos; @@ -1703,14 +1745,15 @@ void trackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, playProperties.playMode = _playMode; playProperties.numberOfTracks = strtoul(*(musicFiles-1), NULL, 10); + // Setting default-values + playProperties.repeatCurrentTrack = false; + playProperties.repeatPlaylist = false; + playProperties.sleepAfterCurrentTrack = false; + playProperties.sleepAfterPlaylist = false; + playProperties.saveLastPlayPosition = false; switch(playProperties.playMode) { case SINGLE_TRACK: { - playProperties.repeatCurrentTrack = false; - playProperties.repeatPlaylist = false; - playProperties.sleepAfterCurrentTrack = false; - playProperties.sleepAfterPlaylist = false; - playProperties.saveLastPlayPosition = false; loggerNl((char *) FPSTR(modeSingleTrack), LOGLEVEL_NOTICE); publishMqtt((char *) FPSTR(topicPlaymodeState), playProperties.playMode, false); publishMqtt((char *) FPSTR(topicRepeatModeState), NO_REPEAT, false); @@ -1720,10 +1763,6 @@ void trackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, case SINGLE_TRACK_LOOP: { playProperties.repeatCurrentTrack = true; - playProperties.repeatPlaylist = false; - playProperties.sleepAfterCurrentTrack = false; - playProperties.sleepAfterPlaylist = false; - playProperties.saveLastPlayPosition = false; loggerNl((char *) FPSTR(modeSingleTrackLoop), LOGLEVEL_NOTICE); publishMqtt((char *) FPSTR(topicPlaymodeState), playProperties.playMode, false); publishMqtt((char *) FPSTR(topicRepeatModeState), TRACK, false); @@ -1732,10 +1771,6 @@ void trackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, } case AUDIOBOOK: { // Tracks need to be alph. sorted! - playProperties.repeatCurrentTrack = false; - playProperties.repeatPlaylist = false; - playProperties.sleepAfterCurrentTrack = false; - playProperties.sleepAfterPlaylist = false; playProperties.saveLastPlayPosition = true; loggerNl((char *) FPSTR(modeSingleAudiobook), LOGLEVEL_NOTICE); publishMqtt((char *) FPSTR(topicPlaymodeState), playProperties.playMode, false); @@ -1746,10 +1781,7 @@ void trackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, } case AUDIOBOOK_LOOP: { // Tracks need to be alph. sorted! - playProperties.repeatCurrentTrack = false; playProperties.repeatPlaylist = true; - playProperties.sleepAfterCurrentTrack = false; - playProperties.sleepAfterPlaylist = false; playProperties.saveLastPlayPosition = true; loggerNl((char *) FPSTR(modeSingleAudiobookLoop), LOGLEVEL_NOTICE); publishMqtt((char *) FPSTR(topicPlaymodeState), playProperties.playMode, false); @@ -1760,11 +1792,6 @@ void trackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, } case ALL_TRACKS_OF_DIR_SORTED: { - playProperties.repeatCurrentTrack = false; - playProperties.repeatPlaylist = false; - playProperties.sleepAfterCurrentTrack = false; - playProperties.sleepAfterPlaylist = false; - playProperties.saveLastPlayPosition = false; snprintf(logBuf, sizeof(logBuf)/sizeof(logBuf[0]), "%s '%s' ", (char *) FPSTR(modeAllTrackAlphSorted), filename); loggerNl(logBuf, LOGLEVEL_NOTICE); sortPlaylist((const char**) musicFiles, strtoul(*(musicFiles-1), NULL, 10)); @@ -1775,11 +1802,6 @@ void trackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, } case ALL_TRACKS_OF_DIR_RANDOM: { - playProperties.repeatCurrentTrack = false; - playProperties.repeatPlaylist = false; - playProperties.sleepAfterCurrentTrack = false; - playProperties.sleepAfterPlaylist = false; - playProperties.saveLastPlayPosition = false; loggerNl((char *) FPSTR(modeAllTrackRandom), LOGLEVEL_NOTICE); randomizePlaylist(musicFiles, strtoul(*(musicFiles-1), NULL, 10)); publishMqtt((char *) FPSTR(topicPlaymodeState), playProperties.playMode, false); @@ -1789,11 +1811,7 @@ void trackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, } case ALL_TRACKS_OF_DIR_SORTED_LOOP: { - playProperties.repeatCurrentTrack = false; playProperties.repeatPlaylist = true; - playProperties.sleepAfterCurrentTrack = false; - playProperties.sleepAfterPlaylist = false; - playProperties.saveLastPlayPosition = false; loggerNl((char *) FPSTR(modeAllTrackAlphSortedLoop), LOGLEVEL_NOTICE); sortPlaylist((const char**) musicFiles, strtoul(*(musicFiles-1), NULL, 10)); publishMqtt((char *) FPSTR(topicPlaymodeState), playProperties.playMode, false); @@ -1803,11 +1821,7 @@ void trackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, } case ALL_TRACKS_OF_DIR_RANDOM_LOOP: { - playProperties.repeatCurrentTrack = false; playProperties.repeatPlaylist = true; - playProperties.sleepAfterCurrentTrack = false; - playProperties.sleepAfterPlaylist = false; - playProperties.saveLastPlayPosition = false; loggerNl((char *) FPSTR(modeAllTrackRandomLoop), LOGLEVEL_NOTICE); randomizePlaylist(musicFiles, strtoul(*(musicFiles-1), NULL, 10)); publishMqtt((char *) FPSTR(topicPlaymodeState), playProperties.playMode, false); @@ -1817,11 +1831,6 @@ void trackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, } case WEBSTREAM: { // This is always just one "track" - playProperties.repeatCurrentTrack = false; - playProperties.repeatPlaylist = false; - playProperties.sleepAfterCurrentTrack = false; - playProperties.sleepAfterPlaylist = false; - playProperties.saveLastPlayPosition = false; loggerNl((char *) FPSTR(modeWebstream), LOGLEVEL_NOTICE); if (wifiManager() == WL_CONNECTED) { xQueueSend(trackQueue, &(musicFiles), 0); @@ -2404,6 +2413,7 @@ void setup() { timerAlarmWrite(timer, 1000, true); // 1000 Hz timerAlarmEnable(timer); + // Create tasks xTaskCreatePinnedToCore( rfidScanner, /* Function to implement the task */ "rfidhandling", /* Name of the task */ @@ -2436,7 +2446,7 @@ void setup() { esp_sleep_enable_ext0_wakeup((gpio_num_t) DREHENCODER_BUTTON, 0); - // Activate internal pullups for all buttons + // Activate internal pullups for all buttons pinMode(DREHENCODER_BUTTON, INPUT_PULLUP); pinMode(PAUSEPLAY_BUTTON, INPUT_PULLUP); pinMode(NEXT_BUTTON, INPUT_PULLUP); @@ -2488,8 +2498,15 @@ void setup() { wServer.begin(); bootComplete = true; - /*File root = SD.open("/"); - printDirectory(root, 0);*/ + + /*char *sdC = (char *) calloc(16384, sizeof(char)); + printSdContent(SD.open("/", FILE_READ), 16384, 1, sdC, 2); + printSdContent(SD.open("/", FILE_READ), 16384, 1, sdC, 2); + Serial.println(sdC); + Serial.println(strlen(sdC)); + Serial.println(ESP.getFreeHeap()); + free (sdC); + Serial.println(ESP.getFreeHeap());*/ }