diff --git a/Images.md b/Images.md index d1cb481..9409647 100644 --- a/Images.md +++ b/Images.md @@ -41,4 +41,6 @@ \ ![ёRadio](images/img19.jpg)\ \ -![ёRadio](images/img20.jpg) +![ёRadio](images/img20.jpg)\ +\ +![ёRadio](images/img21.jpg) diff --git a/README.md b/README.md index 93af113..b49e6ab 100644 --- a/README.md +++ b/README.md @@ -280,6 +280,14 @@ Work is in progress... --- ## Version history +#### v0.6.110 +- the logic of division by cores has been changed +- fixed choppy playback (again) +- improvements in the stability of the web interface +- increased smoothness of the encoder +- bug fixes +- bug fixes + #### v0.6.012 - fixed choppy playback diff --git a/exsamples/displayhandlers.ino b/exsamples/displayhandlers.ino index 6f6edbf..56d8474 100644 --- a/exsamples/displayhandlers.ino +++ b/exsamples/displayhandlers.ino @@ -1,14 +1,17 @@ /************************************************************** -* -* An example of displaying user information on the display. -* This file must be in the root directory of the sketch. -* + + An example of displaying user information on the display. + This file must be in the root directory of the sketch. + **************************************************************/ #if DSP_MODEL==DSP_ST7735 +// 3600s = 60 minutes to not flooding +#define WEATHER_REQUEST_INTERVAL 3600 // 60min #include // https://github.com/Bodmer/OpenWeather #include // https://github.com/Bodmer/JSON_Decoder +#include String api_key = "********************************"; // openweathermap.org API key @@ -19,59 +22,90 @@ String units = "metric"; String language = "ru"; OW_Weather ow; +Ticker ticker; /*********************************************** - * scrolled line + scrolled line ***********************************************/ Scroll hello; +char weather[140] = { 0 }; +bool weatherRequest = false; +TaskHandle_t weatherUpdateTaskHandle; + +void getWeather( void * pvParameters ) { + OW_current *current = new OW_current; + OW_hourly *hourly = new OW_hourly; + OW_daily *daily = new OW_daily; + delay(5000); + ow.getForecast(current, hourly, daily, api_key, latitude, longitude, units, language); + sprintf(weather, "TEMP: %.1f C * PRESS: %d HG * HUM: %d%%", current->temp, (int)(current->pressure / 1.333), current->humidity); + weatherRequest = true; + vTaskDelete( NULL ); +} + +void updateWeather() { + xTaskCreatePinnedToCore( + getWeather, /* Task function. */ + "getWeather1", /* name of task. */ + 8192, /* 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 */ +} /*********************************************** - * Occurs when the display is initialized + Occurs when the network is connected ***********************************************/ -void dsp_on_init(){ - hello.init(" * ", 1, TFT_LINEHGHT*4+6, 2000, ORANGE, TFT_BG); +void network_on_connect() { + ticker.attach(WEATHER_REQUEST_INTERVAL, updateWeather); + updateWeather(); } /********************************************************************************************* - * The display has initialized, the network is connected, the player is ready to play. - * DspCore class documentation is missing :^( See the source in src/displays + The display has initialized, the network is connected, the player is ready to play. + DspCore class documentation is missing :^( See the source in src/displays *********************************************************************************************/ -void dsp_on_start(DspCore *dsp){ - OW_current *current = new OW_current; - OW_hourly *hourly = new OW_hourly; - OW_daily *daily = new OW_daily; - char weather[140] = { 0 }; - ow.getForecast(current, hourly, daily, api_key, latitude, longitude, units, language); +void dsp_on_start(DspCore *dsp) { - sprintf(weather, "temp: %.1f * pressure: %d * humidity: %d", current->temp, (int)(current->pressure/1.333), current->humidity); +} - hello.setText(dsp->utf8Rus(weather, true)); +/*********************************************** + Occurs when the display is initialized + ***********************************************/ +void dsp_on_init() { + hello.init(5, " * ", 1, TFT_LINEHGHT*4+6, 0, ORANGE, TFT_BG); + Serial.println(TFT_LINEHGHT*4+6); } /************************ - * The loop cycle + The loop cycle ************************/ -void dsp_on_loop(){ - if(display.mode==PLAYER) hello.loop(); +void dsp_on_loop() { + if (weatherRequest) { + weatherRequest = false; + hello.setText(weather); + } + if (display.mode == PLAYER) hello.loop(); } /*********************************************** - * Occurs when the display changes mode + Occurs when the display changes mode ***********************************************/ -void dsp_on_newmode(displayMode_e newmode){ +void dsp_on_newmode(displayMode_e newmode) { if (newmode == PLAYER) { hello.reset(); - }else{ + } else { hello.lock(); } } /************************ - * Before print the clock + Before print the clock ************************/ -bool dsp_before_clock(DspCore *dsp, bool dots){ - if(display.mode==PLAYER){ +bool dsp_before_clock(DspCore *dsp, bool dots) { + if (display.mode == PLAYER) { dsp->setFont(); dsp->setTextSize(1); display.centerText(dsp->utf8Rus("Hello from plugin!", true), display.screenheight - TFT_FRAMEWDT * 2 - TFT_LINEHGHT * 2 - 2, PINK, TFT_BG); diff --git a/exsamples/myoptions.h b/exsamples/myoptions.h index 514d9ea..b88cf0c 100644 --- a/exsamples/myoptions.h +++ b/exsamples/myoptions.h @@ -9,10 +9,6 @@ Uncomment the lines you need, to override the default value and set the values a The connection tables are located here https://github.com/e2002/yoradio#connection-tables ********************************************************/ -/* CORE_FOR_LOOP_CONTROLS. See description/available values in the options.h file */ -/* This setting was added to eliminate audio jerking when adjusting the volume/playlist. The default value is 2 */ -#define CORE_FOR_LOOP_CONTROLS 2 -/******************************************/ /* DSP_MODEL. See description/available values in the options.h file */ /* This option is required. Use DSP_DUMMY if no display is connected */ diff --git a/images/img21.jpg b/images/img21.jpg new file mode 100644 index 0000000..327a769 Binary files /dev/null and b/images/img21.jpg differ diff --git a/yoRadio/config.cpp b/yoRadio/config.cpp index 67b2132..6881bdb 100644 --- a/yoRadio/config.cpp +++ b/yoRadio/config.cpp @@ -2,11 +2,13 @@ #include #include #include "display.h" +#include "player.h" Config config; void Config::init() { + EEPROM.begin(EEPROM_SIZE); eepromRead(EEPROM_START, store); - if (store.tz_set!=57){ // update to v0.4.200 + if (store.tz_set != 57) { // update to v0.4.200 store.tz_set = 57; store.tzHour = 3; store.tzMin = 0; @@ -29,22 +31,17 @@ void Config::init() { template int Config::eepromWrite(int ee, const T& value) { const byte* p = (const byte*)(const void*)&value; int i; - EEPROM.begin(EEPROM_SIZE); for (i = 0; i < sizeof(value); i++) EEPROM.write(ee++, *p++); EEPROM.commit(); - delay(20); - EEPROM.end(); return i; } template int Config::eepromRead(int ee, T& value) { byte* p = (byte*)(void*)&value; - int i; - EEPROM.begin(EEPROM_SIZE); + int i;; for (i = 0; i < sizeof(value); i++) *p++ = EEPROM.read(ee++); - EEPROM.end(); return i; } @@ -67,13 +64,13 @@ void Config::setDefaults() { } void Config::setTimezone(int8_t tzh, int8_t tzm) { - store.tzHour=tzh; - store.tzMin=tzm; + store.tzHour = tzh; + store.tzMin = tzm; save(); } void Config::setTimezoneOffset(uint16_t tzo) { - store.timezoneOffset=tzo; + store.timezoneOffset = tzo; save(); } @@ -87,7 +84,11 @@ void Config::save() { byte Config::setVolume(byte val, bool dosave) { store.volume = val; - if (dosave) save(); + if (dosave) { + //save(); + EEPROM.write(EEPROM_START + sizeof(store.config_set), store.volume); + EEPROM.commit(); + } return store.volume; } @@ -128,17 +129,17 @@ byte Config::setLastSSID(byte val) { return store.lastSSID; } -void Config::setTitle(const char* title){ +void Config::setTitle(const char* title) { memset(config.station.title, 0, BUFLEN); strlcpy(config.station.title, title, BUFLEN); - display.refreshTitle = true; + display.title(); } -void Config::setStation(const char* station){ +void Config::setStation(const char* station) { memset(config.station.name, 0, BUFLEN); strlcpy(config.station.name, station, BUFLEN); } - + void Config::indexPlaylist() { File playlist = SPIFFS.open(PLAYLIST_PATH, "r"); if (!playlist) { @@ -244,16 +245,16 @@ bool Config::parseCSV(const char* line, char* name, char* url, int &ovol) { char *tmpe; const char* cursor = line; char buf[5]; - tmpe=strstr(cursor, "\t"); - if(tmpe==NULL) return false; - strlcpy(name, cursor, tmpe-cursor+1); - if(strlen(name)==0) return false; - cursor=tmpe+1; - tmpe=strstr(cursor, "\t"); - if(tmpe==NULL) return false; - strlcpy(url, cursor, tmpe-cursor+1); - if(strlen(url)==0) return false; - cursor=tmpe+1; + tmpe = strstr(cursor, "\t"); + if (tmpe == NULL) return false; + strlcpy(name, cursor, tmpe - cursor + 1); + if (strlen(name) == 0) return false; + cursor = tmpe + 1; + tmpe = strstr(cursor, "\t"); + if (tmpe == NULL) return false; + strlcpy(url, cursor, tmpe - cursor + 1); + if (strlen(url) == 0) return false; + cursor = tmpe + 1; if (strlen(cursor) == 0) return false; strlcpy(buf, cursor, 4); ovol = atoi(buf); @@ -264,68 +265,68 @@ bool Config::parseJSON(const char* line, char* name, char* url, int &ovol) { char* tmps, *tmpe; const char* cursor = line; char port[8], host[254], file[254]; - tmps=strstr(cursor, "\":\""); - if(tmps==NULL) return false; - tmpe=strstr(tmps, "\",\""); - if(tmpe==NULL) return false; - strlcpy(name, tmps+3, tmpe-tmps-3+1); - if(strlen(name)==0) return false; - cursor=tmpe+3; - tmps=strstr(cursor, "\":\""); - if(tmps==NULL) return false; - tmpe=strstr(tmps, "\",\""); - if(tmpe==NULL) return false; - strlcpy(host, tmps+3, tmpe-tmps-3+1); - if(strlen(host)==0) return false; - if(strstr(host,"http://")==NULL && strstr(host,"https://")==NULL) { + tmps = strstr(cursor, "\":\""); + if (tmps == NULL) return false; + tmpe = strstr(tmps, "\",\""); + if (tmpe == NULL) return false; + strlcpy(name, tmps + 3, tmpe - tmps - 3 + 1); + if (strlen(name) == 0) return false; + cursor = tmpe + 3; + tmps = strstr(cursor, "\":\""); + if (tmps == NULL) return false; + tmpe = strstr(tmps, "\",\""); + if (tmpe == NULL) return false; + strlcpy(host, tmps + 3, tmpe - tmps - 3 + 1); + if (strlen(host) == 0) return false; + if (strstr(host, "http://") == NULL && strstr(host, "https://") == NULL) { sprintf(file, "http://%s", host); - strlcpy(host, file, strlen(file)+1); + strlcpy(host, file, strlen(file) + 1); } - cursor=tmpe+3; - tmps=strstr(cursor, "\":\""); - if(tmps==NULL) return false; - tmpe=strstr(tmps, "\",\""); - if(tmpe==NULL) return false; - strlcpy(file, tmps+3, tmpe-tmps-3+1); - cursor=tmpe+3; - tmps=strstr(cursor, "\":\""); - if(tmps==NULL) return false; - tmpe=strstr(tmps, "\",\""); - if(tmpe==NULL) return false; - strlcpy(port, tmps+3, tmpe-tmps-3+1); + cursor = tmpe + 3; + tmps = strstr(cursor, "\":\""); + if (tmps == NULL) return false; + tmpe = strstr(tmps, "\",\""); + if (tmpe == NULL) return false; + strlcpy(file, tmps + 3, tmpe - tmps - 3 + 1); + cursor = tmpe + 3; + tmps = strstr(cursor, "\":\""); + if (tmps == NULL) return false; + tmpe = strstr(tmps, "\",\""); + if (tmpe == NULL) return false; + strlcpy(port, tmps + 3, tmpe - tmps - 3 + 1); int p = atoi(port); - if(p>0){ + if (p > 0) { sprintf(url, "%s:%d%s", host, p, file); - }else{ + } else { sprintf(url, "%s%s", host, file); } - cursor=tmpe+3; - tmps=strstr(cursor, "\":\""); - if(tmps==NULL) return false; - tmpe=strstr(tmps, "\"}"); - if(tmpe==NULL) return false; - strlcpy(port, tmps+3, tmpe-tmps-3+1); + cursor = tmpe + 3; + tmps = strstr(cursor, "\":\""); + if (tmps == NULL) return false; + tmpe = strstr(tmps, "\"}"); + if (tmpe == NULL) return false; + strlcpy(port, tmps + 3, tmpe - tmps - 3 + 1); ovol = atoi(port); return true; } bool Config::parseWsCommand(const char* line, char* cmd, char* val, byte cSize) { char *tmpe; - tmpe=strstr(line, "="); - if(tmpe==NULL) return false; + tmpe = strstr(line, "="); + if (tmpe == NULL) return false; memset(cmd, 0, cSize); - strlcpy(cmd, line, tmpe-line+1); - if (strlen(tmpe+1) == 0) return false; + 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, tmpe + 1 - line + 1); return true; } bool Config::parseSsid(const char* line, char* ssid, char* pass) { char *tmpe; - tmpe=strstr(line, "\t"); - if(tmpe==NULL) return false; - uint16_t pos= tmpe-line; + tmpe = strstr(line, "\t"); + if (tmpe == NULL) return false; + uint16_t pos = tmpe - line; if (pos > 19 || strlen(line) > 61) return false; memset(ssid, 0, 20); strlcpy(ssid, line, pos + 1); diff --git a/yoRadio/config.h b/yoRadio/config.h index e4432d8..d0cc31c 100644 --- a/yoRadio/config.h +++ b/yoRadio/config.h @@ -2,7 +2,7 @@ #define config_h #include "Arduino.h" -#define EEPROM_SIZE 1024 +#define EEPROM_SIZE 32 #define EEPROM_START 0 #define BUFLEN 140 #define PLAYLIST_PATH "/data/playlist.csv" diff --git a/yoRadio/controls.cpp b/yoRadio/controls.cpp index 03de0b0..1371ad1 100644 --- a/yoRadio/controls.cpp +++ b/yoRadio/controls.cpp @@ -103,6 +103,7 @@ void initControls() { } void loopControls() { + if(display.mode==LOST) return; #if ENC_BTNL!=255 encoderLoop(); #endif @@ -204,9 +205,9 @@ void irLoop() { irBlink(); if (display.mode == NUMBERS) { display.swichMode(PLAYER); - //player.play(display.numOfNextStation); - player.request.station = display.numOfNextStation; - player.request.doSave = true; + player.play(display.numOfNextStation); + //player.request.station = display.numOfNextStation; + //player.request.doSave = true; display.numOfNextStation = 0; break; } @@ -300,7 +301,7 @@ void irLoop() { #define TS_Y_MAX 3800 #endif #ifndef TS_STEPS - #define TS_STEPS 70 + #define TS_STEPS 40 #endif boolean wastouched = true; @@ -351,9 +352,9 @@ void touchLoop() { switch (direct) { case TSD_LEFT: case TSD_RIGHT: { + touchLongPress=millis(); if(display.mode==PLAYER || display.mode==VOL){ int16_t xDelta = map(abs(touchVol - touchX), 0, display.screenwidth, 0, TS_STEPS); - Serial.println(touchVol - touchX); display.swichMode(VOL); if (xDelta>1) { controlsEvent((touchVol - touchX)<0); @@ -364,6 +365,7 @@ void touchLoop() { } case TSD_UP: case TSD_DOWN: { + touchLongPress=millis(); if(display.mode==PLAYER || display.mode==STATIONS){ int16_t yDelta = map(abs(touchStation - touchY), 0, display.screenheight, 0, TS_STEPS); display.swichMode(STATIONS); @@ -385,7 +387,7 @@ void touchLoop() { } else { if (wastouched) {/* END TOUCH */ if (direct == TDS_REQUEST) { - if(millis()-touchLongPress < BTN_PRESS_TICKS){ + if(millis()-touchLongPress < BTN_PRESS_TICKS*2){ onBtnClick(EVT_BTNCENTER); }else{ display.swichMode(display.mode == PLAYER ? STATIONS : PLAYER); @@ -473,10 +475,10 @@ void controlsEvent(bool toRight) { } if (display.mode == STATIONS) { int p = toRight ? display.currentPlItem + 1 : display.currentPlItem - 1; - if (p < 1) p = 1; - if (p > config.store.countStation) p = config.store.countStation; + if (p < 1) p = config.store.countStation; + if (p > config.store.countStation) p = 1; display.currentPlItem = p; - display.clear(); + //display.clear(); display.drawPlaylist(); } } @@ -499,9 +501,9 @@ void onBtnClick(int id) { } if (display.mode == STATIONS) { display.swichMode(PLAYER); - //player.play(display.currentPlItem); - player.request.station = display.currentPlItem; - player.request.doSave = true; + player.play(display.currentPlItem); + //player.request.station = display.currentPlItem; + //player.request.doSave = true; } break; } diff --git a/yoRadio/display.cpp b/yoRadio/display.cpp index 5340c16..9de493a 100644 --- a/yoRadio/display.cpp +++ b/yoRadio/display.cpp @@ -21,10 +21,6 @@ void ticks() { #ifndef STARTTIME_PL #define STARTTIME_PL 0 #endif -#ifndef SCROLLDELTA -#define SCROLLDELTA 3 -#define SCROLLTIME 83 -#endif #ifndef META_SIZE #define META_SIZE 2 #endif @@ -62,8 +58,11 @@ void ticks() { #define DO_SCROLL (tWidth > (display.screenwidth - (dsp.fillSpaces?((texttop==0)?CLOCK_SPACE:VOL_SPACE):0))) #endif -void Scroll::init(const char *sep, byte tsize, byte top, uint16_t dlay, uint16_t fgcolor, uint16_t bgcolor) { +byte currentScrollId = 0; /* one scroll on one time */ + +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; if (textsize == 0) return; texttop = top; fg = fgcolor; @@ -77,12 +76,17 @@ void Scroll::init(const char *sep, byte tsize, byte top, uint16_t dlay, uint16_ void Scroll::setText(const char *txt) { if (textsize == 0) return; memset(text, 0, BUFLEN / 2); - strlcpy(text, txt, BUFLEN / 2); + strlcpy(text, txt, BUFLEN / 2 - 1); getbounds(textwidth, textheight, sepwidth); + if (doscroll) { + memset(text2, 0, BUFLEN + 10); + sprintf(text2, "%s%s%s", text, separator, text); + } if (!locked) { clearscrolls(); reset(); } + lockRequest = false; } void Scroll::lock() { @@ -99,8 +103,9 @@ void Scroll::reset() { clear(); setTextParams(); dsp.set_Cursor(TFT_FRAMEWDT, texttop); - dsp.printText(text); + dsp.printText(doscroll ? text2 : text); drawFrame(); + if (currentScrollId == id) currentScrollId = 0; } void Scroll::setTextParams() { @@ -113,11 +118,17 @@ void Scroll::clearscrolls() { if (textsize == 0) return; x = TFT_FRAMEWDT; scrolldelay = millis(); - clear(); + //clear(); } void Scroll::loop() { + if (lockRequest) { + return; + } if (textsize == 0) return; + if (currentScrollId != 0 && currentScrollId != id) { + return; + } if (checkdelay(x == TFT_FRAMEWDT ? delayStartScroll : SCROLLTIME, scrolldelay)) { scroll(); sticks(); @@ -143,17 +154,25 @@ void Scroll::sticks() { if (!doscroll || locked || textsize == 0) return; setTextParams(); dsp.set_Cursor(x, texttop); - dsp.printText(text); - dsp.printText(separator); - dsp.printText(text); - drawFrame(); + dsp.printText(text2); + + //dsp.printText(separator); + //dsp.printText(text); + if (x == TFT_FRAMEWDT) drawFrame(); } void Scroll::scroll() { if (!doscroll || textsize == 0) return; + //if (textwidth > display.screenwidth) { x -= SCROLLDELTA; - if (-x > textwidth + sepwidth - TFT_FRAMEWDT) x = TFT_FRAMEWDT; + if (-x > textwidth + sepwidth - TFT_FRAMEWDT) { + x = TFT_FRAMEWDT; + drawFrame(); + currentScrollId = 0; + } else { + currentScrollId = id; + } //} } @@ -175,14 +194,14 @@ void Scroll::getbounds(uint16_t &tWidth, uint16_t &tHeight, uint16_t &sWidth) { void Display::init() { dsp.initD(screenwidth, screenheight); dsp.drawLogo(); - meta.init(" * ", META_SIZE, TFT_FRAMEWDT, STARTTIME, TFT_LOGO, TFT_BG); - title1.init(" * ", TITLE_SIZE1, TITLE_TOP1, STARTTIME, TITLE_FG1, TFT_BG); - title2.init(" * ", TITLE_SIZE2, TITLE_TOP2, STARTTIME, TITLE_FG2, TFT_BG); + meta.init(1, " * ", META_SIZE, TFT_FRAMEWDT, STARTTIME, TFT_LOGO, TFT_BG); + title1.init(2, " * ", TITLE_SIZE1, TITLE_TOP1, STARTTIME, TITLE_FG1, TFT_BG); + title2.init(3, " * ", TITLE_SIZE2, TITLE_TOP2, STARTTIME, TITLE_FG2, TFT_BG); int yStart = (screenheight / 2 - PLMITEMHEIGHT / 2) + 3; #ifdef PL_TOP yStart = PL_TOP; #endif - plCurrent.init(" * ", PLCURRENT_SIZE, yStart, STARTTIME_PL, TFT_BG, TFT_LOGO); + plCurrent.init(4, " * ", PLCURRENT_SIZE, yStart, STARTTIME_PL, TFT_BG, TFT_LOGO); plCurrent.lock(); if (dsp_on_init) dsp_on_init(); } @@ -196,9 +215,6 @@ void Display::apScreen() { void Display::start() { clear(); - refreshTitle = false; - refreshStation = false; - refreshVolume = false; if (network.status != CONNECTED) { apScreen(); return; @@ -214,7 +230,7 @@ void Display::start() { time(); timer.attach_ms(1000, ticks); if (dsp_on_start) dsp_on_start(&dsp); - // Экстреминатус секвестирован /*дважды*/ трижды + // Экстреминатус секвестирован /*дважды*/ /*трижды*/ четырежды } void Display::clear() { @@ -233,9 +249,11 @@ void Display::swichMode(displayMode_e newmode) { volume(); } if (newmode == PLAYER) { + currentScrollId = 0; meta.reset(); title1.reset(); if (TITLE_SIZE2 != 0) title2.reset(); + player.loop(); plCurrent.lock(); time(true); #ifdef CLOCK_SPACE // if set space for clock in 1602 displays @@ -244,6 +262,7 @@ void Display::swichMode(displayMode_e newmode) { rssi(); volume(); #endif + dsp.loop(true); } else { if (newmode != NUMBERS) { meta.lock(); @@ -257,6 +276,9 @@ void Display::swichMode(displayMode_e newmode) { if (newmode == VOL) { dsp.frameTitle("VOLUME"); } + if (newmode == LOST) { + dsp.frameTitle("* LOST *"); + } if (newmode == NUMBERS) { //dsp.frameTitle("STATION"); meta.reset(); @@ -264,6 +286,7 @@ void Display::swichMode(displayMode_e newmode) { if (newmode == STATIONS) { currentPlItem = config.store.lastStation; plCurrent.reset(); + currentScrollId = 0; drawPlaylist(); } if (dsp_on_newmode) dsp_on_newmode(newmode); @@ -287,10 +310,26 @@ void Display::drawVolume() { } } -void Display::drawPlaylist() { +TaskHandle_t drawPlaylistTaskHandle = NULL; +bool taskDone = true; +void getPlaylist( void * pvParameters ) { char buf[PLMITEMLENGHT]; - dsp.drawPlaylist(currentPlItem, buf); - plCurrent.setText(dsp.utf8Rus(buf, true)); + display.plCurrent.lockRequest = true; + dsp.drawPlaylist(display.currentPlItem, buf); + display.plCurrent.setText(dsp.utf8Rus(buf, true)); + taskDone = true; + vTaskDelete( NULL ); +} + +void Display::drawPlaylist() { + while (!taskDone) player.loop(); + taskDone = false; + xTaskCreatePinnedToCore(getPlaylist, "getPlaylist0", 4096, NULL, 1, &drawPlaylistTaskHandle, 0); + /* + char buf[PLMITEMLENGHT]; + dsp.drawPlaylist(currentPlItem, buf); + plCurrent.setText(dsp.utf8Rus(buf, true)); + */ } void Display::drawNextStationNum(uint16_t num) { @@ -303,18 +342,6 @@ void Display::drawNextStationNum(uint16_t num) { } void Display::loop() { - if(refreshStation){ - refreshStation = false; - station(); - } - if(refreshTitle){ - refreshTitle = false; - title(); - } - if(refreshVolume){ - refreshVolume = false; - volume(); - } switch (mode) { case PLAYER: { drawPlayer(); @@ -344,7 +371,7 @@ void Display::centerText(const char* text, byte y, uint16_t fg, uint16_t bg) { void Display::bootString(const char* text, byte y) { dsp.centerText(text, y == 1 ? BOOTSTR_TOP1 : BOOTSTR_TOP2, TFT_LOGO, TFT_BG); - dsp.loop(); + dsp.loop(true); } void Display::bootLogo() { @@ -358,20 +385,26 @@ void Display::rightText(const char* text, byte y, uint16_t fg, uint16_t bg) { void Display::station() { meta.setText(dsp.utf8Rus(config.station.name, true)); - dsp.loop(); +#ifdef DEBUG_TITLES + meta.setText(dsp.utf8Rus("Utenim adminim veniam FM", true)); +#endif + dsp.loop(true); //netserver.requestOnChange(STATION, 0); } void Display::returnTile() { meta.setText(dsp.utf8Rus(config.station.name, true)); +#ifdef DEBUG_TITLES + meta.setText(dsp.utf8Rus("Utenim adminim veniam FM", true)); +#endif meta.reset(); - dsp.loop(); + dsp.loop(true); } void Display::title() { /* - memset(config.station.title, 0, BUFLEN); - strlcpy(config.station.title, str, BUFLEN); + memset(config.station.title, 0, BUFLEN); + strlcpy(config.station.title, str, BUFLEN); */ char ttl[BUFLEN / 2] = { 0 }; char sng[BUFLEN / 2] = { 0 }; @@ -380,14 +413,19 @@ void Display::title() { if ((ici = strstr(config.station.title, " - ")) != NULL && TITLE_SIZE2 != 0) { strlcpy(sng, ici + 3, BUFLEN / 2); strlcpy(ttl, config.station.title, strlen(config.station.title) - strlen(ici) + 1); + } else { strlcpy(ttl, config.station.title, BUFLEN / 2); sng[0] = '\0'; } +#ifdef DEBUG_TITLES + strlcpy(ttl, "Duis aute irure dolor in reprehenderit in voluptate velit", BUFLEN / 2); + strlcpy(sng, "Excepteur sint occaecat cupidatat non proident", BUFLEN / 2); +#endif title1.setText(dsp.utf8Rus(ttl, true)); if (TITLE_SIZE2 != 0) title2.setText(dsp.utf8Rus(sng, true)); - dsp.loop(); + dsp.loop(true); } //netserver.requestOnChange(TITLE, 0); } @@ -408,10 +446,27 @@ void Display::ip() { dsp.ip(WiFi.localIP().toString().c_str()); } +void Display::checkConnection() { + if (WiFi.status() != WL_CONNECTED) { + bool playing = player.mode == PLAYING; + swichMode(LOST); + if (playing) player.mode = STOPPED; + WiFi.disconnect(); + ip(); + WiFi.reconnect(); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + } + swichMode(PLAYER); + if (playing) player.play(config.store.lastStation); + } +} + void Display::time(bool redraw) { if (dsp_before_clock) if (!dsp_before_clock(&dsp, dt)) return; char timeStringBuff[20] = { 0 }; if (!dt) { + checkConnection(); heap(); rssi(); } @@ -429,8 +484,22 @@ void Display::time(bool redraw) { if (dsp_after_clock) dsp_after_clock(&dsp, dt); } +TaskHandle_t drawVolumeTaskHandle = NULL; +bool taskVDone = true; +void drawVolumeTask( void * pvParameters ) { + delay(20); /* but it's too fast 0__o */ + dsp.drawVolumeBar(true); + taskVDone = true; + vTaskDelete( NULL ); +} + void Display::volume() { - dsp.drawVolumeBar(mode == VOL); - //netserver.requestOnChange(VOLUME, 0); - netserver.volRequest = true; + if (mode == VOL) { + while (!taskVDone) player.loop(); + taskVDone = false; + xTaskCreatePinnedToCore(drawVolumeTask, "drawVolumeTask0", 2048, NULL, 1, &drawVolumeTaskHandle, 0); + } else { + dsp.drawVolumeBar(false); + } + netserver.requestOnChange(VOLUME, 0); } diff --git a/yoRadio/display.h b/yoRadio/display.h index 111df9f..4f9717d 100644 --- a/yoRadio/display.h +++ b/yoRadio/display.h @@ -33,20 +33,22 @@ #include "src/displays/displayCustom.h" #endif -enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS }; +enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST }; class Scroll { public: Scroll() { }; - void init(const char *sep, byte tsize, byte top, uint16_t dlay, uint16_t fgcolor, uint16_t bgcolor); + void init(byte ScrollId, const char *sep, byte tsize, byte top, uint16_t dlay, uint16_t fgcolor, uint16_t bgcolor); void setText(const char *txt); void loop(); void reset(); void lock(); void unlock(); + bool lockRequest; private: - byte textsize, texttop; + byte textsize, texttop, id; char text[BUFLEN/2]; + char text2[BUFLEN+10]; char separator[4]; uint16_t fg, bg; uint16_t delayStartScroll; @@ -71,13 +73,16 @@ class Display { displayMode_e mode; uint16_t currentPlItem; uint16_t numOfNextStation; - bool refreshTitle, refreshStation, refreshVolume; + Scroll plCurrent; public: Display() {}; void init(); void clear(); void loop(); void start(); + void station(); + void title(); + void volume(); 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 bootString(const char* text, byte y); @@ -88,19 +93,17 @@ class Display { void drawNextStationNum(uint16_t num); private: Ticker timer; - Scroll meta, title1, title2, plCurrent; + Scroll meta, title1, title2; bool dt; // dots unsigned long volDelay; void heap(); void rssi(); - void station(); - void title(); - void volume(); void ip(); void time(bool redraw = false); void apScreen(); void drawPlayer(); void drawVolume(); + void checkConnection(); }; extern Display display; diff --git a/yoRadio/netserver.cpp b/yoRadio/netserver.cpp index 7c28b95..f874059 100644 --- a/yoRadio/netserver.cpp +++ b/yoRadio/netserver.cpp @@ -24,7 +24,7 @@ byte ssidCount; bool NetServer::begin() { importRequest = false; - volRequest = false; + webserver.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { ssidCount = 0; request->send(SPIFFS, "/www/index.html", String(), false, processor); @@ -71,10 +71,6 @@ void NetServer::loop() { } importRequest = false; } - if (volRequest) { - requestOnChange(VOLUME, 0); - volRequest = false; - } if(rssi<255){ requestOnChange(NRSSI, 0); } @@ -209,9 +205,9 @@ void NetServer::requestOnChange(requestType_e request, uint8_t clientId) { } case TITLE: { sprintf (buf, "{\"meta\": \"%s\"}", config.station.title); - if (player.requesToStart) { + if (player.requestToStart) { telnet.info(); - player.requesToStart = false; + player.requestToStart = false; } else { telnet.printf("##CLI.META#: %s\n> ", config.station.title); } diff --git a/yoRadio/netserver.h b/yoRadio/netserver.h index 78038e0..c87c882 100644 --- a/yoRadio/netserver.h +++ b/yoRadio/netserver.h @@ -10,7 +10,7 @@ enum requestType_e { PLAYLIST, STATION, ITEM, TITLE, VOLUME, NRSSI, BITRATE, MOD class NetServer { public: uint8_t playlistrequest; // ClientId want the playlist - bool importRequest, volRequest; + bool importRequest; public: NetServer() {}; bool begin(); diff --git a/yoRadio/network.cpp b/yoRadio/network.cpp index c5a7ce3..d649401 100644 --- a/yoRadio/network.cpp +++ b/yoRadio/network.cpp @@ -55,6 +55,7 @@ void Network::begin() { status = CONNECTED; requestTimeSync(); ntimer.attach_ms(TSYNC_DELAY, syncTime); + if (network_on_connect) network_on_connect(); } void Network::requestTimeSync(bool withTelnetOutput) { diff --git a/yoRadio/network.h b/yoRadio/network.h index b4a890d..3788ecb 100644 --- a/yoRadio/network.h +++ b/yoRadio/network.h @@ -24,4 +24,6 @@ class Network { extern Network network; +extern __attribute__((weak)) void network_on_connect(); + #endif diff --git a/yoRadio/options.h b/yoRadio/options.h index f6aaaea..6a19e3b 100644 --- a/yoRadio/options.h +++ b/yoRadio/options.h @@ -1,12 +1,12 @@ #ifndef options_h #define options_h -#define VERSION "0.6.012" +#define VERSION "0.6.110" /******************************************************* DO NOT EDIT THIS FILE. ALL YOUR SETTINGS WILL BE OVERWRITTEN DURING THE UPDATE. -STORE YOUR SETTINGS IN A myoptions.h FILE. +STORE YOUR SETTINGS IN THE *** myoptions.h *** FILE. ********************************************************/ #if __has_include("myoptions.h") @@ -202,9 +202,6 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti #ifndef MUTE_VAL #define MUTE_VAL HIGH // Write this to MUTE_PIN when player is stopped #endif -#ifndef CORE_FOR_LOOP_CONTROLS - #define CORE_FOR_LOOP_CONTROLS 2 // 0 for Core0, 1 for Core1, 2 for Auto, 255 for Not Used -#endif /* *** ST7735 display submodel *** diff --git a/yoRadio/player.cpp b/yoRadio/player.cpp index 380e813..447c756 100644 --- a/yoRadio/player.cpp +++ b/yoRadio/player.cpp @@ -41,7 +41,7 @@ void Player::init() { setVolume(0); mode = STOPPED; setOutputPins(false); - requesToStart = true; + requestToStart = true; zeroRequest(); } @@ -49,7 +49,7 @@ void Player::stopInfo() { config.setSmartStart(0); telnet.info(); netserver.requestOnChange(MODE, 0); - requesToStart = true; + requestToStart = true; } void Player::loop() { @@ -60,7 +60,7 @@ void Player::loop() { //digitalWrite(LED_BUILTIN, LOW); setOutputPins(false); //display.title("[stopped]"); - config.setTitle("[stopped]"); + config.setTitle(display.mode==LOST?"":"[stopped]"); netserver.requestOnChange(TITLE, 0); stopSong(); stopInfo(); @@ -75,13 +75,11 @@ void Player::loop() { } if (request.volume >= 0) { config.setVolume(request.volume, request.doSave); - //display.volume(); - display.refreshVolume = true; telnet.printf("##CLI.VOL#: %d\n", config.store.volume); Audio::setVolume(volToI2S(request.volume)); zeroRequest(); + display.volume(); } - yield(); } void Player::zeroRequest() { @@ -97,31 +95,26 @@ void Player::setOutputPins(bool isPlaying) { void Player::play(uint16_t stationId) { stopSong(); - //digitalWrite(LED_BUILTIN, LOW); setOutputPins(false); - //display.title("[connecting]"); - config.setTitle("[connecting]"); - //display.refreshTitle = true; netserver.requestOnChange(TITLE, 0); //telnet.printf("##CLI.META#: %s\n", config.station.title); config.loadStation(stationId); setVol(config.store.volume, true); - //display.station(); - display.refreshStation = true; + display.station(); netserver.requestOnChange(STATION, 0); telnet.printf("##CLI.NAMESET#: %d %s\n", config.store.lastStation, config.station.name); + display.loop(); if (connecttohost(config.station.url)) { mode = PLAYING; config.setSmartStart(1); netserver.requestOnChange(MODE, 0); - //digitalWrite(LED_BUILTIN, HIGH); setOutputPins(true); - requesToStart = true; + requestToStart = true; }else{ - Serial.println("Some Unknown Bug..."); + Serial.println("some unknown bug..."); } - zeroRequest(); + display.loop(); } void Player::prev() { @@ -172,15 +165,7 @@ void Player::setVol(byte volume, bool inside) { if (inside) { setVolume(volToI2S(volume)); } else { -#if CORE_FOR_LOOP_CONTROLS==255 request.volume = volume; request.doSave = true; -#else - config.setVolume(volume, true); - //display.volume(); - display.refreshVolume = true; - telnet.printf("##CLI.VOL#: %d\n", config.store.volume); - Audio::setVolume(volToI2S(volume)); -#endif } } diff --git a/yoRadio/player.h b/yoRadio/player.h index 98b6998..ac4e20e 100644 --- a/yoRadio/player.h +++ b/yoRadio/player.h @@ -9,24 +9,22 @@ #endif enum audioMode_e { PLAYING, STOPPED }; - struct audiorequest_t { uint16_t station; int volume; bool doSave; }; - class Player: public Audio { public: - audioMode_e mode; - audiorequest_t request; - bool requesToStart; + audioMode_e mode; + audiorequest_t request; + bool requestToStart; + void zeroRequest(); public: Player(); void init(); void loop(); - void zeroRequest(); void play(uint16_t stationId); void prev(); void next(); diff --git a/yoRadio/src/audioI2S/AudioEx.h b/yoRadio/src/audioI2S/AudioEx.h index 4ebaa56..8a14b31 100644 --- a/yoRadio/src/audioI2S/AudioEx.h +++ b/yoRadio/src/audioI2S/AudioEx.h @@ -30,7 +30,9 @@ #include #endif // SDFATFS_USED +#ifndef AUDIOBUFFER_MULTIPLIER #define AUDIOBUFFER_MULTIPLIER 13 +#endif #ifdef SDFATFS_USED typedef File32 File; diff --git a/yoRadio/src/audioVS1053/audioVS1053Ex.h b/yoRadio/src/audioVS1053/audioVS1053Ex.h index ccbcacb..ff79c89 100644 --- a/yoRadio/src/audioVS1053/audioVS1053Ex.h +++ b/yoRadio/src/audioVS1053/audioVS1053Ex.h @@ -9,7 +9,9 @@ #ifndef _vs1053_ext #define _vs1053_ext +#ifndef AUDIOBUFFER_MULTIPLIER #define AUDIOBUFFER_MULTIPLIER 13 +#endif #define VS1053VOLM 128 // 128 or 96 only #define VS1053VOL(v) (VS1053VOLM==128?log10(((float)v+1)) * 50.54571334 + 128:log10(((float)v+1)) * 64.54571334 + 96) @@ -269,7 +271,7 @@ class Audio : private AudioBuffer{ bool isRunning() {/*Serial.printf("m_f_running=%d\n", m_f_running); */return m_f_running;} void setBalance(int8_t bal = 0); void setTone(int8_t gainLowPass, int8_t gainBandPass, int8_t gainHighPass); - + // implement several function with respect to the index of string bool startsWith (const char* base, const char* str) { return (strstr(base, str) - base) == 0;} bool endsWith (const char* base, const char* str) { diff --git a/yoRadio/src/displays/displayDummy.cpp b/yoRadio/src/displays/displayDummy.cpp index cebaeb2..74b4c2f 100644 --- a/yoRadio/src/displays/displayDummy.cpp +++ b/yoRadio/src/displays/displayDummy.cpp @@ -169,7 +169,7 @@ void DspCore::printText(const char* txt) { } -void DspCore::loop() { +void DspCore::loop(bool force) { } diff --git a/yoRadio/src/displays/displayDummy.h b/yoRadio/src/displays/displayDummy.h index 46166bb..5852baf 100644 --- a/yoRadio/src/displays/displayDummy.h +++ b/yoRadio/src/displays/displayDummy.h @@ -37,7 +37,7 @@ class DspCore { void rssi(const char* str); void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); - void loop(); + void loop(bool force=false); private: uint16_t swidth, sheight; diff --git a/yoRadio/src/displays/displayILI9341.cpp b/yoRadio/src/displays/displayILI9341.cpp index 227bc2f..19347e2 100644 --- a/yoRadio/src/displays/displayILI9341.cpp +++ b/yoRadio/src/displays/displayILI9341.cpp @@ -109,7 +109,6 @@ void DspCore::apScreen() { } void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { - //begin(26000000L); /*багиловим*/ begin(); /* SPI_DEFAULT_FREQ 40000000 */ invertDisplay(TFT_INVERT); cp437(true); @@ -143,6 +142,7 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) { } else { setTextColor(iclrs[abs(i - 4)-1], TFT_BG); setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); + fillRect(0, yStart + i * PLMITEMHEIGHT-1, swidth, PLMITEMHEIGHT-4, TFT_BG); print(utf8Rus(plMenu[i], true)); } } @@ -154,8 +154,8 @@ void DspCore::clearDsp() { void DspCore::drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg) { if (TFT_FRAMEWDT==0) return; - fillRect(0, texttop, TFT_FRAMEWDT, textheight, bg); fillRect(swidth - TFT_FRAMEWDT, texttop, TFT_FRAMEWDT, textheight, bg); + fillRect(0, texttop, TFT_FRAMEWDT, textheight, bg); } void DspCore::getScrolBbounds(const char* text, const char* separator, byte textsize, uint16_t &tWidth, uint16_t &tHeight, uint16_t &sWidth) { @@ -365,7 +365,7 @@ void DspCore::printText(const char* txt) { print(txt); } -void DspCore::loop() { +void DspCore::loop(bool force) { } diff --git a/yoRadio/src/displays/displayILI9341.h b/yoRadio/src/displays/displayILI9341.h index b18bab4..11fcf15 100644 --- a/yoRadio/src/displays/displayILI9341.h +++ b/yoRadio/src/displays/displayILI9341.h @@ -13,8 +13,10 @@ #define TITLE_SIZE1 2 #define TITLE_SIZE2 2 +#if !defined(SCROLLDELTA) || !defined(SCROLLTIME) #define SCROLLDELTA 4 -#define SCROLLTIME 60 +#define SCROLLTIME 40 +#endif #define PLMITEMS 9 #define PLMITEMLENGHT 40 @@ -53,7 +55,7 @@ class DspCore: public Adafruit_ILI9341 { void rssi(const char* str); void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); - void loop(); + void loop(bool force=false); private: uint16_t swidth, sheight; char oldTimeBuf[20]; diff --git a/yoRadio/src/displays/displayLC1602.cpp b/yoRadio/src/displays/displayLC1602.cpp index 04b362a..fc25c2d 100644 --- a/yoRadio/src/displays/displayLC1602.cpp +++ b/yoRadio/src/displays/displayLC1602.cpp @@ -52,6 +52,7 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) { for (byte i = 0; i < PLMITEMS; i++) { plMenu[i][0] = '\0'; } + config.fillPlMenu(plMenu, currentItem, PLMITEMS); for (byte i = 0; i < PLMITEMS; i++) { strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); @@ -167,11 +168,10 @@ void DspCore::printText(const char* txt) { setCursor(nextX, yOffset); } -void DspCore::loop() { +void DspCore::loop(bool force) { if (checkdelay(SCROLLTIME, loopdelay)) { //display(); } - yield(); } boolean DspCore::checkdelay(int m, unsigned long & tstamp) { diff --git a/yoRadio/src/displays/displayLC1602.h b/yoRadio/src/displays/displayLC1602.h index 73b4563..8f03ede 100644 --- a/yoRadio/src/displays/displayLC1602.h +++ b/yoRadio/src/displays/displayLC1602.h @@ -20,6 +20,7 @@ #define SCROLLDELTA 1 #define SCROLLTIME 250 + #define BOOTSTR_TOP2 0 #define BOOTSTR_TOP1 1 #define STARTTIME_PL 2000 @@ -57,7 +58,7 @@ class DspCore: public LiquidCrystal { void rssi(const char* str); void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); - void loop(); + void loop(bool force=false); 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 3584680..5fc6fef 100644 --- a/yoRadio/src/displays/displayN5110.cpp +++ b/yoRadio/src/displays/displayN5110.cpp @@ -153,6 +153,7 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) { strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); } else { setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); + fillRect(0, yStart + i * PLMITEMHEIGHT, swidth, PLMITEMHEIGHT - 1, TFT_BG); print(utf8Rus(plMenu[i], true)); } } @@ -309,11 +310,10 @@ void DspCore::printText(const char* txt) { print(txt); } -void DspCore::loop() { - if (checkdelay(83, loopdelay)) { +void DspCore::loop(bool force) { + if (checkdelay(SCROLLTIME, loopdelay) || force) { display(); } - yield(); } boolean DspCore::checkdelay(int m, unsigned long &tstamp) { diff --git a/yoRadio/src/displays/displayN5110.h b/yoRadio/src/displays/displayN5110.h index 7813adc..5cf20b1 100644 --- a/yoRadio/src/displays/displayN5110.h +++ b/yoRadio/src/displays/displayN5110.h @@ -11,8 +11,13 @@ #define TFT_LINEHGHT 8 #define TFT_FRAMEWDT 0 -#define SCROLLDELTA 8 -#define SCROLLTIME 332 +#if !defined(SCROLLDELTA) || !defined(SCROLLTIME) +//#define SCROLLDELTA 8 +//#define SCROLLTIME 332 +#define SCROLLDELTA 4 +#define SCROLLTIME 250 +#endif + #define META_SIZE 1 #define TITLE_TOP1 TFT_FRAMEWDT + TFT_LINEHGHT+1 #define TITLE_SIZE2 0 @@ -50,7 +55,7 @@ class DspCore: public Adafruit_PCD8544 { void rssi(const char* str); void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); - void loop(); + void loop(bool force=false); private: uint16_t swidth, sheight; unsigned long loopdelay; diff --git a/yoRadio/src/displays/displaySH1106.cpp b/yoRadio/src/displays/displaySH1106.cpp index b6c9be7..d262f37 100644 --- a/yoRadio/src/displays/displaySH1106.cpp +++ b/yoRadio/src/displays/displaySH1106.cpp @@ -14,6 +14,10 @@ #define LOGO_WIDTH 21 #define LOGO_HEIGHT 32 +#ifndef I2CFREQ_HZ +#define I2CFREQ_HZ 4000000UL +#endif + const char *dow[7] = {"вс","пн","вт","ср","чт","пт","сб"}; const unsigned char logo [] PROGMEM= @@ -30,7 +34,7 @@ const unsigned char logo [] PROGMEM= TwoWire I2CSH1106 = TwoWire(0); #if DSP_MODEL==DSP_SH1106 -DspCore::DspCore(): Adafruit_SH1106G(128, 64, &I2CSH1106, -1) { +DspCore::DspCore(): Adafruit_SH1106G(128, 64, &I2CSH1106, -1, I2CFREQ_HZ) { } #else @@ -177,9 +181,11 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) { strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); } else { setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); + fillRect(0, yStart + i * PLMITEMHEIGHT, swidth, PLMITEMHEIGHT - 1, TFT_BG); print(utf8Rus(plMenu[i], true)); } } + display(); } void DspCore::clearDsp() { @@ -218,6 +224,7 @@ void DspCore::centerText(const char* text, byte y, uint16_t fg, uint16_t bg) { setCursor((swidth - w) / 2, y); fillRect(0, y, swidth, h, bg); print(txt); + display(); } void DspCore::rightText(const char* text, byte y, uint16_t fg, uint16_t bg) { @@ -246,13 +253,14 @@ void DspCore::printClock(struct tm timeinfo, bool dots, bool redraw) { char timeStringBuff[20] = { 0 }; strftime(timeStringBuff, sizeof(timeStringBuff), "%H:%M", &timeinfo); setTextSize(2); - setCursor(CLCLF, 34); + setCursor(CLCLF, (DSP_MODEL==DSP_SH1107)?30:34); setTextColor(TFT_FG, TFT_BG); print(timeStringBuff); setTextSize(1); - setCursor(CLCLF + 6*2*5+1, 34+1); + setCursor(CLCLF + 6*2*5+1, (DSP_MODEL==DSP_SH1107)?30+1:34+1); sprintf(timeStringBuff, "%02d", timeinfo.tm_sec); print(timeStringBuff); + display(); } void DspCore::drawVolumeBar(bool withNumber) { @@ -270,10 +278,11 @@ void DspCore::drawVolumeBar(bool withNumber) { int16_t x1, y1; sprintf(volstr, "%d", config.store.volume); getTextBounds(volstr, 0, 0, &x1, &y1, &wv, &hv); - fillRect(TFT_FRAMEWDT, 24, swidth - TFT_FRAMEWDT / 2, hv + 3, TFT_BG); + fillRect(TFT_FRAMEWDT, 24, swidth - TFT_FRAMEWDT / 2, hv + 3, TFT_BG);; setCursor((swidth - wv) / 2, 24); print(volstr); } + display(); } void DspCore::drawNextStationNum(uint16_t num) { @@ -287,6 +296,7 @@ void DspCore::drawNextStationNum(uint16_t num) { fillRect(TFT_FRAMEWDT, 24, swidth - TFT_FRAMEWDT / 2, hv + 3, TFT_BG); setCursor((swidth - wv) / 2, 24); print(numstr); + display(); } void DspCore::frameTitle(const char* str) { @@ -324,13 +334,13 @@ void DspCore::set_Cursor(int16_t x, int16_t y) { void DspCore::printText(const char* txt) { print(txt); + display(); } -void DspCore::loop() { - if (checkdelay(SCROLLTIME, loopdelay)) { - display(); +void DspCore::loop(bool force) { + if (checkdelay(SCROLLTIME, loopdelay) || force) { + //display(); } - yield(); } boolean DspCore::checkdelay(int m, unsigned long &tstamp) { diff --git a/yoRadio/src/displays/displaySH1106.h b/yoRadio/src/displays/displaySH1106.h index f1c96ce..d5349a3 100644 --- a/yoRadio/src/displays/displaySH1106.h +++ b/yoRadio/src/displays/displaySH1106.h @@ -14,8 +14,15 @@ #define TITLE_TOP2 TFT_FRAMEWDT + 3 * TFT_LINEHGHT #define PLCURRENT_SIZE 1 #define TFT_FULLTIME 1 + +#if DSP_MODEL==DSP_SH1107 +#define TITLE_SIZE2 0 +#endif + +#if !defined(SCROLLDELTA) || !defined(SCROLLTIME) #define SCROLLDELTA 3 -#define SCROLLTIME 83 +#define SCROLLTIME 60 +#endif #if DSP_MODEL==DSP_SH1106 class DspCore: public Adafruit_SH1106G { @@ -49,7 +56,7 @@ class DspCore: public Adafruit_SH1107 { void rssi(const char* str); void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); - void loop(); + void loop(bool force=false); private: uint16_t swidth, sheight; unsigned long loopdelay; diff --git a/yoRadio/src/displays/displaySSD1305.cpp b/yoRadio/src/displays/displaySSD1305.cpp index 015f93f..f8b7f6c 100644 --- a/yoRadio/src/displays/displaySSD1305.cpp +++ b/yoRadio/src/displays/displaySSD1305.cpp @@ -13,6 +13,10 @@ #define LOGO_WIDTH 21 #define LOGO_HEIGHT 32 +#ifndef DEF_SPI_FREQ +#define DEF_SPI_FREQ 7000000UL /* set it to 0 for system default */ +#endif + const char *dow[7] = {"вс","пн","вт","ср","чт","пт","сб"}; const unsigned char logo [] PROGMEM= @@ -27,7 +31,7 @@ const unsigned char logo [] PROGMEM= 0x1f, 0xff, 0xe0, 0x0f, 0xff, 0xe0, 0x03, 0xff, 0xc0, 0x00, 0xfe, 0x00 }; -DspCore::DspCore(): Adafruit_SSD1305(128, 64, &SPI, TFT_DC, TFT_RST, TFT_CS, 7000000UL) { +DspCore::DspCore(): Adafruit_SSD1305(128, 64, &SPI, TFT_DC, TFT_RST, TFT_CS, DEF_SPI_FREQ) { } @@ -161,6 +165,7 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) { strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); } else { setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); + fillRect(0, yStart + i * PLMITEMHEIGHT, swidth, PLMITEMHEIGHT - 1, TFT_BG); print(utf8Rus(plMenu[i], true)); } } @@ -303,11 +308,10 @@ void DspCore::printText(const char* txt) { print(txt); } -void DspCore::loop() { - if (checkdelay(FPS, loopdelay)) { +void DspCore::loop(bool force) { + if (checkdelay(SCROLLTIME, loopdelay) || force) { display(); } - yield(); } boolean DspCore::checkdelay(int m, unsigned long &tstamp) { diff --git a/yoRadio/src/displays/displaySSD1305.h b/yoRadio/src/displays/displaySSD1305.h index 97796e0..06e3180 100644 --- a/yoRadio/src/displays/displaySSD1305.h +++ b/yoRadio/src/displays/displaySSD1305.h @@ -16,9 +16,11 @@ #define TITLE_TOP2 TFT_FRAMEWDT + 2 * TFT_LINEHGHT #define PLCURRENT_SIZE 1 #define TFT_FULLTIME 1 + +#if !defined(SCROLLDELTA) || !defined(SCROLLTIME) #define SCROLLDELTA 3 #define SCROLLTIME 83 -#define FPS 50 +#endif class DspCore: public Adafruit_SSD1305 { public: @@ -48,7 +50,7 @@ class DspCore: public Adafruit_SSD1305 { void rssi(const char* str); void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); - void loop(); + void loop(bool force=false); private: uint16_t swidth, sheight; unsigned long loopdelay; diff --git a/yoRadio/src/displays/displaySSD1306.cpp b/yoRadio/src/displays/displaySSD1306.cpp index 776591f..254fa03 100644 --- a/yoRadio/src/displays/displaySSD1306.cpp +++ b/yoRadio/src/displays/displaySSD1306.cpp @@ -15,6 +15,7 @@ #define LOGO_WIDTH 21 #define LOGO_HEIGHT 32 + const unsigned char logo [] PROGMEM= { 0x06, 0x03, 0x00, 0x0f, 0x07, 0x80, 0x1f, 0x8f, 0xc0, 0x1f, 0x8f, 0xc0, @@ -28,9 +29,13 @@ const unsigned char logo [] PROGMEM= }; #endif +#ifndef I2CFREQ_HZ +#define I2CFREQ_HZ 4000000UL +#endif + TwoWire I2CSSD1306 = TwoWire(0); -DspCore::DspCore(): Adafruit_SSD1306(128, ((DSP_MODEL==DSP_SSD1306)?64:32), &I2CSSD1306, I2C_RST) { +DspCore::DspCore(): Adafruit_SSD1306(128, ((DSP_MODEL==DSP_SSD1306)?64:32), &I2CSSD1306, I2C_RST, I2CFREQ_HZ) { } @@ -177,6 +182,7 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) { strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); } else { setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); + fillRect(0, yStart + i * PLMITEMHEIGHT, swidth, PLMITEMHEIGHT - 1, TFT_BG); print(utf8Rus(plMenu[i], true)); } } @@ -330,8 +336,8 @@ void DspCore::printText(const char* txt) { print(txt); } -void DspCore::loop() { - if (checkdelay(83, loopdelay)) { +void DspCore::loop(bool force) { + if (checkdelay(83, loopdelay) || force) { #if DSP_MODEL==DSP_SSD1306x32 if(fillSpaces) printClock(insideClc); #endif diff --git a/yoRadio/src/displays/displaySSD1306.h b/yoRadio/src/displays/displaySSD1306.h index 53d42aa..ceb91f7 100644 --- a/yoRadio/src/displays/displaySSD1306.h +++ b/yoRadio/src/displays/displaySSD1306.h @@ -9,6 +9,11 @@ #define TFT_FRAMEWDT 0 #define PLMITEMLENGHT 40 +#if !defined(SCROLLDELTA) || !defined(SCROLLTIME) +#define SCROLLDELTA 2 +#define SCROLLTIME 40 +#endif + #if DSP_MODEL==DSP_SSD1306 #define PLMITEMS 5 @@ -65,7 +70,7 @@ class DspCore: public Adafruit_SSD1306 { void rssi(const char* str); void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); - void loop(); + void loop(bool force=false); private: uint16_t swidth, sheight; unsigned long loopdelay; diff --git a/yoRadio/src/displays/displaySSD1327.cpp b/yoRadio/src/displays/displaySSD1327.cpp index 95cda2f..ec62967 100644 --- a/yoRadio/src/displays/displaySSD1327.cpp +++ b/yoRadio/src/displays/displaySSD1327.cpp @@ -14,7 +14,7 @@ #ifndef I2CFREQ_HZ -#define I2CFREQ_HZ 4000000UL +#define I2CFREQ_HZ 6000000UL #endif TwoWire tw = TwoWire(0); @@ -155,10 +155,11 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) { strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); } else { setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); + fillRect(0, yStart + i * PLMITEMHEIGHT - 1, swidth, PLMITEMHEIGHT - 4, TFT_BG); print(utf8Rus(plMenu[i], true)); } } - //display(); + display(); } void DspCore::clearDsp() { @@ -196,6 +197,7 @@ void DspCore::centerText(const char* text, byte y, uint16_t fg, uint16_t bg) { setCursor((swidth - w) / 2, y); fillRect(0, y, swidth, h, bg); print(txt); + display(); } void DspCore::rightText(const char* text, byte y, uint16_t fg, uint16_t bg) { @@ -206,7 +208,7 @@ void DspCore::rightText(const char* text, byte y, uint16_t fg, uint16_t bg) { setCursor(swidth - w - TFT_FRAMEWDT, y); fillRect(swidth - w - TFT_FRAMEWDT, y, w, h, bg); print(text); - display(); + //display(); } void DspCore::displayHeapForDebug() { @@ -242,6 +244,7 @@ void DspCore::printClock(const char* timestr) { } void DspCore::drawVolumeBar(bool withNumber) { + if (withNumber) delay(150); /* buuuut iiiiit's toooooo faaaast 0000__oooo !!111 ommm____nomm____nomm */ int16_t vTop = sheight - TFT_FRAMEWDT * 2; int16_t vWidth = swidth - TFT_FRAMEWDT - 4; uint8_t ww = map(config.store.volume, 0, 254, 0, vWidth - 2); @@ -249,6 +252,7 @@ void DspCore::drawVolumeBar(bool withNumber) { drawRect(TFT_FRAMEWDT, vTop - 2, vWidth, 6, TFT_LOGO); fillRect(TFT_FRAMEWDT + 1, vTop - 1, ww, 5, TFT_LOGO); if (withNumber) { + setTextSize(1); setTextColor(TFT_FG); setFont(&DS_DIGI28pt7b); @@ -258,11 +262,12 @@ void DspCore::drawVolumeBar(bool withNumber) { sprintf(volstr, "%d", config.store.volume); getTextBounds(volstr, 0, 0, &x1, &y1, &wv, &hv); fillRect(TFT_FRAMEWDT, 48, swidth - TFT_FRAMEWDT / 2, hv + 3, TFT_BG); + //fillRect(24, 48, 80, hv + 3, TFT_BG); setCursor((swidth - wv) / 2, 48 + hv); print(volstr); setFont(); - display(); } + display(); } void DspCore::drawNextStationNum(uint16_t num) { @@ -278,11 +283,13 @@ void DspCore::drawNextStationNum(uint16_t num) { setCursor((swidth - wv) / 2, 48 + hv); print(numstr); setFont(); + display(); } void DspCore::frameTitle(const char* str) { setTextSize(2); centerText(str, TFT_FRAMEWDT, TFT_LOGO, TFT_BG); + //display(); } void DspCore::rssi(const char* str) { @@ -313,11 +320,12 @@ void DspCore::set_Cursor(int16_t x, int16_t y) { void DspCore::printText(const char* txt) { print(txt); + display(); } -void DspCore::loop() { - if (checkdelay(LOOP_DELAY, loopdelay)) { - display(); +void DspCore::loop(bool force) { + if (checkdelay(LOOP_DELAY, loopdelay) || force) { + //display(); } yield(); } diff --git a/yoRadio/src/displays/displaySSD1327.h b/yoRadio/src/displays/displaySSD1327.h index 3f72776..3f7cbf3 100644 --- a/yoRadio/src/displays/displaySSD1327.h +++ b/yoRadio/src/displays/displaySSD1327.h @@ -13,10 +13,27 @@ #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 4 +#define SCROLLTIME 83 +#define LOOP_DELAY 60 +#endif class DspCore: public Adafruit_SSD1327 { public: @@ -46,7 +63,7 @@ class DspCore: public Adafruit_SSD1327 { void rssi(const char* str); void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); - void loop(); + void loop(bool force=false); private: uint16_t swidth, sheight; int16_t x, y; @@ -60,12 +77,18 @@ class DspCore: public Adafruit_SSD1327 { extern DspCore dsp; + /* + SSD1327_GRAYTABLE, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x10, 0x18, 0x20, 0x2f, 0x38, 0x3f, + */ + /* * TFT COLORS */ -#define SILVER 0x7 -#define TFT_BG 0x0 -#define TFT_FG 0x8 -#define TFT_LOGO 0xF +#define SILVER 0x07 +#define TFT_BG 0x00 +#define TFT_FG 0x08 +#define TFT_LOGO 0x3f #endif diff --git a/yoRadio/src/displays/displayST7735.cpp b/yoRadio/src/displays/displayST7735.cpp index fb6ec93..a50255f 100644 --- a/yoRadio/src/displays/displayST7735.cpp +++ b/yoRadio/src/displays/displayST7735.cpp @@ -8,42 +8,6 @@ #include "../../config.h" #include "../../network.h" -class GFXClock { - public: - GFXClock() {}; - uint16_t init(Adafruit_ST7735 &tftd, const GFXfont *font, uint16_t fgcolor, uint16_t bgcolor ) { - _dsp = &tftd; - tftd.setFont(font); - tftd.getTextBounds("88:88", 0, 0, &x, &y, &cwidth, &cheight); - tftd.setFont(); - fg = fgcolor; - bg = bgcolor; - swidth = tftd.width(); - _canvas = new GFXcanvas1(swidth, cheight + 3); - _canvas->setFont(font); - _canvas->setTextWrap(false); - _canvas->setTextColor(WHITE); - uint16_t header = TFT_FRAMEWDT + 4 * TFT_LINEHGHT; - uint16_t footer = TFT_FRAMEWDT * 2 + TFT_LINEHGHT + 5; - clockY = header + (tftd.height() - header - footer) / 2 - cheight / 2; - return cheight; - } - void print(const char* timestr) { - _canvas->fillScreen(BLACK); - _canvas->getTextBounds(timestr, 0, 0, &x, &y, &cwidth, &cheight); - _canvas->setCursor((swidth - cwidth) / 2 - 4, cheight); - _canvas->print(timestr); - _dsp->drawBitmap(0, clockY , _canvas->getBuffer(), swidth, cheight + 3, fg, bg); - } - private: - int16_t x, y; - uint16_t cwidth, cheight, fg, bg, clockY, swidth; - GFXcanvas1 *_canvas; - Adafruit_ST7735 *_dsp; -}; - -GFXClock gclock; - DspCore::DspCore(): Adafruit_ST7735(&SPI, TFT_CS, TFT_DC, TFT_RST) { } @@ -150,7 +114,7 @@ void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { screenheight = height(); swidth = screenwidth; sheight = screenheight; - gclock.init(dsp, &DS_DIGI28pt7b, TFT_LOGO, BLACK); + setClockBounds(); } void DspCore::drawLogo() { @@ -178,6 +142,7 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) { strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); } else { setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); + fillRect(0, yStart + i * PLMITEMHEIGHT - 1, swidth, PLMITEMHEIGHT - 4, TFT_BG); print(utf8Rus(plMenu[i], true)); } } @@ -248,8 +213,67 @@ void DspCore::displayHeapForDebug() { #endif } +void DspCore::setClockBounds(){ + setFont(&DS_DIGI28pt7b); + setTextSize(1); + getTextBounds("88:88", 0, 0, &x, &y, &cwidth, &cheight); + uint16_t header = TFT_FRAMEWDT + 4 * TFT_LINEHGHT; + uint16_t footer = TFT_FRAMEWDT * 2 + TFT_LINEHGHT + 5; + clockY = header + (sheight - header - footer) / 2 - cheight / 2; + setFont(); +} + void DspCore::printClock(const char* timestr) { - gclock.print(timestr); + +} + +byte DspCore::getPw(uint16_t ncwidth){ + byte pw = 6; + if(ncwidth<35) pw = 7; + if(ncwidth<20) pw = 8; + return pw; +} + +void DspCore::printClock(struct tm timeinfo, bool dots, bool redraw){ + char timeBuf[50] = { 0 }; + char tmpBuf[4] = { 0 }; + uint16_t ncwidth, ncheight; + 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, clockY+28+6); + setTextColor(TFT_BG); + print(oldTimeBuf); + dot = (swidth - wot) / 2 - 4; + /* dots */ + strlcpy(tmpBuf, oldTimeBuf, 3); + getTextBounds(tmpBuf, 0, 0, &x, &y, &ncwidth, &ncheight); + dot = dot + ncwidth + getPw(ncwidth); + setCursor(dot, clockY+28+6); + print(":"); + /* dots */ + + strlcpy(oldTimeBuf, timeBuf, 20); + setTextSize(1); + getTextBounds(timeBuf, 0, 0, &x, &y, &ncwidth, &ncheight); + setTextColor(TFT_LOGO); + setCursor((swidth - ncwidth) / 2 - 4, clockY+28+6); + dot = (swidth - ncwidth) / 2 - 4; + setTextSize(1); + print(timeBuf); + /* dots */ + strftime(timeBuf, sizeof(timeBuf), "%H", &timeinfo); + getTextBounds(timeBuf, 0, 0, &x, &y, &ncwidth, &ncheight); + dot = dot + ncwidth + getPw(ncwidth); + /* dots */ + } + setCursor(dot, clockY+28+6); + setTextColor(dots?TFT_BG:TFT_LOGO); + print(":"); + setFont(); + yield(); } void DspCore::drawVolumeBar(bool withNumber) { @@ -325,7 +349,7 @@ void DspCore::printText(const char* txt) { print(txt); } -void DspCore::loop() { +void DspCore::loop(bool force) { } diff --git a/yoRadio/src/displays/displayST7735.h b/yoRadio/src/displays/displayST7735.h index a31bc20..54230ce 100644 --- a/yoRadio/src/displays/displayST7735.h +++ b/yoRadio/src/displays/displayST7735.h @@ -15,8 +15,12 @@ #define TITLE_TOP2 TFT_FRAMEWDT + 3 * TFT_LINEHGHT #define TITLE_FG2 SILVER +#if !defined(SCROLLDELTA) || !defined(SCROLLTIME) #define SCROLLDELTA 3 -#define SCROLLTIME 67 +#define SCROLLTIME 65 +#endif + +#define TFT_FULLTIME 1 class DspCore: public Adafruit_ST7735 { public: @@ -34,6 +38,7 @@ class DspCore: public Adafruit_ST7735 { void set_Cursor(int16_t x, int16_t y); void printText(const char* txt); void printClock(const char* timestr); + void printClock(struct tm timeinfo, bool dots, bool redraw = false); void displayHeapForDebug(); void drawVolumeBar(bool withNumber); void drawNextStationNum(uint16_t num); @@ -45,10 +50,15 @@ class DspCore: public Adafruit_ST7735 { void rssi(const char* str); void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); - void loop(); + void loop(bool force=false); private: uint16_t swidth, sheight; - + char oldTimeBuf[20]; + uint16_t wot, hot, dot; + int16_t x, y; + uint16_t cwidth, cheight; + void setClockBounds(); + byte getPw(uint16_t ncwidth); }; extern DspCore dsp; diff --git a/yoRadio/src/displays/displayST7789.cpp b/yoRadio/src/displays/displayST7789.cpp index f2b7d44..ac4fa6d 100644 --- a/yoRadio/src/displays/displayST7789.cpp +++ b/yoRadio/src/displays/displayST7789.cpp @@ -140,16 +140,17 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) { config.fillPlMenu(plMenu, currentItem - 4, PLMITEMS); setTextSize(2); int yStart = (sheight / 2 - PLMITEMHEIGHT / 2) - PLMITEMHEIGHT * (PLMITEMS - 1) / 2 + 3; - fillRect(0, (sheight / 2 - PLMITEMHEIGHT / 2) - 1, swidth, PLMITEMHEIGHT + 2, TFT_LOGO); + for (byte i = 0; i < PLMITEMS; i++) { if (i == 4) { + //fillRect(0, (sheight / 2 - PLMITEMHEIGHT / 2) - 1, swidth, PLMITEMHEIGHT + 2, TFT_LOGO); strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); } else { setTextColor(iclrs[abs(i - 4)-1], TFT_BG); setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); + fillRect(0, yStart + i * PLMITEMHEIGHT - 1, swidth, PLMITEMHEIGHT - 2, TFT_BG); print(utf8Rus(plMenu[i], true)); } - yield(); } } @@ -159,9 +160,8 @@ void DspCore::clearDsp() { void DspCore::drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg) { if (TFT_FRAMEWDT==0) return; - fillRect(0, texttop, TFT_FRAMEWDT, textheight, bg); fillRect(swidth - TFT_FRAMEWDT, texttop, TFT_FRAMEWDT, textheight, bg); - yield(); + fillRect(0, texttop, TFT_FRAMEWDT, textheight, bg); } void DspCore::getScrolBbounds(const char* text, const char* separator, byte textsize, uint16_t &tWidth, uint16_t &tHeight, uint16_t &sWidth) { @@ -176,7 +176,7 @@ void DspCore::getScrolBbounds(const char* text, const char* separator, byte text } void DspCore::clearScroll(uint16_t texttop, uint16_t textheight, uint16_t bg) { - fillRect(0, texttop, swidth, textheight, bg); + fillRect(0, texttop-4, swidth, textheight+7, bg); yield(); } @@ -364,10 +364,9 @@ void DspCore::set_Cursor(int16_t x, int16_t y) { void DspCore::printText(const char* txt) { print(txt); - yield(); } -void DspCore::loop() { +void DspCore::loop(bool force) { } diff --git a/yoRadio/src/displays/displayST7789.h b/yoRadio/src/displays/displayST7789.h index 60168d9..a8f27d2 100644 --- a/yoRadio/src/displays/displayST7789.h +++ b/yoRadio/src/displays/displayST7789.h @@ -13,8 +13,10 @@ #define TITLE_SIZE1 2 #define TITLE_SIZE2 2 -#define SCROLLDELTA 6 -#define SCROLLTIME 83 +#if !defined(SCROLLDELTA) || !defined(SCROLLTIME) +#define SCROLLDELTA 5 +#define SCROLLTIME 50 +#endif #define PLMITEMS 9 #define PLMITEMLENGHT 40 @@ -53,7 +55,7 @@ class DspCore: public Adafruit_ST7789 { void rssi(const char* str); void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); - void loop(); + void loop(bool force=false); private: uint16_t swidth, sheight; char oldTimeBuf[20]; diff --git a/yoRadio/yoRadio.ino b/yoRadio/yoRadio.ino index c6d8ab6..6da7d04 100644 --- a/yoRadio/yoRadio.ino +++ b/yoRadio/yoRadio.ino @@ -11,17 +11,9 @@ #include "controls.h" #include "mqtt.h" -#if CORE_FOR_LOOP_CONTROLS != 255 -TaskHandle_t TaskCore0; -#ifndef CORE_FOR_LOOP_STACK_SIZE -#define CORE_FOR_LOOP_STACK_SIZE 8192 -#endif -#endif - void setup() { Serial.begin(115200); pinMode(LED_BUILTIN, OUTPUT); - //digitalWrite(LED_BUILTIN, LOW); config.init(); display.init(); player.init(); @@ -34,57 +26,22 @@ void setup() { netserver.begin(); telnet.begin(); player.setVol(config.store.volume, true); - if(CORE_FOR_LOOP_CONTROLS == 255){ - initControls(); - display.start(); - } - + initControls(); + display.start(); + #ifdef MQTT_HOST mqttInit(); #endif -#if CORE_FOR_LOOP_CONTROLS != 255 - BaseType_t coreId = xPortGetCoreID(); - BaseType_t newCoreId = (CORE_FOR_LOOP_CONTROLS==2)?!coreId:CORE_FOR_LOOP_CONTROLS; - xTaskCreatePinnedToCore( - loopCore0, /* Task function. */ - "TaskCore0", /* name of task. */ - CORE_FOR_LOOP_STACK_SIZE, /* Stack size of task */ - NULL, /* parameter of the task */ - 1, /* priority of the task */ - &TaskCore0, /* Task handle to keep track of created task */ - newCoreId); /* pin task to core CORE_FOR_LOOP_CONTROLS */ -#endif - - delay(500); - if(config.store.smartstart==1) player.play(config.store.lastStation); -} - -#if CORE_FOR_LOOP_CONTROLS != 255 -void setupCore0(){ - initControls(); - display.start(); + if (config.store.smartstart == 1) player.play(config.store.lastStation); } -void loopCore0( void * pvParameters ){ - setupCore0(); - for(;;){ - micros(); - if (network.status == CONNECTED) { - loopControls(); - } - display.loop(); - vTaskDelay(10); - } -} -#endif - void loop() { if (network.status == CONNECTED) { telnet.loop(); player.loop(); - if(CORE_FOR_LOOP_CONTROLS==255) loopControls(); + loopControls(); } - if(CORE_FOR_LOOP_CONTROLS==255 || network.status != CONNECTED) display.loop(); + display.loop(); netserver.loop(); }