schematic update using cube IDE
This commit is contained in:
BIN
FW/.DS_Store
vendored
Normal file
BIN
FW/.DS_Store
vendored
Normal file
Binary file not shown.
5
FW/.gitignore
vendored
Normal file
5
FW/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
7
FW/.vscode/extensions.json
vendored
Normal file
7
FW/.vscode/extensions.json
vendored
Normal 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"
|
||||
]
|
||||
}
|
||||
39
FW/include/README
Normal file
39
FW/include/README
Normal file
@@ -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
|
||||
46
FW/lib/README
Normal file
46
FW/lib/README
Normal file
@@ -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 <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
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
|
||||
18
FW/platformio.ini
Normal file
18
FW/platformio.ini
Normal file
@@ -0,0 +1,18 @@
|
||||
; 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:m5stack-core2]
|
||||
platform = espressif32
|
||||
board = m5stack-core2
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
earlephilhower/ESP8266Audio@^1.9.2
|
||||
m5stack/M5Core2@^0.0.4
|
||||
monitor_speed = 115200
|
||||
451
FW/src/main.cpp
Normal file
451
FW/src/main.cpp
Normal file
@@ -0,0 +1,451 @@
|
||||
|
||||
|
||||
/*
|
||||
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();
|
||||
}
|
||||
}
|
||||
11
FW/test/README
Normal file
11
FW/test/README
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user