From 442d970fd9abb62a4fe5395673e3b193ea9ce972 Mon Sep 17 00:00:00 2001 From: e2002 Date: Mon, 15 Aug 2022 14:19:39 +0300 Subject: [PATCH] v0.7.330 --- README.md | 66 ++- exsamples/myoptions.h | 57 +- images/settings.png | Bin 0 -> 163171 bytes yoRadio/config.cpp | 74 ++- yoRadio/config.h | 46 +- yoRadio/controls.cpp | 35 +- yoRadio/controls.h | 4 + yoRadio/data/www/dragpl.js.gz | Bin 440 -> 440 bytes yoRadio/data/www/elogo.png | Bin 2126 -> 761 bytes yoRadio/data/www/elogo100.png | Bin 6438 -> 0 bytes yoRadio/data/www/elogo84.png | Bin 0 -> 3794 bytes yoRadio/data/www/index.html | 95 +--- yoRadio/data/www/ir.html | 10 +- yoRadio/data/www/script.js.gz | Bin 4072 -> 5106 bytes yoRadio/data/www/settings.css.gz | Bin 0 -> 2412 bytes yoRadio/data/www/settings.html | 216 ++++++++ yoRadio/data/www/style.css.gz | Bin 10501 -> 6382 bytes yoRadio/data/www/update.html | 6 +- yoRadio/display.cpp | 179 ++++++- yoRadio/display.h | 32 +- yoRadio/display_vu.h | 27 +- yoRadio/netserver.cpp | 519 +++++++++++++++++-- yoRadio/netserver.h | 6 +- yoRadio/network.cpp | 15 +- yoRadio/options.h | 60 +-- yoRadio/player.cpp | 8 +- yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.cpp | 2 +- yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.h | 2 +- yoRadio/src/audioVS1053/audioVS1053Ex.cpp | 2 - yoRadio/src/displays/displayDummy.h | 2 + yoRadio/src/displays/displayGC9106.cpp | 26 +- yoRadio/src/displays/displayGC9106.h | 4 + yoRadio/src/displays/displayILI9225.cpp | 11 +- yoRadio/src/displays/displayILI9225.h | 5 + yoRadio/src/displays/displayILI9341.cpp | 10 +- yoRadio/src/displays/displayILI9341.h | 5 + yoRadio/src/displays/displayLC1602.h | 4 + yoRadio/src/displays/displayN5110.cpp | 14 +- yoRadio/src/displays/displayN5110.h | 2 + yoRadio/src/displays/displaySH1106.cpp | 21 +- yoRadio/src/displays/displaySH1106.h | 2 + yoRadio/src/displays/displaySSD1305.cpp | 9 +- yoRadio/src/displays/displaySSD1305.h | 4 + yoRadio/src/displays/displaySSD1306.cpp | 12 +- yoRadio/src/displays/displaySSD1306.h | 2 + yoRadio/src/displays/displaySSD1327.cpp | 13 +- yoRadio/src/displays/displaySSD1327.h | 25 +- yoRadio/src/displays/displayST7735.cpp | 31 +- yoRadio/src/displays/displayST7735.h | 5 + yoRadio/src/displays/displayST7789.cpp | 21 +- yoRadio/src/displays/displayST7789.h | 5 + yoRadio/src/displays/nextion.cpp | 28 +- 52 files changed, 1363 insertions(+), 359 deletions(-) create mode 100644 images/settings.png delete mode 100644 yoRadio/data/www/elogo100.png create mode 100644 yoRadio/data/www/elogo84.png create mode 100644 yoRadio/data/www/settings.css.gz create mode 100644 yoRadio/data/www/settings.html diff --git a/README.md b/README.md index 2ec0cc2..f9779a4 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ - [Software dependencies](#dependencies) - [Hardware setup](#hardware-setup) - [Quick start](#quick-start) +- [Detailed start](https://github.com/e2002/yoradio/wiki/How-to-flash) - [Update](#update) - [Update over web-interface](#update-over-web-interface) - [Controls](Controls.md) @@ -63,17 +64,19 @@ https://www.aliexpress.com/item/33009687492.html --- ## Connection tables -| SPI Display | ESP-32 | options.h | +##### SPI Displays +| Display | ESP-32 | myoptions.h | | ------ | ------ | ------ | | GND | GND | - | | VCC | +5v | - | | SCL | 18 | - | | SDA | 23 | - | | CSL | 5* | TFT_CS | -| RSTL | 15* | TFT_RST | +| RST | 15* | TFT_RST | | DCL | 4* | TFT_DC | -| NOKIA5110 | ESP-32 | options.h | +##### Nokia 5110 +| NOKIA5110 | ESP-32 | myoptions.h | | ------ | ------ | ------ | | RST | 15* | TFT_RST | | CE | 5* | TFT_CS | @@ -83,14 +86,16 @@ https://www.aliexpress.com/item/33009687492.html | VCC | +3v3 | - | | GND | GND | - | -| I2C Display | ESP-32 | options.h | +##### I2C Displays +| Display | ESP-32 | myoptions.h | | ------ | ------ | ------ | | GND | GND | - | | VCC | +5v | - | -| SDA | 13* | I2C_SDA | -| SCL | 14* | I2C_SCL | +| SDA | 21* | I2C_SDA | +| SCL | 22* | I2C_SCL | -| LCD 1602 | ESP-32 | options.h | +##### LCD Displays (1602, 2004) +| Display | ESP-32 | myoptions.h | | ------ | ------ | ------ | | GND | GND | - | | VCC | +5v | - | @@ -101,7 +106,8 @@ https://www.aliexpress.com/item/33009687492.html | D6 | any* | LCD_D6 | | D7 | any* | LCD_D7 | -| Touchscreen | ESP-32 | options.h | +##### Touchscreen +| Touchscreen | ESP-32 | myoptions.h | | ------ | ------ | ------ | | GND | GND | - | | VCC | +3.3v | - | @@ -111,7 +117,8 @@ https://www.aliexpress.com/item/33009687492.html | IRQ | N/C | - | | CS | any* | TS_CS | -| I2S DAC | ESP-32 | options.h | +##### I2S DAC +| I2S DAC | ESP-32 | myoptions.h | | ------ | ------ | ------ | | GND | GND | - | | VIN | +5v | - | @@ -119,7 +126,8 @@ https://www.aliexpress.com/item/33009687492.html | BCLK | 26* | I2S_BCLK | | LRC(WSEL) | 25* | I2S_LRC | -| VS1053 | ESP-32 | options.h | +##### VS1053 +| VS1053 | ESP-32 | myoptions.h | | ------ | ------ | ------ | | XDCS | 25* | VS1053_DCS | | XCS | 27* | VS1053_CS | @@ -132,10 +140,19 @@ https://www.aliexpress.com/item/33009687492.html | DGND | GND | - | _\#\# Important! You must choose between I2S DAC and VS1053 by disabling the second module in the settings (see below)_ +##### Nextion Displays +| Display | ESP-32 | myoptions.h | +| ------ | ------ | ------ | +| GND | GND | - | +| VCC | +5v | - | +| TX | 14* | NEXTION_RX | +| RX | 15* | NEXTION_TX | -| Buttons, Encoder, LED, IR, Joystick | ESP-32 | options.h | +##### Controls +| Buttons, Encoder, LED, IR, Joystick | ESP-32 | myoptions.h | | ------ | ------ | ------ | | GND | GND | - | +| 5v | 3v3 | - | | PIN | any* | ENC_BTNx, BTN_xxx, LED_BUILTIN, IR_PIN | _\* Any free pin, configured in myoptions.h_ \ @@ -150,7 +167,9 @@ _\** GPIO 16 and 17 are used by PSRAM on the WROVER modules._ \* _if you need MQTT support_ #### Tool: -[ESP32 Filesystem Uploader](https://randomnerdtutorials.com/install-esp32-filesystem-uploader-arduino-ide/) +[ESP32 Filesystem Uploader](https://randomnerdtutorials.com/install-esp32-filesystem-uploader-arduino-ide/) \ + +**See [wiki](https://github.com/e2002/yoradio/wiki/How-to-flash#preparing) for details** --- ## Hardware setup @@ -206,6 +225,8 @@ _\*this step can be skipped if you add WiFiSSID WiFiPassword pairs to the [yoRad **Localization:** Если Adafruit_GFX ещё не русифицирована, русифицировать её, заменив файл Arduino/libraries/Adafruit_GFX_Library/glcdfont.c файлом [yoRadio/fonts/glcdfont.c](yoRadio/fonts/glcdfont.c) +**See [wiki](https://github.com/e2002/yoradio/wiki/How-to-flash#build--flash) for details** + --- ## Update 1. Backup your settings: \ @@ -291,11 +312,22 @@ download _http://\/data/playlist.csv_ and _http://\/data --- ## Plugins -At the moment, you can display additional information on the display by writing a few additional functions. There is no documentation yet, you will have to deal with the example, which is in file [exsamples/plugins/displayhandlers.ino](exsamples/plugins/displayhandlers.ino).\ +At the moment, you can display additional information on the display by writing a few additional functions. There is no documentation yet, you will have to deal with the examples, which is in directory [exsamples/plugins/](https://github.com/e2002/yoradio/tree/main/exsamples/plugins).\ Work is in progress... --- ## Version history +#### v0.7.330 +**!!! a [full update](#update-over-web-interface) with Sketch data upload is required. After updating please press CTRL+F5 in browser !!!** \ +**Please backup playlist.csv and wifi.csv before updating.** +- added the ability to configure parameters through the [web interface](images/settings.png) +- new parameter BRIGHTNESS_PIN - pin for adjusting the brightness of the display. Details in [exsamples/myoptions.h](exsamples/myoptions.h#L105) +- the weather plugin is integrated into the code, the settings are made through the web interface + +_**PS:** Due to the change in the storage location of settings in the ESP memory, settings such as:_ \ +**smartstart, audioinfo, time zone, IR remote, last volume level, last played station, equalizer** \ +_will have to be configured again through the web interface. Please understand and forgive._ + #### v0.7.017 - fix initialization of some vs1053b green boards - fix VU initialization on vs1053b boards @@ -317,7 +349,7 @@ Work is in progress... #### v0.6.494 - adding VU meter for displays ST7735 160x128, ST7735 128x128, ILI9341 320x240, ST7789 320x240 \ - option ENABLE_VU_METER (see [myoptions.h](exsamples/myoptions.h#L113) for exsample) \ + option ENABLE_VU_METER (see [myoptions.h](exsamples/myoptions.h) for exsample) \ **!!! Important !!!** \ if you enable this feathure on the esp32 wroom, due to lack of memory, you must modify the file Arduino/libraries/AsyncTCP/src/AsyncTCP.cpp \ **replace the line 221** \ @@ -344,8 +376,8 @@ Work is in progress... #### v0.6.355 - added support for ST7789 1.3' 240x240 SPI displays \ - _!!! Important !!! This display requires further development when used in conjunction with the VS1053 module. \ - See this link for details https://www.instructables.com/Adding-CS-Pin-to-13-LCD/_ + _!!! Important !!! This display requires further development when used in conjunction with the VS1053 module._ \ + See this link for details https://www.instructables.com/Adding-CS-Pin-to-13-LCD/ #### v0.6.348 - fixed display bugs in the rssibitrate plugin @@ -368,7 +400,7 @@ Work is in progress... - added support for ILI9225 220x176 SPI displays - added support for I2S internal DAC, option I2S_INTERNAL (see [myoptions.h](exsamples/myoptions.h#L111) for exsample) \ _(this option worked only with esp32 core version==2.0.0)_ -- new option SOFT_AP_REBOOT_DELAY (see [myoptions.h](exsamples/myoptions.h#L112) for exsample) +- new option SOFT_AP_REBOOT_DELAY (see [myoptions.h](exsamples/myoptions.h) for exsample) - fixed MQTT connection when WiFi reconnected - fixed date display for ILI9341 displays - fixed garbage on volume control with displays ILI9341 diff --git a/exsamples/myoptions.h b/exsamples/myoptions.h index 6c7b32c..43aae4e 100644 --- a/exsamples/myoptions.h +++ b/exsamples/myoptions.h @@ -13,6 +13,14 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti /* DSP_MODEL. See description/available values in the options.h file */ /* This option is required. Use DSP_DUMMY if no display is connected */ #define DSP_MODEL DSP_DUMMY +/* + * !!! Important !!! + * if you use colored TFT displays with the esp32 wroom, due to lack of memory, you must modify the file Arduino/libraries/AsyncTCP/src/AsyncTCP.cpp + * replace the line 221 + * xTaskCreateUniversal(_async_service_task, "async_tcp", 8192 * 2, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE); + * with + * xTaskCreateUniversal(_async_service_task, "async_tcp", 8192 / 2, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE); +*/ /******************************************/ /* SPI PINS. SCL(SCK, CLK) must be connected to pin 18 @@ -25,9 +33,6 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti /* 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 */ //#define I2C_SDA 21 /* I2C SDA pin. It is best to connect to pin 21. */ @@ -41,11 +46,12 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti /******************************************/ /* VS1053 PINS. VS1053 SCK must be connected to pin 18 + VS1053 MISO must be connected to pin 19 VS1053 MOSI must be connected to pin 23 */ -//#define VS1053_CS 255 /* Should be set to 255 if the board is not used */ -//#define VS1053_DCS 25 -//#define VS1053_DREQ 26 -//#define VS1053_RST -1 /* Set to -1 if connected to Esp EN pin */ +//#define VS1053_CS 255 /* XCS pin. Should be set to 255 if the board is not used */ +//#define VS1053_DCS 25 /* XDCS pin. */ +//#define VS1053_DREQ 26 /* DREQ pin. */ +//#define VS1053_RST -1 /* XRESET pin. Set to -1 if connected to Esp EN pin */ /******************************************/ /* ENCODER */ @@ -91,41 +97,25 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti DO must be connected to pin 19 IRQ - not connected */ //#define TS_CS 255 /* Touch screen CS pin -//#define TS_ROTATE 1 /* Touch screen rotation. 0 - 0, 1 - 90, 2 - 180, 3 - 270 degrees */ -//#define TS_DBG false /* Generate debug to Serial output */ /******************************************/ /* Other settings. */ //#define DTYPE INITR_BLACKTAB /* ST7735 display submodel */ - /* Could be one of: */ - /* INITR_BLACKTAB 1.8' https://aliexpress.com/item/1005002822797745.html */ - /* (See this note If INITR_BLACKTAB have a noisy line on one side of the screen https://github.com/e2002/yoradio#note-if-initr_blacktab-dsp-have-a-noisy-line-on-one-side-of-the-screen-then-in-adafruit_st7735cpp ) */ - /* INITR_144GREENTAB // 1.44' https://aliexpress.com/item/1005002822797745.html */ - /* INITR_MINI160x80 // 0.96' 160x80 ST7735S https://???? */ - /* INITR_GREENTAB */ - /* INITR_REDTAB */ + /* Could be one of: */ + /* INITR_BLACKTAB 1.8' https://aliexpress.com/item/1005002822797745.html */ + /* (See this note If INITR_BLACKTAB have a noisy line on one side of the screen https://github.com/e2002/yoradio#note-if-initr_blacktab-dsp-have-a-noisy-line-on-one-side-of-the-screen-then-in-adafruit_st7735cpp ) */ + /* INITR_144GREENTAB // 1.44' https://aliexpress.com/item/1005002822797745.html */ + /* INITR_MINI160x80 // 0.96' 160x80 ST7735S https://???? */ + /* INITR_GREENTAB */ + /* INITR_REDTAB */ //#define LED_BUILTIN 2 /* LED Pin */ -//#define TFT_ROTATE 3 /* Display rotation. 0 - 0, 1 - 90, 2 - 180, 3 - 270 degrees */ -//#define TFT_CONTRAST 55 /* Nokia 5110 contrast */ -//#define TFT_INVERT true /* Invert the display colors (usually true) */ -//#define VOL_STEP 1 /* Volume control step */ -//#define VOL_ACCELERATION 200 /* Encoder vol acceleration; 0 or 1 means disabled acceleration */ //#define MUTE_PIN 255 /* MUTE Pin */ //#define MUTE_VAL HIGH /* Write this to MUTE_PIN when player is stopped */ -//#define PL_WITH_NUMBERS /* show the number of station in the playlist */ +//#define BRIGHTNESS_PIN 255 /* Pin for adjusting the brightness of the display (output 0 - 3v3) */ //#define PLAYER_FORCE_MONO false /* mono option on boot - false stereo, true mono */ -//#define SNTP_SERVER "pool.ntp.org", "0.ru.pool.ntp.org" /* custom ntp servers min 1 max 3 comma separated values */ //#define I2S_INTERNAL false /* If true - use esp32 internal DAC */ -//#define SOFT_AP_REBOOT_DELAY 0 /* Delay in milliseconds after which ESP is rebooting if it is in softAP mode (0 - disabled) */ -//#define ENABLE_VU_METER false /* enable? vu meter for some displays */ -/* - * !!! Important !!! - * if you enable this feathure on the esp32 wroom, due to lack of memory, you must modify the file Arduino/libraries/AsyncTCP/src/AsyncTCP.cpp - * replace the line 221 - * xTaskCreateUniversal(_async_service_task, "async_tcp", 8192 * 2, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE); - * with - * xTaskCreateUniversal(_async_service_task, "async_tcp", 8192 / 2, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE); -*/ +//#define ROTATE_90 false /* Optional 90 degree rotation for square displays */ + /* 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 | fade speed | horisontal | Max Bands Color | Min Bands Color */ @@ -136,7 +126,6 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti /* IR control */ //#define IR_PIN 255 //#define IR_TIMEOUT 80 /* see kTimeout description in IRremoteESP8266 exsample https://github.com/crankyoldgit/IRremoteESP8266/blob/master/examples/IRrecvDumpV2/IRrecvDumpV2.ino */ -//#define IR_TLP 40 /* see kTolerancePercentage description in IRremoteESP8266 exsample https://github.com/crankyoldgit/IRremoteESP8266/blob/master/examples/IRrecvDumpV2/IRrecvDumpV2.ino */ /******************************************/ diff --git a/images/settings.png b/images/settings.png new file mode 100644 index 0000000000000000000000000000000000000000..382ec521aae3a424e5f3627e068536f52cf3adec GIT binary patch literal 163171 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

_G3 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 literal 0 HcmV?d00001 diff --git a/yoRadio/config.cpp b/yoRadio/config.cpp index 4d0a6ec..6bf1305 100644 --- a/yoRadio/config.cpp +++ b/yoRadio/config.cpp @@ -11,13 +11,7 @@ void Config::init() { irindex=-1; #endif eepromRead(EEPROM_START, store); - if (store.tz_set != 57) { // update to v0.4.200 - store.tz_set = 57; - store.tzHour = 3; - store.tzMin = 0; - store.timezoneOffset = 0; - } - if (store.config_set != 4256) setDefaults(); + if (store.config_set != 4262) setDefaults(); //if (!SPIFFS.begin(false, "/spiffs", 30)) { if (!SPIFFS.begin(false)) { return; @@ -36,6 +30,10 @@ void Config::init() { memset(ircodes.irVals, 0, sizeof(ircodes.irVals)); } #endif +#if BRIGHTNESS_PIN!=255 + pinMode(BRIGHTNESS_PIN, OUTPUT); + setBrightness(false); +#endif } template int Config::eepromWrite(int ee, const T& value) { @@ -56,7 +54,7 @@ template int Config::eepromRead(int ee, T& value) { } void Config::setDefaults() { - store.config_set = 4256; + store.config_set = 4262; store.volume = 12; store.balance = 0; store.trebble = 0; @@ -67,10 +65,41 @@ void Config::setDefaults() { store.lastSSID = 0; store.audioinfo = false; store.smartstart = 2; - store.tz_set = 57; store.tzHour = 3; store.tzMin = 0; store.timezoneOffset = 0; + + store.vumeter=false; + store.softapdelay=0; + store.flipscreen=false; + store.invertdisplay=false; + store.numplaylist=false; + store.fliptouch=false; + store.dbgtouch=false; + store.dspon=true; + store.brightness=100; + store.contrast=55; + strlcpy(store.sntp1,"0.ru.pool.ntp.org", 35); + strlcpy(store.sntp2,"1.ru.pool.ntp.org", 35); + store.showweather=false; + strlcpy(store.weatherlat,"55.7512", 10); + strlcpy(store.weatherlon,"37.6184", 10); + strlcpy(store.weatherkey,"", 64); + store.volsteps = 1; + store.encacc = 200; + store.irto = 80; + store.irtlp = 35; + store.btnpullup = true; + store.btnlongpress = 200; + store.btnclickticks = 300; + store.btnpressticks = 500; + store.encpullup = false; + store.enchalf = false; + store.enc2pullup = false; + store.enc2half = false; + store.forcemono = false; + store.i2sinternal = false; + store.rotate90 = false; } void Config::setTimezone(int8_t tzh, int8_t tzm) { @@ -247,17 +276,17 @@ void Config::fillPlMenu(char plmenu[][40], int from, byte count, bool removeNum) } while (playlist.available()) { if (parseCSV(playlist.readStringUntil('\n').c_str(), sName, sUrl, sOvol)) { -#ifdef PL_WITH_NUMBERS - if(removeNum){ - strlcpy(plmenu[c], sName, 39); + if(config.store.numplaylist){ + if(removeNum){ + strlcpy(plmenu[c], sName, 39); + }else{ + char buf[BUFLEN+10]; + sprintf(buf, "%d %s", (int)(from+c), sName); + strlcpy(plmenu[c], buf, 39); + } }else{ - char buf[BUFLEN+10]; - sprintf(buf, "%d %s", (int)(from+c), sName); - strlcpy(plmenu[c], buf, 39); + strlcpy(plmenu[c], sName, 39); } -#else - strlcpy(plmenu[c], sName, 39); -#endif c++; } if (c >= count) break; @@ -344,7 +373,7 @@ bool Config::parseWsCommand(const char* line, char* cmd, char* val, byte cSize) strlcpy(cmd, line, tmpe - line + 1); if (strlen(tmpe + 1) == 0) return false; memset(val, 0, cSize); - strlcpy(val, tmpe + 1, tmpe + 1 - line + 1); + strlcpy(val, tmpe + 1, strlen(line) - strlen(cmd) + 1); return true; } @@ -391,3 +420,10 @@ bool Config::initNetwork() { file.close(); return true; } + +void Config::setBrightness(bool dosave){ +#if BRIGHTNESS_PIN!=255 + analogWrite(BRIGHTNESS_PIN, config.store.dspon?map(store.brightness, 0, 100, 0, 255):0); + if(dosave) save(); +#endif +} diff --git a/yoRadio/config.h b/yoRadio/config.h index 57e3f0c..be658a6 100644 --- a/yoRadio/config.h +++ b/yoRadio/config.h @@ -4,8 +4,9 @@ #include "options.h" #define EEPROM_SIZE 768 -#define EEPROM_START 0 -#define EEPROM_START_IR 100 +#define EEPROM_START 500 +#define EEPROM_START_IR 0 +#define EEPROM_START_2 10 #define BUFLEN 140 #define PLAYLIST_PATH "/data/playlist.csv" #define SSIDS_PATH "/data/wifi.csv" @@ -14,7 +15,7 @@ struct config_t { - unsigned int config_set; //must be 4256 + unsigned int config_set; //must be 4262 byte volume; int8_t balance; int8_t trebble; @@ -25,10 +26,41 @@ struct config_t byte lastSSID; bool audioinfo; byte smartstart; - byte tz_set; // must be 57 int8_t tzHour; int8_t tzMin; uint16_t timezoneOffset; + + bool vumeter; + uint8_t softapdelay; + bool flipscreen; + bool invertdisplay; + bool numplaylist; + bool fliptouch; + bool dbgtouch; + bool dspon; + uint8_t brightness; + uint8_t contrast; + char sntp1[35]; + char sntp2[35]; + bool showweather; + char weatherlat[10]; + char weatherlon[10]; + char weatherkey[64]; + uint8_t volsteps; + uint16_t encacc; + uint8_t irto; + uint8_t irtlp; + bool btnpullup; + uint16_t btnlongpress; + uint16_t btnclickticks; + uint16_t btnpressticks; + bool encpullup; + bool enchalf; + bool enc2pullup; + bool enc2half; + bool forcemono; + bool i2sinternal; + bool rotate90; }; #if IR_PIN!=255 @@ -74,7 +106,7 @@ class Config { void init(); byte setVolume(byte val); void saveVolume(); - void setTone(int8_t bass, int8_t middle, int8_t trebble); + void setTone(int8_t bass, int8_t middle, int8_t trebble); void setBalance(int8_t balance); byte setLastStation(byte val); byte setCountStation(byte val); @@ -91,10 +123,12 @@ class Config { void setSmartStart(byte ss); void initPlaylist(); void indexPlaylist(); - void fillPlMenu(char plmenu[][40], int from, byte count, bool removeNum=false); + void fillPlMenu(char plmenu[][40], int from, byte count, bool removeNum = false); void setTimezone(int8_t tzh, int8_t tzm); void setTimezoneOffset(uint16_t tzo); uint16_t getTimezoneOffset(); + void setBrightness(bool dosave=false); + private: template int eepromWrite(int ee, const T& value); template int eepromRead(int ee, T& value); diff --git a/yoRadio/controls.cpp b/yoRadio/controls.cpp index e90f4e7..70f4139 100644 --- a/yoRadio/controls.cpp +++ b/yoRadio/controls.cpp @@ -59,7 +59,6 @@ byte irVolRepeat = 0; const uint16_t kCaptureBufferSize = 1024; const uint8_t kTimeout = IR_TIMEOUT; const uint16_t kMinUnknownSize = 12; -const uint8_t kTolerancePercentage = IR_TLP; //kTolerance; // kTolerance is normally 25% #define LEGACY_TIMING_INFO false IRrecv irrecv(IR_PIN, kCaptureBufferSize, kTimeout, true); @@ -85,13 +84,13 @@ void initControls() { encoder.begin(); encoder.setup(readEncoderISR); encoder.setBoundaries(0, 254, true); - encoder.setAcceleration(VOL_ACCELERATION); + encoder.setAcceleration(config.store.encacc); #endif #if ENC2_BTNL!=255 encoder2.begin(); encoder2.setup(readEncoder2ISR); encoder2.setBoundaries(0, 254, true); - encoder2.setAcceleration(VOL_ACCELERATION); + encoder2.setAcceleration(config.store.encacc); #endif #if ISPUSHBUTTONS @@ -116,7 +115,7 @@ void initControls() { #endif #if TS_CS!=255 ts.begin(); - ts.setRotation(TS_ROTATE); + ts.setRotation(config.store.fliptouch?3:1); #endif #if IR_PIN!=255 pinMode(IR_PIN, INPUT); @@ -124,7 +123,7 @@ void initControls() { #if DECODE_HASH irrecv.setUnknownThreshold(kMinUnknownSize); #endif // DECODE_HASH - irrecv.setTolerance(kTolerancePercentage); + irrecv.setTolerance(config.store.irtlp); irrecv.enableIRIn(); #endif // IR_PIN!=255 } @@ -411,7 +410,7 @@ void touchLoop() { int16_t yDelta = map(abs(touchStation - touchY), 0, display.screenheight, 0, TS_STEPS); display.putRequest({NEWMODE, STATIONS}); if (yDelta>1) { - controlsEvent((touchStation - touchY)>0); + controlsEvent((touchStation - touchY)<0); touchStation = touchY; } } @@ -421,7 +420,7 @@ void touchLoop() { break; } } - if (TS_DBG) { + if (config.store.dbgtouch) { Serial.print(", x = "); Serial.print(p.x); Serial.print(", y = "); @@ -609,3 +608,25 @@ void onBtnDoubleClick(int id) { break; } } +void setIRTolerance(uint8_t tl){ + config.store.irtlp=tl; + config.save(); +#if IR_PIN!=255 + irrecv.setTolerance(config.store.irtlp); +#endif +} +void setEncAcceleration(uint16_t acc){ + config.store.encacc=acc; + config.save(); +#if ENC_BTNL!=255 + encoder.setAcceleration(config.store.encacc); +#endif +#if ENC2_BTNL!=255 + encoder2.setAcceleration(config.store.encacc); +#endif +} +void flipTS(){ +#if TS_CS!=255 + ts.setRotation(config.store.fliptouch?3:1); +#endif +} diff --git a/yoRadio/controls.h b/yoRadio/controls.h index e0afdf0..84a76d1 100644 --- a/yoRadio/controls.h +++ b/yoRadio/controls.h @@ -29,6 +29,10 @@ void onBtnLongPressStart(int id); void onBtnLongPressStop(int id); tsDirection_e tsDirection(uint16_t x, uint16_t y); +void setIRTolerance(uint8_t tl); +void setEncAcceleration(uint16_t acc); +void flipTS(); + extern __attribute__((weak)) void ctrls_on_loop(); #endif diff --git a/yoRadio/data/www/dragpl.js.gz b/yoRadio/data/www/dragpl.js.gz index 9d5b729190e527dc9a77fc2dfb451d92e98828fe..55df2e049ec648eadf54e266294c8d27bd29f811 100644 GIT binary patch delta 16 XcmdnNyn~rtzMF$1LFd~>_Kl1HDn$h( delta 16 XcmdnNyn~rtzMF&N-0Fah>>C*YEdvE> diff --git a/yoRadio/data/www/elogo.png b/yoRadio/data/www/elogo.png index cb92ffdc7b5f23db20a131f79c74f4ff423d51ab..9d9d42ce3740ae33e11367c44142fde489b207cf 100644 GIT binary patch delta 738 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 diff --git a/yoRadio/data/www/elogo100.png b/yoRadio/data/www/elogo100.png deleted file mode 100644 index d1508d53d088cc623d6d6a05ab85a53c45147af2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6438 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 diff --git a/yoRadio/data/www/elogo84.png b/yoRadio/data/www/elogo84.png new file mode 100644 index 0000000000000000000000000000000000000000..ee369bfccd398a34df8c84f904f7b082eed28eb0 GIT binary patch literal 3794 zcmXw5cQ~8v7k;eTqoG2yw)%W_jSy;&7`1EFXi=-E)-I(+ONxqFHG-mp)-F1zy(>|% zg$}bds`ev3pwg-SO0O|m2Q2v+yFWF`R^+Lg4Kl;&}*lGdsNB^z1TC7r2K-CSh!~&Fr*Z|o7 ze@hdj0susN2xnLV022NBx3SG)8vuw0l7>8Fetw>e z^M3=NmwfyPKobB^3$fh-0zkGx36{w`P~!vuBy!vg05s|o0CLI4Rsfy@KnnoG0|EYG zAV3G%phe~Y*a9FB0BFJ#092tdY(+?l@DUr~P5>GJCs2n|%piH_gL-drG7G~XHrs=CNAQbE3^RyO% zWEZ?8f4KcSY$q~pA^2JM+=wFllQhScDBBNSreVAdw8-~3rOr4d!d->A2>Hnf`Tii; zL0_pahJ4=@I0xQbYD-b=Hsbps#l9eRdJRrbOjql=CN_8F{FDX{Ns4{mkZ(+qU2&ur zS|3ydT9{Y@D=OOFc1G%>%u8!*R8z0wBLc7TFx8%AW1>6W+gbWXeDCh8r+tS0)Y1OZ zWNU6(oUglsj1cE!UCG@LA4?PTMM+6fL4IBY>(`;T&vCfaQCp5~^KLR@~N)y4eCNa)wgFkzshY2`Vyn&aWXq0iOjyv|aB zq_LtyQ>XIN#d%X}#?W(WB|U5sMqF9x8h629Fw0H5P9F8s0%!U8|4p#1(kZUa?GV-* z4v+jeFfe%QeaJr|uL^#j0Gq~qkJ+%9ng)$2IvnBw+dJE`~-8C&@lq7=G{OB@l0zsq=bVXTgvd9zZ~3iV_2i^>8d zEtC}`7z0I~i^-08Jw3NNRwBW*V-pwCDnQPzXU@x#Ip? z$hwCfoFyTv8(At!8wOgM8d7YiN_^;+yP0g5AM)Pu3pd(|*%+yQEoskG9tQUifsbk| z>kEzB<^`q{30?7O%^hcP8Vl56v1m}k5 z^o3uVH3HN0xaRhNXt@~C**Tv}oXPZysfjT z0quxc6X5b_AE-{)c_L%Zmv*T7AX5ITfWH zQ7_d!vn6yJ(-Z|1?|KiY-Z%dw>v&@RUH|D?`iBjF^f?+-S#QoUV`~~Yw&y)&jK%v{hHOCVNU`> zdvl+Z6hEK6oz44(;Braoh1hs1&&Ro^^!0W_+5H>2NsT`v;Wcz%;c1^Mi#=+S4xlbh3OK6R!+EUf7?bZ*;H3# zEYLsUFL9*|Xp7d9xGUvz@YPKOh4^j|o2wD7nNt~MI^P>c#(Z58l>`^Da8}huzX+WhQ1Zi)%ftS@m#6Cq87;H+efTk$bkFsmc}_Rif9o(a8uzz=(6& z-rM`W?OrH&(Kpg7`OC)vjln8m#dBDzD`IsgdXBqS;IEBM4He|Qa`bcRc6QuGq)U!! zeU$>|#%d6)x1(vB=FnmE6VGqDrH;3=9O?UIYI_;JTt7PcMKfb*V59oBQ+jmsjfr$5 z(LlEn?%J{IY}r)Bbj(9~Y*hBr{mCWDrW^^9qmTp-e6p0^(9*2n1Kw~Ujm0f*se-qU zE%C%Tl&AU_6W}i2yyNG&Tn}00aCM(`^|TRS1;7i2A(aRi~gc!I<}kt(d&!x)~P#k z;+=HCYtBOh`_uxW70bH1TRm5M-&@t-ajnDM+B|ksA#1SAw>ECEa?vli?>H^eBp%tB zbfq~bF=I6M{d#yNJHBuwX|FQaDxw0A-Yoq*m2h4C-3=$ytO{yUd z(f)gJ%o)d zTH;ZJGv+KEw>>%>$HZ1sOU$}jr)EOsqae?>D - - ёRadio + + ёRadio - Player
- - + diff --git a/yoRadio/display.cpp b/yoRadio/display.cpp index 0e067d2..4c2affa 100644 --- a/yoRadio/display.cpp +++ b/yoRadio/display.cpp @@ -3,7 +3,7 @@ #include "WiFi.h" #include "time.h" #include "display.h" -#if ENABLE_VU_METER +#if VU_READY==1 #include "display_vu.h" #endif #include "player.h" @@ -73,6 +73,13 @@ void ticks() { byte currentScrollId = 0; /* one scroll on one time */ +#if WEATHER_READY==1 +bool weatherRequest = false; +TaskHandle_t weatherUpdateTaskHandle; +Ticker weatherTicker; +char weatherText[254] = { 0 }; +#endif + void Scroll::init(byte ScrollId, const char *sep, byte tsize, byte top, uint16_t dlay, uint16_t fgcolor, uint16_t bgcolor) { textsize = tsize; id = ScrollId; @@ -239,6 +246,15 @@ void Display::init() { #endif plCurrent.init(4, " * ", PLCURRENT_SIZE, yStart, STARTTIME_PL, TFT_BG, TFT_LOGO); plCurrent.lock(); +#if WEATHER_READY==1 + if (DSP_MODEL == DSP_ST7735 || (DSP_MODEL == DSP_SSD1327)) { + weatherScroll.init(5, " * ", 1, TFT_LINEHGHT * 4 + 6, 0, ORANGE, TFT_BG); + }else if(DSP_MODEL == DSP_ILI9225){ + weatherScroll.init(5, " * ", 1, TFT_LINEHGHT * 6 + 5, 0, ORANGE, TFT_BG); + } else { + weatherScroll.init(5, " * ", 2, TFT_LINEHGHT * 9 + 5, 0, ORANGE, TFT_BG); + } +#endif if (dsp_on_init) dsp_on_init(); } @@ -476,6 +492,9 @@ void Display::loop() { switch (mode) { case PLAYER: { drawPlayer(); +#if WEATHER_READY==1 + weatherScroll.loop(); +#endif break; } case INFO: @@ -500,9 +519,15 @@ void Display::loop() { } dsp.loop(); if (dsp_on_loop) dsp_on_loop(&dsp); -#if ENABLE_VU_METER +#if VU_READY==1 drawVU(&dsp); #endif +#if WEATHER_READY==1 + if (weatherRequest) { + weatherRequest = false; + weatherScroll.setText(dsp.utf8Rus(weatherText, true)); + } +#endif } void Display::centerText(const char* text, byte y, uint16_t fg, uint16_t bg) { @@ -635,6 +660,19 @@ void Display::volume() { #endif //netserver.requestOnChange(VOLUME, 0); } + +void Display::flip(){ + dsp.flip(); +} + +void Display::invert(){ + dsp.invert(); +} +#if DSP_MODEL==DSP_NOKIA5110 +void Display::setContrast(){ + dsp.setContrast(config.store.contrast); +} +#endif // DSP_MODEL==DSP_NOKIA5110 /******************************************************************************************************************/ #endif // !DUMMYDISPLAY @@ -662,3 +700,140 @@ void Display::putRequest(requestParams_t request){ } /******************************************************************************************************************/ #endif // DUMMYDISPLAY + +#ifndef DUMMYDISPLAY +#if WEATHER_READY==1 + +bool 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", config.store.weatherlat, config.store.weatherlon, config.store.weatherkey, 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); + + Serial.printf("## OPENWEATHERMAP ###: description: %s, temp:%.1f C, pressure:%dmmHg, humidity:%s%%\n", desc, tempf, pressi, hum); + sprintf(weatherText, "%s, %.1f C * давление: %d мм * влажность: %s%%", desc, tempf, pressi, hum); + return true; + +} + +void Display::getWeather( void * pvParameters ) { + delay(200); + if (getForecast()) { + weatherRequest = true; + weatherTicker.detach(); + weatherTicker.attach(WEATHER_REQUEST_INTERVAL, display.updateWeather); + } else { + weatherTicker.detach(); + weatherTicker.attach(WEATHER_REQUEST_INTERVAL_FAULTY, display.updateWeather); + } + vTaskDelete( NULL ); +} +#endif // WEATHER_READY==1 + +void Display::updateWeather(){ +#if WEATHER_READY==1 + if(!config.store.showweather || strlen(config.store.weatherkey)==0) return; + xTaskCreatePinnedToCore( + getWeather, /* Task function. */ + "dspGetWeather1", /* name of task. */ + 1024 * 4, /* Stack size of task */ + NULL, /* parameter of the task */ + 0, /* priority of the task */ + &weatherUpdateTaskHandle, /* Task handle to keep track of created task */ + 0); /* pin task to core CORE_FOR_LOOP_CONTROLS */ +#endif // WEATHER_READY==1 +} + +void Display::showWeather(){ +#if WEATHER_READY==1 + if(strlen(config.store.weatherkey)!=0 && config.store.showweather) display.updateWeather(); + if(!config.store.showweather){ + memset(weatherText, 0, sizeof(weatherText)); + weatherScroll.setText(weatherText); + } +#endif // WEATHER_READY==1 +} +/******************************************************************************************************************/ +#endif // !DUMMYDISPLAY diff --git a/yoRadio/display.h b/yoRadio/display.h index c484607..a5409e1 100644 --- a/yoRadio/display.h +++ b/yoRadio/display.h @@ -38,8 +38,20 @@ #elif DSP_MODEL==DSP_ILI9225 #include "src/displays/displayILI9225.h" #endif +#ifndef VU_READY +#define VU_READY 0 +#endif +#ifndef DSP_FLIPPED +#define DSP_FLIPPED 1 +#endif +#ifndef WEATHER_READY +#define WEATHER_READY 0 +#else +#define WEATHER_REQUEST_INTERVAL 1800 //30min +#define WEATHER_REQUEST_INTERVAL_FAULTY 30 +#endif -enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST, UPDATING, INFO, SETTINGS, TIMEZONE, WIFI }; +enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST, UPDATING, INFO, SETTINGS, TIMEZONE, WIFI, CLEAR }; enum displayRequestType_e { NEWMODE, CLOCK, NEWTITLE, RETURNTITLE, NEWSTATION, NEXTSTATION, DRAWPLAYLIST, DRAWVOL }; struct requestParams_t @@ -111,6 +123,15 @@ class Display { void bootString(const char* text, byte y); void bootLogo(); void putRequest(requestParams_t request); + void flip(); + void invert(); + static void updateWeather(); + void showWeather(); +#if DSP_MODEL==DSP_NOKIA5110 + void setContrast(); +#else + void setContrast(){}; +#endif // DSP_MODEL==DSP_NOKIA5110 #else void init(); void loop(){}; @@ -122,9 +143,18 @@ class Display { void bootString(const char* text, byte y); void bootLogo(){}; void putRequest(requestParams_t request); + void flip(){}; + void invert(){}; + void setContrast(){}; + static void updateWeather(){}; + void showWeather(){}; #endif #ifndef DUMMYDISPLAY private: +#if WEATHER_READY==1 + Scroll weatherScroll; + static void getWeather( void * pvParameters ); +#endif Ticker timer; Scroll meta, title1, title2; bool clockRequest; diff --git a/yoRadio/display_vu.h b/yoRadio/display_vu.h index db34015..7a076f2 100644 --- a/yoRadio/display_vu.h +++ b/yoRadio/display_vu.h @@ -1,4 +1,3 @@ -#if ENABLE_VU_METER #ifndef display_vu_h #define display_vu_h #include "player.h" @@ -21,23 +20,29 @@ enum : uint16_t VU_PARAMS2; /**********************************************************************************************************************************************************************************/ /* 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 */ -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 }; +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 */ -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 }; +enum : uint16_t { VU_X = 4, VU_Y = 97, 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 + #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_FS = 5, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY }; +enum : uint16_t { VU_X = 4, VU_Y = 116, VU_BW = 24, VU_BH = 80, VU_BS = 4, VU_NB = 8, VU_FS = 5, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY }; + #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_FS = 3, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY }; +enum : uint16_t { VU_X = 4, VU_Y = 116, VU_BW = 24, VU_BH = 80, VU_BS = 4, VU_NB = 8, VU_FS = 5, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = GRAY }; + #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_FS = 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 */ -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 }; +enum : uint16_t { VU_X = 4, VU_Y = 80, VU_BW = 13, VU_BH = 56, VU_BS = 2, VU_NB = 8, 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 */ -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 -#error YOUR DISPLAY DOES NOT SUPPORT ENABLE_VU_METER FEATURE YET +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 }; + #endif #endif //VU_PARAMS /**********************************************************************************************************************************************************************************/ @@ -47,6 +52,7 @@ void drawVU(DspCore *dsp); GFXcanvas16 gfxc(VU_BW*2+VU_BS,VU_BH); void drawVU(DspCore *dsp){ + if(!config.store.vumeter) return; if(display.mode!=PLAYER && display.mode!=VOL) return; #ifdef GREENTAB128 if(display.mode==VOL) return; @@ -106,4 +112,3 @@ void drawVU(DspCore *dsp){ } } #endif -#endif diff --git a/yoRadio/netserver.cpp b/yoRadio/netserver.cpp index df9785a..b7074b6 100644 --- a/yoRadio/netserver.cpp +++ b/yoRadio/netserver.cpp @@ -8,12 +8,15 @@ #include "options.h" #include "network.h" #include "mqtt.h" +#include "controls.h" #include #ifndef MIN_MALLOC #define MIN_MALLOC 24112 #endif +#define CORS_DEBUG + NetServer netserver; AsyncWebServer webserver(80); @@ -25,7 +28,6 @@ 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 handleHTTPPost(AsyncWebServerRequest * request); -byte ssidCount; bool shouldReboot = false; char* updateError(){ @@ -34,23 +36,40 @@ char* updateError(){ return ret; } +void NetServer::takeMallocDog(){ + int mcb = heap_caps_get_free_size(MALLOC_CAP_8BIT); + int mci = heap_caps_get_free_size(MALLOC_CAP_INTERNAL); + (void)mci; + log_i("[yoradio] webserver.on / - MALLOC_CAP_INTERNAL=%d, MALLOC_CAP_8BIT=%d", mci, mcb); + resumePlay = mcb < MIN_MALLOC; + if (resumePlay) { + player.toggle(); + while (player.isRunning()) { + vTaskDelay(10); + } + vTaskDelay(50); + } +} + +void NetServer::giveMallocDog(){ + if (resumePlay) { + resumePlay = false; + vTaskDelay(100); + player.toggle(); + } +} + bool NetServer::begin() { importRequest = false; irRecordEnable = false; webserver.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { - ssidCount = 0; - int mcb = heap_caps_get_free_size(MALLOC_CAP_8BIT); - int mci = heap_caps_get_free_size(MALLOC_CAP_INTERNAL); - (void)mci; - log_i("[yoradio] webserver.on / - MALLOC_CAP_INTERNAL=%d, MALLOC_CAP_8BIT=%d", mci, mcb); - netserver.resumePlay = mcb < MIN_MALLOC; - if (netserver.resumePlay) { - player.toggle(); - while (player.isRunning()) { - delay(10); - } + netserver.takeMallocDog(); + if (network.status == CONNECTED) { + request->send(SPIFFS, "/www/index.html", String(), false, processor); + }else{ + request->send(SPIFFS, "/www/settings.html", String(), false, processor); } - request->send(SPIFFS, "/www/index.html", String(), false, processor); + netserver.giveMallocDog(); }); webserver.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=31536000"); @@ -59,23 +78,37 @@ bool NetServer::begin() { handleHTTPPost(request); }); webserver.on(PLAYLIST_PATH, HTTP_GET, [](AsyncWebServerRequest * request) { + netserver.takeMallocDog(); request->send(SPIFFS, PLAYLIST_PATH, "application/octet-stream"); + netserver.giveMallocDog(); }); webserver.on(INDEX_PATH, HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, INDEX_PATH, "application/octet-stream"); }); webserver.on(SSIDS_PATH, HTTP_GET, [](AsyncWebServerRequest * request) { + netserver.takeMallocDog(); request->send(SPIFFS, SSIDS_PATH, "application/octet-stream"); + netserver.giveMallocDog(); }); webserver.on("/upload", HTTP_POST, [](AsyncWebServerRequest * request) { //request->send(200); + }, handleUpload); webserver.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){ + netserver.takeMallocDog(); request->send(SPIFFS, "/www/update.html", String(), false, processor); + netserver.giveMallocDog(); + }); + webserver.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){ + netserver.takeMallocDog(); + request->send(SPIFFS, "/www/settings.html", String(), false, processor); + netserver.giveMallocDog(); }); #if IR_PIN!=255 webserver.on("/ir", HTTP_GET, [](AsyncWebServerRequest *request){ + netserver.takeMallocDog(); request->send(SPIFFS, "/www/ir.html", String(), false, processor); + netserver.giveMallocDog(); }); #endif webserver.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){ @@ -109,6 +142,10 @@ bool NetServer::begin() { } } }); +#ifdef CORS_DEBUG + DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Origin"), F("*")); + DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Headers"), F("content-type")); +#endif webserver.begin(); websocket.onEvent(onWsEvent); webserver.addHandler(&websocket); @@ -136,7 +173,7 @@ void NetServer::loop() { } if (importRequest) { if (importPlaylist()) { - requestOnChange(PLAYLIST, 0); + //requestOnChange(PLAYLIST, 0); } importRequest = false; } @@ -157,16 +194,355 @@ void NetServer::irValsToWs(){ websocket.textAll(buf); } #endif -void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len) { +void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t clientId) { AwsFrameInfo *info = (AwsFrameInfo*)arg; if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) { data[len] = 0; - char cmd[15], val[15]; - if (config.parseWsCommand((const char*)data, cmd, val, 15)) { + char cmd[65], val[65]; + if (config.parseWsCommand((const char*)data, cmd, val, 65)) { + if (strcmp(cmd, "getmode") == 0) { + requestOnChange(GETMODE,clientId); + return; + } + if (strcmp(cmd, "getindex") == 0) { + requestOnChange(GETINDEX,clientId); + return; + } + if (strcmp(cmd, "getsystem") == 0) { + requestOnChange(GETSYSTEM,clientId); + return; + } + if (strcmp(cmd, "getscreen") == 0) { + requestOnChange(GETSCREEN,clientId); + return; + } + if (strcmp(cmd, "gettimezone") == 0) { + requestOnChange(GETTIMEZONE,clientId); + return; + } + if (strcmp(cmd, "getcontrols") == 0) { + requestOnChange(GETCONTROLS,clientId); + return; + } + if (strcmp(cmd, "getweather") == 0) { + requestOnChange(GETWEATHER,clientId); + return; + } + if (strcmp(cmd, "getactive") == 0) { + requestOnChange(GETACTIVE,clientId); + return; + } + + if (strcmp(cmd, "smartstart") == 0) { + byte valb=atoi(val); + config.store.smartstart=valb==1?1:2; + if(!player.isRunning() && config.store.smartstart==1) config.store.smartstart=0; + config.save(); + return; + } + if (strcmp(cmd, "audioinfo") == 0) { + byte valb=atoi(val); + config.store.audioinfo=valb; + config.save(); + display.putRequest({NEWMODE, CLEAR}); + display.putRequest({NEWMODE, PLAYER}); + return; + } + if (strcmp(cmd, "vumeter") == 0) { + byte valb=atoi(val); + config.store.vumeter=valb; + config.save(); + display.putRequest({NEWMODE, CLEAR}); + display.putRequest({NEWMODE, PLAYER}); + return; + } + if (strcmp(cmd, "softap") == 0) { + byte valb=atoi(val); + config.store.softapdelay=valb; + config.save(); + return; + } + if (strcmp(cmd, "invertdisplay") == 0) { + byte valb=atoi(val); + config.store.invertdisplay=valb; + config.save(); + display.invert(); + return; + } + if (strcmp(cmd, "numplaylist") == 0) { + byte valb=atoi(val); + config.store.numplaylist=valb; + config.save(); + display.putRequest({NEWMODE, CLEAR}); + display.putRequest({NEWMODE, PLAYER}); + return; + } + + if (strcmp(cmd, "fliptouch") == 0) { + byte valb=atoi(val); + config.store.fliptouch=valb==1; + config.save(); + flipTS(); + return; + } + if (strcmp(cmd, "dbgtouch") == 0) { + byte valb=atoi(val); + config.store.dbgtouch=valb==1; + config.save(); + return; + } + if (strcmp(cmd, "flipscreen") == 0) { + byte valb=atoi(val); + config.store.flipscreen=valb; + config.save(); + display.flip(); + display.putRequest({NEWMODE, CLEAR}); + display.putRequest({NEWMODE, PLAYER}); + return; + } + if (strcmp(cmd, "brightness") == 0) { + byte valb=atoi(val); + config.store.brightness=valb; + //display.setContrast(); + config.setBrightness(true); + return; + } + if (strcmp(cmd, "screenon") == 0) { + byte valb=atoi(val); + config.store.dspon=valb==1; + config.setBrightness(true); + return; + } + if (strcmp(cmd, "contrast") == 0) { + byte valb=atoi(val); + config.store.contrast=valb; + config.save(); + display.setContrast(); + return; + } + if (strcmp(cmd, "tzh") == 0) { + int vali=atoi(val); + config.store.tzHour=vali; + return; + } + if (strcmp(cmd, "tzm") == 0) { + int vali=atoi(val); + config.store.tzMin=vali; + return; + } + if (strcmp(cmd, "sntp2") == 0) { + strlcpy(config.store.sntp2,val, 35); + return; + } + if (strcmp(cmd, "sntp1") == 0) { + strlcpy(config.store.sntp1,val, 35); + bool tzdone=false; + if(strlen(config.store.sntp1)>0 && strlen(config.store.sntp2)>0){ + configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1, config.store.sntp2); + tzdone=true; + }else if(strlen(config.store.sntp1)>0){ + configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1); + tzdone=true; + } + if(tzdone){ + network.requestTimeSync(true); + config.save(); + } + return; + } + + if (strcmp(cmd, "volsteps") == 0) { + uint8_t valb=atoi(val); + config.store.volsteps=valb; + config.save(); + return; + } + if (strcmp(cmd, "encacceleration") == 0) { + uint16_t valb=atoi(val); + setEncAcceleration(valb); + config.store.encacc=valb; + config.save(); + return; + } + if (strcmp(cmd, "irtlp") == 0) { + uint8_t valb=atoi(val); + setIRTolerance(valb); + return; + } + if (strcmp(cmd, "showweather") == 0) { + uint8_t valb=atoi(val); + config.store.showweather=valb==1; + config.save(); + display.showWeather(); +#ifdef USE_NEXTION + nextion.startWeather(); +#endif + display.putRequest({NEWMODE, CLEAR}); + display.putRequest({NEWMODE, PLAYER}); + return; + } + if (strcmp(cmd, "lat") == 0) { + strlcpy(config.store.weatherlat,val, 10); + return; + } + if (strcmp(cmd, "lon") == 0) { + strlcpy(config.store.weatherlon,val, 10); + return; + } + if (strcmp(cmd, "key") == 0) { + strlcpy(config.store.weatherkey,val, 64); + config.save(); + display.showWeather(); +#ifdef USE_NEXTION + nextion.startWeather(); +#endif + display.putRequest({NEWMODE, CLEAR}); + display.putRequest({NEWMODE, PLAYER}); + return; + } + + if (strcmp(cmd, "reset") == 0) { + if (strcmp(val, "system") == 0) { + config.store.smartstart=2; + config.store.audioinfo=false; + config.store.vumeter=false; + config.store.softapdelay=0; + config.save(); + display.putRequest({NEWMODE, CLEAR}); + display.putRequest({NEWMODE, PLAYER}); + requestOnChange(GETSYSTEM,clientId); + return; + } + if (strcmp(val, "screen") == 0) { + config.store.flipscreen=false; + display.flip(); + config.store.invertdisplay=false; + display.invert(); + config.store.dspon=true; + config.store.brightness=100; + config.setBrightness(false); + config.store.contrast=55; + display.setContrast(); + config.store.numplaylist=false; + config.save(); + display.putRequest({NEWMODE, CLEAR}); + display.putRequest({NEWMODE, PLAYER}); + requestOnChange(GETSCREEN,clientId); + return; + } + if (strcmp(val, "timezone") == 0) { + config.store.tzHour=3; + config.store.tzMin=0; + strlcpy(config.store.sntp1,"pool.ntp.org", 35); + strlcpy(config.store.sntp2,"0.ru.pool.ntp.org", 35); + config.save(); + configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1, config.store.sntp2); + network.requestTimeSync(true); + requestOnChange(GETTIMEZONE,clientId); + return; + } + if (strcmp(val, "weather") == 0) { + config.store.showweather=0; + strlcpy(config.store.weatherlat,"55.7512", 10); + strlcpy(config.store.weatherlon,"37.6184", 10); + strlcpy(config.store.weatherkey,"", 64); + config.save(); + display.showWeather(); +#ifdef USE_NEXTION + nextion.startWeather(); +#endif + display.putRequest({NEWMODE, CLEAR}); + display.putRequest({NEWMODE, PLAYER}); + requestOnChange(GETWEATHER,clientId); + return; + } + if (strcmp(val, "controls") == 0) { + config.store.volsteps=1; + config.store.fliptouch=false; + config.store.dbgtouch=false; + setEncAcceleration(200); + setIRTolerance(40); + requestOnChange(GETCONTROLS,clientId); + return; + } + } if (strcmp(cmd, "volume") == 0) { byte v = atoi(val); player.setVol(v, false); } + + /* REMOVE FROM POST + * if (request->hasParam("trebble", true)) { + AsyncWebParameter* pt = request->getParam("trebble", true); + AsyncWebParameter* pm = request->getParam("middle", true); + AsyncWebParameter* pb = request->getParam("bass", true); + int t = atoi(pt->value().c_str()); + int m = atoi(pm->value().c_str()); + int b = atoi(pb->value().c_str()); + //setTone(int8_t gainLowPass, int8_t gainBandPass, int8_t gainHighPass) + player.setTone(b, m, t); + config.setTone(b, m, t); + netserver.requestOnChange(EQUALIZER, 0); + request->send(200); + return; + } + if (request->hasParam("ballance", true)) { + AsyncWebParameter* p = request->getParam("ballance", true); + int b = atoi(p->value().c_str()); + player.setBalance(b); + config.setBalance(b); + netserver.requestOnChange(BALANCE, 0); + request->send(200); + return; + } + */ + if (strcmp(cmd, "balance") == 0) { + int8_t valb=atoi(val); + player.setBalance(valb); + config.setBalance(valb); + netserver.requestOnChange(BALANCE, 0); + return; + } + if (strcmp(cmd, "treble") == 0) { + int8_t valb=atoi(val); + player.setTone(config.store.bass, config.store.middle, valb); + config.setTone(config.store.bass, config.store.middle, valb); + netserver.requestOnChange(EQUALIZER, 0); + return; + } + if (strcmp(cmd, "middle") == 0) { + int8_t valb=atoi(val); + player.setTone(config.store.bass, valb, config.store.trebble); + config.setTone(config.store.bass, valb, config.store.trebble); + netserver.requestOnChange(EQUALIZER, 0); + return; + } + if (strcmp(cmd, "bass") == 0) { + int8_t valb=atoi(val); + player.setTone(valb, config.store.middle, config.store.trebble); + config.setTone(valb, config.store.middle, config.store.trebble); + netserver.requestOnChange(EQUALIZER, 0); + return; + } + if (strcmp(cmd, "submitplaylist") == 0) { + if(player.isRunning()){ + player.toggle(); + while (player.isRunning()) { + vTaskDelay(10); + } + vTaskDelay(50); + resumePlay=true; + } + return; + } + if (strcmp(cmd, "submitplaylistdone") == 0) { + if(resumePlay){ + vTaskDelay(100); + player.toggle(); + resumePlay=false; + } + return; + } #if IR_PIN!=255 if (strcmp(cmd, "irbtn") == 0) { config.irindex=atoi(val); @@ -264,7 +640,7 @@ bool NetServer::importPlaylist() { } void NetServer::requestOnChange(requestType_e request, uint8_t clientId) { - char buf[BUFLEN + 50] = { 0 }; + char buf[BUFLEN * 2] = { 0 }; switch (request) { case PLAYLIST: { getPlaylist(clientId); @@ -279,6 +655,90 @@ void NetServer::requestOnChange(requestType_e request, uint8_t clientId) { #endif break; } + case GETACTIVE: { + bool dbgact = false; + String act="\"group_wifi\","; + if (network.status == CONNECTED) { + act+="\"group_system\","; + if(BRIGHTNESS_PIN!=255 || DSP_FLIPPED==1 || DSP_MODEL==DSP_NOKIA5110 || dbgact){ + act+="\"group_display\","; + } +#ifdef USE_NEXTION + act+="\"group_nextion\","; + if (WEATHER_READY==0 || dbgact){ + act+="\"group_weather\","; + } +#endif + if(VU_READY==1 || dbgact){ + act+="\"group_vu\","; + } + if(BRIGHTNESS_PIN!=255 || dbgact){ + act+="\"group_brightness\","; + } + if(DSP_FLIPPED==1 || dbgact){ + act+="\"group_tft\","; + } + if(TS_CS!=255 || dbgact){ + act+="\"group_touch\","; + } + if(DSP_MODEL==DSP_NOKIA5110){ + act+="\"group_nokia\","; + } + if(DSP_MODEL!=DSP_DUMMY || dbgact){ + act+="\"group_timezone\","; + + } + if (WEATHER_READY==1 || dbgact){ + act+="\"group_weather\","; + } + act+="\"group_controls\","; + if(ENC_BTNL!=255 || ENC2_BTNL!=255 || dbgact){ + act+="\"group_encoder\","; + } + if(IR_PIN!=255 || dbgact){ + act+="\"group_ir\","; + } + } + act = act.substring(0, act.length()-1); + sprintf (buf, "{\"act\":[%s]}", act.c_str()); + break; + } + case GETMODE: { + sprintf (buf, "{\"pmode\":\"%s\"}", network.status == CONNECTED?"player":"ap"); + break; + } + case GETINDEX: { + requestOnChange(STATION, clientId); + requestOnChange(TITLE, clientId); + requestOnChange(VOLUME, clientId); + requestOnChange(EQUALIZER, clientId); + requestOnChange(BALANCE, clientId); + requestOnChange(BITRATE, clientId); + requestOnChange(MODE, clientId); + //playlistrequest = clientId; /* Cleanup this */ + return; + break; + } + case GETSYSTEM: { + sprintf (buf, "{\"sst\":%d,\"aif\":%d,\"vu\":%d,\"softr\":%d}", config.store.smartstart!=2, config.store.audioinfo, config.store.vumeter, config.store.softapdelay); + break; + } + case GETSCREEN: { + sprintf (buf, "{\"flip\":%d,\"inv\":%d,\"nump\":%d,\"tsf\":%d,\"tsd\":%d,\"dspon\":%d,\"br\":%d,\"con\":%d}", config.store.flipscreen, config.store.invertdisplay, config.store.numplaylist, config.store.fliptouch, config.store.dbgtouch, config.store.dspon, config.store.brightness, config.store.contrast); + break; + } + case GETTIMEZONE: { + sprintf (buf, "{\"tzh\":%d,\"tzm\":%d,\"sntp1\":\"%s\",\"sntp2\":\"%s\"}", config.store.tzHour, config.store.tzMin, config.store.sntp1, config.store.sntp2); + break; + } + case GETWEATHER: { + sprintf (buf, "{\"wen\":%d,\"wlat\":\"%s\",\"wlon\":\"%s\",\"wkey\":\"%s\"}", config.store.showweather, config.store.weatherlat, config.store.weatherlon, config.store.weatherkey); + break; + } + case GETCONTROLS: { + sprintf (buf, "{\"vols\":%d,\"enca\":%d,\"irtl\":%d}", config.store.volsteps, config.store.encacc, config.store.irtlp); + break; + } case STATION: { sprintf (buf, "{\"nameset\": \"%s\"}", config.station.name); requestOnChange(ITEM, clientId); @@ -343,22 +803,6 @@ String processor(const String& var) { // %Templates% if (var == "VERSION") { return VERSION; } - if (var == "SSID") { - ssidCount++; - return String(config.ssids[ssidCount - 1].ssid); - } - if (var == "PASS") { - return String(config.ssids[ssidCount - 1].password); - } - if (var == "APMODE") { - return network.status == CONNECTED ? "" : " style=\"display: none!important\""; - } - if (var == "NOTAPMODE") { - return network.status == CONNECTED ? " hidden" : ""; - } - if (var == "IRMODE") { - return IR_PIN == 255 ? "" : " ir"; - } return String(); } @@ -381,22 +825,21 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp switch (type) { case WS_EVT_CONNECT: 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(VOLUME, client->id()); netserver.requestOnChange(EQUALIZER, client->id()); netserver.requestOnChange(BALANCE, client->id()); netserver.requestOnChange(BITRATE, client->id()); netserver.requestOnChange(MODE, client->id()); - netserver.playlistrequest = client->id(); + netserver.playlistrequest = client->id();*/ break; case WS_EVT_DISCONNECT: if(config.store.audioinfo) Serial.printf("WebSocket client #%u disconnected\n", client->id()); break; case WS_EVT_DATA: - netserver.onWsMessage(arg, data, len); + netserver.onWsMessage(arg, data, len, client->id()); break; case WS_EVT_PONG: case WS_EVT_ERROR: diff --git a/yoRadio/netserver.h b/yoRadio/netserver.h index 62a562b..b211db4 100644 --- a/yoRadio/netserver.h +++ b/yoRadio/netserver.h @@ -5,7 +5,7 @@ #include "ESPAsyncWebServer.h" #include "AsyncUDP.h" -enum requestType_e { PLAYLIST, STATION, ITEM, TITLE, VOLUME, NRSSI, BITRATE, MODE, EQUALIZER, BALANCE, PLAYLISTSAVED }; +enum requestType_e { PLAYLIST, STATION, ITEM, TITLE, VOLUME, NRSSI, BITRATE, MODE, EQUALIZER, BALANCE, PLAYLISTSAVED, GETMODE, GETINDEX, GETACTIVE, GETSYSTEM, GETSCREEN, GETTIMEZONE, GETWEATHER, GETCONTROLS }; class NetServer { public: @@ -18,8 +18,10 @@ class NetServer { void loop(); void requestOnChange(requestType_e request, uint8_t clientId); void setRSSI(int val); - void onWsMessage(void *arg, uint8_t *data, size_t len); + void onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t clientId); bool savePlaylist(const char* post); + void takeMallocDog(); + void giveMallocDog(); #if IR_PIN!=255 bool irRecordEnable; void irToWs(const char* protocol, uint64_t irvalue); diff --git a/yoRadio/network.cpp b/yoRadio/network.cpp index bc76cb9..63f11d7 100644 --- a/yoRadio/network.cpp +++ b/yoRadio/network.cpp @@ -62,13 +62,19 @@ void Network::begin() { digitalWrite(LED_BUILTIN, LOW); status = CONNECTED; WiFi.setSleep(false); - configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), SNTP_SERVER); - //getLocalTime(&timeinfo); + //configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), SNTP_SERVER); + if(strlen(config.store.sntp1)>0 && strlen(config.store.sntp2)>0){ + configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1, config.store.sntp2); + }else if(strlen(config.store.sntp1)>0){ + configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1); + } + ////getLocalTime(&timeinfo); stimer.once_ms(200,getFirstTime); ntimer.attach_ms(TSYNC_DELAY, syncTime); #ifdef USE_NEXTION nextion.startWeather(); #endif + display.updateWeather(); if (network_on_connect) network_on_connect(); } @@ -91,7 +97,6 @@ void Network::raiseSoftAP() { WiFi.softAP(apSsid, apPassword); Serial.printf("\n\nRunning in AP mode.\nConnect to AP %s with password %s for settings.\n\n", apSsid, apPassword); status = SOFT_AP; -#if SOFT_AP_REBOOT_DELAY>0 - rtimer.attach_ms(SOFT_AP_REBOOT_DELAY, rebootTime); -#endif + if(config.store.softapdelay>0) + rtimer.attach_ms(config.store.softapdelay*1000*60, rebootTime); } diff --git a/yoRadio/options.h b/yoRadio/options.h index 73848b2..820f196 100644 --- a/yoRadio/options.h +++ b/yoRadio/options.h @@ -1,7 +1,7 @@ #ifndef options_h #define options_h -#define VERSION "0.7.017" +#define VERSION "0.7.330" /******************************************************* DO NOT EDIT THIS FILE. @@ -64,22 +64,13 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti #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 */ #ifndef I2C_SDA - #define I2C_SDA 13 + #define I2C_SDA 21 #endif #ifndef I2C_SCL - #define I2C_SCL 14 + #define I2C_SCL 22 #endif #ifndef I2C_RST #define I2C_RST -1 @@ -176,12 +167,6 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti #ifndef TS_CS #define TS_CS 255 #endif -#ifndef TS_ROTATE - #define TS_ROTATE 1 -#endif -#ifndef TS_DBG - #define TS_DBG false -#endif /* LCD DISPLAY */ #ifndef LCD_RS @@ -209,49 +194,23 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti #endif /* Other settings. You can overwrite them in the myoptions.h file */ -#ifndef TFT_ROTATE - #define TFT_ROTATE 3 // display rotation. 0 - 0, 1 - 90, 2 - 180, 3 - 270 degrees -#endif -#ifndef TFT_CONTRAST - #define TFT_CONTRAST 55 // Nokia 5110 contrast -#endif -#ifndef TFT_INVERT - #define TFT_INVERT true // invert the display colors (usually true) -#endif -#ifndef VOL_STEP - #define VOL_STEP 1 // Encoder vol step -#endif -#ifndef VOL_ACCELERATION - #define VOL_ACCELERATION 200 // Encoder vol acceleration; 0 or 1 means disabled acceleration -#endif #ifndef MUTE_PIN #define MUTE_PIN 255 // MUTE Pin #endif #ifndef MUTE_VAL #define MUTE_VAL HIGH // Write this to MUTE_PIN when player is stopped #endif +#ifndef BRIGHTNESS_PIN + #define BRIGHTNESS_PIN 255 // BRIGHTNESS Pin +#endif #ifndef PLAYER_FORCE_MONO #define PLAYER_FORCE_MONO false // mono option - false stereo, true mono #endif -#ifndef SNTP_SERVER - #define SNTP_SERVER "pool.ntp.org", "0.ru.pool.ntp.org" // custom ntp servers min 1 max 3 comma separated values -#endif #ifndef I2S_INTERNAL #define I2S_INTERNAL false // If true - use esp32 internal DAC #endif -#ifndef SOFT_AP_REBOOT_DELAY - #define SOFT_AP_REBOOT_DELAY 0 // Delay in ms after which ESP is rebooting if it is in softAP mode (0 - disabled) -#endif -#ifndef ENABLE_VU_METER - #define ENABLE_VU_METER false // enable? vu meter for some displays -/* - * !!! Important !!! - * if you enable this feathure on the esp32 wroom, due to lack of memory, you must modify the file Arduino/libraries/AsyncTCP/src/AsyncTCP.cpp - * replace the line 221 - * xTaskCreateUniversal(_async_service_task, "async_tcp", 8192 * 2, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE); - * with - * xTaskCreateUniversal(_async_service_task, "async_tcp", 8192 / 2, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE); -*/ +#ifndef ROTATE_90 + #define ROTATE_90 false // Optional 90 degree rotation for square displays #endif /* *** ST7735 display submodel *** @@ -273,8 +232,5 @@ INITR_REDTAB #ifndef IR_TIMEOUT #define IR_TIMEOUT 80 // kTimeout, see IRremoteESP8266 documentation #endif -#ifndef IR_TLP - #define IR_TLP 40 // kTolerancePercentage, see IRremoteESP8266 documentation -#endif #endif diff --git a/yoRadio/player.cpp b/yoRadio/player.cpp index d9e9640..bd3f649 100644 --- a/yoRadio/player.cpp +++ b/yoRadio/player.cpp @@ -156,14 +156,14 @@ void Player::toggle() { void Player::stepVol(bool up) { if (up) { - if (config.store.volume <= 254 - VOL_STEP) { - setVol(config.store.volume + VOL_STEP, false); + if (config.store.volume <= 254 - config.store.volsteps) { + setVol(config.store.volume + config.store.volsteps, false); }else{ setVol(254, false); } } else { - if (config.store.volume >= VOL_STEP) { - setVol(config.store.volume - VOL_STEP, false); + if (config.store.volume >= config.store.volsteps) { + setVol(config.store.volume - config.store.volsteps, false); }else{ setVol(0, false); } diff --git a/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.cpp b/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.cpp index e5b539e..add322f 100644 --- a/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.cpp +++ b/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.cpp @@ -545,7 +545,7 @@ void TFT_22_ILI9225::clear() { } -void TFT_22_ILI9225::invert(boolean flag) { +void TFT_22_ILI9225::invertDisplay(boolean flag) { startWrite(); _writeCommand16(flag ? ILI9225C_INVON : ILI9225C_INVOFF); //_writeCommand(0x00, flag ? ILI9225C_INVON : ILI9225C_INVOFF); diff --git a/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.h b/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.h index 79b0089..16cfb2d 100644 --- a/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.h +++ b/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.h @@ -186,7 +186,7 @@ class TFT_22_ILI9225 { /// Invert screen /// @param flag true to invert, false for normal screen - void invert(boolean flag); + void invertDisplay(boolean flag); /// Switch backlight on or off /// @param flag true=on, false=off diff --git a/yoRadio/src/audioVS1053/audioVS1053Ex.cpp b/yoRadio/src/audioVS1053/audioVS1053Ex.cpp index 9e1b724..29d92bd 100644 --- a/yoRadio/src/audioVS1053/audioVS1053Ex.cpp +++ b/yoRadio/src/audioVS1053/audioVS1053Ex.cpp @@ -1569,7 +1569,6 @@ void Audio::setDefaults(){ * \n The VU meter takes about 0.2MHz of processing power with 48 kHz samplerate. */ void Audio::setVUmeter() { -// if(!ENABLE_VU_METER) return; uint16_t MP3Status = read_register(SCI_STATUS); if(MP3Status==0) { Serial.println("VS1053 Error: Unable to write SCI_STATUS"); @@ -1593,7 +1592,6 @@ void Audio::setVUmeter() { * \warning This feature is only available with patches that support VU meter. */ void Audio::getVUlevel() { -// if(!ENABLE_VU_METER) return; if(!_vuInitalized) return; int16_t reg = read_register(SCI_AICTRL3); uint8_t rl = map((uint8_t)reg, 85, 92, 0, 255); diff --git a/yoRadio/src/displays/displayDummy.h b/yoRadio/src/displays/displayDummy.h index 9a710fc..47cdd98 100644 --- a/yoRadio/src/displays/displayDummy.h +++ b/yoRadio/src/displays/displayDummy.h @@ -15,6 +15,8 @@ #define SCROLLTIME 60 #endif +#define DSP_FLIPPED 0 + class DspCore { public: DspCore(); diff --git a/yoRadio/src/displays/displayGC9106.cpp b/yoRadio/src/displays/displayGC9106.cpp index ad237b9..08cb734 100644 --- a/yoRadio/src/displays/displayGC9106.cpp +++ b/yoRadio/src/displays/displayGC9106.cpp @@ -12,11 +12,7 @@ #define DEF_SPI_FREQ 24000000 /* set it to 0 for system default */ #endif -#if ENABLE_VU_METER #define CLOCK_DELTA 16 -#else -#define CLOCK_DELTA 0 -#endif #define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY) #define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl) @@ -120,12 +116,9 @@ void DspCore::apScreen() { void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { begin(DEF_SPI_FREQ); cp437(true); - invertDisplay(!TFT_INVERT); + invert(); fillScreen(TFT_BG); - byte tftRotate = TFT_ROTATE; - if(tftRotate>1) tftRotate=3; - if(tftRotate==0) tftRotate=1; - setRotation(tftRotate); + flip(); setTextWrap(false); screenwidth = width(); screenheight = height(); @@ -239,15 +232,16 @@ void DspCore::printClock(struct tm timeinfo, bool dots, bool redraw){ char timeBuf[50] = { 0 }; char tmpBuf[4] = { 0 }; uint16_t ncwidth, ncheight; + uint16_t clockdelta=config.store.vumeter?CLOCK_DELTA:0; strftime(timeBuf, sizeof(timeBuf), "%H %M", &timeinfo); setTextSize(1); setFont(&DS_DIGI28pt7b); if(strstr(oldTimeBuf, timeBuf)==NULL || redraw){ getTextBounds(oldTimeBuf, 0, 0, &x, &y, &wot, &hot); - setCursor((swidth - wot) / 2 - 4 + CLOCK_DELTA, clockY+28+6); + setCursor((swidth - wot) / 2 - 4 + clockdelta, clockY+28+6); setTextColor(TFT_BG); print(oldTimeBuf); - dot = (swidth - wot) / 2 - 4 + CLOCK_DELTA; + dot = (swidth - wot) / 2 - 4 + clockdelta; /* dots */ strlcpy(tmpBuf, oldTimeBuf, 3); getTextBounds(tmpBuf, 0, 0, &x, &y, &ncwidth, &ncheight); @@ -260,8 +254,8 @@ void DspCore::printClock(struct tm timeinfo, bool dots, bool redraw){ setTextSize(1); getTextBounds(timeBuf, 0, 0, &x, &y, &ncwidth, &ncheight); setTextColor(TFT_LOGO); - setCursor((swidth - ncwidth) / 2 - 4 + CLOCK_DELTA, clockY+28+6); - dot = (swidth - ncwidth) / 2 - 4 + CLOCK_DELTA; + setCursor((swidth - ncwidth) / 2 - 4 + clockdelta, clockY+28+6); + dot = (swidth - ncwidth) / 2 - 4 + clockdelta; setTextSize(1); print(timeBuf); /* dots */ @@ -384,5 +378,11 @@ void DspCore::printText(const char* txt) { void DspCore::loop(bool force) { } +void DspCore::flip(){ + setRotation(config.store.flipscreen?1:3); +} +void DspCore::invert(){ + invertDisplay(config.store.invertdisplay); +} #endif diff --git a/yoRadio/src/displays/displayGC9106.h b/yoRadio/src/displays/displayGC9106.h index d159529..3c5f4f3 100644 --- a/yoRadio/src/displays/displayGC9106.h +++ b/yoRadio/src/displays/displayGC9106.h @@ -7,6 +7,8 @@ #include "../Adafruit_GC9106Ex/Adafruit_GC9106Ex.h" #include "fonts/DS_DIGI28pt7b.h" +#define VU_READY 1 + #define TFT_LINEHGHT 10 #define TFT_FRAMEWDT 0 @@ -58,6 +60,8 @@ class DspCore: public Adafruit_GC9106Ex { void loop(bool force=false); virtual void startWrite(void); virtual void endWrite(void); + void flip(); + void invert(); /*virtual void sendCommand(uint8_t commandByte, uint8_t *dataBytes, uint8_t numDataBytes); virtual void sendCommand(uint8_t commandByte, const uint8_t *dataBytes = NULL, diff --git a/yoRadio/src/displays/displayILI9225.cpp b/yoRadio/src/displays/displayILI9225.cpp index 21291de..e5919b9 100644 --- a/yoRadio/src/displays/displayILI9225.cpp +++ b/yoRadio/src/displays/displayILI9225.cpp @@ -190,10 +190,10 @@ void DspCore::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { //hspi.begin(); begin(); - invert(TFT_INVERT); + invert(); setBackgroundColor(TFT_BG); clear(); - setOrientation(TFT_ROTATE); + flip(); setTextSize(1); screenwidth = maxX(); screenheight = maxY(); @@ -449,5 +449,10 @@ void DspCore::drawRGBBitmap(int16_t x, int16_t y, const uint16_t *bitmap, int16_ drawBitmap(x, y, bitmap, w, h); GIVE_MUTEX(); } - +void DspCore::flip(){ + setOrientation(config.store.flipscreen?3:1); +} +void DspCore::invert(){ + invertDisplay(config.store.invertdisplay); +} #endif diff --git a/yoRadio/src/displays/displayILI9225.h b/yoRadio/src/displays/displayILI9225.h index e0e806b..6229e58 100644 --- a/yoRadio/src/displays/displayILI9225.h +++ b/yoRadio/src/displays/displayILI9225.h @@ -5,6 +5,9 @@ #include "../ILI9225Fix/TFT_22_ILI9225Fix.h" #include "fonts/DS_DIGI28pt7b.h" +#define VU_READY 1 +#define WEATHER_READY 1 + #define TFT_LINEHGHT 10 #define TFT_FRAMEWDT 4 #define META_SIZE 2 @@ -73,6 +76,8 @@ class DspCore: public TFT_22_ILI9225 { int16_t width(void) { return (int16_t)maxX(); } int16_t height(void) { return (int16_t)maxY(); } void drawRGBBitmap(int16_t x, int16_t y, const uint16_t *bitmap, int16_t w, int16_t h); + void flip(); + void invert(); private: uint16_t swidth, sheight; uint16_t bgcolor, fgcolor; diff --git a/yoRadio/src/displays/displayILI9341.cpp b/yoRadio/src/displays/displayILI9341.cpp index 0605d1e..fec2192 100644 --- a/yoRadio/src/displays/displayILI9341.cpp +++ b/yoRadio/src/displays/displayILI9341.cpp @@ -113,10 +113,10 @@ void DspCore::apScreen() { void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { begin(); /* SPI_DEFAULT_FREQ 40000000 */ - invertDisplay(TFT_INVERT); + invert(); cp437(true); fillScreen(TFT_BG); - setRotation(TFT_ROTATE); + flip(); setTextWrap(false); setTextSize(1); screenwidth = width(); @@ -385,5 +385,11 @@ void DspCore::printText(const char* txt) { void DspCore::loop(bool force) { } +void DspCore::flip(){ + setRotation(config.store.flipscreen?1:3); +} +void DspCore::invert(){ + invertDisplay(config.store.invertdisplay); +} #endif diff --git a/yoRadio/src/displays/displayILI9341.h b/yoRadio/src/displays/displayILI9341.h index 48f3934..dfa7afc 100644 --- a/yoRadio/src/displays/displayILI9341.h +++ b/yoRadio/src/displays/displayILI9341.h @@ -7,6 +7,9 @@ // https://tchapi.github.io/Adafruit-GFX-Font-Customiser/ #include "fonts/DS_DIGI42pt7b.h" +#define VU_READY 1 +#define WEATHER_READY 1 + #define TFT_LINEHGHT 10 #define TFT_FRAMEWDT 8 #define META_SIZE 3 @@ -58,6 +61,8 @@ class DspCore: public Adafruit_ILI9341 { void loop(bool force=false); virtual void startWrite(void); virtual void endWrite(void); + void flip(); + void invert(); private: uint16_t swidth, sheight; char oldTimeBuf[20]; diff --git a/yoRadio/src/displays/displayLC1602.h b/yoRadio/src/displays/displayLC1602.h index 3d7b872..1252b9c 100644 --- a/yoRadio/src/displays/displayLC1602.h +++ b/yoRadio/src/displays/displayLC1602.h @@ -3,6 +3,8 @@ #include "Arduino.h" +#define DSP_FLIPPED 0 + #if DSP_MODEL==DSP_2004 || DSP_MODEL==DSP_2004I2C #define LCD_2004 #endif @@ -89,6 +91,8 @@ class DspCore: public LiquidCrystal { void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); void loop(bool force=false); + void flip(){}; + void invert(){}; private: uint16_t swidth, sheight, xOffset, yOffset; int16_t nextX; diff --git a/yoRadio/src/displays/displayN5110.cpp b/yoRadio/src/displays/displayN5110.cpp index 6900a2c..6b7837a 100644 --- a/yoRadio/src/displays/displayN5110.cpp +++ b/yoRadio/src/displays/displayN5110.cpp @@ -134,13 +134,11 @@ void DspCore::data(uint8_t c) { void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { begin(); - setContrast(TFT_CONTRAST); + setContrast(config.store.contrast); cp437(true); + invert(); fillScreen(TFT_BG); - byte tftRotate = TFT_ROTATE; - if(tftRotate>2) tftRotate=2; - if(tftRotate==1) tftRotate=0; - setRotation(tftRotate); + flip(); setTextWrap(false); screenwidth = width(); screenheight = height(); @@ -339,5 +337,11 @@ boolean DspCore::checkdelay(int m, unsigned long &tstamp) { return false; } } +void DspCore::flip(){ + setRotation(config.store.flipscreen?2:0); +} +void DspCore::invert(){ + invertDisplay(config.store.invertdisplay); +} #endif diff --git a/yoRadio/src/displays/displayN5110.h b/yoRadio/src/displays/displayN5110.h index 424fc90..b9a4406 100644 --- a/yoRadio/src/displays/displayN5110.h +++ b/yoRadio/src/displays/displayN5110.h @@ -58,6 +58,8 @@ class DspCore: public Adafruit_PCD8544 { void loop(bool force=false); virtual void command(uint8_t c); virtual void data(uint8_t c); + void flip(); + void invert(); private: uint16_t swidth, sheight; unsigned long loopdelay; diff --git a/yoRadio/src/displays/displaySH1106.cpp b/yoRadio/src/displays/displaySH1106.cpp index 81d9847..2088ee0 100644 --- a/yoRadio/src/displays/displaySH1106.cpp +++ b/yoRadio/src/displays/displaySH1106.cpp @@ -142,12 +142,8 @@ void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { } cp437(true); fillScreen(TFT_BG); - byte tftRotate = TFT_ROTATE; -#if DSP_MODEL==DSP_SH1107 - if(tftRotate>=2) tftRotate=3; - if(tftRotate==0) tftRotate=1; -#endif - setRotation(tftRotate); + flip(); + invert(); setTextWrap(false); screenwidth = width(); screenheight = height(); @@ -348,5 +344,16 @@ boolean DspCore::checkdelay(int m, unsigned long &tstamp) { return false; } } - +void DspCore::flip(){ +#if DSP_MODEL==DSP_SH1107 + setRotation(config.store.flipscreen?3:1); +#endif +#if DSP_MODEL==DSP_SH1106 + setRotation(config.store.flipscreen?2:0); +#endif +} + +void DspCore::invert(){ + invertDisplay(config.store.invertdisplay); +} #endif diff --git a/yoRadio/src/displays/displaySH1106.h b/yoRadio/src/displays/displaySH1106.h index 964548e..eeac7de 100644 --- a/yoRadio/src/displays/displaySH1106.h +++ b/yoRadio/src/displays/displaySH1106.h @@ -57,6 +57,8 @@ class DspCore: public Adafruit_SH1107 { void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); void loop(bool force=false); + void flip(); + void invert(); private: uint16_t swidth, sheight; unsigned long loopdelay; diff --git a/yoRadio/src/displays/displaySSD1305.cpp b/yoRadio/src/displays/displaySSD1305.cpp index a7e55e3..01ee651 100644 --- a/yoRadio/src/displays/displaySSD1305.cpp +++ b/yoRadio/src/displays/displaySSD1305.cpp @@ -144,7 +144,8 @@ void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { } cp437(true); fillScreen(TFT_BG); - setRotation(TFT_ROTATE); + flip(); + invert(); setTextWrap(false); screenwidth = width(); screenheight = height(); @@ -332,5 +333,11 @@ boolean DspCore::checkdelay(int m, unsigned long &tstamp) { return false; } } +void DspCore::flip(){ + setRotation(config.store.flipscreen?2:0); +} +void DspCore::invert(){ + invertDisplay(config.store.invertdisplay); +} #endif diff --git a/yoRadio/src/displays/displaySSD1305.h b/yoRadio/src/displays/displaySSD1305.h index 79976d8..ef411a9 100644 --- a/yoRadio/src/displays/displaySSD1305.h +++ b/yoRadio/src/displays/displaySSD1305.h @@ -5,6 +5,8 @@ #include #include +#define WEATHER_READY 0 + #define TFT_LINEHGHT 8 #define TFT_FRAMEWDT 0 @@ -51,6 +53,8 @@ class DspCore: public Adafruit_SSD1305 { void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); void loop(bool force=false); + void flip(); + void invert(); private: uint16_t swidth, sheight; unsigned long loopdelay; diff --git a/yoRadio/src/displays/displaySSD1306.cpp b/yoRadio/src/displays/displaySSD1306.cpp index c1215bc..e662ed1 100644 --- a/yoRadio/src/displays/displaySSD1306.cpp +++ b/yoRadio/src/displays/displaySSD1306.cpp @@ -141,10 +141,8 @@ void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { } cp437(true); fillScreen(TFT_BG); - byte tftRotate = TFT_ROTATE; - if(tftRotate>2) tftRotate=2; - if(tftRotate==1) tftRotate=0; - setRotation(tftRotate); + flip(); + invert(); setTextWrap(false); screenwidth = width(); screenheight = height(); @@ -355,5 +353,11 @@ boolean DspCore::checkdelay(int m, unsigned long &tstamp) { return false; } } +void DspCore::flip(){ + setRotation(config.store.flipscreen?2:0); +} +void DspCore::invert(){ + invertDisplay(config.store.invertdisplay); +} #endif diff --git a/yoRadio/src/displays/displaySSD1306.h b/yoRadio/src/displays/displaySSD1306.h index 226f88b..cbebbb2 100644 --- a/yoRadio/src/displays/displaySSD1306.h +++ b/yoRadio/src/displays/displaySSD1306.h @@ -71,6 +71,8 @@ class DspCore: public Adafruit_SSD1306 { void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); void loop(bool force=false); + void flip(); + void invert(); private: uint16_t swidth, sheight; unsigned long loopdelay; diff --git a/yoRadio/src/displays/displaySSD1327.cpp b/yoRadio/src/displays/displaySSD1327.cpp index 0f8e99e..2d9bfd9 100644 --- a/yoRadio/src/displays/displaySSD1327.cpp +++ b/yoRadio/src/displays/displaySSD1327.cpp @@ -123,7 +123,8 @@ void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { } cp437(true); fillScreen(TFT_BG); - setRotation(TFT_ROTATE); + flip(); + invert(); setTextWrap(false); screenwidth = width(); screenheight = height(); @@ -401,5 +402,15 @@ boolean DspCore::checkdelay(int m, unsigned long &tstamp) { return false; } } +void DspCore::flip(){ + if(ROTATE_90){ + setRotation(config.store.flipscreen?3:1); + }else{ + setRotation(config.store.flipscreen?2:0); + } +} +void DspCore::invert(){ + invertDisplay(config.store.invertdisplay); +} #endif diff --git a/yoRadio/src/displays/displaySSD1327.h b/yoRadio/src/displays/displaySSD1327.h index c242f3d..052315c 100644 --- a/yoRadio/src/displays/displaySSD1327.h +++ b/yoRadio/src/displays/displaySSD1327.h @@ -6,6 +6,8 @@ #include #include "fonts/DS_DIGI28pt7b.h" +#define WEATHER_READY 1 + #define TFT_LINEHGHT 10 #define TFT_FRAMEWDT 4 @@ -13,26 +15,9 @@ #define PLMITEMLENGHT 40 #define PLMITEMHEIGHT 22 #define TITLE_TOP2 TFT_FRAMEWDT + 3 * TFT_LINEHGHT -/* -#ifdef DSP_FPS -#if DSP_FPS!=0 -#define SCROLLDELTA (DSP_FPS>30)?3:(80/DSP_FPS) -#define SCROLLTIME (DSP_FPS>30)?34:(1000/DSP_FPS) -#else -#define SCROLLDELTA 4 -#define SCROLLTIME 83 -#define LOOP_DELAY 83 -#endif -#else -#define SCROLLDELTA 4 -#define SCROLLTIME 83 -#define LOOP_DELAY 40 -#endif -*/ + #if !defined(SCROLLDELTA) || !defined(SCROLLTIME) -/*#define SCROLLDELTA 5 -#define SCROLLTIME 83 -#define LOOP_DELAY 100*/ + #define SCROLLDELTA 2 #define SCROLLTIME 30 #define LOOP_DELAY 33 @@ -70,6 +55,8 @@ class DspCore: public Adafruit_SSD1327 { void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); void loop(bool force=false); + void flip(); + void invert(); private: uint16_t swidth, sheight; int16_t x, y; diff --git a/yoRadio/src/displays/displayST7735.cpp b/yoRadio/src/displays/displayST7735.cpp index faab6f3..c6b752d 100644 --- a/yoRadio/src/displays/displayST7735.cpp +++ b/yoRadio/src/displays/displayST7735.cpp @@ -13,11 +13,9 @@ #include "../../network.h" #ifndef DEF_SPI_FREQ -#define DEF_SPI_FREQ 40000000UL /* set it to 0 for system default */ +#define DEF_SPI_FREQ 26000000UL /* set it to 0 for system default */ #endif -#if ENABLE_VU_METER - #if DTYPE==INITR_BLACKTAB #define CLOCK_DELTA 12 #elif DTYPE==INITR_MINI160x80 @@ -26,10 +24,6 @@ #define CLOCK_DELTA 0 #endif -#else // !ENABLE_VU_METER -#define CLOCK_DELTA 0 -#endif - #define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY) #define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl) @@ -133,9 +127,9 @@ void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { initR(DTYPE); if(DEF_SPI_FREQ > 0) setSPISpeed(DEF_SPI_FREQ); cp437(true); - invertDisplay((DTYPE==INITR_MINI160x80)?TFT_INVERT:!TFT_INVERT); + invert(); fillScreen(TFT_BG); - setRotation(TFT_ROTATE); + flip(); setTextWrap(false); screenwidth = width(); screenheight = height(); @@ -270,15 +264,16 @@ void DspCore::printClock(struct tm timeinfo, bool dots, bool redraw){ char timeBuf[50] = { 0 }; char tmpBuf[4] = { 0 }; uint16_t ncwidth, ncheight; + uint16_t clockdelta=config.store.vumeter?CLOCK_DELTA:0; strftime(timeBuf, sizeof(timeBuf), "%H %M", &timeinfo); setTextSize(1); setFont(&DS_DIGI28pt7b); if(strstr(oldTimeBuf, timeBuf)==NULL || redraw){ getTextBounds(oldTimeBuf, 0, 0, &x, &y, &wot, &hot); - setCursor((swidth - wot) / 2 - 4 + CLOCK_DELTA, clockY+28+6); + setCursor((swidth - wot) / 2 - 4 + clockdelta, clockY+28+6); setTextColor(TFT_BG); print(oldTimeBuf); - dot = (swidth - wot) / 2 - 4 + CLOCK_DELTA; + dot = (swidth - wot) / 2 - 4 + clockdelta; /* dots */ strlcpy(tmpBuf, oldTimeBuf, 3); getTextBounds(tmpBuf, 0, 0, &x, &y, &ncwidth, &ncheight); @@ -291,8 +286,8 @@ void DspCore::printClock(struct tm timeinfo, bool dots, bool redraw){ setTextSize(1); getTextBounds(timeBuf, 0, 0, &x, &y, &ncwidth, &ncheight); setTextColor(TFT_LOGO); - setCursor((swidth - ncwidth) / 2 - 4 + CLOCK_DELTA, clockY+28+6); - dot = (swidth - ncwidth) / 2 - 4 + CLOCK_DELTA; + setCursor((swidth - ncwidth) / 2 - 4 + clockdelta, clockY+28+6); + dot = (swidth - ncwidth) / 2 - 4 + clockdelta; setTextSize(1); print(timeBuf); /* dots */ @@ -406,5 +401,15 @@ void DspCore::printText(const char* txt) { void DspCore::loop(bool force) { } +void DspCore::flip(){ + if(ROTATE_90){ + setRotation(config.store.flipscreen?2:0); + }else{ + setRotation(config.store.flipscreen?3:1); + } +} +void DspCore::invert(){ + invertDisplay((DTYPE==INITR_MINI160x80)?!config.store.invertdisplay:config.store.invertdisplay); +} #endif diff --git a/yoRadio/src/displays/displayST7735.h b/yoRadio/src/displays/displayST7735.h index c17966a..eb141e4 100644 --- a/yoRadio/src/displays/displayST7735.h +++ b/yoRadio/src/displays/displayST7735.h @@ -6,6 +6,9 @@ #include #include "fonts/DS_DIGI28pt7b.h" +#define VU_READY 1 +#define WEATHER_READY 1 + #define TFT_LINEHGHT 10 #if DTYPE==INITR_MINI160x80 #define TFT_FRAMEWDT 0 @@ -69,6 +72,8 @@ class DspCore: public Adafruit_ST7735 { void loop(bool force=false); virtual void startWrite(void); virtual void endWrite(void); + void flip(); + void invert(); private: uint16_t swidth, sheight; char oldTimeBuf[20]; diff --git a/yoRadio/src/displays/displayST7789.cpp b/yoRadio/src/displays/displayST7789.cpp index c5cc37e..12be91b 100644 --- a/yoRadio/src/displays/displayST7789.cpp +++ b/yoRadio/src/displays/displayST7789.cpp @@ -117,10 +117,10 @@ void DspCore::apScreen() { void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { init(240,(DSP_MODEL==DSP_ST7789)?320:240); if(DEF_SPI_FREQ > 0) setSPISpeed(DEF_SPI_FREQ); - invertDisplay(TFT_INVERT); + invert(); cp437(true); fillScreen(TFT_BG); - setRotation(TFT_ROTATE); + flip(); setTextWrap(false); setTextSize(1); screenwidth = width(); @@ -382,5 +382,20 @@ void DspCore::printText(const char* txt) { void DspCore::loop(bool force) { } - +void DspCore::flip(){ +#if DSP_MODEL==DSP_ST7789 + setRotation(config.store.flipscreen?3:1); +#endif +#if DSP_MODEL==DSP_ST7789_240 + if(ROTATE_90){ + setRotation(config.store.flipscreen?3:1); + }else{ + setRotation(config.store.flipscreen?2:0); + } +#endif +} + +void DspCore::invert(){ + invertDisplay(config.store.invertdisplay); +} #endif diff --git a/yoRadio/src/displays/displayST7789.h b/yoRadio/src/displays/displayST7789.h index 1c5b0aa..331600c 100644 --- a/yoRadio/src/displays/displayST7789.h +++ b/yoRadio/src/displays/displayST7789.h @@ -7,6 +7,9 @@ // https://tchapi.github.io/Adafruit-GFX-Font-Customiser/ #include "fonts/DS_DIGI42pt7b.h" +#define VU_READY 1 +#define WEATHER_READY 1 + #define TFT_LINEHGHT 10 #define TFT_FRAMEWDT 8 #define META_SIZE 3 @@ -58,6 +61,8 @@ class DspCore: public Adafruit_ST7789 { void loop(bool force=false); virtual void startWrite(void); virtual void endWrite(void); + void flip(); + void invert(); private: uint16_t swidth, sheight; char oldTimeBuf[20]; diff --git a/yoRadio/src/displays/nextion.cpp b/yoRadio/src/displays/nextion.cpp index f04de3b..5d55817 100644 --- a/yoRadio/src/displays/nextion.cpp +++ b/yoRadio/src/displays/nextion.cpp @@ -320,12 +320,22 @@ void Nextion::loop() { } 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); + //configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), SNTP_SERVER); + if(strlen(config.store.sntp1)>0 && strlen(config.store.sntp2)>0){ + configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1, config.store.sntp2); + }else if(strlen(config.store.sntp1)>0){ + configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1); + } 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); + //configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), SNTP_SERVER); + if(strlen(config.store.sntp1)>0 && strlen(config.store.sntp2)>0){ + configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1, config.store.sntp2); + }else if(strlen(config.store.sntp1)>0){ + configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1); + } network.requestTimeSync(true); } if (sscanf(rxbuf, "audioinfo=%d", &scanDigit) == 1){ @@ -558,7 +568,7 @@ bool Nextion::getForecast(){ 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); + 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", config.store.weatherlat, config.store.weatherlon, config.store.weatherkey, host); client.print(httpget); unsigned long timeout = millis(); while (client.available() == 0) { @@ -684,6 +694,10 @@ void Nextion::getWeather(void * pvParameters){ } void Nextion::updateWeather() { + if(strlen(config.store.weatherkey)==0 || !config.store.showweather) { + nextion.weatherVisible(0); + return; + } xTaskCreatePinnedToCore( nextion.getWeather, /* Task function. */ "nextiongetWeather", /* name of task. */ @@ -691,15 +705,11 @@ void Nextion::updateWeather() { 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 */ + 0); /* pin task to core 0 */ } 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 */ + updateWeather(); } /*