ESP32 Internet Radio Fancy

ESP32 Internet Radio Fancy

This is related to a past blog. https://matthewbullweb.co.uk/esp32-internet-radio-display/

Failed WiFi Animation

When my project started up it expects to be connected to my WiFi network. If this failed for any reason a animation will be played for 5 seconds before the board reboots to try again. It will keep doing this until it connects.

while (WiFi.waitForConnectResult() != WL_CONNECTED) {
  Serial.println("Connection Failed! Rebooting...");
  delay(5000);
  ESP.restart();
}

This is built off a past blog esp32-oled-animation using a larger bouncing circle animation. A separate task is used with a while that checks a variable for playing the animation. If the WiFi disconnects while radio is running the animation plays and stops again when reconnected.

In the past I have used p in place of WiFi.waitForConnectResult() != WL_CONNECTED This is so I could turn the animation on or off via code. E.g. on a button press or timer for a alarm clock animation with sound playing alongside. I may blog about this separately in the future.

void TaskAnimation( void *pvParameters );

const unsigned char PROGMEM circles[][2048];

void TaskAnimation(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  
  for (;;) // A Task shall never return or exit.
  {
    while(WiFi.waitForConnectResult() != WL_CONNECTED) {
      for (int i = 0; i <= 27; i++)
      {
        display.clearDisplay();
        int tt=0;

        unsigned char* PROGMEM frame;

        frame = (unsigned char*) circles[i];
            
        display.clearDisplay();
        display.drawBitmap(
          (display.width()  - LOGO_WIDTH ) / 2,
          (display.height() - LOGO_HEIGHT) / 2,
          frame, LOGO_WIDTH, LOGO_HEIGHT, 1);
        display.display();
        vTaskDelay(tt);
      }
    }
    delay(1000);
  }
}

Storing playing channel and resuming

When the power is turned off the radio goes back to Gold. I used the EPROM to store the number of the channel being played. Once the device is powered cycled (on and off) this value is read and the matching link number is played.

The below code if for the play selection button.

  if ((currentMillis - lastPlayDebounceTime) > debouncePlayDelay)
  {
    lastPlayDebounceTime = currentMillis;
    
    if (buttonRead != buttonState) {
      buttonState = buttonRead;
      
      if (buttonRead == LOW) {        
        // only play if the button state is HIGH
        audio.stopSong();

        audio.connecttohost(staList[infolnc]);

        //clear 2nd line of display
        infoln[1] = (char*) "";

        staNumber = infolnc;
        EEPROM.write(0, staNumber);
        EEPROM.commit();
        
        //play the sound flag
        p = true;
  
        Serial.println(infolnc);
      }
    }

Resuming on Startup

Below is the minimal code I have to added to the sketch and setup functions;

#include <EEPROM.h> // read and write from flash memory
// define the number of bytes you want to access
#define EEPROM_SIZE 1

void setup() {
  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  staNumber = EEPROM.read(0);
  Serial.printf("staNumber: %u%\n\r", staNumber);

  audio.connecttohost(staList[staNumber]);
}

Explaining the boot flag I used for testing

There are a couple of libraries required to read and set the boot flag. The sketch partition scheme also needs to be the default one (NO OTA only have one partition).

#include "esp_partition.h"
#include "esp_ota_ops.h"

This prints the currently running partition

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.print("\n");
  Serial.setDebugOutput(true);

  Serial.println("OTA Tool Example");
  const esp_partition_t *running = esp_ota_get_running_partition();
  // Display the running partition
  Serial.printf("Running partition: %s", running->label);
  Serial.println();
  Serial.println("Example end");
}

Code that triggers the switch trigger and could be after a delay of button denounced if statement.

//boot to other app
const esp_partition_t *next_update_partition = esp_ota_get_next_update_partition(NULL);
if(esp_ota_set_boot_partition(next_update_partition) == ESP_OK) esp_restart();

I included webserver code

Once the SPIFFS is formatted I could connect and upload and delete small sound files. The internal memory could be accessed by the same library used for the internet radio.

The command for this is below. Its a case of swapping out the file name.

audio.connecttoFS(FILESYSTEM, "/sample_00.mp3");