schematic update using cube IDE

This commit is contained in:
2021-08-02 08:33:06 +02:00
parent c328b68aba
commit 30cc2e863c
267 changed files with 158786 additions and 1054 deletions

BIN
FW/.DS_Store vendored Normal file

Binary file not shown.

5
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

7
FW/.vscode/extensions.json vendored Normal file
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"
]
}

39
FW/include/README Normal file
View 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
View 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
View 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
View 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
View 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