pcb routing ready

This commit is contained in:
2021-08-08 21:15:37 +02:00
parent c934528f13
commit 155b302765
187 changed files with 59632 additions and 8279 deletions

BIN
FW/.DS_Store vendored

Binary file not shown.

BIN
FW/Leo_muziekdoos_fw/.DS_Store vendored Normal file

Binary file not shown.

5
FW/Leo_muziekdoos_fw/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

View File

@@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

Binary file not shown.

Binary file not shown.

BIN
FW/Leo_muziekdoos_fw/FS/003.mp3 Executable file

Binary file not shown.

BIN
FW/Leo_muziekdoos_fw/FS/004.mp3 Executable file

Binary file not shown.

View File

@@ -8,11 +8,16 @@
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:m5stack-core2]
platform = espressif32
board = m5stack-core2
[env:genericSTM32F411CE]
platform = ststm32
board = genericSTM32F411CE
framework = arduino
upload_protocol = stlink
debug_tool = stlink
lib_deps =
earlephilhower/ESP8266Audio@^1.9.2
m5stack/M5Core2@^0.0.4
monitor_speed = 115200
; stm32duino/STM32duino STM32SD@^1.2.3
; adafruit/Audio - Adafruit Fork@^1.3.1
adafruit/Adafruit Zero I2S Library@^1.2.1
build_flags =
-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
-D PIO_FRAMEWORK_ARDUINO_USB_FULLSPEED_FULLMODE

View File

@@ -0,0 +1,166 @@
// Arduino Zero / Feather M0 I2S audio tone generation example.
// Author: Tony DiCola
//
// Connect an I2S DAC or amp (like the UDA1334A) to the Arduino Zero
// and play back simple sine, sawtooth, triangle, and square waves.
// Makes your Zero sound like a NES!
//
// NOTE: The I2S signal generated by the Zero does NOT have a MCLK /
// master clock signal. You must use an I2S receiver that can operate
// without a MCLK signal (like the UDA1334A).
//
// For an Arduino Zero / Feather M0 connect it to you I2S hardware as follows:
// - Digital 0 -> I2S LRCLK / FS (left/right / frame select clock)
// - Digital 1 -> I2S BCLK / SCLK (bit / serial clock)
// - Digital 9 -> I2S DIN / SD (data output)
// - Ground
//
// Released under a MIT license: https://opensource.org/licenses/MIT
#include "Adafruit_ZeroI2S.h"
#define SAMPLERATE_HZ 44100 // The sample rate of the audio. Higher sample rates have better fidelity,
// but these tones are so simple it won't make a difference. 44.1khz is
// standard CD quality sound.
#define AMPLITUDE ((1<<29)-1) // Set the amplitude of generated waveforms. This controls how loud
// the signals are, and can be any value from 0 to 2**31 - 1. Start with
// a low value to prevent damaging speakers!
#define WAV_SIZE 256 // The size of each generated waveform. The larger the size the higher
// quality the signal. A size of 256 is more than enough for these simple
// waveforms.
// Define the frequency of music notes (from http://www.phy.mtu.edu/~suits/notefreqs.html):
#define C4_HZ 261.63
#define D4_HZ 293.66
#define E4_HZ 329.63
#define F4_HZ 349.23
#define G4_HZ 392.00
#define A4_HZ 440.00
#define B4_HZ 493.88
// Define a C-major scale to play all the notes up and down.
float scale[] = { C4_HZ, D4_HZ, E4_HZ, F4_HZ, G4_HZ, A4_HZ, B4_HZ, A4_HZ, G4_HZ, F4_HZ, E4_HZ, D4_HZ, C4_HZ };
// Store basic waveforms in memory.
int32_t sine[WAV_SIZE] = {0};
int32_t sawtooth[WAV_SIZE] = {0};
int32_t triangle[WAV_SIZE] = {0};
int32_t square[WAV_SIZE] = {0};
// Create I2S audio transmitter object.
Adafruit_ZeroI2S i2s;
#define Serial Serial
void generateSine(int32_t amplitude, int32_t* buffer, uint16_t length) {
// Generate a sine wave signal with the provided amplitude and store it in
// the provided buffer of size length.
for (int i=0; i<length; ++i) {
buffer[i] = int32_t(float(amplitude)*sin(2.0*PI*(1.0/length)*i));
}
}
void generateSawtooth(int32_t amplitude, int32_t* buffer, uint16_t length) {
// Generate a sawtooth signal that goes from -amplitude/2 to amplitude/2
// and store it in the provided buffer of size length.
float delta = float(amplitude)/float(length);
for (int i=0; i<length; ++i) {
buffer[i] = -(amplitude/2)+delta*i;
}
}
void generateTriangle(int32_t amplitude, int32_t* buffer, uint16_t length) {
// Generate a triangle wave signal with the provided amplitude and store it in
// the provided buffer of size length.
float delta = float(amplitude)/float(length);
for (int i=0; i<length/2; ++i) {
buffer[i] = -(amplitude/2)+delta*i;
}
for (int i=length/2; i<length; ++i) {
buffer[i] = (amplitude/2)-delta*(i-length/2);
}
}
void generateSquare(int32_t amplitude, int32_t* buffer, uint16_t length) {
// Generate a square wave signal with the provided amplitude and store it in
// the provided buffer of size length.
for (int i=0; i<length/2; ++i) {
buffer[i] = -(amplitude/2);
}
for (int i=length/2; i<length; ++i) {
buffer[i] = (amplitude/2);
}
}
void playWave(int32_t* buffer, uint16_t length, float frequency, float seconds) {
// Play back the provided waveform buffer for the specified
// amount of seconds.
// First calculate how many samples need to play back to run
// for the desired amount of seconds.
uint32_t iterations = seconds*SAMPLERATE_HZ;
// Then calculate the 'speed' at which we move through the wave
// buffer based on the frequency of the tone being played.
float delta = (frequency*length)/float(SAMPLERATE_HZ);
// Now loop through all the samples and play them, calculating the
// position within the wave buffer for each moment in time.
for (uint32_t i=0; i<iterations; ++i) {
uint16_t pos = uint32_t(i*delta) % length;
int32_t sample = buffer[pos];
// Duplicate the sample so it's sent to both the left and right channel.
// It appears the order is right channel, left channel if you want to write
// stereo sound.
i2s.write(sample, sample);
}
}
void setup() {
// Configure serial port.
Serial.begin(115200);
Serial.println("Zero I2S Audio Tone Generator");
// Initialize the I2S transmitter.
if (!i2s.begin(I2S_32_BIT, SAMPLERATE_HZ)) {
Serial.println("Failed to initialize I2S transmitter!");
while (1);
}
i2s.enableTx();
// Generate waveforms.
generateSine(AMPLITUDE, sine, WAV_SIZE);
generateSawtooth(AMPLITUDE, sawtooth, WAV_SIZE);
generateTriangle(AMPLITUDE, triangle, WAV_SIZE);
generateSquare(AMPLITUDE, square, WAV_SIZE);
}
void loop() {
Serial.println("Sine wave");
for (int i=0; i<sizeof(scale)/sizeof(float); ++i) {
// Play the note for a quarter of a second.
playWave(sine, WAV_SIZE, scale[i], 0.25);
// Pause for a tenth of a second between notes.
delay(100);
}
Serial.println("Sawtooth wave");
for (int i=0; i<sizeof(scale)/sizeof(float); ++i) {
// Play the note for a quarter of a second.
playWave(sawtooth, WAV_SIZE, scale[i], 0.25);
// Pause for a tenth of a second between notes.
delay(100);
}
Serial.println("Triangle wave");
for (int i=0; i<sizeof(scale)/sizeof(float); ++i) {
// Play the note for a quarter of a second.
playWave(triangle, WAV_SIZE, scale[i], 0.25);
// Pause for a tenth of a second between notes.
delay(100);
}
Serial.println("Square wave");
for (int i=0; i<sizeof(scale)/sizeof(float); ++i) {
// Play the note for a quarter of a second.
playWave(square, WAV_SIZE, scale[i], 0.25);
// Pause for a tenth of a second between notes.
delay(100);
}
}

View File

@@ -1,451 +0,0 @@
/*
March 28, 2021
Made changes to the Example Core2 Web Radio Player from:
https://www.hackster.io/tommyho/arduino-web-radio-player-c4cb23
I see that the actual library for the functions came from:
Earle Philhower III
Who credits his library to : StellaPlayer and libMAD
https://github.com/earlephilhower/ESP8266Audio
*/
//
// m5StreamTest Version 2020.12b (Source/Buffer Tester)
// Board: M5StackCore2 (esp32)
// Author: tommyho510@gmail.com
// Required: Arduino library ESP8266Audio 1.60
//
#include <M5Core2.h>
#include <driver/i2s.h>
#include <WiFi.h>
#include <AudioFileSourceICYStream.h>
#include <AudioFileSource.h>
#include <AudioFileSourceBuffer.h>
#include <AudioFileSourceSPIRAMBuffer.h>
#include <AudioGeneratorMP3.h>
#include <AudioOutputI2S.h>
#include "Free_Fonts.h"
//#include <spiram-fast.h>
const int bufferSize = 128 * 1024; // buffer size in byte
// Enter your WiFi, Station, button settings here:
const char *SSID = "poes";
const char *PASSWORD = "Rijnstraat214";
// Added Charlie FM in Portland Oregon
//http://24083.live.streamtheworld.com:80/KYCHFM_SC
//
//Removed these from the list:
// {"Mega Shuffle", "http://jenny.torontocast.com:8134/stream"},
// {"Way Up Radio", "http://188.165.212.154:8478/stream"},
// {"Asia Dream", "https://igor.torontocast.com:1025/;.-mp3"},
// {"KPop Way Radio", "http://streamer.radio.co/s06b196587/listen"},
// {"SomaFM", "http://ice2.somafm.com/christmas-128-mp3"}
const int stations = 6;// Change Number here if you add feeds!
char * stationList[stations][2] = {
{"Charlie FM", "http://24083.live.streamtheworld.com:80/KYCHFM_SC"},
{"MAXXED Out", "http://149.56.195.94:8015/steam"},
{"Smooth Jazz", "http://sj32.hnux.com/stream?type=http&nocache=3104"},
{"Smooth Lounge", "http://sl32.hnux.com/stream?type=http&nocache=1257"},
{"Classic FM", "http://media-ice.musicradio.com:80/ClassicFMMP3"},
{"Lite Favorites", "http://naxos.cdnstream.com:80/1255_128"}
};
float audioGain = 0.0;
float gainfactor = 0.08;
int currentStationNumber = 0;
unsigned long disUpdate = millis();
AudioGeneratorMP3 *mp3;
AudioFileSourceICYStream *filemp3;
AudioFileSourceBuffer *buffmp3;
AudioOutputI2S *out, *outmp3;
// Draw a + mark centred on x,y
void drawDatumMarker(int x, int y)
{
M5.Lcd.drawLine(x - 5, y, x + 5, y, TFT_GREEN);
M5.Lcd.drawLine(x, y - 5, x, y + 5, TFT_GREEN);
}
/// WIFI Routines *********************
void initwifi() {
M5.Lcd.setTextColor(TFT_BLUE, TFT_BLACK);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextDatum(BC_DATUM);
M5.Lcd.setFreeFont(FSB12);
M5.Lcd.drawString("Connecting..", M5.Lcd.width()/2, 200, GFXFF);
WiFi.disconnect();
WiFi.softAPdisconnect(true);
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, PASSWORD);
// Try forever
int i = 0;
while (WiFi.status() != WL_CONNECTED) {
Serial.print("STATUS(Connecting to WiFi) ");
delay(1500);
i = i + 1;
if (i > 15) {
ESP.restart();
}
}
Serial.println("\nWiFi Connected!\n");
}
// Display network information on the LCD
void displayWiFiInformation() {
M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
M5.Lcd.setTextSize(1);
M5.Lcd.setFreeFont(FSS9);
M5.Lcd.setTextDatum(BL_DATUM);
M5.Lcd.drawString("Network: ", 10, 165, GFXFF);
M5.Lcd.drawString("IP: " , 10, 190, GFXFF);
M5.Lcd.drawString(SSID, 90, 165, GFXFF);
M5.Lcd.drawString(WiFi.localIP().toString(),40,190,GFXFF);
}
// Update WiFi Signal Strength
void updateWiFiSignal() {
// Display the WiFi Signal Strength
M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
M5.Lcd.setTextSize(1);
M5.Lcd.setFreeFont(FSS9);
M5.Lcd.setTextDatum(BL_DATUM);
M5.Lcd.drawString("WiFi Signal: ", 10, 215, GFXFF);
M5.Lcd.fillRect(112,195,30,20,BLACK);
uint16_t clr = GREEN;
clr = (WiFi.RSSI() < -70) ? TFT_RED : TFT_GREEN;
M5.Lcd.setTextColor(clr, TFT_BLACK);
M5.Lcd.drawString(String(WiFi.RSSI()),115, 215, GFXFF);
}
/// Battery ***************************
// Calculate Battery Useable range (3.2 to 4.1 Volts)
void displayBattery() {
M5.Lcd.setTextSize(1);
M5.Lcd.setFreeFont(FSS9);
int maxVolts = 410; // Battery Max volts * 100
int minVolts = 320; // Battery Min Volts * 100
M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
M5.Lcd.setTextSize(1);
char battInfo[5];
dtostrf(M5.Axp.GetBatVoltage(),1,2,battInfo);
String btInfo = "Batt: " + String(battInfo);
M5.Lcd.setTextDatum(BL_DATUM);
M5.Lcd.drawString(btInfo, 230, 215, GFXFF);
// drawDatumMarker(230,215);
int batt = map(M5.Axp.GetBatVoltage() * 100, minVolts, maxVolts, 0 , 10000) / 100.0;
// Draw Battery bar(s) on the right side of the screen
uint16_t clr = GREEN;
for (int x = 9; x >= 0; x--) {
if (x < 3) clr = RED;
else if (x < 6) clr = YELLOW;
M5.Lcd.fillRoundRect(314, (216 - (x * 24)), 6, 21, 2, (batt > (x * 10)) ? clr : BLACK);
M5.Lcd.drawRoundRect(314, (216 - (x * 24)), 6, 21, 2, TFT_LIGHTGREY);
}
}
// MISC ****************************
// Remove the Track information (While changing stations)
void clearTrack() {
M5.Lcd.fillRect(10, 55, 300, 70, TFT_DARKGREY); // Clear the area of old data
M5.Lcd.drawRect(10, 55, 300, 70, BLUE); // Draw a box around the Track Information
}
// Identify buttons at the bottom of screen
void drawButtons() {
M5.Lcd.fillRect(10,220,300,25,YELLOW);
M5.Lcd.setTextColor(TFT_BLACK);
M5.Lcd.setTextSize(1);
M5.Lcd.setTextDatum(TC_DATUM);
M5.Lcd.setFreeFont(FSB12);
M5.Lcd.drawString("Volume", 55,220, GFXFF);
M5.Lcd.drawString("Station", M5.Lcd.width()/2,220, GFXFF);
M5.Lcd.drawString("Mute", 270 ,220, GFXFF);
}
// Get the Split String Value Used for Band or Track
String getValue(String data, char separator, int index) {
int found = 0;
int strIndex[] = {0, -1};
int maxIndex = data.length() - 1;
for (int i = 0; i <= maxIndex && found <= index; i++) {
if (data.charAt(i) == separator || i == maxIndex) {
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i + 1 : i;
}
}
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}
// MP3, Audio etc. ****************************
// Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc.
void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) {
const char *ptr = reinterpret_cast<const char *>(cbData);
(void) isUnicode; // Punt this ball for now
// Note that the type and string may be in PROGMEM, so copy them to RAM for printf
char s1[32], s2[64];
strncpy_P(s1, type, sizeof(s1));
s1[sizeof(s1) - 1] = 0;
strncpy_P(s2, string, sizeof(s2));
s2[sizeof(s2) - 1] = 0;
String band = getValue(s2, '-', 0);
band.trim();
String track = getValue(s2, '-', 1);
track.trim();
if(band.length() > 30) band = band.substring(0, 30);
if(track.length() > 30) track = track.substring(0, 30);
// Serial.printf("Band: %s Track: %s \n", band.c_str(), track.c_str());
Serial.printf("METADATA(%s) '%s' = '%s'\n", ptr, s1, s2);
M5.Lcd.setTextSize(1);
M5.Lcd.setTextColor(TFT_BLACK, TFT_DARKGREY );
clearTrack();
M5.Lcd.setTextDatum(MC_DATUM);
M5.Lcd.setFreeFont(FSS9);
if(band.length() < 20) M5.Lcd.setFreeFont(FSS12); // Select the font
M5.Lcd.drawString(band, M5.Lcd.width()/2, 72, GFXFF);
M5.Lcd.setFreeFont(FSS9);
if(track.length() < 20) M5.Lcd.setFreeFont(FSS12);
// M5.Lcd.setTextDatum(MC_DATUM);
M5.Lcd.drawString(track, M5.Lcd.width()/2, 107, GFXFF);
Serial.flush();
// Make sure the new song information does not overwrite the battery
displayBattery();
}
// Called when there's a warning or error (like a buffer underflow or decode hiccup)
void StatusCallback(void *cbData, int code, const char *string) {
const char *ptr = reinterpret_cast<const char *>(cbData);
// Note that the string may be in PROGMEM, so copy it to RAM for printf
char s1[64];
strncpy_P(s1, string, sizeof(s1));
s1[sizeof(s1) - 1] = 0;
Serial.printf("STATUS(%s) '%d' = '%s'\n", ptr, code, s1);
Serial.flush();
}
void stopPlaying() {
Serial.printf("Stopping MP3...\n");
if (mp3) {
mp3->stop();
delete mp3;
mp3 = NULL;
}
Serial.printf("MP3 Stopped, Stopping Buffer...\n");
if (buffmp3) {
buffmp3->close();
delete buffmp3;
buffmp3 = NULL;
}
Serial.printf("Buffer stopped... Stopping File ...\n");
if (filemp3) {
filemp3->close();
delete filemp3;
filemp3 = NULL;
}
if (outmp3) {
// filemp3->close();
delete outmp3;
outmp3 = NULL;
}
Serial.printf("STATUS(Stopped)\n");
Serial.flush();
}
// Update the Station Label
void updateStation(String message) {
M5.Lcd.fillRect(10, 10, 300, 35, BLACK); // Clear out other information on the line
M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK);
M5.Lcd.setTextSize(1);
M5.Lcd.setTextDatum(TC_DATUM);
M5.Lcd.setFreeFont(FSB18);
M5.Lcd.drawString(message, M5.Lcd.width()/2, 10, GFXFF);
}
// Change to the next station
void changeStation() {
updateStation("Changing..Wait..");
currentStationNumber++;
if (currentStationNumber >= stations) currentStationNumber = 0;
Serial.printf("\n******** Changing to channel number: %i\n", currentStationNumber);
}
// Change the volume level
// Update the volume graphic
void changeVolume() {
audioGain += 1.0;
if (audioGain > 10.0) {
audioGain = 1.0;
}
if (audioGain < 0.0) {
audioGain = 0.0;
}
int xtPos = 260; // X Position for the Volume indication
outmp3->SetGain(audioGain * gainfactor); // Change Volume to new level
//---------New Volume Bar on left side of LCD *******************
// Draw Volume bar(s) on the left side of the screen
uint16_t clr = RED;
for (int x = 9; x >= 0; x--) {
if (x < 5) clr = GREEN;
else if (x < 8) clr = TFT_ORANGE;
M5.Lcd.fillRoundRect(0, (216 - (x * 24)), 6, 21, 2, (audioGain > x ) ? clr : BLACK);
M5.Lcd.drawRoundRect(0, (216 - (x * 24)), 6, 21, 2, TFT_LIGHTGREY);
}
// Alternate Draw the Volume Indicator (Triangle)
// M5.Lcd.fillTriangle(xtPos, 20, xtPos + 50, 20, xtPos + 50, 0, BLACK); // Clear out old Meter
// if (audioGain > 9) { // If we are full, draw red, blue and green
// M5.Lcd.fillTriangle(xtPos, 20, xtPos + (5 * audioGain), 20, xtPos + (5 * audioGain), 20 - (2 * audioGain), RED);
// M5.Lcd.fillTriangle(xtPos, 20, xtPos + (5 * 9), 20, xtPos + (5 * 9), 20 - (2 * 9), BLUE);
// M5.Lcd.fillTriangle(xtPos, 20, xtPos + (5 * 6), 20, xtPos + (5 * 6), 20 - (2 * 6), GREEN);
// }
// else if (audioGain >= 6) { // if above 5, draw blue and green
// M5.Lcd.fillTriangle(xtPos, 20, xtPos + (5 * audioGain), 20, xtPos + (5 * audioGain), 20 - (2 * audioGain), BLUE);
// M5.Lcd.fillTriangle(xtPos, 20, xtPos + (5 * 6), 20, xtPos + (5 * 6), 20 - (2 * 6), GREEN);
// }
// else if (audioGain >= 1)
// M5.Lcd.fillTriangle(xtPos, 20, xtPos + (5 * audioGain), 20, xtPos + (5 * audioGain), 20 - (2 * audioGain), GREEN);
}
/*
Setup output to I2S Device
Set Pins and Gain
Set FileSource as web radio station
Join FileSource to get MetaData
Create Buffer for data
Register Callback for...?
Begin the MP3 playback
*/
void playMP3() {
outmp3 = new AudioOutputI2S(0, 0); // Output to builtInDAC
outmp3->SetPinout(12, 0, 2);
outmp3->SetOutputModeMono(true);
outmp3->SetGain(audioGain * gainfactor);
filemp3 = new AudioFileSourceICYStream(stationList[currentStationNumber][1]);
filemp3->RegisterMetadataCB(MDCallback, (void*)"ICY"); // ID3TAG // ICY
// StreamTitle
buffmp3 = new AudioFileSourceBuffer(filemp3, bufferSize);
buffmp3->RegisterStatusCB(StatusCallback, (void*)"buffer");
mp3 = new AudioGeneratorMP3();
mp3->RegisterStatusCB(StatusCallback, (void*)"mp3");
mp3->begin(buffmp3, outmp3);
Serial.printf("STATUS(URL) %s %s\n", stationList[currentStationNumber][0], stationList[currentStationNumber][1]);
Serial.flush();
updateStation(String(stationList[currentStationNumber][0]));
}
void loopMP3() {
if (mp3 != NULL) { // To avoid crash while changing stationsI
if (mp3->isRunning()) {
if (!mp3->loop()) mp3->stop();
} else {
Serial.printf("Status(Stream) Stopped \n");
clearTrack();
changeStation();
// stopPlaying();
delay(1000);
playMP3();
}
}
}
// General Arduino Routines
void setup() {
Serial.begin(115200);
M5.begin();
M5.Axp.SetSpkEnable(true);
// M5.Lcd.setRotation(3);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextWrap(false);
M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK);
M5.Lcd.setTextSize(1);
M5.Lcd.setTextDatum(TC_DATUM);
M5.Lcd.setFreeFont(FSB18);
M5.Lcd.drawString("Core2 Web Radio", M5.Lcd.width()/2, 20, GFXFF);
initwifi();
delay(500);
M5.Lcd.clear();
drawButtons();
playMP3();
changeVolume(); // To update Volume setting and graphic
displayWiFiInformation();
}
void loop() {
loopMP3();
M5.update();
if (m5.BtnA.wasPressed()) { //Change Volume(Button A)
changeVolume();
}
if (m5.BtnB.wasPressed()) { //Change Station(Button B)
clearTrack();
changeStation();
stopPlaying();
playMP3();
}
if (m5.BtnC.wasPressed()) { //Mute (Button C)
audioGain = -1.0;
changeVolume();
}
// Update the battery voltage, and WiFi Signal every second
if ((disUpdate + 1000) < millis()) {
disUpdate = millis();
displayBattery();
updateWiFiSignal();
}
}