v0.7.000
This commit is contained in:
@@ -295,6 +295,13 @@ Work is in progress...
|
|||||||
|
|
||||||
---
|
---
|
||||||
## Version history
|
## Version history
|
||||||
|
#### v0.7.000
|
||||||
|
- added support for Nextion displays ([more info](nextion/README.md))
|
||||||
|
- fixed work of VU Meter
|
||||||
|
- fixed time lag when adjusting the volume / selecting a station
|
||||||
|
- optimization of work with the DSP_DUMMY option
|
||||||
|
- some bug fixes
|
||||||
|
|
||||||
#### v0.6.530
|
#### v0.6.530
|
||||||
- adding VU meter for displays ST7735 160x80, GC9106 160x80, ILI9225 220x176, ST7789 240x240
|
- adding VU meter for displays ST7735 160x80, GC9106 160x80, ILI9225 220x176, ST7789 240x240
|
||||||
- TFT_22_ILI9225 library is integrated into the project
|
- TFT_22_ILI9225 library is integrated into the project
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
|
|||||||
//#define TFT_DC 4 /* SPI DC/RS pin */
|
//#define TFT_DC 4 /* SPI DC/RS pin */
|
||||||
/******************************************/
|
/******************************************/
|
||||||
|
|
||||||
|
/* NEXTION */
|
||||||
|
//#define NEXTION_RX 255 /* Nextion RX pin */
|
||||||
|
//#define NEXTION_TX 255 /* Nextion TX pin */
|
||||||
|
//#define NEXTION_WEATHER_LAT "55.7512" /* Nextion latitude for display Weather */
|
||||||
|
//#define NEXTION_WEATHER_LON "37.6184" /* Nextion longitude for display Weather */
|
||||||
|
//#define NEXTION_WEATHER_KEY "" /* Openweathermap API key https://openweathermap.org/appid */
|
||||||
|
|
||||||
/* I2C PINS */
|
/* I2C PINS */
|
||||||
//#define I2C_SDA 21 /* I2C SDA pin. It is best to connect to pin 21. */
|
//#define I2C_SDA 21 /* I2C SDA pin. It is best to connect to pin 21. */
|
||||||
//#define I2C_SCL 22 /* I2C SCL pin. It is best to connect to pin 22. */
|
//#define I2C_SCL 22 /* I2C SCL pin. It is best to connect to pin 22. */
|
||||||
@@ -120,11 +127,11 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
|
|||||||
* xTaskCreateUniversal(_async_service_task, "async_tcp", 8192 / 2, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE);
|
* xTaskCreateUniversal(_async_service_task, "async_tcp", 8192 / 2, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE);
|
||||||
*/
|
*/
|
||||||
/* VU settings. See the default settings for your display in file yoRadio/display_vu.h */
|
/* VU settings. See the default settings for your display in file yoRadio/display_vu.h */
|
||||||
/*****************************************************************************************************************************************************************************/
|
/************************************************************************************************************************************************************************************/
|
||||||
/* vu left | vu top | band width | band height | band space | num of bands | max samples | horisontal | Max Bands Color | Min Bands Color */
|
/* vu left | vu top | band width | band height | band space | num of bands | fade speed | horisontal | Max Bands Color | Min Bands Color */
|
||||||
/*****************************************************************************************************************************************************************************/
|
/************************************************************************************************************************************************************************************/
|
||||||
//#define VU_PARAMS { VU_X = 4, VU_Y = 60, VU_BW = 10, VU_BH = 34, VU_BS = 2, VU_NB = 8, VU_BMS = 2, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = SILVER }
|
//#define VU_PARAMS2 { VU_X = 4, VU_Y = 60, VU_BW = 10, VU_BH = 34, VU_BS = 2, VU_NB = 8, VU_FS = 2, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = SILVER }
|
||||||
/******************************************/
|
/************************************************************************************************************************************************************************************/
|
||||||
|
|
||||||
/* IR control */
|
/* IR control */
|
||||||
//#define IR_PIN 255
|
//#define IR_PIN 255
|
||||||
|
|||||||
BIN
images/board.jpg
BIN
images/board.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 103 KiB |
BIN
nextion/NX4024K032.HMI
Normal file
BIN
nextion/NX4024K032.HMI
Normal file
Binary file not shown.
17
nextion/README.md
Normal file
17
nextion/README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<img src="images/nextion_preview.png" width="830" height="498"><br />
|
||||||
|
|
||||||
|
#### Tested to work with display models:
|
||||||
|
- NX4024K032 400x240 3.2' https://aliexpress.com/item/4001118814367.html
|
||||||
|
|
||||||
|
#### HOWTO
|
||||||
|
- Download & install Nextion Editor (ver 1.63.3 or higher) https://nextion.tech/nextion-editor/
|
||||||
|
- Connect your display to USB port via UART adapter
|
||||||
|
- Open HMI project and Upload it
|
||||||
|
|
||||||
|
#### Connection options for ESP32
|
||||||
|
- NEXTION_RX - Nextion RX pin (any available GPIO beginning with 13)
|
||||||
|
- NEXTION_TX - Nextion TX pin (any available GPIO beginning with 13)
|
||||||
|
- NEXTION_WEATHER_LAT - Nextion latitude for display Weather (e.g "48.8542")
|
||||||
|
- NEXTION_WEATHER_LON - Nextion longitude for display Weather (e.g "2.3325")
|
||||||
|
- NEXTION_WEATHER_KEY - Openweathermap API key https://openweathermap.org/appid \
|
||||||
|
See examples/myoptions.h for details
|
||||||
BIN
nextion/images/nextion_preview.png
Normal file
BIN
nextion/images/nextion_preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
@@ -1,6 +1,12 @@
|
|||||||
void audio_info(const char *info) {
|
void audio_info(const char *info) {
|
||||||
if(config.store.audioinfo) telnet.printf("##AUDIO.INFO#: %s\n", info);
|
if(config.store.audioinfo) telnet.printf("##AUDIO.INFO#: %s\n", info);
|
||||||
if (strstr(info, "failed!") != NULL || strstr(info, " 404") != NULL) {
|
#ifdef USE_NEXTION
|
||||||
|
if (strstr(info, "format is aac") != NULL) nextion.bitratePic(ICON_AAC);
|
||||||
|
if (strstr(info, "format is flac") != NULL) nextion.bitratePic(ICON_FLAC);
|
||||||
|
if (strstr(info, "format is mp3") != NULL) nextion.bitratePic(ICON_MP3);
|
||||||
|
if (strstr(info, "format is wav") != NULL) nextion.bitratePic(ICON_WAV);
|
||||||
|
#endif
|
||||||
|
if (strstr(info, "failed!") != NULL || strstr(info, " 404") != NULL || strstr(info, " 403") != NULL || strstr(info, "address is empty") != NULL) {
|
||||||
config.setTitle("[request failed]");
|
config.setTitle("[request failed]");
|
||||||
netserver.requestOnChange(TITLE, 0);
|
netserver.requestOnChange(TITLE, 0);
|
||||||
player.setOutputPins(false);
|
player.setOutputPins(false);
|
||||||
@@ -13,8 +19,11 @@ void audio_info(const char *info) {
|
|||||||
|
|
||||||
void audio_bitrate(const char *info)
|
void audio_bitrate(const char *info)
|
||||||
{
|
{
|
||||||
telnet.printf("%s %s\n", "##AUDIO.BITRATE#:", info);
|
if(config.store.audioinfo) telnet.printf("%s %s\n", "##AUDIO.BITRATE#:", info);
|
||||||
config.station.bitrate = atoi(info) / 1000;
|
config.station.bitrate = atoi(info) / 1000;
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.bitrate(config.station.bitrate);
|
||||||
|
#endif
|
||||||
netserver.requestOnChange(BITRATE, 0);
|
netserver.requestOnChange(BITRATE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ void Config::loadStation(uint16_t ls) {
|
|||||||
playlist.close();
|
playlist.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::fillPlMenu(char plmenu[][40], int from, byte count) {
|
void Config::fillPlMenu(char plmenu[][40], int from, byte count, bool removeNum) {
|
||||||
int ls = from;
|
int ls = from;
|
||||||
byte c = 0;
|
byte c = 0;
|
||||||
bool finded = false;
|
bool finded = false;
|
||||||
@@ -248,9 +248,13 @@ void Config::fillPlMenu(char plmenu[][40], int from, byte count) {
|
|||||||
while (playlist.available()) {
|
while (playlist.available()) {
|
||||||
if (parseCSV(playlist.readStringUntil('\n').c_str(), sName, sUrl, sOvol)) {
|
if (parseCSV(playlist.readStringUntil('\n').c_str(), sName, sUrl, sOvol)) {
|
||||||
#ifdef PL_WITH_NUMBERS
|
#ifdef PL_WITH_NUMBERS
|
||||||
char buf[BUFLEN+10];
|
if(removeNum){
|
||||||
sprintf(buf, "%d %s", (int)(from+c), sName);
|
strlcpy(plmenu[c], sName, 39);
|
||||||
strlcpy(plmenu[c], buf, 39);
|
}else{
|
||||||
|
char buf[BUFLEN+10];
|
||||||
|
sprintf(buf, "%d %s", (int)(from+c), sName);
|
||||||
|
strlcpy(plmenu[c], buf, 39);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
strlcpy(plmenu[c], sName, 39);
|
strlcpy(plmenu[c], sName, 39);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class Config {
|
|||||||
void setSmartStart(byte ss);
|
void setSmartStart(byte ss);
|
||||||
void initPlaylist();
|
void initPlaylist();
|
||||||
void indexPlaylist();
|
void indexPlaylist();
|
||||||
void fillPlMenu(char plmenu[][40], int from, byte count);
|
void fillPlMenu(char plmenu[][40], int from, byte count, bool removeNum=false);
|
||||||
void setTimezone(int8_t tzh, int8_t tzm);
|
void setTimezone(int8_t tzh, int8_t tzm);
|
||||||
void setTimezoneOffset(uint16_t tzo);
|
void setTimezoneOffset(uint16_t tzo);
|
||||||
uint16_t getTimezoneOffset();
|
uint16_t getTimezoneOffset();
|
||||||
|
|||||||
@@ -12,9 +12,15 @@
|
|||||||
|
|
||||||
DspCore dsp;
|
DspCore dsp;
|
||||||
Display display;
|
Display display;
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
Nextion nextion;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DUMMYDISPLAY
|
#ifndef DUMMYDISPLAY
|
||||||
|
/******************************************************************************************************************/
|
||||||
void ticks() {
|
void ticks() {
|
||||||
|
network.timeinfo.tm_sec ++;
|
||||||
|
mktime(&network.timeinfo);
|
||||||
display.putRequest({CLOCK,0});
|
display.putRequest({CLOCK,0});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,6 +225,9 @@ void loopCore0( void * pvParameters ){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Display::init() {
|
void Display::init() {
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.begin();
|
||||||
|
#endif
|
||||||
dsp.initD(screenwidth, screenheight);
|
dsp.initD(screenwidth, screenheight);
|
||||||
dsp.drawLogo();
|
dsp.drawLogo();
|
||||||
meta.init(1, " * ", META_SIZE, TFT_FRAMEWDT, STARTTIME, TFT_LOGO, TFT_BG);
|
meta.init(1, " * ", META_SIZE, TFT_FRAMEWDT, STARTTIME, TFT_LOGO, TFT_BG);
|
||||||
@@ -261,9 +270,15 @@ void Display::start(bool reboot) {
|
|||||||
clear();
|
clear();
|
||||||
if (network.status != CONNECTED) {
|
if (network.status != CONNECTED) {
|
||||||
apScreen();
|
apScreen();
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.apScreen();
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mode = PLAYER;
|
mode = PLAYER;
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.putcmd("page player");
|
||||||
|
#endif
|
||||||
if(!reboot){
|
if(!reboot){
|
||||||
config.setTitle("[READY]");
|
config.setTitle("[READY]");
|
||||||
//loop();
|
//loop();
|
||||||
@@ -284,10 +299,13 @@ void Display::clear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Display::swichMode(displayMode_e newmode) {
|
void Display::swichMode(displayMode_e newmode) {
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.swichMode(newmode);
|
||||||
|
#endif
|
||||||
if (newmode == VOL) {
|
if (newmode == VOL) {
|
||||||
volDelay = millis();
|
volDelay = millis();
|
||||||
}
|
}
|
||||||
if (newmode == mode) return;
|
if (newmode == mode || network.status != CONNECTED) return;
|
||||||
clear();
|
clear();
|
||||||
mode = newmode;
|
mode = newmode;
|
||||||
if (newmode != STATIONS) {
|
if (newmode != STATIONS) {
|
||||||
@@ -332,6 +350,9 @@ void Display::swichMode(displayMode_e newmode) {
|
|||||||
if (newmode == UPDATING) {
|
if (newmode == UPDATING) {
|
||||||
dsp.frameTitle("* UPDATING *");
|
dsp.frameTitle("* UPDATING *");
|
||||||
}
|
}
|
||||||
|
if (newmode == INFO || newmode == SETTINGS || newmode == TIMEZONE || newmode == WIFI) {
|
||||||
|
dsp.frameTitle("* NEXTION *");
|
||||||
|
}
|
||||||
if (newmode == NUMBERS) {
|
if (newmode == NUMBERS) {
|
||||||
//dsp.frameTitle("STATION");
|
//dsp.frameTitle("STATION");
|
||||||
meta.reset();
|
meta.reset();
|
||||||
@@ -348,8 +369,8 @@ void Display::swichMode(displayMode_e newmode) {
|
|||||||
void Display::drawPlayer() {
|
void Display::drawPlayer() {
|
||||||
if (clockRequest) {
|
if (clockRequest) {
|
||||||
//getLocalTime(&network.timeinfo);
|
//getLocalTime(&network.timeinfo);
|
||||||
network.timeinfo.tm_sec ++;
|
//network.timeinfo.tm_sec ++;
|
||||||
mktime(&network.timeinfo);
|
//mktime(&network.timeinfo);
|
||||||
time();
|
time();
|
||||||
clockRequest = false;
|
clockRequest = false;
|
||||||
}
|
}
|
||||||
@@ -358,6 +379,16 @@ void Display::drawPlayer() {
|
|||||||
if (TITLE_SIZE2 != 0) title2.loop();
|
if (TITLE_SIZE2 != 0) title2.loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Display::sendInfo(){
|
||||||
|
if (clockRequest) {
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
if(mode==TIMEZONE) nextion.localTime(network.timeinfo);
|
||||||
|
if(mode==INFO) nextion.rssi();
|
||||||
|
#endif
|
||||||
|
clockRequest = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Display::drawVolume() {
|
void Display::drawVolume() {
|
||||||
if (millis() - volDelay > 3000) {
|
if (millis() - volDelay > 3000) {
|
||||||
volDelay = millis();
|
volDelay = millis();
|
||||||
@@ -373,15 +404,21 @@ void Display::drawPlaylist() {
|
|||||||
char buf[PLMITEMLENGHT];
|
char buf[PLMITEMLENGHT];
|
||||||
dsp.drawPlaylist(currentPlItem, buf);
|
dsp.drawPlaylist(currentPlItem, buf);
|
||||||
plCurrent.setText(dsp.utf8Rus(buf, true));
|
plCurrent.setText(dsp.utf8Rus(buf, true));
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.drawPlaylist(currentPlItem);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::drawNextStationNum(uint16_t num) {
|
void Display::drawNextStationNum(uint16_t num) {
|
||||||
char plMenu[1][40];
|
char plMenu[1][40];
|
||||||
char currentItemText[40] = {0};
|
char currentItemText[40] = {0};
|
||||||
config.fillPlMenu(plMenu, num, 1);
|
config.fillPlMenu(plMenu, num, 1, true);
|
||||||
strlcpy(currentItemText, plMenu[0], 39);
|
strlcpy(currentItemText, plMenu[0], 39);
|
||||||
meta.setText(dsp.utf8Rus(currentItemText, true));
|
meta.setText(dsp.utf8Rus(currentItemText, true));
|
||||||
dsp.drawNextStationNum(num);
|
dsp.drawNextStationNum(num);
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.drawNextStationNum(num);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::putRequest(requestParams_t request){
|
void Display::putRequest(requestParams_t request){
|
||||||
@@ -391,6 +428,9 @@ void Display::putRequest(requestParams_t request){
|
|||||||
|
|
||||||
void Display::loop() {
|
void Display::loop() {
|
||||||
if(displayQueue==NULL) return;
|
if(displayQueue==NULL) return;
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.loop();
|
||||||
|
#endif
|
||||||
requestParams_t request;
|
requestParams_t request;
|
||||||
if(xQueueReceive(displayQueue, &request, 20)){
|
if(xQueueReceive(displayQueue, &request, 20)){
|
||||||
switch (request.type){
|
switch (request.type){
|
||||||
@@ -438,6 +478,11 @@ void Display::loop() {
|
|||||||
drawPlayer();
|
drawPlayer();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case INFO:
|
||||||
|
case TIMEZONE: {
|
||||||
|
sendInfo();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case VOL: {
|
case VOL: {
|
||||||
drawVolume();
|
drawVolume();
|
||||||
break;
|
break;
|
||||||
@@ -468,6 +513,9 @@ void Display::bootString(const char* text, byte y) {
|
|||||||
dsp.set_TextSize(1);
|
dsp.set_TextSize(1);
|
||||||
dsp.centerText(text, y == 1 ? BOOTSTR_TOP1 : BOOTSTR_TOP2, TFT_LOGO, TFT_BG);
|
dsp.centerText(text, y == 1 ? BOOTSTR_TOP1 : BOOTSTR_TOP2, TFT_LOGO, TFT_BG);
|
||||||
dsp.loop(true);
|
dsp.loop(true);
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
if(y==2) nextion.bootString(text);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::bootLogo() {
|
void Display::bootLogo() {
|
||||||
@@ -481,6 +529,11 @@ void Display::rightText(const char* text, byte y, uint16_t fg, uint16_t bg) {
|
|||||||
|
|
||||||
void Display::station() {
|
void Display::station() {
|
||||||
meta.setText(dsp.utf8Rus(config.station.name, true));
|
meta.setText(dsp.utf8Rus(config.station.name, true));
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.newNameset(config.station.name);
|
||||||
|
nextion.bitrate(config.station.bitrate);
|
||||||
|
nextion.bitratePic(ICON_NA);
|
||||||
|
#endif
|
||||||
#ifdef DEBUG_TITLES
|
#ifdef DEBUG_TITLES
|
||||||
meta.setText(dsp.utf8Rus("Utenim adminim veniam FM", true));
|
meta.setText(dsp.utf8Rus("Utenim adminim veniam FM", true));
|
||||||
#endif
|
#endif
|
||||||
@@ -490,6 +543,9 @@ void Display::station() {
|
|||||||
|
|
||||||
void Display::returnTile() {
|
void Display::returnTile() {
|
||||||
meta.setText(dsp.utf8Rus(config.station.name, true));
|
meta.setText(dsp.utf8Rus(config.station.name, true));
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.newNameset(config.station.name);
|
||||||
|
#endif
|
||||||
#ifdef DEBUG_TITLES
|
#ifdef DEBUG_TITLES
|
||||||
meta.setText(dsp.utf8Rus("Utenim adminim veniam FM", true));
|
meta.setText(dsp.utf8Rus("Utenim adminim veniam FM", true));
|
||||||
#endif
|
#endif
|
||||||
@@ -520,7 +576,9 @@ void Display::title() {
|
|||||||
#endif
|
#endif
|
||||||
title1.setText(dsp.utf8Rus(ttl, true));
|
title1.setText(dsp.utf8Rus(ttl, true));
|
||||||
if (TITLE_SIZE2 != 0) title2.setText(dsp.utf8Rus(sng, true));
|
if (TITLE_SIZE2 != 0) title2.setText(dsp.utf8Rus(sng, true));
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.newTitle(config.station.title);
|
||||||
|
#endif
|
||||||
//dsp.loop(true);
|
//dsp.loop(true);
|
||||||
if (player_on_track_change) player_on_track_change();
|
if (player_on_track_change) player_on_track_change();
|
||||||
}
|
}
|
||||||
@@ -542,12 +600,12 @@ void Display::rssi() {
|
|||||||
|
|
||||||
void Display::ip() {
|
void Display::ip() {
|
||||||
if (dsp_before_ip) if (!dsp_before_ip(&dsp)) return;
|
if (dsp_before_ip) if (!dsp_before_ip(&dsp)) return;
|
||||||
dsp.ip(WiFi.localIP().toString().c_str());
|
dsp.ip(network.status == CONNECTED?WiFi.localIP().toString().c_str():WiFi.softAPIP().toString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::time(bool redraw) {
|
void Display::time(bool redraw) {
|
||||||
if (dsp_before_clock) if (!dsp_before_clock(&dsp, dt)) return;
|
if (dsp_before_clock) if (!dsp_before_clock(&dsp, dt)) return;
|
||||||
char timeStringBuff[20] = { 0 };
|
char timeStringBuff[40] = { 0 };
|
||||||
(void)timeStringBuff;
|
(void)timeStringBuff;
|
||||||
if (!dt) {
|
if (!dt) {
|
||||||
heap();
|
heap();
|
||||||
@@ -562,6 +620,9 @@ void Display::time(bool redraw) {
|
|||||||
dsp.printClock(timeStringBuff);
|
dsp.printClock(timeStringBuff);
|
||||||
#else
|
#else
|
||||||
dsp.printClock(network.timeinfo, dt, redraw);
|
dsp.printClock(network.timeinfo, dt, redraw);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.printClock(network.timeinfo);
|
||||||
#endif
|
#endif
|
||||||
dt = !dt;
|
dt = !dt;
|
||||||
if (dsp_after_clock) dsp_after_clock(&dsp, dt);
|
if (dsp_after_clock) dsp_after_clock(&dsp, dt);
|
||||||
@@ -569,7 +630,35 @@ void Display::time(bool redraw) {
|
|||||||
|
|
||||||
void Display::volume() {
|
void Display::volume() {
|
||||||
dsp.drawVolumeBar(mode == VOL);
|
dsp.drawVolumeBar(mode == VOL);
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.setVol(config.store.volume, mode == VOL);
|
||||||
|
#endif
|
||||||
//netserver.requestOnChange(VOLUME, 0);
|
//netserver.requestOnChange(VOLUME, 0);
|
||||||
}
|
}
|
||||||
|
/******************************************************************************************************************/
|
||||||
|
#endif // !DUMMYDISPLAY
|
||||||
|
|
||||||
|
#ifdef DUMMYDISPLAY
|
||||||
|
/******************************************************************************************************************/
|
||||||
|
void Display::bootString(const char* text, byte y) {
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
if(y==2) nextion.bootString(text);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void Display::init(){
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.begin(true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void Display::start(bool reboot){
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.start();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void Display::putRequest(requestParams_t request){
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.putRequest(request);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/******************************************************************************************************************/
|
||||||
#endif // DUMMYDISPLAY
|
#endif // DUMMYDISPLAY
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#if DSP_MODEL==DSP_DUMMY
|
#if DSP_MODEL==DSP_DUMMY
|
||||||
|
#define DUMMYDISPLAY
|
||||||
#include "src/displays/displayDummy.h"
|
#include "src/displays/displayDummy.h"
|
||||||
#elif DSP_MODEL==DSP_ST7735
|
#elif DSP_MODEL==DSP_ST7735
|
||||||
#include "src/displays/displayST7735.h"
|
#include "src/displays/displayST7735.h"
|
||||||
@@ -38,7 +39,7 @@
|
|||||||
#include "src/displays/displayILI9225.h"
|
#include "src/displays/displayILI9225.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST, UPDATING };
|
enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST, UPDATING, INFO, SETTINGS, TIMEZONE, WIFI };
|
||||||
|
|
||||||
enum displayRequestType_e { NEWMODE, CLOCK, NEWTITLE, RETURNTITLE, NEWSTATION, NEXTSTATION, DRAWPLAYLIST, DRAWVOL };
|
enum displayRequestType_e { NEWMODE, CLOCK, NEWTITLE, RETURNTITLE, NEWSTATION, NEXTSTATION, DRAWPLAYLIST, DRAWVOL };
|
||||||
struct requestParams_t
|
struct requestParams_t
|
||||||
@@ -47,6 +48,11 @@ struct requestParams_t
|
|||||||
int payload;
|
int payload;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if NEXTION_RX!=255 && NEXTION_TX!=255
|
||||||
|
#define USE_NEXTION
|
||||||
|
#include "src/displays/nextion.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DUMMYDISPLAY
|
#ifndef DUMMYDISPLAY
|
||||||
void loopCore0( void * pvParameters );
|
void loopCore0( void * pvParameters );
|
||||||
|
|
||||||
@@ -91,6 +97,7 @@ class Display {
|
|||||||
Scroll plCurrent;
|
Scroll plCurrent;
|
||||||
#endif
|
#endif
|
||||||
bool busy;
|
bool busy;
|
||||||
|
bool dt; // dots
|
||||||
public:
|
public:
|
||||||
Display() {};
|
Display() {};
|
||||||
#ifndef DUMMYDISPLAY
|
#ifndef DUMMYDISPLAY
|
||||||
@@ -105,23 +112,22 @@ class Display {
|
|||||||
void bootLogo();
|
void bootLogo();
|
||||||
void putRequest(requestParams_t request);
|
void putRequest(requestParams_t request);
|
||||||
#else
|
#else
|
||||||
void init(){};
|
void init();
|
||||||
void loop(){};
|
void loop(){};
|
||||||
void start(bool reboot=false){};
|
void start(bool reboot=false);
|
||||||
void stop(){};
|
void stop(){};
|
||||||
void resetQueue(){};
|
void resetQueue(){};
|
||||||
void centerText(const char* text, byte y, uint16_t fg, uint16_t bg){};
|
void centerText(const char* text, byte y, uint16_t fg, uint16_t bg){};
|
||||||
void rightText(const char* text, byte y, uint16_t fg, uint16_t bg){};
|
void rightText(const char* text, byte y, uint16_t fg, uint16_t bg){};
|
||||||
void bootString(const char* text, byte y){};
|
void bootString(const char* text, byte y);
|
||||||
void bootLogo(){};
|
void bootLogo(){};
|
||||||
void putRequest(requestParams_t request){};
|
void putRequest(requestParams_t request);
|
||||||
#endif
|
#endif
|
||||||
#ifndef DUMMYDISPLAY
|
#ifndef DUMMYDISPLAY
|
||||||
private:
|
private:
|
||||||
Ticker timer;
|
Ticker timer;
|
||||||
Scroll meta, title1, title2;
|
Scroll meta, title1, title2;
|
||||||
bool clockRequest;
|
bool clockRequest;
|
||||||
bool dt; // dots
|
|
||||||
unsigned long volDelay;
|
unsigned long volDelay;
|
||||||
void clear();
|
void clear();
|
||||||
void heap();
|
void heap();
|
||||||
@@ -130,6 +136,7 @@ class Display {
|
|||||||
void time(bool redraw = false);
|
void time(bool redraw = false);
|
||||||
void apScreen();
|
void apScreen();
|
||||||
void drawPlayer();
|
void drawPlayer();
|
||||||
|
void sendInfo();
|
||||||
void drawVolume();
|
void drawVolume();
|
||||||
void swichMode(displayMode_e newmode);
|
void swichMode(displayMode_e newmode);
|
||||||
void drawPlaylist();
|
void drawPlaylist();
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
#define display_vu_h
|
#define display_vu_h
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
|
||||||
#ifdef VU_PARAMS
|
#ifdef VU_PARAMS2
|
||||||
enum : uint16_t VU_PARAMS;
|
enum : uint16_t VU_PARAMS2;
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* vu left - left position
|
* vu left - left position
|
||||||
@@ -13,29 +13,29 @@ enum : uint16_t VU_PARAMS;
|
|||||||
* band height - height of band
|
* band height - height of band
|
||||||
* band space - space between bands
|
* band space - space between bands
|
||||||
* num of bands - num of bands
|
* num of bands - num of bands
|
||||||
* max samples - for i2s dac: count of measurements before fixing the value
|
* fade speed - fade speed
|
||||||
* horisontal - bands orientation
|
* horisontal - bands orientation
|
||||||
* Max/Min Bands Color - color of bands
|
* Max/Min Bands Color - color of bands
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**********************************************************************************************************************************************************************************/
|
/**********************************************************************************************************************************************************************************/
|
||||||
/* vu left | vu top | band width | band height | band space | num of bands | max samples | horisontal | Max Bands Color | Min Bands Color */
|
/* vu left | vu top | band width | band height | band space | num of bands | fade speed | horisontal | Max Bands Color | Min Bands Color */
|
||||||
/**********************************************************************************************************************************************************************************/
|
/**********************************************************************************************************************************************************************************/
|
||||||
#if DSP_MODEL==DSP_ST7735 && DTYPE==INITR_BLACKTAB /* ST7735 160x128 */
|
#if DSP_MODEL==DSP_ST7735 && DTYPE==INITR_BLACKTAB /* ST7735 160x128 */
|
||||||
enum : uint16_t { VU_X = 4, VU_Y = 50, VU_BW = 10, VU_BH = 44, VU_BS = 2, VU_NB = 8, VU_BMS = 2, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = SILVER };
|
enum : uint16_t { VU_X = 4, VU_Y = 50, VU_BW = 10, VU_BH = 44, VU_BS = 2, VU_NB = 8, VU_FS = 2, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY };
|
||||||
#elif DSP_MODEL==DSP_ST7735 && DTYPE==INITR_144GREENTAB /* ST7735 128x128 */
|
#elif DSP_MODEL==DSP_ST7735 && DTYPE==INITR_144GREENTAB /* ST7735 128x128 */
|
||||||
enum : uint16_t { VU_X = 4, VU_Y = 45, VU_BW = 60, VU_BH = 8, VU_BS = 0, VU_NB = 10, VU_BMS = 3, VU_HOR = 1, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = SILVER };
|
enum : uint16_t { VU_X = 4, VU_Y = 45, VU_BW = 60, VU_BH = 8, VU_BS = 0, VU_NB = 10, VU_FS = 2, VU_HOR = 1, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = DARK_GRAY };
|
||||||
#define GREENTAB128
|
#define GREENTAB128
|
||||||
#elif DSP_MODEL==DSP_ILI9341 /* ILI9341 320x240 */
|
#elif DSP_MODEL==DSP_ILI9341 /* ILI9341 320x240 */
|
||||||
enum : uint16_t { VU_X = 4, VU_Y = 100, VU_BW = 20, VU_BH = 86, VU_BS = 4, VU_NB = 10, VU_BMS = 2, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY };
|
enum : uint16_t { VU_X = 4, VU_Y = 100, VU_BW = 20, VU_BH = 86, VU_BS = 4, VU_NB = 10, VU_FS = 5, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY };
|
||||||
#elif DSP_MODEL==DSP_ST7789 /* ST7789 320x240 */
|
#elif DSP_MODEL==DSP_ST7789 /* ST7789 320x240 */
|
||||||
enum : uint16_t { VU_X = 4, VU_Y = 100, VU_BW = 20, VU_BH = 86, VU_BS = 4, VU_NB = 10, VU_BMS = 3, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY };
|
enum : uint16_t { VU_X = 4, VU_Y = 100, VU_BW = 20, VU_BH = 86, VU_BS = 4, VU_NB = 10, VU_FS = 3, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY };
|
||||||
#elif DSP_MODEL==DSP_ST7789_240 /* ST7789 240x240 */
|
#elif DSP_MODEL==DSP_ST7789_240 /* ST7789 240x240 */
|
||||||
enum : uint16_t { VU_X = 4, VU_Y = 90, VU_BW = 120, VU_BH = 20, VU_BS = 0, VU_NB = 12, VU_BMS = 3, VU_HOR = 1, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY };
|
enum : uint16_t { VU_X = 4, VU_Y = 90, VU_BW = 120, VU_BH = 20, VU_BS = 0, VU_NB = 12, VU_FS = 3, VU_HOR = 1, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY };
|
||||||
#elif DSP_MODEL==DSP_ILI9225 /* ILI9225 220x176 */
|
#elif DSP_MODEL==DSP_ILI9225 /* ILI9225 220x176 */
|
||||||
enum : uint16_t { VU_X = 4, VU_Y = 74, VU_BW = 13, VU_BH = 60, VU_BS = 2, VU_NB = 10, VU_BMS = 2, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY };
|
enum : uint16_t { VU_X = 4, VU_Y = 74, VU_BW = 13, VU_BH = 60, VU_BS = 2, VU_NB = 10, VU_FS = 3, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY };
|
||||||
#elif (DSP_MODEL==DSP_ST7735 && DTYPE==INITR_MINI160x80) || (DSP_MODEL==DSP_GC9106) /* ST7735 160x80, GC9106 160x80 */
|
#elif (DSP_MODEL==DSP_ST7735 && DTYPE==INITR_MINI160x80) || (DSP_MODEL==DSP_GC9106) /* ST7735 160x80, GC9106 160x80 */
|
||||||
enum : uint16_t { VU_X = 1, VU_Y = 30, VU_BW = 12, VU_BH = 36, VU_BS = 4, VU_NB = 8, VU_BMS = 2, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY };
|
enum : uint16_t { VU_X = 1, VU_Y = 30, VU_BW = 12, VU_BH = 36, VU_BS = 4, VU_NB = 8, VU_FS = 2, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY };
|
||||||
#else
|
#else
|
||||||
#error YOUR DISPLAY DOES NOT SUPPORT ENABLE_VU_METER FEATURE YET
|
#error YOUR DISPLAY DOES NOT SUPPORT ENABLE_VU_METER FEATURE YET
|
||||||
#endif
|
#endif
|
||||||
@@ -51,31 +51,37 @@ void drawVU(DspCore *dsp){
|
|||||||
#ifdef GREENTAB128
|
#ifdef GREENTAB128
|
||||||
if(display.mode==VOL) return;
|
if(display.mode==VOL) return;
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(USE_NEXTION) && I2S_DOUT==255
|
||||||
player.getVUlevel();
|
player.getVUlevel();
|
||||||
static uint16_t samples_cnt, measL, measR;
|
|
||||||
uint16_t bandColor;
|
|
||||||
samples_cnt++;
|
|
||||||
uint16_t dimension = VU_HOR?VU_BW:VU_BH;
|
|
||||||
uint8_t L = map((VS1053_CS!=255)?player.vuLeft:log(player.vuLeft)*38+45, 255, 0, 0, dimension);
|
|
||||||
uint8_t R = map((VS1053_CS!=255)?player.vuRight:log(player.vuRight)*38+45, 255, 0, 0, dimension);
|
|
||||||
if(player.isRunning()){
|
|
||||||
if(L>measL) measL=L;
|
|
||||||
if(R>measR) measR=R;
|
|
||||||
}else{
|
|
||||||
if(measL<dimension) measL+=2;
|
|
||||||
if(measR<dimension) measR+=2;
|
|
||||||
}
|
|
||||||
#if VS1053_CS==255
|
|
||||||
if(samples_cnt<VU_BMS) return;
|
|
||||||
#endif
|
#endif
|
||||||
samples_cnt=0;
|
static uint16_t /*samples_cnt, */measL, measR;
|
||||||
|
uint16_t bandColor;
|
||||||
|
uint16_t dimension = VU_HOR?VU_BW:VU_BH;
|
||||||
|
uint8_t L = map(player.vuLeft, 255, 0, 0, dimension);
|
||||||
|
uint8_t R = map(player.vuRight, 255, 0, 0, dimension);
|
||||||
|
if(player.isRunning()){
|
||||||
|
measL=(L>=measL)?measL+VU_FS:L;
|
||||||
|
measR=(R>=measR)?measR+VU_FS:R;
|
||||||
|
}else{
|
||||||
|
if(measL<dimension) measL+=VU_FS;
|
||||||
|
if(measR<dimension) measR+=VU_FS;
|
||||||
|
}
|
||||||
|
if(measL>dimension) measL=dimension;
|
||||||
|
if(measR>dimension) measR=dimension;
|
||||||
uint8_t h=(dimension/VU_NB)-2;
|
uint8_t h=(dimension/VU_NB)-2;
|
||||||
for(int i=0; i<dimension; i++){
|
for(int i=0; i<dimension; i++){
|
||||||
if(i%(dimension/VU_NB)==0){
|
if(i%(dimension/VU_NB)==0){
|
||||||
if(VU_HOR){
|
if(VU_HOR){
|
||||||
|
#ifndef BOOMBOX_STYLE
|
||||||
bandColor = (i>VU_BW-(VU_BW/VU_NB)*4)?VU_COLOR_MAX:VU_COLOR_MIN;
|
bandColor = (i>VU_BW-(VU_BW/VU_NB)*4)?VU_COLOR_MAX:VU_COLOR_MIN;
|
||||||
gfxc.fillRect(i, 0, h, VU_BH, bandColor);
|
gfxc.fillRect(i, 0, h, VU_BH, bandColor);
|
||||||
gfxc.fillRect(i+VU_BW+VU_BS, 0, h, VU_BH, bandColor);
|
gfxc.fillRect(i+VU_BW+VU_BS, 0, h, VU_BH, bandColor);
|
||||||
|
#else
|
||||||
|
bandColor = (i>(VU_BW/VU_NB))?VU_COLOR_MIN:VU_COLOR_MAX;
|
||||||
|
gfxc.fillRect(i, 0, h, VU_BH, bandColor);
|
||||||
|
bandColor = (i>VU_BW-(VU_BW/VU_NB)*3)?VU_COLOR_MAX:VU_COLOR_MIN;
|
||||||
|
gfxc.fillRect(i+VU_BW+VU_BS, 0, h, VU_BH, bandColor);
|
||||||
|
#endif
|
||||||
}else{
|
}else{
|
||||||
bandColor = (i<(VU_BH/VU_NB)*3)?VU_COLOR_MAX:VU_COLOR_MIN;
|
bandColor = (i<(VU_BH/VU_NB)*3)?VU_COLOR_MAX:VU_COLOR_MIN;
|
||||||
gfxc.fillRect(0, i, VU_BW, h, bandColor);
|
gfxc.fillRect(0, i, VU_BW, h, bandColor);
|
||||||
@@ -84,19 +90,20 @@ void drawVU(DspCore *dsp){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(VU_HOR){
|
if(VU_HOR){
|
||||||
|
#ifndef BOOMBOX_STYLE
|
||||||
gfxc.fillRect(VU_BW-measL, 0, measL, VU_BW, TFT_BG);
|
gfxc.fillRect(VU_BW-measL, 0, measL, VU_BW, TFT_BG);
|
||||||
gfxc.fillRect(VU_BW*2+VU_BS-measR, 0, measR, VU_BW, TFT_BG);
|
gfxc.fillRect(VU_BW*2+VU_BS-measR, 0, measR, VU_BW, TFT_BG);
|
||||||
dsp->drawRGBBitmap(VU_X, (display.mode==VOL && DSP_MODEL==DSP_ST7789_240)?VU_Y-40:VU_Y, gfxc.getBuffer(), VU_BW*2+VU_BS, VU_BH);
|
dsp->drawRGBBitmap(VU_X, (display.mode==VOL && DSP_MODEL==DSP_ST7789_240)?VU_Y-40:VU_Y, gfxc.getBuffer(), VU_BW*2+VU_BS, VU_BH);
|
||||||
|
#else
|
||||||
|
gfxc.fillRect(0, 0, VU_BW-(VU_BW-measL), VU_BW, TFT_BG);
|
||||||
|
gfxc.fillRect(VU_BW*2+VU_BS-measR, 0, measR, VU_BW, TFT_BG);
|
||||||
|
dsp->drawRGBBitmap(VU_X, (display.mode==VOL && DSP_MODEL==DSP_ST7789_240)?VU_Y-40:VU_Y, gfxc.getBuffer(), VU_BW*2+VU_BS, VU_BH);
|
||||||
|
#endif
|
||||||
}else{
|
}else{
|
||||||
gfxc.fillRect(0, 0, VU_BW, measL, TFT_BG);
|
gfxc.fillRect(0, 0, VU_BW, measL, TFT_BG);
|
||||||
gfxc.fillRect(VU_BW+VU_BS, 0, VU_BW, measR, TFT_BG);
|
gfxc.fillRect(VU_BW+VU_BS, 0, VU_BW, measR, TFT_BG);
|
||||||
dsp->drawRGBBitmap(VU_X, VU_Y, gfxc.getBuffer(), VU_BW*2+VU_BS, VU_BH);
|
dsp->drawRGBBitmap(VU_X, VU_Y, gfxc.getBuffer(), VU_BW*2+VU_BS, VU_BH);
|
||||||
}
|
}
|
||||||
if(player.isRunning()){
|
|
||||||
measL=0;
|
|
||||||
measR=0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index,
|
|||||||
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
|
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case WS_EVT_CONNECT:
|
case WS_EVT_CONNECT:
|
||||||
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
|
if(config.store.audioinfo) Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
|
||||||
|
|
||||||
netserver.requestOnChange(STATION, client->id());
|
netserver.requestOnChange(STATION, client->id());
|
||||||
netserver.requestOnChange(TITLE, client->id());
|
netserver.requestOnChange(TITLE, client->id());
|
||||||
@@ -393,7 +393,7 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case WS_EVT_DISCONNECT:
|
case WS_EVT_DISCONNECT:
|
||||||
Serial.printf("WebSocket client #%u disconnected\n", client->id());
|
if(config.store.audioinfo) Serial.printf("WebSocket client #%u disconnected\n", client->id());
|
||||||
break;
|
break;
|
||||||
case WS_EVT_DATA:
|
case WS_EVT_DATA:
|
||||||
netserver.onWsMessage(arg, data, len);
|
netserver.onWsMessage(arg, data, len);
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ void Network::begin() {
|
|||||||
//getLocalTime(&timeinfo);
|
//getLocalTime(&timeinfo);
|
||||||
stimer.once_ms(200,getFirstTime);
|
stimer.once_ms(200,getFirstTime);
|
||||||
ntimer.attach_ms(TSYNC_DELAY, syncTime);
|
ntimer.attach_ms(TSYNC_DELAY, syncTime);
|
||||||
|
#ifdef USE_NEXTION
|
||||||
|
nextion.startWeather();
|
||||||
|
#endif
|
||||||
if (network_on_connect) network_on_connect();
|
if (network_on_connect) network_on_connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef options_h
|
#ifndef options_h
|
||||||
#define options_h
|
#define options_h
|
||||||
|
|
||||||
#define VERSION "0.6.530"
|
#define VERSION "0.7.000"
|
||||||
|
|
||||||
/*******************************************************
|
/*******************************************************
|
||||||
DO NOT EDIT THIS FILE.
|
DO NOT EDIT THIS FILE.
|
||||||
@@ -57,6 +57,23 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
|
|||||||
#define TFT_DC 4
|
#define TFT_DC 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* NEXTION */
|
||||||
|
#ifndef NEXTION_RX
|
||||||
|
#define NEXTION_RX 255
|
||||||
|
#endif
|
||||||
|
#ifndef NEXTION_TX
|
||||||
|
#define NEXTION_TX 255
|
||||||
|
#endif
|
||||||
|
#ifndef NEXTION_WEATHER_LAT
|
||||||
|
#define NEXTION_WEATHER_LAT "55.7512"
|
||||||
|
#endif
|
||||||
|
#ifndef NEXTION_WEATHER_LON
|
||||||
|
#define NEXTION_WEATHER_LON "37.6184"
|
||||||
|
#endif
|
||||||
|
#ifndef NEXTION_WEATHER_KEY
|
||||||
|
#define NEXTION_WEATHER_KEY ""
|
||||||
|
#endif
|
||||||
|
|
||||||
/* OLED I2C DISPLAY */
|
/* OLED I2C DISPLAY */
|
||||||
#ifndef I2C_SDA
|
#ifndef I2C_SDA
|
||||||
#define I2C_SDA 13
|
#define I2C_SDA 13
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ void Player::stepVol(bool up) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
byte Player::volToI2S(byte volume) {
|
byte Player::volToI2S(byte volume) {
|
||||||
int vol = map(volume, 0, 254 - config.station.ovol * 2 , 0, 254);
|
int vol = map(volume, 0, 254 - config.station.ovol * 3 , 0, 254);
|
||||||
if (vol > 254) vol = 254;
|
if (vol > 254) vol = 254;
|
||||||
if (vol < 0) vol = 0;
|
if (vol < 0) vol = 0;
|
||||||
return vol;
|
return vol;
|
||||||
|
|||||||
@@ -2157,6 +2157,11 @@ bool Audio::pauseResume() {
|
|||||||
bool Audio::playChunk() {
|
bool Audio::playChunk() {
|
||||||
// If we've got data, try and pump it out..
|
// If we've got data, try and pump it out..
|
||||||
int16_t sample[2];
|
int16_t sample[2];
|
||||||
|
/* VU Meter ************************************************************************************************************/
|
||||||
|
/* По мотивам https://github.com/schreibfaul1/ESP32-audioI2S/pull/170/commits/6cce84217e5bc8f2f8925936affc84576932a29b */
|
||||||
|
uint8_t maxl = 0, maxr = 0;
|
||||||
|
uint8_t minl = 0xFF, minr = 0xFF;
|
||||||
|
/************************************************************************************************************ VU Meter */
|
||||||
if(getBitsPerSample() == 8) {
|
if(getBitsPerSample() == 8) {
|
||||||
if(getChannels() == 1) {
|
if(getChannels() == 1) {
|
||||||
while(m_validSamples) {
|
while(m_validSamples) {
|
||||||
@@ -2164,11 +2169,19 @@ bool Audio::playChunk() {
|
|||||||
uint8_t y = (m_outBuff[m_curSample] & 0xFF00) >> 8;
|
uint8_t y = (m_outBuff[m_curSample] & 0xFF00) >> 8;
|
||||||
sample[LEFTCHANNEL] = x;
|
sample[LEFTCHANNEL] = x;
|
||||||
sample[RIGHTCHANNEL] = x;
|
sample[RIGHTCHANNEL] = x;
|
||||||
|
if(sample[LEFTCHANNEL] > maxl ) maxl = sample[LEFTCHANNEL];
|
||||||
|
if(sample[RIGHTCHANNEL] > maxr ) maxr = sample[RIGHTCHANNEL];
|
||||||
|
if(sample[LEFTCHANNEL] < minl ) minl = sample[LEFTCHANNEL];
|
||||||
|
if(sample[RIGHTCHANNEL] < minr ) minr = sample[RIGHTCHANNEL];
|
||||||
while(1) {
|
while(1) {
|
||||||
if(playSample(sample)) break;
|
if(playSample(sample)) break;
|
||||||
} // Can't send?
|
} // Can't send?
|
||||||
sample[LEFTCHANNEL] = y;
|
sample[LEFTCHANNEL] = y;
|
||||||
sample[RIGHTCHANNEL] = y;
|
sample[RIGHTCHANNEL] = y;
|
||||||
|
if(sample[LEFTCHANNEL] > maxl ) maxl = sample[LEFTCHANNEL];
|
||||||
|
if(sample[RIGHTCHANNEL] > maxr ) maxr = sample[RIGHTCHANNEL];
|
||||||
|
if(sample[LEFTCHANNEL] < minl ) minl = sample[LEFTCHANNEL];
|
||||||
|
if(sample[RIGHTCHANNEL] < minr ) minr = sample[RIGHTCHANNEL];
|
||||||
while(1) {
|
while(1) {
|
||||||
if(playSample(sample)) break;
|
if(playSample(sample)) break;
|
||||||
} // Can't send?
|
} // Can't send?
|
||||||
@@ -2189,7 +2202,10 @@ bool Audio::playChunk() {
|
|||||||
sample[LEFTCHANNEL] = xy;
|
sample[LEFTCHANNEL] = xy;
|
||||||
sample[RIGHTCHANNEL] = xy;
|
sample[RIGHTCHANNEL] = xy;
|
||||||
}
|
}
|
||||||
|
if(sample[LEFTCHANNEL] > maxl ) maxl = sample[LEFTCHANNEL];
|
||||||
|
if(sample[RIGHTCHANNEL] > maxr ) maxr = sample[RIGHTCHANNEL];
|
||||||
|
if(sample[LEFTCHANNEL] < minl ) minl = sample[LEFTCHANNEL];
|
||||||
|
if(sample[RIGHTCHANNEL] < minr ) minr = sample[RIGHTCHANNEL];
|
||||||
while(1) {
|
while(1) {
|
||||||
if(playSample(sample)) break;
|
if(playSample(sample)) break;
|
||||||
} // Can't send?
|
} // Can't send?
|
||||||
@@ -2197,6 +2213,8 @@ bool Audio::playChunk() {
|
|||||||
m_curSample++;
|
m_curSample++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vuLeft = maxl - minl;
|
||||||
|
vuRight = maxr - minr;
|
||||||
m_curSample = 0;
|
m_curSample = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2205,6 +2223,10 @@ bool Audio::playChunk() {
|
|||||||
while(m_validSamples) {
|
while(m_validSamples) {
|
||||||
sample[LEFTCHANNEL] = m_outBuff[m_curSample];
|
sample[LEFTCHANNEL] = m_outBuff[m_curSample];
|
||||||
sample[RIGHTCHANNEL] = m_outBuff[m_curSample];
|
sample[RIGHTCHANNEL] = m_outBuff[m_curSample];
|
||||||
|
if(sample[LEFTCHANNEL] > maxl ) maxl = sample[LEFTCHANNEL];
|
||||||
|
if(sample[RIGHTCHANNEL] > maxr ) maxr = sample[RIGHTCHANNEL];
|
||||||
|
if(sample[LEFTCHANNEL] < minl ) minl = sample[LEFTCHANNEL];
|
||||||
|
if(sample[RIGHTCHANNEL] < minr ) minr = sample[RIGHTCHANNEL];
|
||||||
if(!playSample(sample)) {
|
if(!playSample(sample)) {
|
||||||
return false;
|
return false;
|
||||||
} // Can't send
|
} // Can't send
|
||||||
@@ -2223,6 +2245,10 @@ bool Audio::playChunk() {
|
|||||||
sample[LEFTCHANNEL] = xy;
|
sample[LEFTCHANNEL] = xy;
|
||||||
sample[RIGHTCHANNEL] = xy;
|
sample[RIGHTCHANNEL] = xy;
|
||||||
}
|
}
|
||||||
|
if(sample[LEFTCHANNEL] > maxl ) maxl = sample[LEFTCHANNEL];
|
||||||
|
if(sample[RIGHTCHANNEL] > maxr ) maxr = sample[RIGHTCHANNEL];
|
||||||
|
if(sample[LEFTCHANNEL] < minl ) minl = sample[LEFTCHANNEL];
|
||||||
|
if(sample[RIGHTCHANNEL] < minr ) minr = sample[RIGHTCHANNEL];
|
||||||
if(!playSample(sample)) {
|
if(!playSample(sample)) {
|
||||||
return false;
|
return false;
|
||||||
} // Can't send
|
} // Can't send
|
||||||
@@ -2230,6 +2256,8 @@ bool Audio::playChunk() {
|
|||||||
m_curSample++;
|
m_curSample++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vuLeft = maxl - minl;
|
||||||
|
vuRight = maxr - minr;
|
||||||
m_curSample = 0;
|
m_curSample = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4269,8 +4297,6 @@ int32_t Audio::Gain(int16_t s[2]) {
|
|||||||
step = step * m_balance * 16;
|
step = step * m_balance * 16;
|
||||||
r = (uint8_t)(step);
|
r = (uint8_t)(step);
|
||||||
}
|
}
|
||||||
vuLeft = s[LEFTCHANNEL] >> 7;
|
|
||||||
vuRight = s[RIGHTCHANNEL] >> 7;
|
|
||||||
v[LEFTCHANNEL] = (s[LEFTCHANNEL] * (m_vol - l)) >> 8;
|
v[LEFTCHANNEL] = (s[LEFTCHANNEL] * (m_vol - l)) >> 8;
|
||||||
v[RIGHTCHANNEL]= (s[RIGHTCHANNEL] * (m_vol - r)) >> 8;
|
v[RIGHTCHANNEL]= (s[RIGHTCHANNEL] * (m_vol - r)) >> 8;
|
||||||
|
|
||||||
|
|||||||
@@ -467,6 +467,7 @@ void Audio::stopSong()
|
|||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void Audio::softReset()
|
void Audio::softReset()
|
||||||
{
|
{
|
||||||
|
if(VS1053_RST>0) return; // Hard resrt present
|
||||||
write_register(SCI_MODE, _BV (SM_SDINEW) | _BV(SM_RESET));
|
write_register(SCI_MODE, _BV (SM_SDINEW) | _BV(SM_RESET));
|
||||||
delay(10);
|
delay(10);
|
||||||
await_data_request();
|
await_data_request();
|
||||||
@@ -1568,7 +1569,7 @@ void Audio::setDefaults(){
|
|||||||
* \n The VU meter takes about 0.2MHz of processing power with 48 kHz samplerate.
|
* \n The VU meter takes about 0.2MHz of processing power with 48 kHz samplerate.
|
||||||
*/
|
*/
|
||||||
void Audio::setVUmeter() {
|
void Audio::setVUmeter() {
|
||||||
if(!ENABLE_VU_METER) return;
|
// if(!ENABLE_VU_METER) return;
|
||||||
uint16_t MP3Status = read_register(SCI_STATUS);
|
uint16_t MP3Status = read_register(SCI_STATUS);
|
||||||
write_register(SCI_STATUS, MP3Status | _BV(9));
|
write_register(SCI_STATUS, MP3Status | _BV(9));
|
||||||
}
|
}
|
||||||
@@ -1586,12 +1587,14 @@ void Audio::setVUmeter() {
|
|||||||
* \warning This feature is only available with patches that support VU meter.
|
* \warning This feature is only available with patches that support VU meter.
|
||||||
*/
|
*/
|
||||||
void Audio::getVUlevel() {
|
void Audio::getVUlevel() {
|
||||||
if(!ENABLE_VU_METER) return;
|
// if(!ENABLE_VU_METER) return;
|
||||||
int16_t reg = read_register(SCI_AICTRL3);
|
int16_t reg = read_register(SCI_AICTRL3);
|
||||||
uint8_t rl = map((uint8_t)reg, 81, 92, 0, 255);
|
uint8_t rl = map((uint8_t)reg, 85, 92, 0, 255);
|
||||||
uint8_t rr = map((uint8_t)(reg >> 8), 81, 92, 0, 255);
|
uint8_t rr = map((uint8_t)(reg >> 8), 85, 92, 0, 255);
|
||||||
if(rl>30 || !isRunning()) vuLeft = rl;
|
//if(rl>30 || !isRunning()) vuLeft = rl;
|
||||||
if(rr>30 || !isRunning()) vuRight = rr;
|
//if(rr>30 || !isRunning()) vuRight = rr;
|
||||||
|
vuLeft = rl;
|
||||||
|
vuRight = rr;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
bool Audio::connecttohost(String host){
|
bool Audio::connecttohost(String host){
|
||||||
|
|||||||
778
yoRadio/src/displays/nextion.cpp
Normal file
778
yoRadio/src/displays/nextion.cpp
Normal file
@@ -0,0 +1,778 @@
|
|||||||
|
#include "../../options.h"
|
||||||
|
|
||||||
|
#if NEXTION_RX!=255 && NEXTION_TX!=255
|
||||||
|
#include "nextion.h"
|
||||||
|
#include "../../config.h"
|
||||||
|
|
||||||
|
#include "../../player.h"
|
||||||
|
#include "../../controls.h"
|
||||||
|
#include "../../netserver.h"
|
||||||
|
#include "../../network.h"
|
||||||
|
|
||||||
|
#ifndef CORE_STACK_SIZE
|
||||||
|
#define CORE_STACK_SIZE 1024*3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HardwareSerial hSerial(1); // use UART1
|
||||||
|
Ticker weatherticker;
|
||||||
|
//char weather[254] = { 0 };
|
||||||
|
//bool weatherRequest = false;
|
||||||
|
|
||||||
|
|
||||||
|
const char *ndow[7] = {"воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"};
|
||||||
|
const char *nmnths[12] = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"};
|
||||||
|
|
||||||
|
#ifdef DUMMYDISPLAY
|
||||||
|
void ticks() {
|
||||||
|
network.timeinfo.tm_sec ++;
|
||||||
|
mktime(&network.timeinfo);
|
||||||
|
nextion.putRequest({CLOCK,0});
|
||||||
|
if(nextion.mode==TIMEZONE) nextion.localTime(network.timeinfo);
|
||||||
|
if(nextion.mode==INFO) nextion.rssi();
|
||||||
|
if(nextion.dt){
|
||||||
|
int rssi = WiFi.RSSI();
|
||||||
|
netserver.setRSSI(rssi);
|
||||||
|
}
|
||||||
|
nextion.dt=!nextion.dt;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Nextion::Nextion() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void nextionCore0( void * pvParameters ){
|
||||||
|
delay(500);
|
||||||
|
while(true){
|
||||||
|
// if(displayQueue==NULL) break;
|
||||||
|
nextion.loop();
|
||||||
|
vTaskDelay(5);
|
||||||
|
}
|
||||||
|
vTaskDelete( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::createCore0Task(){
|
||||||
|
xTaskCreatePinnedToCore(
|
||||||
|
nextionCore0, /* Task function. */
|
||||||
|
"TaskCore0", /* name of task. */
|
||||||
|
CORE_STACK_SIZE, /* Stack size of task */
|
||||||
|
NULL, /* parameter of the task */
|
||||||
|
4, /* no one flies higher than the Toruk */
|
||||||
|
&_TaskCore0, /* Task handle to keep track of created task */
|
||||||
|
!xPortGetCoreID()); /* pin task to core 0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::begin(bool dummy) {
|
||||||
|
_dummyDisplay=dummy;
|
||||||
|
hSerial.begin(NEXTION_BAUD, SERIAL_8N1, NEXTION_RX, NEXTION_TX);
|
||||||
|
if (!hSerial) {
|
||||||
|
Serial.println("Invalid HardwareSerial pin configuration, check config");
|
||||||
|
while (1) {
|
||||||
|
delay (1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rx_pos = 0;
|
||||||
|
_volInside=false;
|
||||||
|
snprintf(_espcoreversion, sizeof(_espcoreversion) - 1, "%d.%d.%d", ESP_ARDUINO_VERSION_MAJOR, ESP_ARDUINO_VERSION_MINOR, ESP_ARDUINO_VERSION_PATCH);
|
||||||
|
putcmd("rest");
|
||||||
|
delay(200);
|
||||||
|
putcmd("bkcmd=0");
|
||||||
|
// putcmd("page boot");
|
||||||
|
if(dummy) {
|
||||||
|
_displayQueue = xQueueCreate( 5, sizeof( requestParams_t ) );
|
||||||
|
createCore0Task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::start(){
|
||||||
|
if (network.status != CONNECTED) {
|
||||||
|
apScreen();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef DUMMYDISPLAY
|
||||||
|
if(_dummyDisplay) _timer.attach_ms(1000, ticks);
|
||||||
|
display.mode = PLAYER;
|
||||||
|
config.setTitle("[READY]");
|
||||||
|
#endif
|
||||||
|
mode = PLAYER;
|
||||||
|
putcmd("page player");
|
||||||
|
delay(100);
|
||||||
|
#ifdef DUMMYDISPLAY
|
||||||
|
newNameset(config.station.name);
|
||||||
|
newTitle(config.station.title);
|
||||||
|
#endif
|
||||||
|
setVol(config.store.volume, mode == VOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::apScreen() {
|
||||||
|
putcmd("apscreenlock=1");
|
||||||
|
putcmd("page settings_wifi");
|
||||||
|
//char cmd[20];
|
||||||
|
/*for(int i=0;i<5;i++){
|
||||||
|
snprintf(cmd, sizeof(cmd)-1, "vis b%d,%d", i, 0);
|
||||||
|
putcmd(cmd);
|
||||||
|
}*/
|
||||||
|
//putcmd("vis btnBack,0");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::putRequest(requestParams_t request){
|
||||||
|
if(_displayQueue==NULL) return;
|
||||||
|
xQueueSend(_displayQueue, &request, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::processQueue(){
|
||||||
|
if(_displayQueue==NULL) return;
|
||||||
|
requestParams_t request;
|
||||||
|
if(xQueueReceive(_displayQueue, &request, 20)){
|
||||||
|
switch (request.type){
|
||||||
|
case NEWMODE: {
|
||||||
|
swichMode((displayMode_e)request.payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CLOCK: {
|
||||||
|
printClock(network.timeinfo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NEWTITLE: {
|
||||||
|
newTitle(config.station.title);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RETURNTITLE: {
|
||||||
|
//returnTile();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NEWSTATION: {
|
||||||
|
newNameset(config.station.name);
|
||||||
|
bitrate(config.station.bitrate);
|
||||||
|
bitratePic(ICON_NA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NEXTSTATION: {
|
||||||
|
drawNextStationNum((displayMode_e)request.payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DRAWPLAYLIST: {
|
||||||
|
int p = request.payload ? display.currentPlItem + 1 : display.currentPlItem - 1;
|
||||||
|
if (p < 1) p = config.store.countStation;
|
||||||
|
if (p > config.store.countStation) p = 1;
|
||||||
|
display.currentPlItem = p;
|
||||||
|
drawPlaylist(display.currentPlItem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DRAWVOL: {
|
||||||
|
if(!_volInside){
|
||||||
|
setVol(config.store.volume, mode == VOL);
|
||||||
|
}
|
||||||
|
_volInside=false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (mode) {
|
||||||
|
case PLAYER: {
|
||||||
|
//drawPlayer();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INFO:
|
||||||
|
case TIMEZONE: {
|
||||||
|
//sendInfo();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VOL: {
|
||||||
|
if (millis() - _volDelay > 3000) {
|
||||||
|
_volDelay = millis();
|
||||||
|
swichMode(PLAYER);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NUMBERS: {
|
||||||
|
//meta.loop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STATIONS: {
|
||||||
|
//plCurrent.loop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::loop() {
|
||||||
|
processQueue();
|
||||||
|
drawVU();
|
||||||
|
char RxTemp;
|
||||||
|
char scanBuf[50];
|
||||||
|
int scanDigit; (void)scanDigit;
|
||||||
|
static String wifisettings;
|
||||||
|
if (hSerial.available() > 4) {
|
||||||
|
RxTemp = hSerial.read();
|
||||||
|
if (RxTemp != '^') {
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
rx_pos = 0;
|
||||||
|
rxbuf[rx_pos] = '\0';
|
||||||
|
}
|
||||||
|
while (hSerial.available()) {
|
||||||
|
RxTemp = hSerial.read();
|
||||||
|
if (RxTemp == '^') {
|
||||||
|
rx_pos = 0;
|
||||||
|
rxbuf[rx_pos] = '\0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (RxTemp != '$') {
|
||||||
|
rxbuf[rx_pos] = RxTemp;
|
||||||
|
rx_pos++;
|
||||||
|
} else {
|
||||||
|
rxbuf[rx_pos] = '\0';
|
||||||
|
rx_pos = 0;
|
||||||
|
if (sscanf(rxbuf, "page=%s", scanBuf) == 1){
|
||||||
|
if(strcmp(scanBuf, "player") == 0) display.putRequest({NEWMODE, PLAYER});
|
||||||
|
if(strcmp(scanBuf, "playlist") == 0) display.putRequest({NEWMODE, STATIONS});
|
||||||
|
if(strcmp(scanBuf, "info") == 0) {
|
||||||
|
putcmd("yoversion.txt", VERSION);
|
||||||
|
putcmd("espcore.txt", _espcoreversion);
|
||||||
|
putcmd("ipaddr.txt", WiFi.localIP().toString().c_str());
|
||||||
|
putcmd("ssid.txt", WiFi.SSID().c_str());
|
||||||
|
display.putRequest({NEWMODE, INFO});
|
||||||
|
}
|
||||||
|
if(strcmp(scanBuf, "eq") == 0) {
|
||||||
|
putcmd("t4.txt", config.store.balance, true);
|
||||||
|
putcmd("h0.val", config.store.balance+16);
|
||||||
|
putcmd("t5.txt", config.store.trebble, true);
|
||||||
|
putcmd("h1.val", config.store.trebble+16);
|
||||||
|
putcmd("t6.txt", config.store.middle, true);
|
||||||
|
putcmd("h2.val", config.store.middle+16);
|
||||||
|
putcmd("t7.txt", config.store.bass, true);
|
||||||
|
putcmd("h3.val", config.store.bass+16);
|
||||||
|
display.putRequest({NEWMODE, SETTINGS});
|
||||||
|
}
|
||||||
|
if(strcmp(scanBuf, "wifi") == 0) {
|
||||||
|
if(mode != WIFI){
|
||||||
|
char cell[10];
|
||||||
|
wifisettings="";
|
||||||
|
for(int i=0;i<config.ssidsCount;i++){
|
||||||
|
snprintf(cell, sizeof(cell) - 1, "t%d.txt", i*2);
|
||||||
|
putcmd(cell, config.ssids[i].ssid);
|
||||||
|
snprintf(cell, sizeof(cell) - 1, "t%d.txt", i*2+1);
|
||||||
|
putcmd(cell, config.ssids[i].password);
|
||||||
|
}
|
||||||
|
display.putRequest({NEWMODE, WIFI});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(strcmp(scanBuf, "time") == 0) {
|
||||||
|
putcmdf("tzHourText.txt=\"%02d\"", config.store.tzHour);
|
||||||
|
putcmd("tzHour.val", config.store.tzHour);
|
||||||
|
putcmdf("tzMinText.txt=\"%02d\"", config.store.tzMin);
|
||||||
|
putcmd("tzMin.val", config.store.tzMin);
|
||||||
|
display.putRequest({NEWMODE, TIMEZONE});
|
||||||
|
}
|
||||||
|
if(strcmp(scanBuf, "sys") == 0) {
|
||||||
|
putcmd("smartstart.val", config.store.smartstart==2?0:1);
|
||||||
|
putcmd("audioinfo.val", config.store.audioinfo);
|
||||||
|
display.putRequest({NEWMODE, SETTINGS});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "ctrls=%s", scanBuf) == 1){
|
||||||
|
if(strcmp(scanBuf, "up") == 0) {
|
||||||
|
display.resetQueue();
|
||||||
|
display.putRequest({DRAWPLAYLIST, false});
|
||||||
|
}
|
||||||
|
if(strcmp(scanBuf, "dn") == 0) {
|
||||||
|
display.resetQueue();
|
||||||
|
display.putRequest({DRAWPLAYLIST, true});
|
||||||
|
}
|
||||||
|
if(strcmp(scanBuf, "go") == 0) {
|
||||||
|
display.putRequest({NEWMODE, PLAYER});
|
||||||
|
player.request.station=display.currentPlItem;
|
||||||
|
}
|
||||||
|
if(strcmp(scanBuf, "toggle") == 0) {
|
||||||
|
player.toggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "vol=%d", &scanDigit) == 1){
|
||||||
|
_volInside = true;
|
||||||
|
player.request.volume=scanDigit;
|
||||||
|
player.request.doSave=true;
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "balance=%d", &scanDigit) == 1){
|
||||||
|
config.setBalance((int8_t)scanDigit);
|
||||||
|
player.setBalance(config.store.balance);
|
||||||
|
netserver.requestOnChange(BALANCE, 0);
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "treble=%d", &scanDigit) == 1){
|
||||||
|
player.setTone(config.store.bass, config.store.middle, scanDigit);
|
||||||
|
config.setTone(config.store.bass, config.store.middle, scanDigit);
|
||||||
|
netserver.requestOnChange(EQUALIZER, 0);
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "middle=%d", &scanDigit) == 1){
|
||||||
|
player.setTone(config.store.bass, scanDigit, config.store.trebble);
|
||||||
|
config.setTone(config.store.bass, scanDigit, config.store.trebble);
|
||||||
|
netserver.requestOnChange(EQUALIZER, 0);
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "bass=%d", &scanDigit) == 1){
|
||||||
|
player.setTone(scanDigit, config.store.middle, config.store.trebble);
|
||||||
|
config.setTone(scanDigit, config.store.middle, config.store.trebble);
|
||||||
|
netserver.requestOnChange(EQUALIZER, 0);
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "tzhour=%d", &scanDigit) == 1){
|
||||||
|
config.setTimezone((int8_t)scanDigit, config.store.tzMin);
|
||||||
|
configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), SNTP_SERVER);
|
||||||
|
network.requestTimeSync(true);
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "tzmin=%d", &scanDigit) == 1){
|
||||||
|
config.setTimezone(config.store.tzHour, (int8_t)scanDigit);
|
||||||
|
configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), SNTP_SERVER);
|
||||||
|
network.requestTimeSync(true);
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "audioinfo=%d", &scanDigit) == 1){
|
||||||
|
config.store.audioinfo = scanDigit;
|
||||||
|
config.save();
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "smartstart=%d", &scanDigit) == 1){
|
||||||
|
config.store.smartstart = scanDigit==0?2:1;
|
||||||
|
config.save();
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "addssid=%s", scanBuf) == 1){
|
||||||
|
wifisettings+=(String(scanBuf)+"\t");
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "addpass=%s", scanBuf) == 1){
|
||||||
|
wifisettings+=(String(scanBuf)+"\n");
|
||||||
|
}
|
||||||
|
if (sscanf(rxbuf, "wifidone=%d", &scanDigit) == 1){
|
||||||
|
config.saveWifi(wifisettings.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::drawVU(){
|
||||||
|
//if(mode!=PLAYER) return;
|
||||||
|
if(mode!=PLAYER && mode!=VOL) return;
|
||||||
|
static uint8_t measL, measR;
|
||||||
|
player.getVUlevel();
|
||||||
|
uint8_t L = map(player.vuLeft, 0, 255, 0, 100);
|
||||||
|
uint8_t R = map(player.vuRight, 0, 255, 0, 100);
|
||||||
|
if(player.isRunning()){
|
||||||
|
measL=(L<=measL)?measL-5:L;
|
||||||
|
measR=(R<=measR)?measR-5:R;
|
||||||
|
}else{
|
||||||
|
if(measL>0) measL-=5;
|
||||||
|
if(measR>0) measR-=5;
|
||||||
|
}
|
||||||
|
if(measL>100) measL=0;
|
||||||
|
if(measR>100) measR=0;
|
||||||
|
fillVU(measL, measR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::putcmd(const char* cmd) {
|
||||||
|
snprintf(txbuf, sizeof(txbuf) - 1, "%s\xFF\xFF\xFF", cmd);
|
||||||
|
hSerial.print(txbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::putcmd(const char* cmd, const char* val, uint16_t dl) {
|
||||||
|
snprintf(txbuf, sizeof(txbuf) - 1, "%s=\"%s\"\xFF\xFF\xFF", cmd, val);
|
||||||
|
hSerial.print(txbuf);
|
||||||
|
if(dl>0) delay(dl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::putcmd(const char* cmd, int val, bool toString, uint16_t dl) {
|
||||||
|
if(toString){
|
||||||
|
snprintf(txbuf, sizeof(txbuf) - 1, "%s=\"%d\"\xFF\xFF\xFF", cmd, val);
|
||||||
|
}else{
|
||||||
|
snprintf(txbuf, sizeof(txbuf) - 1, "%s=%d\xFF\xFF\xFF", cmd, val);
|
||||||
|
}
|
||||||
|
hSerial.print(txbuf);
|
||||||
|
if(dl>0) delay(dl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::putcmdf(const char* fmt, int val, uint16_t dl) {
|
||||||
|
snprintf(txbuf, sizeof(txbuf) - 1, fmt, val);
|
||||||
|
hSerial.print(txbuf);
|
||||||
|
hSerial.print("\xFF\xFF\xFF");
|
||||||
|
if(dl>0) delay(dl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::bitrate(int bpm){
|
||||||
|
if(bpm>0){
|
||||||
|
putcmd("player.bitrate.txt", bpm, true);
|
||||||
|
}else{
|
||||||
|
putcmd("player.bitrate.txt=\"und\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::rssi(){
|
||||||
|
putcmdf("rssi.txt=\"%d dBm\"", WiFi.RSSI());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::weatherVisible(uint8_t vis){
|
||||||
|
putcmd("weatherVisible", vis, false, 20);
|
||||||
|
putcmdf("vis press_img,%d", vis, 20);
|
||||||
|
putcmdf("vis press_txt,%d", vis, 20);
|
||||||
|
putcmdf("vis hum_img,%d", vis, 20);
|
||||||
|
putcmdf("vis hum_txt,%d", vis, 20);
|
||||||
|
putcmdf("vis temp_img,%d", vis, 20);
|
||||||
|
putcmdf("vis temp_txt,%d", vis, 20);
|
||||||
|
putcmdf("vis cond_img,%d", vis, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::bitratePic(uint8_t pic){
|
||||||
|
putcmd("player.bitrate.pic", pic);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::bootString(const char* bs) {
|
||||||
|
char buf[50] = { 0 };
|
||||||
|
strlcpy(buf, bs, 50);
|
||||||
|
putcmd("boot.bootstring.txt", utf8Rus(buf, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::newNameset(const char* meta){
|
||||||
|
char newnameset[59] = { 0 };
|
||||||
|
strlcpy(newnameset, meta, 59);
|
||||||
|
putcmd("player.meta.txt", utf8Rus(newnameset, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::setVol(uint8_t vol, bool dialog){
|
||||||
|
if(dialog){
|
||||||
|
putcmd("dialog.text.txt", vol, true);
|
||||||
|
}/*else{
|
||||||
|
putcmd("player.volText.txt", vol, true);
|
||||||
|
putcmd("player.volumeSlider.val", vol);
|
||||||
|
}*/
|
||||||
|
putcmd("player.volText.txt", vol, true);
|
||||||
|
putcmd("player.volumeSlider.val", vol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::fillVU(uint8_t LC, uint8_t RC){
|
||||||
|
putcmd("player.vul.val", LC);
|
||||||
|
putcmd("player.vur.val", RC);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::newTitle(const char* title){
|
||||||
|
char ttl[50] = { 0 };
|
||||||
|
char sng[50] = { 0 };
|
||||||
|
if (strlen(title) > 0) {
|
||||||
|
char* ici;
|
||||||
|
if ((ici = strstr(title, " - ")) != NULL) {
|
||||||
|
strlcpy(sng, ici + 3, 50);
|
||||||
|
strlcpy(ttl, title, strlen(title) - strlen(ici) + 1);
|
||||||
|
} else {
|
||||||
|
strlcpy(ttl, title, 50);
|
||||||
|
sng[0] = '\0';
|
||||||
|
}
|
||||||
|
putcmd("player.title1.txt", utf8Rus(ttl, true));
|
||||||
|
putcmd("player.title2.txt", utf8Rus(sng, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::printClock(struct tm timeinfo){
|
||||||
|
char timeStringBuff[70] = { 0 };
|
||||||
|
strftime(timeStringBuff, sizeof(timeStringBuff), "player.clock.txt=\"%H:%M\"", &timeinfo);
|
||||||
|
putcmd(timeStringBuff);
|
||||||
|
putcmdf("player.secText.txt=\"%02d\"", timeinfo.tm_sec);
|
||||||
|
snprintf(timeStringBuff, sizeof(timeStringBuff), "player.dateText.txt=\"%s, %d %s %d\"", ndow[timeinfo.tm_wday], timeinfo.tm_mday, nmnths[timeinfo.tm_mon], timeinfo.tm_year+1900);
|
||||||
|
putcmd(utf8Rus(timeStringBuff, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::localTime(struct tm timeinfo){
|
||||||
|
char timeStringBuff[40] = { 0 };
|
||||||
|
strftime(timeStringBuff, sizeof(timeStringBuff), "localTime.txt=\"%H:%M:%S\"", &timeinfo);
|
||||||
|
putcmd(timeStringBuff);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::drawPlaylist(uint16_t currentPlItem){
|
||||||
|
char plMenu[7][40];
|
||||||
|
for (byte i = 0; i < 7; i++) {
|
||||||
|
plMenu[i][0] = '\0';
|
||||||
|
}
|
||||||
|
config.fillPlMenu(plMenu, currentPlItem - 3, 7);
|
||||||
|
char cmd[60]={0};
|
||||||
|
for (byte i = 0; i < 7; i++) {
|
||||||
|
snprintf(cmd, sizeof(cmd) - 1, "t%d.txt=\"%s\"", i, nextion.utf8Rus(plMenu[i], true));
|
||||||
|
putcmd(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::drawNextStationNum(uint16_t num) {//dialog
|
||||||
|
char plMenu[1][40];
|
||||||
|
char currentItemText[40] = {0};
|
||||||
|
config.fillPlMenu(plMenu, num, 1, true);
|
||||||
|
strlcpy(currentItemText, plMenu[0], 39);
|
||||||
|
//meta.setText(dsp.utf8Rus(currentItemText, true));
|
||||||
|
putcmd("dialog.title.txt", utf8Rus(currentItemText, true));
|
||||||
|
putcmd("dialog.text.txt", num, true);
|
||||||
|
//dsp.drawNextStationNum(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::swichMode(displayMode_e newmode){
|
||||||
|
if (newmode == VOL) {
|
||||||
|
_volDelay = millis();
|
||||||
|
}
|
||||||
|
if (newmode == mode) return;
|
||||||
|
mode = newmode;
|
||||||
|
#ifdef DUMMYDISPLAY
|
||||||
|
display.mode = newmode;
|
||||||
|
#endif
|
||||||
|
/* if (newmode != STATIONS) {
|
||||||
|
ip();
|
||||||
|
volume();
|
||||||
|
}*/
|
||||||
|
if (newmode == PLAYER) {
|
||||||
|
putcmd("page player");
|
||||||
|
putcmd("dialog.title.txt", "");
|
||||||
|
putcmd("dialog.text.txt", "");
|
||||||
|
}
|
||||||
|
if (newmode == VOL) {
|
||||||
|
putcmd("dialog.title.txt", "VOLUME");
|
||||||
|
putcmd("page dialog");
|
||||||
|
putcmd("icon.pic", 65);
|
||||||
|
}
|
||||||
|
if (newmode == LOST) {
|
||||||
|
putcmd("page lost");
|
||||||
|
}
|
||||||
|
if (newmode == UPDATING) {
|
||||||
|
putcmd("page updating");
|
||||||
|
}
|
||||||
|
if (newmode == NUMBERS) {
|
||||||
|
putcmd("page dialog");
|
||||||
|
putcmd("icon.pic", 63);
|
||||||
|
}
|
||||||
|
if (newmode == STATIONS) {
|
||||||
|
putcmd("page playlist");
|
||||||
|
#ifdef DUMMYDISPLAY
|
||||||
|
display.currentPlItem = config.store.lastStation;
|
||||||
|
#endif
|
||||||
|
drawPlaylist(config.store.lastStation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Nextion::getForecast(){
|
||||||
|
WiFiClient client;
|
||||||
|
const char* host = "api.openweathermap.org";
|
||||||
|
if (!client.connect(host, 80)) {
|
||||||
|
Serial.println("## OPENWEATHERMAP ###: connection failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char httpget[250] = {0};
|
||||||
|
sprintf(httpget, "GET /data/2.5/weather?lat=%s&lon=%s&units=metric&lang=ru&appid=%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", NEXTION_WEATHER_LAT, NEXTION_WEATHER_LON, NEXTION_WEATHER_KEY, host);
|
||||||
|
client.print(httpget);
|
||||||
|
unsigned long timeout = millis();
|
||||||
|
while (client.available() == 0) {
|
||||||
|
if (millis() - timeout > 2000UL) {
|
||||||
|
Serial.println("## OPENWEATHERMAP ###: client available timeout !");
|
||||||
|
client.stop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timeout = millis();
|
||||||
|
String line = "";
|
||||||
|
if (client.connected()) {
|
||||||
|
while (client.available())
|
||||||
|
{
|
||||||
|
line = client.readStringUntil('\n');
|
||||||
|
if (strstr(line.c_str(), "\"temp\"") != NULL) {
|
||||||
|
client.stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((millis() - timeout) > 500)
|
||||||
|
{
|
||||||
|
client.stop();
|
||||||
|
Serial.println("## OPENWEATHERMAP ###: client read timeout !");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strstr(line.c_str(), "\"temp\"") == NULL) {
|
||||||
|
Serial.println("## OPENWEATHERMAP ###: weather not found !");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char *tmpe;
|
||||||
|
char *tmps;
|
||||||
|
const char* cursor = line.c_str();
|
||||||
|
char desc[120], temp[20], hum[20], press[20], icon[5];
|
||||||
|
|
||||||
|
tmps = strstr(cursor, "\"description\":\"");
|
||||||
|
if (tmps == NULL) { Serial.println("## OPENWEATHERMAP ###: description not found !"); return false;}
|
||||||
|
tmps += 15;
|
||||||
|
tmpe = strstr(tmps, "\",\"");
|
||||||
|
if (tmpe == NULL) { Serial.println("## OPENWEATHERMAP ###: description not found !"); return false;}
|
||||||
|
strlcpy(desc, tmps, tmpe - tmps + 1);
|
||||||
|
cursor = tmpe + 2;
|
||||||
|
|
||||||
|
// "ясно","icon":"01d"}],
|
||||||
|
tmps = strstr(cursor, "\"icon\":\"");
|
||||||
|
if (tmps == NULL) { Serial.println("## OPENWEATHERMAP ###: icon not found !"); return false;}
|
||||||
|
tmps += 8;
|
||||||
|
tmpe = strstr(tmps, "\"}");
|
||||||
|
if (tmpe == NULL) { Serial.println("## OPENWEATHERMAP ###: icon not found !"); return false;}
|
||||||
|
strlcpy(icon, tmps, tmpe - tmps + 1);
|
||||||
|
cursor = tmpe + 2;
|
||||||
|
|
||||||
|
tmps = strstr(cursor, "\"temp\":");
|
||||||
|
if (tmps == NULL) { Serial.println("## OPENWEATHERMAP ###: temp not found !"); return false;}
|
||||||
|
tmps += 7;
|
||||||
|
tmpe = strstr(tmps, ",\"");
|
||||||
|
if (tmpe == NULL) { Serial.println("## OPENWEATHERMAP ###: temp not found !"); return false;}
|
||||||
|
strlcpy(temp, tmps, tmpe - tmps + 1);
|
||||||
|
cursor = tmpe + 2;
|
||||||
|
float tempf = atof(temp);
|
||||||
|
tmps = strstr(cursor, "\"pressure\":");
|
||||||
|
if (tmps == NULL) { Serial.println("## OPENWEATHERMAP ###: pressure not found !"); return false;}
|
||||||
|
tmps += 11;
|
||||||
|
tmpe = strstr(tmps, ",\"");
|
||||||
|
if (tmpe == NULL) { Serial.println("## OPENWEATHERMAP ###: pressure not found !"); return false;}
|
||||||
|
strlcpy(press, tmps, tmpe - tmps + 1);
|
||||||
|
cursor = tmpe + 2;
|
||||||
|
int pressi = (float)atoi(press) / 1.333;
|
||||||
|
|
||||||
|
tmps = strstr(cursor, "humidity\":");
|
||||||
|
if (tmps == NULL) { Serial.println("## OPENWEATHERMAP ###: humidity not found !"); return false;}
|
||||||
|
tmps += 10;
|
||||||
|
tmpe = strstr(tmps, ",\"");
|
||||||
|
if (tmpe == NULL) { Serial.println("## OPENWEATHERMAP ###: humidity not found !"); return false;}
|
||||||
|
strlcpy(hum, tmps, tmpe - tmps + 1);
|
||||||
|
|
||||||
|
if(config.store.audioinfo) Serial.printf("## OPENWEATHERMAP ###: description: %s, temp:%.1f C, pressure:%dmmHg, humidity:%s%%\n", desc, tempf, pressi, hum);
|
||||||
|
|
||||||
|
putcmdf("press_txt.txt=\"%dmm\"", pressi);
|
||||||
|
putcmdf("hum_txt.txt=\"%d%%\"", atoi(hum));
|
||||||
|
char cmd[30];
|
||||||
|
snprintf(cmd, sizeof(cmd)-1,"temp_txt.txt=\"%.1f\"", tempf);
|
||||||
|
putcmd(cmd);
|
||||||
|
int iconofset;
|
||||||
|
if(strstr(icon,"01")!=NULL){
|
||||||
|
iconofset = 0;
|
||||||
|
}else if(strstr(icon,"02")!=NULL){
|
||||||
|
iconofset = 1;
|
||||||
|
}else if(strstr(icon,"03")!=NULL){
|
||||||
|
iconofset = 2;
|
||||||
|
}else if(strstr(icon,"04")!=NULL){
|
||||||
|
iconofset = 3;
|
||||||
|
}else if(strstr(icon,"09")!=NULL){
|
||||||
|
iconofset = 4;
|
||||||
|
}else if(strstr(icon,"10")!=NULL){
|
||||||
|
iconofset = 5;
|
||||||
|
}else if(strstr(icon,"11")!=NULL){
|
||||||
|
iconofset = 6;
|
||||||
|
}else if(strstr(icon,"13")!=NULL){
|
||||||
|
iconofset = 7;
|
||||||
|
}else if(strstr(icon,"50")!=NULL){
|
||||||
|
iconofset = 8;
|
||||||
|
}else{
|
||||||
|
iconofset = 9;
|
||||||
|
}
|
||||||
|
putcmd("cond_img.pic", 50+iconofset);
|
||||||
|
weatherVisible(1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::getWeather(void * pvParameters){
|
||||||
|
delay(200);
|
||||||
|
if (nextion.getForecast()) {
|
||||||
|
// nextion.weatherRequest = true;
|
||||||
|
weatherticker.detach();
|
||||||
|
weatherticker.attach(WEATHER_REQUEST_INTERVAL, nextion.updateWeather);
|
||||||
|
} else {
|
||||||
|
weatherticker.detach();
|
||||||
|
weatherticker.attach(WEATHER_REQUEST_INTERVAL_FAULTY, nextion.updateWeather);
|
||||||
|
}
|
||||||
|
vTaskDelete( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::updateWeather() {
|
||||||
|
xTaskCreatePinnedToCore(
|
||||||
|
nextion.getWeather, /* Task function. */
|
||||||
|
"nextiongetWeather", /* name of task. */
|
||||||
|
1024 * 4, /* Stack size of task */
|
||||||
|
NULL, /* parameter of the task */
|
||||||
|
0, /* priority of the task */
|
||||||
|
&nextion.weatherUpdateTaskHandle, /* Task handle to keep track of created task */
|
||||||
|
0); /* pin task to core CORE_FOR_LOOP_CONTROLS */
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nextion::startWeather(){
|
||||||
|
if(strlen(NEXTION_WEATHER_KEY)==0) {
|
||||||
|
Serial.println("## OPENWEATHERMAP ###: ERROR: NEXTION_WEATHER_KEY not configured");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateWeather(); /* pin task to core CORE_FOR_LOOP_CONTROLS */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
По мотивам https://forum.amperka.ru/threads/%D0%94%D0%B8%D1%81%D0%BF%D0%BB%D0%B5%D0%B9-nextion-%D0%B0%D0%B7%D1%8B-arduino-esp8266.9204/page-18#post-173442
|
||||||
|
*/
|
||||||
|
char* Nextion::utf8Rus(char* str, bool uppercase) {
|
||||||
|
int index = 0;
|
||||||
|
static char out[BUFLEN];
|
||||||
|
bool E = false;
|
||||||
|
memset(out, 0, sizeof(out));
|
||||||
|
if (uppercase) {
|
||||||
|
bool next = false;
|
||||||
|
for (char *iter = str; *iter != '\0'; ++iter)
|
||||||
|
{
|
||||||
|
if (E) {
|
||||||
|
E = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
byte rus = (byte) * iter;
|
||||||
|
if (rus == 208 && (byte) * (iter + 1) == 129) {
|
||||||
|
*iter = (char)209;
|
||||||
|
*(iter + 1) = (char)145;
|
||||||
|
E = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (rus == 209 && (byte) * (iter + 1) == 145) {
|
||||||
|
*iter = (char)209;
|
||||||
|
*(iter + 1) = (char)145;
|
||||||
|
E = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (next) {
|
||||||
|
if (rus >= 128 && rus <= 143) *iter = (char)(rus + 32);
|
||||||
|
if (rus >= 176 && rus <= 191) *iter = (char)(rus - 32);
|
||||||
|
next = false;
|
||||||
|
}
|
||||||
|
if (rus == 208) next = true;
|
||||||
|
if (rus == 209) {
|
||||||
|
*iter = (char)208;
|
||||||
|
next = true;
|
||||||
|
}
|
||||||
|
*iter = toupper(*iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t codepoint = 0;
|
||||||
|
while (str[index])
|
||||||
|
{
|
||||||
|
uint8_t ch = (uint8_t) (str[index]);
|
||||||
|
if (ch <= 0x7f)
|
||||||
|
codepoint = ch;
|
||||||
|
else if (ch <= 0xbf)
|
||||||
|
codepoint = (codepoint << 6) | (ch & 0x3f);
|
||||||
|
else if (ch <= 0xdf)
|
||||||
|
codepoint = ch & 0x1f;
|
||||||
|
else if (ch <= 0xef)
|
||||||
|
codepoint = ch & 0x0f;
|
||||||
|
else
|
||||||
|
codepoint = ch & 0x07;
|
||||||
|
++index;
|
||||||
|
if (((str[index] & 0xc0) != 0x80) && (codepoint <= 0x10ffff))
|
||||||
|
{
|
||||||
|
if (codepoint <= 255)
|
||||||
|
{
|
||||||
|
out[strlen(out)]=(uint8_t)codepoint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(codepoint > 0x400){
|
||||||
|
out[strlen(out)]=(uint8_t)(codepoint - 0x360);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out[strlen(out)+1]=0;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //NEXTION_RX!=255 && NEXTION_TX!=255
|
||||||
78
yoRadio/src/displays/nextion.h
Normal file
78
yoRadio/src/displays/nextion.h
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#ifndef NEXTION_H
|
||||||
|
#define NEXTION_H
|
||||||
|
|
||||||
|
//#include <SoftwareSerial.h>
|
||||||
|
#include <HardwareSerial.h>
|
||||||
|
#include "../../display.h"
|
||||||
|
|
||||||
|
#define TXBUFLEN 255
|
||||||
|
#define RXBUFLEN 50
|
||||||
|
//#define NEXTION_BAUD 38400
|
||||||
|
//#define NEXTION_BAUD 74880
|
||||||
|
#define NEXTION_BAUD 115200
|
||||||
|
|
||||||
|
#define ICON_NA 44
|
||||||
|
#define ICON_AAC ICON_NA+1
|
||||||
|
#define ICON_FLAC ICON_NA+2
|
||||||
|
#define ICON_MP3 ICON_NA+3
|
||||||
|
#define ICON_WAV ICON_NA+4
|
||||||
|
|
||||||
|
#define WEATHER_REQUEST_INTERVAL 1800 //30min
|
||||||
|
#define WEATHER_REQUEST_INTERVAL_FAULTY 30
|
||||||
|
|
||||||
|
class Nextion {
|
||||||
|
private:
|
||||||
|
char txbuf[TXBUFLEN];
|
||||||
|
char rxbuf[RXBUFLEN];
|
||||||
|
uint16_t rx_pos;
|
||||||
|
int _tchY;
|
||||||
|
char _espcoreversion[16];
|
||||||
|
TaskHandle_t _TaskCore0=NULL;
|
||||||
|
QueueHandle_t _displayQueue=NULL;
|
||||||
|
bool _dummyDisplay;
|
||||||
|
bool _volInside;
|
||||||
|
Ticker _timer;
|
||||||
|
unsigned long _volDelay;
|
||||||
|
void createCore0Task();
|
||||||
|
void processQueue();
|
||||||
|
void drawVU();
|
||||||
|
public:
|
||||||
|
displayMode_e mode;
|
||||||
|
bool dt;
|
||||||
|
TaskHandle_t weatherUpdateTaskHandle;
|
||||||
|
// bool weatherRequest;
|
||||||
|
public:
|
||||||
|
Nextion();
|
||||||
|
void begin(bool dummy=false);
|
||||||
|
void start();
|
||||||
|
void apScreen();
|
||||||
|
void loop();
|
||||||
|
void putcmd(const char* cmd);
|
||||||
|
void putcmd(const char* cmd, const char* val, uint16_t dl=0);
|
||||||
|
void putcmd(const char* cmd, int val, bool toString=false, uint16_t dl=0);
|
||||||
|
void putcmdf(const char* fmt, int val, uint16_t dl=0);
|
||||||
|
void bootString(const char* bs);
|
||||||
|
void newTitle(const char* title);
|
||||||
|
void newNameset(const char* meta);
|
||||||
|
void setVol(uint8_t vol, bool dialog);
|
||||||
|
void fillVU(uint8_t LC, uint8_t RC);
|
||||||
|
char* utf8Rus(char* str, bool uppercase);
|
||||||
|
void printClock(struct tm timeinfo);
|
||||||
|
void bitrate(int bpm);
|
||||||
|
void bitratePic(uint8_t pic);
|
||||||
|
void rssi();
|
||||||
|
void weatherVisible(uint8_t vis);
|
||||||
|
void localTime(struct tm timeinfo);
|
||||||
|
void drawPlaylist(uint16_t currentPlItem);
|
||||||
|
void swichMode(displayMode_e newmode);
|
||||||
|
void drawNextStationNum(uint16_t num);
|
||||||
|
void putRequest(requestParams_t request);
|
||||||
|
void startWeather();
|
||||||
|
bool getForecast();
|
||||||
|
static void updateWeather();
|
||||||
|
static void getWeather(void * pvParameters);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Nextion nextion;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -214,7 +214,7 @@ void Telnet::on_input(const char* str, byte clientId) {
|
|||||||
int sstart;
|
int sstart;
|
||||||
if (sscanf(str, "smartstart(%d)", &sstart) == 1 || sscanf(str, "cli.smartstart(\"%d\")", &sstart) == 1 || sscanf(str, "smartstart %d", &sstart) == 1) {
|
if (sscanf(str, "smartstart(%d)", &sstart) == 1 || sscanf(str, "cli.smartstart(\"%d\")", &sstart) == 1 || sscanf(str, "smartstart %d", &sstart) == 1) {
|
||||||
config.store.smartstart = (byte)sstart;
|
config.store.smartstart = (byte)sstart;
|
||||||
printf(clientId, "new smartstart value is: %d\n> ", config.store.audioinfo);
|
printf(clientId, "new smartstart value is: %d\n> ", config.store.smartstart);
|
||||||
config.save();
|
config.save();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user