pcb routing ready
This commit is contained in:
BIN
FW/.DS_Store
vendored
BIN
FW/.DS_Store
vendored
Binary file not shown.
BIN
FW/Leo_muziekdoos_fw/.DS_Store
vendored
Normal file
BIN
FW/Leo_muziekdoos_fw/.DS_Store
vendored
Normal file
Binary file not shown.
5
FW/Leo_muziekdoos_fw/.gitignore
vendored
Normal file
5
FW/Leo_muziekdoos_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/Leo_muziekdoos_fw/.vscode/extensions.json
vendored
Normal file
7
FW/Leo_muziekdoos_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"
|
||||
]
|
||||
}
|
||||
BIN
FW/Leo_muziekdoos_fw/FS/001 - Pure Shores.mp3
Executable file
BIN
FW/Leo_muziekdoos_fw/FS/001 - Pure Shores.mp3
Executable file
Binary file not shown.
BIN
FW/Leo_muziekdoos_fw/FS/002 - Never Ever.mp3
Executable file
BIN
FW/Leo_muziekdoos_fw/FS/002 - Never Ever.mp3
Executable file
Binary file not shown.
BIN
FW/Leo_muziekdoos_fw/FS/003.mp3
Executable file
BIN
FW/Leo_muziekdoos_fw/FS/003.mp3
Executable file
Binary file not shown.
BIN
FW/Leo_muziekdoos_fw/FS/004.mp3
Executable file
BIN
FW/Leo_muziekdoos_fw/FS/004.mp3
Executable file
Binary file not shown.
@@ -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
|
||||
166
FW/Leo_muziekdoos_fw/src/main.cpp
Normal file
166
FW/Leo_muziekdoos_fw/src/main.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
451
FW/src/main.cpp
451
FW/src/main.cpp
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user