This commit is contained in:
e2002
2022-04-05 12:18:25 +03:00
parent 864d8f9dcd
commit 40f194ab26
40 changed files with 530 additions and 367 deletions

View File

@@ -41,4 +41,6 @@
\ \
![ёRadio](images/img19.jpg)\ ![ёRadio](images/img19.jpg)\
\ \
![ёRadio](images/img20.jpg) ![ёRadio](images/img20.jpg)\
\
![ёRadio](images/img21.jpg)

View File

@@ -280,6 +280,14 @@ Work is in progress...
--- ---
## Version history ## 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 #### v0.6.012
- fixed choppy playback - fixed choppy playback

View File

@@ -1,14 +1,17 @@
/************************************************************** /**************************************************************
*
* An example of displaying user information on the display. An example of displaying user information on the display.
* This file must be in the root directory of the sketch. This file must be in the root directory of the sketch.
*
**************************************************************/ **************************************************************/
#if DSP_MODEL==DSP_ST7735 #if DSP_MODEL==DSP_ST7735
// 3600s = 60 minutes to not flooding
#define WEATHER_REQUEST_INTERVAL 3600 // 60min
#include <JSON_Decoder.h> // https://github.com/Bodmer/OpenWeather #include <JSON_Decoder.h> // https://github.com/Bodmer/OpenWeather
#include <OpenWeather.h> // https://github.com/Bodmer/JSON_Decoder #include <OpenWeather.h> // https://github.com/Bodmer/JSON_Decoder
#include <Ticker.h>
String api_key = "********************************"; // openweathermap.org API key String api_key = "********************************"; // openweathermap.org API key
@@ -19,45 +22,76 @@ String units = "metric";
String language = "ru"; String language = "ru";
OW_Weather ow; OW_Weather ow;
Ticker ticker;
/*********************************************** /***********************************************
* scrolled line scrolled line
***********************************************/ ***********************************************/
Scroll hello; Scroll hello;
char weather[140] = { 0 };
bool weatherRequest = false;
TaskHandle_t weatherUpdateTaskHandle;
/*********************************************** void getWeather( void * pvParameters ) {
* Occurs when the display is initialized
***********************************************/
void dsp_on_init(){
hello.init(" * ", 1, TFT_LINEHGHT*4+6, 2000, ORANGE, TFT_BG);
}
/*********************************************************************************************
* 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_current *current = new OW_current;
OW_hourly *hourly = new OW_hourly; OW_hourly *hourly = new OW_hourly;
OW_daily *daily = new OW_daily; OW_daily *daily = new OW_daily;
char weather[140] = { 0 }; delay(5000);
ow.getForecast(current, hourly, daily, api_key, latitude, longitude, units, language); 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 );
}
sprintf(weather, "temp: %.1f * pressure: %d * humidity: %d", current->temp, (int)(current->pressure/1.333), current->humidity); 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 */
}
hello.setText(dsp->utf8Rus(weather, true)); /***********************************************
Occurs when the network is connected
***********************************************/
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
*********************************************************************************************/
void dsp_on_start(DspCore *dsp) {
}
/***********************************************
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() { void dsp_on_loop() {
if (weatherRequest) {
weatherRequest = false;
hello.setText(weather);
}
if (display.mode == PLAYER) hello.loop(); 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) { if (newmode == PLAYER) {
@@ -68,7 +102,7 @@ void dsp_on_newmode(displayMode_e newmode){
} }
/************************ /************************
* Before print the clock Before print the clock
************************/ ************************/
bool dsp_before_clock(DspCore *dsp, bool dots) { bool dsp_before_clock(DspCore *dsp, bool dots) {
if (display.mode == PLAYER) { if (display.mode == PLAYER) {

View File

@@ -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 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 */ /* DSP_MODEL. See description/available values in the options.h file */
/* This option is required. Use DSP_DUMMY if no display is connected */ /* This option is required. Use DSP_DUMMY if no display is connected */

BIN
images/img21.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

View File

@@ -2,9 +2,11 @@
#include <EEPROM.h> #include <EEPROM.h>
#include <SPIFFS.h> #include <SPIFFS.h>
#include "display.h" #include "display.h"
#include "player.h"
Config config; Config config;
void Config::init() { void Config::init() {
EEPROM.begin(EEPROM_SIZE);
eepromRead(EEPROM_START, store); 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.tz_set = 57;
@@ -29,22 +31,17 @@ void Config::init() {
template <class T> int Config::eepromWrite(int ee, const T& value) { template <class T> int Config::eepromWrite(int ee, const T& value) {
const byte* p = (const byte*)(const void*)&value; const byte* p = (const byte*)(const void*)&value;
int i; int i;
EEPROM.begin(EEPROM_SIZE);
for (i = 0; i < sizeof(value); i++) for (i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++); EEPROM.write(ee++, *p++);
EEPROM.commit(); EEPROM.commit();
delay(20);
EEPROM.end();
return i; return i;
} }
template <class T> int Config::eepromRead(int ee, T& value) { template <class T> int Config::eepromRead(int ee, T& value) {
byte* p = (byte*)(void*)&value; byte* p = (byte*)(void*)&value;
int i; int i;;
EEPROM.begin(EEPROM_SIZE);
for (i = 0; i < sizeof(value); i++) for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++); *p++ = EEPROM.read(ee++);
EEPROM.end();
return i; return i;
} }
@@ -87,7 +84,11 @@ void Config::save() {
byte Config::setVolume(byte val, bool dosave) { byte Config::setVolume(byte val, bool dosave) {
store.volume = val; store.volume = val;
if (dosave) save(); if (dosave) {
//save();
EEPROM.write(EEPROM_START + sizeof(store.config_set), store.volume);
EEPROM.commit();
}
return store.volume; return store.volume;
} }
@@ -131,7 +132,7 @@ byte Config::setLastSSID(byte val) {
void Config::setTitle(const char* title) { void Config::setTitle(const char* title) {
memset(config.station.title, 0, BUFLEN); memset(config.station.title, 0, BUFLEN);
strlcpy(config.station.title, title, BUFLEN); strlcpy(config.station.title, title, BUFLEN);
display.refreshTitle = true; display.title();
} }
void Config::setStation(const char* station) { void Config::setStation(const char* station) {

View File

@@ -2,7 +2,7 @@
#define config_h #define config_h
#include "Arduino.h" #include "Arduino.h"
#define EEPROM_SIZE 1024 #define EEPROM_SIZE 32
#define EEPROM_START 0 #define EEPROM_START 0
#define BUFLEN 140 #define BUFLEN 140
#define PLAYLIST_PATH "/data/playlist.csv" #define PLAYLIST_PATH "/data/playlist.csv"

View File

@@ -103,6 +103,7 @@ void initControls() {
} }
void loopControls() { void loopControls() {
if(display.mode==LOST) return;
#if ENC_BTNL!=255 #if ENC_BTNL!=255
encoderLoop(); encoderLoop();
#endif #endif
@@ -204,9 +205,9 @@ void irLoop() {
irBlink(); irBlink();
if (display.mode == NUMBERS) { if (display.mode == NUMBERS) {
display.swichMode(PLAYER); display.swichMode(PLAYER);
//player.play(display.numOfNextStation); player.play(display.numOfNextStation);
player.request.station = display.numOfNextStation; //player.request.station = display.numOfNextStation;
player.request.doSave = true; //player.request.doSave = true;
display.numOfNextStation = 0; display.numOfNextStation = 0;
break; break;
} }
@@ -300,7 +301,7 @@ void irLoop() {
#define TS_Y_MAX 3800 #define TS_Y_MAX 3800
#endif #endif
#ifndef TS_STEPS #ifndef TS_STEPS
#define TS_STEPS 70 #define TS_STEPS 40
#endif #endif
boolean wastouched = true; boolean wastouched = true;
@@ -351,9 +352,9 @@ void touchLoop() {
switch (direct) { switch (direct) {
case TSD_LEFT: case TSD_LEFT:
case TSD_RIGHT: { case TSD_RIGHT: {
touchLongPress=millis();
if(display.mode==PLAYER || display.mode==VOL){ if(display.mode==PLAYER || display.mode==VOL){
int16_t xDelta = map(abs(touchVol - touchX), 0, display.screenwidth, 0, TS_STEPS); int16_t xDelta = map(abs(touchVol - touchX), 0, display.screenwidth, 0, TS_STEPS);
Serial.println(touchVol - touchX);
display.swichMode(VOL); display.swichMode(VOL);
if (xDelta>1) { if (xDelta>1) {
controlsEvent((touchVol - touchX)<0); controlsEvent((touchVol - touchX)<0);
@@ -364,6 +365,7 @@ void touchLoop() {
} }
case TSD_UP: case TSD_UP:
case TSD_DOWN: { case TSD_DOWN: {
touchLongPress=millis();
if(display.mode==PLAYER || display.mode==STATIONS){ if(display.mode==PLAYER || display.mode==STATIONS){
int16_t yDelta = map(abs(touchStation - touchY), 0, display.screenheight, 0, TS_STEPS); int16_t yDelta = map(abs(touchStation - touchY), 0, display.screenheight, 0, TS_STEPS);
display.swichMode(STATIONS); display.swichMode(STATIONS);
@@ -385,7 +387,7 @@ void touchLoop() {
} else { } else {
if (wastouched) {/* END TOUCH */ if (wastouched) {/* END TOUCH */
if (direct == TDS_REQUEST) { if (direct == TDS_REQUEST) {
if(millis()-touchLongPress < BTN_PRESS_TICKS){ if(millis()-touchLongPress < BTN_PRESS_TICKS*2){
onBtnClick(EVT_BTNCENTER); onBtnClick(EVT_BTNCENTER);
}else{ }else{
display.swichMode(display.mode == PLAYER ? STATIONS : PLAYER); display.swichMode(display.mode == PLAYER ? STATIONS : PLAYER);
@@ -473,10 +475,10 @@ void controlsEvent(bool toRight) {
} }
if (display.mode == STATIONS) { if (display.mode == STATIONS) {
int p = toRight ? display.currentPlItem + 1 : display.currentPlItem - 1; int p = toRight ? display.currentPlItem + 1 : display.currentPlItem - 1;
if (p < 1) p = 1; if (p < 1) p = config.store.countStation;
if (p > config.store.countStation) p = config.store.countStation; if (p > config.store.countStation) p = 1;
display.currentPlItem = p; display.currentPlItem = p;
display.clear(); //display.clear();
display.drawPlaylist(); display.drawPlaylist();
} }
} }
@@ -499,9 +501,9 @@ void onBtnClick(int id) {
} }
if (display.mode == STATIONS) { if (display.mode == STATIONS) {
display.swichMode(PLAYER); display.swichMode(PLAYER);
//player.play(display.currentPlItem); player.play(display.currentPlItem);
player.request.station = display.currentPlItem; //player.request.station = display.currentPlItem;
player.request.doSave = true; //player.request.doSave = true;
} }
break; break;
} }

View File

@@ -21,10 +21,6 @@ void ticks() {
#ifndef STARTTIME_PL #ifndef STARTTIME_PL
#define STARTTIME_PL 0 #define STARTTIME_PL 0
#endif #endif
#ifndef SCROLLDELTA
#define SCROLLDELTA 3
#define SCROLLTIME 83
#endif
#ifndef META_SIZE #ifndef META_SIZE
#define META_SIZE 2 #define META_SIZE 2
#endif #endif
@@ -62,8 +58,11 @@ void ticks() {
#define DO_SCROLL (tWidth > (display.screenwidth - (dsp.fillSpaces?((texttop==0)?CLOCK_SPACE:VOL_SPACE):0))) #define DO_SCROLL (tWidth > (display.screenwidth - (dsp.fillSpaces?((texttop==0)?CLOCK_SPACE:VOL_SPACE):0)))
#endif #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; textsize = tsize;
id = ScrollId;
if (textsize == 0) return; if (textsize == 0) return;
texttop = top; texttop = top;
fg = fgcolor; 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) { void Scroll::setText(const char *txt) {
if (textsize == 0) return; if (textsize == 0) return;
memset(text, 0, BUFLEN / 2); memset(text, 0, BUFLEN / 2);
strlcpy(text, txt, BUFLEN / 2); strlcpy(text, txt, BUFLEN / 2 - 1);
getbounds(textwidth, textheight, sepwidth); getbounds(textwidth, textheight, sepwidth);
if (doscroll) {
memset(text2, 0, BUFLEN + 10);
sprintf(text2, "%s%s%s", text, separator, text);
}
if (!locked) { if (!locked) {
clearscrolls(); clearscrolls();
reset(); reset();
} }
lockRequest = false;
} }
void Scroll::lock() { void Scroll::lock() {
@@ -99,8 +103,9 @@ void Scroll::reset() {
clear(); clear();
setTextParams(); setTextParams();
dsp.set_Cursor(TFT_FRAMEWDT, texttop); dsp.set_Cursor(TFT_FRAMEWDT, texttop);
dsp.printText(text); dsp.printText(doscroll ? text2 : text);
drawFrame(); drawFrame();
if (currentScrollId == id) currentScrollId = 0;
} }
void Scroll::setTextParams() { void Scroll::setTextParams() {
@@ -113,11 +118,17 @@ void Scroll::clearscrolls() {
if (textsize == 0) return; if (textsize == 0) return;
x = TFT_FRAMEWDT; x = TFT_FRAMEWDT;
scrolldelay = millis(); scrolldelay = millis();
clear(); //clear();
} }
void Scroll::loop() { void Scroll::loop() {
if (lockRequest) {
return;
}
if (textsize == 0) return; if (textsize == 0) return;
if (currentScrollId != 0 && currentScrollId != id) {
return;
}
if (checkdelay(x == TFT_FRAMEWDT ? delayStartScroll : SCROLLTIME, scrolldelay)) { if (checkdelay(x == TFT_FRAMEWDT ? delayStartScroll : SCROLLTIME, scrolldelay)) {
scroll(); scroll();
sticks(); sticks();
@@ -143,17 +154,25 @@ void Scroll::sticks() {
if (!doscroll || locked || textsize == 0) return; if (!doscroll || locked || textsize == 0) return;
setTextParams(); setTextParams();
dsp.set_Cursor(x, texttop); dsp.set_Cursor(x, texttop);
dsp.printText(text); dsp.printText(text2);
dsp.printText(separator);
dsp.printText(text); //dsp.printText(separator);
drawFrame(); //dsp.printText(text);
if (x == TFT_FRAMEWDT) drawFrame();
} }
void Scroll::scroll() { void Scroll::scroll() {
if (!doscroll || textsize == 0) return; if (!doscroll || textsize == 0) return;
//if (textwidth > display.screenwidth) { //if (textwidth > display.screenwidth) {
x -= SCROLLDELTA; 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() { void Display::init() {
dsp.initD(screenwidth, screenheight); dsp.initD(screenwidth, screenheight);
dsp.drawLogo(); dsp.drawLogo();
meta.init(" * ", META_SIZE, TFT_FRAMEWDT, STARTTIME, TFT_LOGO, TFT_BG); meta.init(1, " * ", META_SIZE, TFT_FRAMEWDT, STARTTIME, TFT_LOGO, TFT_BG);
title1.init(" * ", TITLE_SIZE1, TITLE_TOP1, STARTTIME, TITLE_FG1, TFT_BG); title1.init(2, " * ", TITLE_SIZE1, TITLE_TOP1, STARTTIME, TITLE_FG1, TFT_BG);
title2.init(" * ", TITLE_SIZE2, TITLE_TOP2, STARTTIME, TITLE_FG2, TFT_BG); title2.init(3, " * ", TITLE_SIZE2, TITLE_TOP2, STARTTIME, TITLE_FG2, TFT_BG);
int yStart = (screenheight / 2 - PLMITEMHEIGHT / 2) + 3; int yStart = (screenheight / 2 - PLMITEMHEIGHT / 2) + 3;
#ifdef PL_TOP #ifdef PL_TOP
yStart = PL_TOP; yStart = PL_TOP;
#endif #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(); plCurrent.lock();
if (dsp_on_init) dsp_on_init(); if (dsp_on_init) dsp_on_init();
} }
@@ -196,9 +215,6 @@ void Display::apScreen() {
void Display::start() { void Display::start() {
clear(); clear();
refreshTitle = false;
refreshStation = false;
refreshVolume = false;
if (network.status != CONNECTED) { if (network.status != CONNECTED) {
apScreen(); apScreen();
return; return;
@@ -214,7 +230,7 @@ void Display::start() {
time(); time();
timer.attach_ms(1000, ticks); timer.attach_ms(1000, ticks);
if (dsp_on_start) dsp_on_start(&dsp); if (dsp_on_start) dsp_on_start(&dsp);
// Экстреминатус секвестирован /*дважды*/ трижды // Экстреминатус секвестирован /*дважды*/ /*трижды*/ четырежды
} }
void Display::clear() { void Display::clear() {
@@ -233,9 +249,11 @@ void Display::swichMode(displayMode_e newmode) {
volume(); volume();
} }
if (newmode == PLAYER) { if (newmode == PLAYER) {
currentScrollId = 0;
meta.reset(); meta.reset();
title1.reset(); title1.reset();
if (TITLE_SIZE2 != 0) title2.reset(); if (TITLE_SIZE2 != 0) title2.reset();
player.loop();
plCurrent.lock(); plCurrent.lock();
time(true); time(true);
#ifdef CLOCK_SPACE // if set space for clock in 1602 displays #ifdef CLOCK_SPACE // if set space for clock in 1602 displays
@@ -244,6 +262,7 @@ void Display::swichMode(displayMode_e newmode) {
rssi(); rssi();
volume(); volume();
#endif #endif
dsp.loop(true);
} else { } else {
if (newmode != NUMBERS) { if (newmode != NUMBERS) {
meta.lock(); meta.lock();
@@ -257,6 +276,9 @@ void Display::swichMode(displayMode_e newmode) {
if (newmode == VOL) { if (newmode == VOL) {
dsp.frameTitle("VOLUME"); dsp.frameTitle("VOLUME");
} }
if (newmode == LOST) {
dsp.frameTitle("* LOST *");
}
if (newmode == NUMBERS) { if (newmode == NUMBERS) {
//dsp.frameTitle("STATION"); //dsp.frameTitle("STATION");
meta.reset(); meta.reset();
@@ -264,6 +286,7 @@ void Display::swichMode(displayMode_e newmode) {
if (newmode == STATIONS) { if (newmode == STATIONS) {
currentPlItem = config.store.lastStation; currentPlItem = config.store.lastStation;
plCurrent.reset(); plCurrent.reset();
currentScrollId = 0;
drawPlaylist(); drawPlaylist();
} }
if (dsp_on_newmode) dsp_on_newmode(newmode); if (dsp_on_newmode) dsp_on_newmode(newmode);
@@ -287,10 +310,26 @@ void Display::drawVolume() {
} }
} }
TaskHandle_t drawPlaylistTaskHandle = NULL;
bool taskDone = true;
void getPlaylist( void * pvParameters ) {
char buf[PLMITEMLENGHT];
display.plCurrent.lockRequest = true;
dsp.drawPlaylist(display.currentPlItem, buf);
display.plCurrent.setText(dsp.utf8Rus(buf, true));
taskDone = true;
vTaskDelete( NULL );
}
void Display::drawPlaylist() { void Display::drawPlaylist() {
while (!taskDone) player.loop();
taskDone = false;
xTaskCreatePinnedToCore(getPlaylist, "getPlaylist0", 4096, NULL, 1, &drawPlaylistTaskHandle, 0);
/*
char buf[PLMITEMLENGHT]; char buf[PLMITEMLENGHT];
dsp.drawPlaylist(currentPlItem, buf); dsp.drawPlaylist(currentPlItem, buf);
plCurrent.setText(dsp.utf8Rus(buf, true)); plCurrent.setText(dsp.utf8Rus(buf, true));
*/
} }
void Display::drawNextStationNum(uint16_t num) { void Display::drawNextStationNum(uint16_t num) {
@@ -303,18 +342,6 @@ void Display::drawNextStationNum(uint16_t num) {
} }
void Display::loop() { void Display::loop() {
if(refreshStation){
refreshStation = false;
station();
}
if(refreshTitle){
refreshTitle = false;
title();
}
if(refreshVolume){
refreshVolume = false;
volume();
}
switch (mode) { switch (mode) {
case PLAYER: { case PLAYER: {
drawPlayer(); 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) { void Display::bootString(const char* text, byte y) {
dsp.centerText(text, y == 1 ? BOOTSTR_TOP1 : BOOTSTR_TOP2, TFT_LOGO, TFT_BG); dsp.centerText(text, y == 1 ? BOOTSTR_TOP1 : BOOTSTR_TOP2, TFT_LOGO, TFT_BG);
dsp.loop(); dsp.loop(true);
} }
void Display::bootLogo() { void Display::bootLogo() {
@@ -358,14 +385,20 @@ void Display::rightText(const char* text, byte y, uint16_t fg, uint16_t bg) {
void Display::station() { void Display::station() {
meta.setText(dsp.utf8Rus(config.station.name, true)); meta.setText(dsp.utf8Rus(config.station.name, true));
dsp.loop(); #ifdef DEBUG_TITLES
meta.setText(dsp.utf8Rus("Utenim adminim veniam FM", true));
#endif
dsp.loop(true);
//netserver.requestOnChange(STATION, 0); //netserver.requestOnChange(STATION, 0);
} }
void Display::returnTile() { void Display::returnTile() {
meta.setText(dsp.utf8Rus(config.station.name, true)); meta.setText(dsp.utf8Rus(config.station.name, true));
#ifdef DEBUG_TITLES
meta.setText(dsp.utf8Rus("Utenim adminim veniam FM", true));
#endif
meta.reset(); meta.reset();
dsp.loop(); dsp.loop(true);
} }
void Display::title() { void Display::title() {
@@ -380,14 +413,19 @@ void Display::title() {
if ((ici = strstr(config.station.title, " - ")) != NULL && TITLE_SIZE2 != 0) { if ((ici = strstr(config.station.title, " - ")) != NULL && TITLE_SIZE2 != 0) {
strlcpy(sng, ici + 3, BUFLEN / 2); strlcpy(sng, ici + 3, BUFLEN / 2);
strlcpy(ttl, config.station.title, strlen(config.station.title) - strlen(ici) + 1); strlcpy(ttl, config.station.title, strlen(config.station.title) - strlen(ici) + 1);
} else { } else {
strlcpy(ttl, config.station.title, BUFLEN / 2); strlcpy(ttl, config.station.title, BUFLEN / 2);
sng[0] = '\0'; 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)); title1.setText(dsp.utf8Rus(ttl, true));
if (TITLE_SIZE2 != 0) title2.setText(dsp.utf8Rus(sng, true)); if (TITLE_SIZE2 != 0) title2.setText(dsp.utf8Rus(sng, true));
dsp.loop(); dsp.loop(true);
} }
//netserver.requestOnChange(TITLE, 0); //netserver.requestOnChange(TITLE, 0);
} }
@@ -408,10 +446,27 @@ void Display::ip() {
dsp.ip(WiFi.localIP().toString().c_str()); 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) { void Display::time(bool redraw) {
if (dsp_before_clock) if (!dsp_before_clock(&dsp, dt)) return; if (dsp_before_clock) if (!dsp_before_clock(&dsp, dt)) return;
char timeStringBuff[20] = { 0 }; char timeStringBuff[20] = { 0 };
if (!dt) { if (!dt) {
checkConnection();
heap(); heap();
rssi(); rssi();
} }
@@ -429,8 +484,22 @@ void Display::time(bool redraw) {
if (dsp_after_clock) dsp_after_clock(&dsp, dt); if (dsp_after_clock) dsp_after_clock(&dsp, dt);
} }
void Display::volume() { TaskHandle_t drawVolumeTaskHandle = NULL;
dsp.drawVolumeBar(mode == VOL); bool taskVDone = true;
//netserver.requestOnChange(VOLUME, 0); void drawVolumeTask( void * pvParameters ) {
netserver.volRequest = true; delay(20); /* but it's too fast 0__o */
dsp.drawVolumeBar(true);
taskVDone = true;
vTaskDelete( NULL );
}
void Display::volume() {
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);
} }

View File

@@ -33,20 +33,22 @@
#include "src/displays/displayCustom.h" #include "src/displays/displayCustom.h"
#endif #endif
enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS }; enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST };
class Scroll { class Scroll {
public: public:
Scroll() { }; 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 setText(const char *txt);
void loop(); void loop();
void reset(); void reset();
void lock(); void lock();
void unlock(); void unlock();
bool lockRequest;
private: private:
byte textsize, texttop; byte textsize, texttop, id;
char text[BUFLEN/2]; char text[BUFLEN/2];
char text2[BUFLEN+10];
char separator[4]; char separator[4];
uint16_t fg, bg; uint16_t fg, bg;
uint16_t delayStartScroll; uint16_t delayStartScroll;
@@ -71,13 +73,16 @@ class Display {
displayMode_e mode; displayMode_e mode;
uint16_t currentPlItem; uint16_t currentPlItem;
uint16_t numOfNextStation; uint16_t numOfNextStation;
bool refreshTitle, refreshStation, refreshVolume; Scroll plCurrent;
public: public:
Display() {}; Display() {};
void init(); void init();
void clear(); void clear();
void loop(); void loop();
void start(); void start();
void station();
void title();
void volume();
void centerText(const char* text, byte y, uint16_t fg, uint16_t bg); void centerText(const char* text, byte y, uint16_t fg, uint16_t bg);
void rightText(const char* text, byte y, uint16_t fg, uint16_t bg); void rightText(const char* text, byte y, uint16_t fg, uint16_t bg);
void bootString(const char* text, byte y); void bootString(const char* text, byte y);
@@ -88,19 +93,17 @@ class Display {
void drawNextStationNum(uint16_t num); void drawNextStationNum(uint16_t num);
private: private:
Ticker timer; Ticker timer;
Scroll meta, title1, title2, plCurrent; Scroll meta, title1, title2;
bool dt; // dots bool dt; // dots
unsigned long volDelay; unsigned long volDelay;
void heap(); void heap();
void rssi(); void rssi();
void station();
void title();
void volume();
void ip(); void ip();
void time(bool redraw = false); void time(bool redraw = false);
void apScreen(); void apScreen();
void drawPlayer(); void drawPlayer();
void drawVolume(); void drawVolume();
void checkConnection();
}; };
extern Display display; extern Display display;

View File

@@ -24,7 +24,7 @@ byte ssidCount;
bool NetServer::begin() { bool NetServer::begin() {
importRequest = false; importRequest = false;
volRequest = false;
webserver.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { webserver.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
ssidCount = 0; ssidCount = 0;
request->send(SPIFFS, "/www/index.html", String(), false, processor); request->send(SPIFFS, "/www/index.html", String(), false, processor);
@@ -71,10 +71,6 @@ void NetServer::loop() {
} }
importRequest = false; importRequest = false;
} }
if (volRequest) {
requestOnChange(VOLUME, 0);
volRequest = false;
}
if(rssi<255){ if(rssi<255){
requestOnChange(NRSSI, 0); requestOnChange(NRSSI, 0);
} }
@@ -209,9 +205,9 @@ void NetServer::requestOnChange(requestType_e request, uint8_t clientId) {
} }
case TITLE: { case TITLE: {
sprintf (buf, "{\"meta\": \"%s\"}", config.station.title); sprintf (buf, "{\"meta\": \"%s\"}", config.station.title);
if (player.requesToStart) { if (player.requestToStart) {
telnet.info(); telnet.info();
player.requesToStart = false; player.requestToStart = false;
} else { } else {
telnet.printf("##CLI.META#: %s\n> ", config.station.title); telnet.printf("##CLI.META#: %s\n> ", config.station.title);
} }

View File

@@ -10,7 +10,7 @@ enum requestType_e { PLAYLIST, STATION, ITEM, TITLE, VOLUME, NRSSI, BITRATE, MOD
class NetServer { class NetServer {
public: public:
uint8_t playlistrequest; // ClientId want the playlist uint8_t playlistrequest; // ClientId want the playlist
bool importRequest, volRequest; bool importRequest;
public: public:
NetServer() {}; NetServer() {};
bool begin(); bool begin();

View File

@@ -55,6 +55,7 @@ void Network::begin() {
status = CONNECTED; status = CONNECTED;
requestTimeSync(); requestTimeSync();
ntimer.attach_ms(TSYNC_DELAY, syncTime); ntimer.attach_ms(TSYNC_DELAY, syncTime);
if (network_on_connect) network_on_connect();
} }
void Network::requestTimeSync(bool withTelnetOutput) { void Network::requestTimeSync(bool withTelnetOutput) {

View File

@@ -24,4 +24,6 @@ class Network {
extern Network network; extern Network network;
extern __attribute__((weak)) void network_on_connect();
#endif #endif

View File

@@ -1,12 +1,12 @@
#ifndef options_h #ifndef options_h
#define options_h #define options_h
#define VERSION "0.6.012" #define VERSION "0.6.110"
/******************************************************* /*******************************************************
DO NOT EDIT THIS FILE. DO NOT EDIT THIS FILE.
ALL YOUR SETTINGS WILL BE OVERWRITTEN DURING THE UPDATE. 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") #if __has_include("myoptions.h")
@@ -202,9 +202,6 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
#ifndef MUTE_VAL #ifndef MUTE_VAL
#define MUTE_VAL HIGH // Write this to MUTE_PIN when player is stopped #define MUTE_VAL HIGH // Write this to MUTE_PIN when player is stopped
#endif #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 *** *** ST7735 display submodel ***

View File

@@ -41,7 +41,7 @@ void Player::init() {
setVolume(0); setVolume(0);
mode = STOPPED; mode = STOPPED;
setOutputPins(false); setOutputPins(false);
requesToStart = true; requestToStart = true;
zeroRequest(); zeroRequest();
} }
@@ -49,7 +49,7 @@ void Player::stopInfo() {
config.setSmartStart(0); config.setSmartStart(0);
telnet.info(); telnet.info();
netserver.requestOnChange(MODE, 0); netserver.requestOnChange(MODE, 0);
requesToStart = true; requestToStart = true;
} }
void Player::loop() { void Player::loop() {
@@ -60,7 +60,7 @@ void Player::loop() {
//digitalWrite(LED_BUILTIN, LOW); //digitalWrite(LED_BUILTIN, LOW);
setOutputPins(false); setOutputPins(false);
//display.title("[stopped]"); //display.title("[stopped]");
config.setTitle("[stopped]"); config.setTitle(display.mode==LOST?"":"[stopped]");
netserver.requestOnChange(TITLE, 0); netserver.requestOnChange(TITLE, 0);
stopSong(); stopSong();
stopInfo(); stopInfo();
@@ -75,13 +75,11 @@ void Player::loop() {
} }
if (request.volume >= 0) { if (request.volume >= 0) {
config.setVolume(request.volume, request.doSave); config.setVolume(request.volume, request.doSave);
//display.volume();
display.refreshVolume = true;
telnet.printf("##CLI.VOL#: %d\n", config.store.volume); telnet.printf("##CLI.VOL#: %d\n", config.store.volume);
Audio::setVolume(volToI2S(request.volume)); Audio::setVolume(volToI2S(request.volume));
zeroRequest(); zeroRequest();
display.volume();
} }
yield();
} }
void Player::zeroRequest() { void Player::zeroRequest() {
@@ -97,31 +95,26 @@ void Player::setOutputPins(bool isPlaying) {
void Player::play(uint16_t stationId) { void Player::play(uint16_t stationId) {
stopSong(); stopSong();
//digitalWrite(LED_BUILTIN, LOW);
setOutputPins(false); setOutputPins(false);
//display.title("[connecting]");
config.setTitle("[connecting]"); config.setTitle("[connecting]");
//display.refreshTitle = true;
netserver.requestOnChange(TITLE, 0); netserver.requestOnChange(TITLE, 0);
//telnet.printf("##CLI.META#: %s\n", config.station.title); //telnet.printf("##CLI.META#: %s\n", config.station.title);
config.loadStation(stationId); config.loadStation(stationId);
setVol(config.store.volume, true); setVol(config.store.volume, true);
//display.station(); display.station();
display.refreshStation = true;
netserver.requestOnChange(STATION, 0); netserver.requestOnChange(STATION, 0);
telnet.printf("##CLI.NAMESET#: %d %s\n", config.store.lastStation, config.station.name); telnet.printf("##CLI.NAMESET#: %d %s\n", config.store.lastStation, config.station.name);
display.loop();
if (connecttohost(config.station.url)) { if (connecttohost(config.station.url)) {
mode = PLAYING; mode = PLAYING;
config.setSmartStart(1); config.setSmartStart(1);
netserver.requestOnChange(MODE, 0); netserver.requestOnChange(MODE, 0);
//digitalWrite(LED_BUILTIN, HIGH);
setOutputPins(true); setOutputPins(true);
requesToStart = true; requestToStart = true;
}else{ }else{
Serial.println("Some Unknown Bug..."); Serial.println("some unknown bug...");
} }
zeroRequest(); display.loop();
} }
void Player::prev() { void Player::prev() {
@@ -172,15 +165,7 @@ void Player::setVol(byte volume, bool inside) {
if (inside) { if (inside) {
setVolume(volToI2S(volume)); setVolume(volToI2S(volume));
} else { } else {
#if CORE_FOR_LOOP_CONTROLS==255
request.volume = volume; request.volume = volume;
request.doSave = true; 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
} }
} }

View File

@@ -9,24 +9,22 @@
#endif #endif
enum audioMode_e { PLAYING, STOPPED }; enum audioMode_e { PLAYING, STOPPED };
struct audiorequest_t struct audiorequest_t
{ {
uint16_t station; uint16_t station;
int volume; int volume;
bool doSave; bool doSave;
}; };
class Player: public Audio { class Player: public Audio {
public: public:
audioMode_e mode; audioMode_e mode;
audiorequest_t request; audiorequest_t request;
bool requesToStart; bool requestToStart;
void zeroRequest();
public: public:
Player(); Player();
void init(); void init();
void loop(); void loop();
void zeroRequest();
void play(uint16_t stationId); void play(uint16_t stationId);
void prev(); void prev();
void next(); void next();

View File

@@ -30,7 +30,9 @@
#include <FFat.h> #include <FFat.h>
#endif // SDFATFS_USED #endif // SDFATFS_USED
#ifndef AUDIOBUFFER_MULTIPLIER
#define AUDIOBUFFER_MULTIPLIER 13 #define AUDIOBUFFER_MULTIPLIER 13
#endif
#ifdef SDFATFS_USED #ifdef SDFATFS_USED
typedef File32 File; typedef File32 File;

View File

@@ -9,7 +9,9 @@
#ifndef _vs1053_ext #ifndef _vs1053_ext
#define _vs1053_ext #define _vs1053_ext
#ifndef AUDIOBUFFER_MULTIPLIER
#define AUDIOBUFFER_MULTIPLIER 13 #define AUDIOBUFFER_MULTIPLIER 13
#endif
#define VS1053VOLM 128 // 128 or 96 only #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) #define VS1053VOL(v) (VS1053VOLM==128?log10(((float)v+1)) * 50.54571334 + 128:log10(((float)v+1)) * 64.54571334 + 96)

View File

@@ -169,7 +169,7 @@ void DspCore::printText(const char* txt) {
} }
void DspCore::loop() { void DspCore::loop(bool force) {
} }

View File

@@ -37,7 +37,7 @@ class DspCore {
void rssi(const char* str); void rssi(const char* str);
void ip(const char* str); void ip(const char* str);
void drawPlaylist(uint16_t currentItem, char* currentItemText); void drawPlaylist(uint16_t currentItem, char* currentItemText);
void loop(); void loop(bool force=false);
private: private:
uint16_t swidth, sheight; uint16_t swidth, sheight;

View File

@@ -109,7 +109,6 @@ void DspCore::apScreen() {
} }
void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) {
//begin(26000000L); /*багиловим*/
begin(); /* SPI_DEFAULT_FREQ 40000000 */ begin(); /* SPI_DEFAULT_FREQ 40000000 */
invertDisplay(TFT_INVERT); invertDisplay(TFT_INVERT);
cp437(true); cp437(true);
@@ -143,6 +142,7 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) {
} else { } else {
setTextColor(iclrs[abs(i - 4)-1], TFT_BG); setTextColor(iclrs[abs(i - 4)-1], TFT_BG);
setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT);
fillRect(0, yStart + i * PLMITEMHEIGHT-1, swidth, PLMITEMHEIGHT-4, TFT_BG);
print(utf8Rus(plMenu[i], true)); print(utf8Rus(plMenu[i], true));
} }
} }
@@ -154,8 +154,8 @@ void DspCore::clearDsp() {
void DspCore::drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg) { void DspCore::drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg) {
if (TFT_FRAMEWDT==0) return; if (TFT_FRAMEWDT==0) return;
fillRect(0, texttop, TFT_FRAMEWDT, textheight, bg);
fillRect(swidth - TFT_FRAMEWDT, 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) { 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); print(txt);
} }
void DspCore::loop() { void DspCore::loop(bool force) {
} }

View File

@@ -13,8 +13,10 @@
#define TITLE_SIZE1 2 #define TITLE_SIZE1 2
#define TITLE_SIZE2 2 #define TITLE_SIZE2 2
#if !defined(SCROLLDELTA) || !defined(SCROLLTIME)
#define SCROLLDELTA 4 #define SCROLLDELTA 4
#define SCROLLTIME 60 #define SCROLLTIME 40
#endif
#define PLMITEMS 9 #define PLMITEMS 9
#define PLMITEMLENGHT 40 #define PLMITEMLENGHT 40
@@ -53,7 +55,7 @@ class DspCore: public Adafruit_ILI9341 {
void rssi(const char* str); void rssi(const char* str);
void ip(const char* str); void ip(const char* str);
void drawPlaylist(uint16_t currentItem, char* currentItemText); void drawPlaylist(uint16_t currentItem, char* currentItemText);
void loop(); void loop(bool force=false);
private: private:
uint16_t swidth, sheight; uint16_t swidth, sheight;
char oldTimeBuf[20]; char oldTimeBuf[20];

View File

@@ -52,6 +52,7 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) {
for (byte i = 0; i < PLMITEMS; i++) { for (byte i = 0; i < PLMITEMS; i++) {
plMenu[i][0] = '\0'; plMenu[i][0] = '\0';
} }
config.fillPlMenu(plMenu, currentItem, PLMITEMS); config.fillPlMenu(plMenu, currentItem, PLMITEMS);
for (byte i = 0; i < PLMITEMS; i++) { for (byte i = 0; i < PLMITEMS; i++) {
strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1);
@@ -167,11 +168,10 @@ void DspCore::printText(const char* txt) {
setCursor(nextX, yOffset); setCursor(nextX, yOffset);
} }
void DspCore::loop() { void DspCore::loop(bool force) {
if (checkdelay(SCROLLTIME, loopdelay)) { if (checkdelay(SCROLLTIME, loopdelay)) {
//display(); //display();
} }
yield();
} }
boolean DspCore::checkdelay(int m, unsigned long & tstamp) { boolean DspCore::checkdelay(int m, unsigned long & tstamp) {

View File

@@ -20,6 +20,7 @@
#define SCROLLDELTA 1 #define SCROLLDELTA 1
#define SCROLLTIME 250 #define SCROLLTIME 250
#define BOOTSTR_TOP2 0 #define BOOTSTR_TOP2 0
#define BOOTSTR_TOP1 1 #define BOOTSTR_TOP1 1
#define STARTTIME_PL 2000 #define STARTTIME_PL 2000
@@ -57,7 +58,7 @@ class DspCore: public LiquidCrystal {
void rssi(const char* str); void rssi(const char* str);
void ip(const char* str); void ip(const char* str);
void drawPlaylist(uint16_t currentItem, char* currentItemText); void drawPlaylist(uint16_t currentItem, char* currentItemText);
void loop(); void loop(bool force=false);
private: private:
uint16_t swidth, sheight, xOffset, yOffset; uint16_t swidth, sheight, xOffset, yOffset;
int16_t nextX; int16_t nextX;

View File

@@ -153,6 +153,7 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) {
strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1);
} else { } else {
setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT);
fillRect(0, yStart + i * PLMITEMHEIGHT, swidth, PLMITEMHEIGHT - 1, TFT_BG);
print(utf8Rus(plMenu[i], true)); print(utf8Rus(plMenu[i], true));
} }
} }
@@ -309,11 +310,10 @@ void DspCore::printText(const char* txt) {
print(txt); print(txt);
} }
void DspCore::loop() { void DspCore::loop(bool force) {
if (checkdelay(83, loopdelay)) { if (checkdelay(SCROLLTIME, loopdelay) || force) {
display(); display();
} }
yield();
} }
boolean DspCore::checkdelay(int m, unsigned long &tstamp) { boolean DspCore::checkdelay(int m, unsigned long &tstamp) {

View File

@@ -11,8 +11,13 @@
#define TFT_LINEHGHT 8 #define TFT_LINEHGHT 8
#define TFT_FRAMEWDT 0 #define TFT_FRAMEWDT 0
#define SCROLLDELTA 8 #if !defined(SCROLLDELTA) || !defined(SCROLLTIME)
#define SCROLLTIME 332 //#define SCROLLDELTA 8
//#define SCROLLTIME 332
#define SCROLLDELTA 4
#define SCROLLTIME 250
#endif
#define META_SIZE 1 #define META_SIZE 1
#define TITLE_TOP1 TFT_FRAMEWDT + TFT_LINEHGHT+1 #define TITLE_TOP1 TFT_FRAMEWDT + TFT_LINEHGHT+1
#define TITLE_SIZE2 0 #define TITLE_SIZE2 0
@@ -50,7 +55,7 @@ class DspCore: public Adafruit_PCD8544 {
void rssi(const char* str); void rssi(const char* str);
void ip(const char* str); void ip(const char* str);
void drawPlaylist(uint16_t currentItem, char* currentItemText); void drawPlaylist(uint16_t currentItem, char* currentItemText);
void loop(); void loop(bool force=false);
private: private:
uint16_t swidth, sheight; uint16_t swidth, sheight;
unsigned long loopdelay; unsigned long loopdelay;

View File

@@ -14,6 +14,10 @@
#define LOGO_WIDTH 21 #define LOGO_WIDTH 21
#define LOGO_HEIGHT 32 #define LOGO_HEIGHT 32
#ifndef I2CFREQ_HZ
#define I2CFREQ_HZ 4000000UL
#endif
const char *dow[7] = {"вс","пн","вт","ср","чт","пт","сб"}; const char *dow[7] = {"вс","пн","вт","ср","чт","пт","сб"};
const unsigned char logo [] PROGMEM= const unsigned char logo [] PROGMEM=
@@ -30,7 +34,7 @@ const unsigned char logo [] PROGMEM=
TwoWire I2CSH1106 = TwoWire(0); TwoWire I2CSH1106 = TwoWire(0);
#if DSP_MODEL==DSP_SH1106 #if DSP_MODEL==DSP_SH1106
DspCore::DspCore(): Adafruit_SH1106G(128, 64, &I2CSH1106, -1) { DspCore::DspCore(): Adafruit_SH1106G(128, 64, &I2CSH1106, -1, I2CFREQ_HZ) {
} }
#else #else
@@ -177,9 +181,11 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) {
strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1);
} else { } else {
setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT);
fillRect(0, yStart + i * PLMITEMHEIGHT, swidth, PLMITEMHEIGHT - 1, TFT_BG);
print(utf8Rus(plMenu[i], true)); print(utf8Rus(plMenu[i], true));
} }
} }
display();
} }
void DspCore::clearDsp() { 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); setCursor((swidth - w) / 2, y);
fillRect(0, y, swidth, h, bg); fillRect(0, y, swidth, h, bg);
print(txt); print(txt);
display();
} }
void DspCore::rightText(const char* text, byte y, uint16_t fg, uint16_t bg) { 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 }; char timeStringBuff[20] = { 0 };
strftime(timeStringBuff, sizeof(timeStringBuff), "%H:%M", &timeinfo); strftime(timeStringBuff, sizeof(timeStringBuff), "%H:%M", &timeinfo);
setTextSize(2); setTextSize(2);
setCursor(CLCLF, 34); setCursor(CLCLF, (DSP_MODEL==DSP_SH1107)?30:34);
setTextColor(TFT_FG, TFT_BG); setTextColor(TFT_FG, TFT_BG);
print(timeStringBuff); print(timeStringBuff);
setTextSize(1); 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); sprintf(timeStringBuff, "%02d", timeinfo.tm_sec);
print(timeStringBuff); print(timeStringBuff);
display();
} }
void DspCore::drawVolumeBar(bool withNumber) { void DspCore::drawVolumeBar(bool withNumber) {
@@ -270,10 +278,11 @@ void DspCore::drawVolumeBar(bool withNumber) {
int16_t x1, y1; int16_t x1, y1;
sprintf(volstr, "%d", config.store.volume); sprintf(volstr, "%d", config.store.volume);
getTextBounds(volstr, 0, 0, &x1, &y1, &wv, &hv); 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); setCursor((swidth - wv) / 2, 24);
print(volstr); print(volstr);
} }
display();
} }
void DspCore::drawNextStationNum(uint16_t num) { 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); fillRect(TFT_FRAMEWDT, 24, swidth - TFT_FRAMEWDT / 2, hv + 3, TFT_BG);
setCursor((swidth - wv) / 2, 24); setCursor((swidth - wv) / 2, 24);
print(numstr); print(numstr);
display();
} }
void DspCore::frameTitle(const char* str) { 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) { void DspCore::printText(const char* txt) {
print(txt); print(txt);
}
void DspCore::loop() {
if (checkdelay(SCROLLTIME, loopdelay)) {
display(); display();
} }
yield();
void DspCore::loop(bool force) {
if (checkdelay(SCROLLTIME, loopdelay) || force) {
//display();
}
} }
boolean DspCore::checkdelay(int m, unsigned long &tstamp) { boolean DspCore::checkdelay(int m, unsigned long &tstamp) {

View File

@@ -14,8 +14,15 @@
#define TITLE_TOP2 TFT_FRAMEWDT + 3 * TFT_LINEHGHT #define TITLE_TOP2 TFT_FRAMEWDT + 3 * TFT_LINEHGHT
#define PLCURRENT_SIZE 1 #define PLCURRENT_SIZE 1
#define TFT_FULLTIME 1 #define TFT_FULLTIME 1
#if DSP_MODEL==DSP_SH1107
#define TITLE_SIZE2 0
#endif
#if !defined(SCROLLDELTA) || !defined(SCROLLTIME)
#define SCROLLDELTA 3 #define SCROLLDELTA 3
#define SCROLLTIME 83 #define SCROLLTIME 60
#endif
#if DSP_MODEL==DSP_SH1106 #if DSP_MODEL==DSP_SH1106
class DspCore: public Adafruit_SH1106G { class DspCore: public Adafruit_SH1106G {
@@ -49,7 +56,7 @@ class DspCore: public Adafruit_SH1107 {
void rssi(const char* str); void rssi(const char* str);
void ip(const char* str); void ip(const char* str);
void drawPlaylist(uint16_t currentItem, char* currentItemText); void drawPlaylist(uint16_t currentItem, char* currentItemText);
void loop(); void loop(bool force=false);
private: private:
uint16_t swidth, sheight; uint16_t swidth, sheight;
unsigned long loopdelay; unsigned long loopdelay;

View File

@@ -13,6 +13,10 @@
#define LOGO_WIDTH 21 #define LOGO_WIDTH 21
#define LOGO_HEIGHT 32 #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 char *dow[7] = {"вс","пн","вт","ср","чт","пт","сб"};
const unsigned char logo [] PROGMEM= 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 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); strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1);
} else { } else {
setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT);
fillRect(0, yStart + i * PLMITEMHEIGHT, swidth, PLMITEMHEIGHT - 1, TFT_BG);
print(utf8Rus(plMenu[i], true)); print(utf8Rus(plMenu[i], true));
} }
} }
@@ -303,11 +308,10 @@ void DspCore::printText(const char* txt) {
print(txt); print(txt);
} }
void DspCore::loop() { void DspCore::loop(bool force) {
if (checkdelay(FPS, loopdelay)) { if (checkdelay(SCROLLTIME, loopdelay) || force) {
display(); display();
} }
yield();
} }
boolean DspCore::checkdelay(int m, unsigned long &tstamp) { boolean DspCore::checkdelay(int m, unsigned long &tstamp) {

View File

@@ -16,9 +16,11 @@
#define TITLE_TOP2 TFT_FRAMEWDT + 2 * TFT_LINEHGHT #define TITLE_TOP2 TFT_FRAMEWDT + 2 * TFT_LINEHGHT
#define PLCURRENT_SIZE 1 #define PLCURRENT_SIZE 1
#define TFT_FULLTIME 1 #define TFT_FULLTIME 1
#if !defined(SCROLLDELTA) || !defined(SCROLLTIME)
#define SCROLLDELTA 3 #define SCROLLDELTA 3
#define SCROLLTIME 83 #define SCROLLTIME 83
#define FPS 50 #endif
class DspCore: public Adafruit_SSD1305 { class DspCore: public Adafruit_SSD1305 {
public: public:
@@ -48,7 +50,7 @@ class DspCore: public Adafruit_SSD1305 {
void rssi(const char* str); void rssi(const char* str);
void ip(const char* str); void ip(const char* str);
void drawPlaylist(uint16_t currentItem, char* currentItemText); void drawPlaylist(uint16_t currentItem, char* currentItemText);
void loop(); void loop(bool force=false);
private: private:
uint16_t swidth, sheight; uint16_t swidth, sheight;
unsigned long loopdelay; unsigned long loopdelay;

View File

@@ -15,6 +15,7 @@
#define LOGO_WIDTH 21 #define LOGO_WIDTH 21
#define LOGO_HEIGHT 32 #define LOGO_HEIGHT 32
const unsigned char logo [] PROGMEM= const unsigned char logo [] PROGMEM=
{ {
0x06, 0x03, 0x00, 0x0f, 0x07, 0x80, 0x1f, 0x8f, 0xc0, 0x1f, 0x8f, 0xc0, 0x06, 0x03, 0x00, 0x0f, 0x07, 0x80, 0x1f, 0x8f, 0xc0, 0x1f, 0x8f, 0xc0,
@@ -28,9 +29,13 @@ const unsigned char logo [] PROGMEM=
}; };
#endif #endif
#ifndef I2CFREQ_HZ
#define I2CFREQ_HZ 4000000UL
#endif
TwoWire I2CSSD1306 = TwoWire(0); 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); strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1);
} else { } else {
setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT);
fillRect(0, yStart + i * PLMITEMHEIGHT, swidth, PLMITEMHEIGHT - 1, TFT_BG);
print(utf8Rus(plMenu[i], true)); print(utf8Rus(plMenu[i], true));
} }
} }
@@ -330,8 +336,8 @@ void DspCore::printText(const char* txt) {
print(txt); print(txt);
} }
void DspCore::loop() { void DspCore::loop(bool force) {
if (checkdelay(83, loopdelay)) { if (checkdelay(83, loopdelay) || force) {
#if DSP_MODEL==DSP_SSD1306x32 #if DSP_MODEL==DSP_SSD1306x32
if(fillSpaces) printClock(insideClc); if(fillSpaces) printClock(insideClc);
#endif #endif

View File

@@ -9,6 +9,11 @@
#define TFT_FRAMEWDT 0 #define TFT_FRAMEWDT 0
#define PLMITEMLENGHT 40 #define PLMITEMLENGHT 40
#if !defined(SCROLLDELTA) || !defined(SCROLLTIME)
#define SCROLLDELTA 2
#define SCROLLTIME 40
#endif
#if DSP_MODEL==DSP_SSD1306 #if DSP_MODEL==DSP_SSD1306
#define PLMITEMS 5 #define PLMITEMS 5
@@ -65,7 +70,7 @@ class DspCore: public Adafruit_SSD1306 {
void rssi(const char* str); void rssi(const char* str);
void ip(const char* str); void ip(const char* str);
void drawPlaylist(uint16_t currentItem, char* currentItemText); void drawPlaylist(uint16_t currentItem, char* currentItemText);
void loop(); void loop(bool force=false);
private: private:
uint16_t swidth, sheight; uint16_t swidth, sheight;
unsigned long loopdelay; unsigned long loopdelay;

View File

@@ -14,7 +14,7 @@
#ifndef I2CFREQ_HZ #ifndef I2CFREQ_HZ
#define I2CFREQ_HZ 4000000UL #define I2CFREQ_HZ 6000000UL
#endif #endif
TwoWire tw = TwoWire(0); TwoWire tw = TwoWire(0);
@@ -155,10 +155,11 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) {
strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1);
} else { } else {
setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT);
fillRect(0, yStart + i * PLMITEMHEIGHT - 1, swidth, PLMITEMHEIGHT - 4, TFT_BG);
print(utf8Rus(plMenu[i], true)); print(utf8Rus(plMenu[i], true));
} }
} }
//display(); display();
} }
void DspCore::clearDsp() { 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); setCursor((swidth - w) / 2, y);
fillRect(0, y, swidth, h, bg); fillRect(0, y, swidth, h, bg);
print(txt); print(txt);
display();
} }
void DspCore::rightText(const char* text, byte y, uint16_t fg, uint16_t bg) { 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); setCursor(swidth - w - TFT_FRAMEWDT, y);
fillRect(swidth - w - TFT_FRAMEWDT, y, w, h, bg); fillRect(swidth - w - TFT_FRAMEWDT, y, w, h, bg);
print(text); print(text);
display(); //display();
} }
void DspCore::displayHeapForDebug() { void DspCore::displayHeapForDebug() {
@@ -242,6 +244,7 @@ void DspCore::printClock(const char* timestr) {
} }
void DspCore::drawVolumeBar(bool withNumber) { 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 vTop = sheight - TFT_FRAMEWDT * 2;
int16_t vWidth = swidth - TFT_FRAMEWDT - 4; int16_t vWidth = swidth - TFT_FRAMEWDT - 4;
uint8_t ww = map(config.store.volume, 0, 254, 0, vWidth - 2); 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); drawRect(TFT_FRAMEWDT, vTop - 2, vWidth, 6, TFT_LOGO);
fillRect(TFT_FRAMEWDT + 1, vTop - 1, ww, 5, TFT_LOGO); fillRect(TFT_FRAMEWDT + 1, vTop - 1, ww, 5, TFT_LOGO);
if (withNumber) { if (withNumber) {
setTextSize(1); setTextSize(1);
setTextColor(TFT_FG); setTextColor(TFT_FG);
setFont(&DS_DIGI28pt7b); setFont(&DS_DIGI28pt7b);
@@ -258,11 +262,12 @@ void DspCore::drawVolumeBar(bool withNumber) {
sprintf(volstr, "%d", config.store.volume); sprintf(volstr, "%d", config.store.volume);
getTextBounds(volstr, 0, 0, &x1, &y1, &wv, &hv); getTextBounds(volstr, 0, 0, &x1, &y1, &wv, &hv);
fillRect(TFT_FRAMEWDT, 48, swidth - TFT_FRAMEWDT / 2, hv + 3, TFT_BG); 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); setCursor((swidth - wv) / 2, 48 + hv);
print(volstr); print(volstr);
setFont(); setFont();
display();
} }
display();
} }
void DspCore::drawNextStationNum(uint16_t num) { void DspCore::drawNextStationNum(uint16_t num) {
@@ -278,11 +283,13 @@ void DspCore::drawNextStationNum(uint16_t num) {
setCursor((swidth - wv) / 2, 48 + hv); setCursor((swidth - wv) / 2, 48 + hv);
print(numstr); print(numstr);
setFont(); setFont();
display();
} }
void DspCore::frameTitle(const char* str) { void DspCore::frameTitle(const char* str) {
setTextSize(2); setTextSize(2);
centerText(str, TFT_FRAMEWDT, TFT_LOGO, TFT_BG); centerText(str, TFT_FRAMEWDT, TFT_LOGO, TFT_BG);
//display();
} }
void DspCore::rssi(const char* str) { 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) { void DspCore::printText(const char* txt) {
print(txt); print(txt);
display();
} }
void DspCore::loop() { void DspCore::loop(bool force) {
if (checkdelay(LOOP_DELAY, loopdelay)) { if (checkdelay(LOOP_DELAY, loopdelay) || force) {
display(); //display();
} }
yield(); yield();
} }

View File

@@ -13,10 +13,27 @@
#define PLMITEMLENGHT 40 #define PLMITEMLENGHT 40
#define PLMITEMHEIGHT 22 #define PLMITEMHEIGHT 22
#define TITLE_TOP2 TFT_FRAMEWDT + 3 * TFT_LINEHGHT #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 SCROLLDELTA 4
#define SCROLLTIME 83 #define SCROLLTIME 83
#define LOOP_DELAY 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 { class DspCore: public Adafruit_SSD1327 {
public: public:
@@ -46,7 +63,7 @@ class DspCore: public Adafruit_SSD1327 {
void rssi(const char* str); void rssi(const char* str);
void ip(const char* str); void ip(const char* str);
void drawPlaylist(uint16_t currentItem, char* currentItemText); void drawPlaylist(uint16_t currentItem, char* currentItemText);
void loop(); void loop(bool force=false);
private: private:
uint16_t swidth, sheight; uint16_t swidth, sheight;
int16_t x, y; int16_t x, y;
@@ -60,12 +77,18 @@ class DspCore: public Adafruit_SSD1327 {
extern DspCore dsp; extern DspCore dsp;
/*
SSD1327_GRAYTABLE,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x10, 0x18, 0x20, 0x2f, 0x38, 0x3f,
*/
/* /*
* TFT COLORS * TFT COLORS
*/ */
#define SILVER 0x7 #define SILVER 0x07
#define TFT_BG 0x0 #define TFT_BG 0x00
#define TFT_FG 0x8 #define TFT_FG 0x08
#define TFT_LOGO 0xF #define TFT_LOGO 0x3f
#endif #endif

View File

@@ -8,42 +8,6 @@
#include "../../config.h" #include "../../config.h"
#include "../../network.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) { 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(); screenheight = height();
swidth = screenwidth; swidth = screenwidth;
sheight = screenheight; sheight = screenheight;
gclock.init(dsp, &DS_DIGI28pt7b, TFT_LOGO, BLACK); setClockBounds();
} }
void DspCore::drawLogo() { void DspCore::drawLogo() {
@@ -178,6 +142,7 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) {
strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1);
} else { } else {
setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT);
fillRect(0, yStart + i * PLMITEMHEIGHT - 1, swidth, PLMITEMHEIGHT - 4, TFT_BG);
print(utf8Rus(plMenu[i], true)); print(utf8Rus(plMenu[i], true));
} }
} }
@@ -248,8 +213,67 @@ void DspCore::displayHeapForDebug() {
#endif #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) { 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) { void DspCore::drawVolumeBar(bool withNumber) {
@@ -325,7 +349,7 @@ void DspCore::printText(const char* txt) {
print(txt); print(txt);
} }
void DspCore::loop() { void DspCore::loop(bool force) {
} }

View File

@@ -15,8 +15,12 @@
#define TITLE_TOP2 TFT_FRAMEWDT + 3 * TFT_LINEHGHT #define TITLE_TOP2 TFT_FRAMEWDT + 3 * TFT_LINEHGHT
#define TITLE_FG2 SILVER #define TITLE_FG2 SILVER
#if !defined(SCROLLDELTA) || !defined(SCROLLTIME)
#define SCROLLDELTA 3 #define SCROLLDELTA 3
#define SCROLLTIME 67 #define SCROLLTIME 65
#endif
#define TFT_FULLTIME 1
class DspCore: public Adafruit_ST7735 { class DspCore: public Adafruit_ST7735 {
public: public:
@@ -34,6 +38,7 @@ class DspCore: public Adafruit_ST7735 {
void set_Cursor(int16_t x, int16_t y); void set_Cursor(int16_t x, int16_t y);
void printText(const char* txt); void printText(const char* txt);
void printClock(const char* timestr); void printClock(const char* timestr);
void printClock(struct tm timeinfo, bool dots, bool redraw = false);
void displayHeapForDebug(); void displayHeapForDebug();
void drawVolumeBar(bool withNumber); void drawVolumeBar(bool withNumber);
void drawNextStationNum(uint16_t num); void drawNextStationNum(uint16_t num);
@@ -45,10 +50,15 @@ class DspCore: public Adafruit_ST7735 {
void rssi(const char* str); void rssi(const char* str);
void ip(const char* str); void ip(const char* str);
void drawPlaylist(uint16_t currentItem, char* currentItemText); void drawPlaylist(uint16_t currentItem, char* currentItemText);
void loop(); void loop(bool force=false);
private: private:
uint16_t swidth, sheight; 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; extern DspCore dsp;

View File

@@ -140,16 +140,17 @@ void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) {
config.fillPlMenu(plMenu, currentItem - 4, PLMITEMS); config.fillPlMenu(plMenu, currentItem - 4, PLMITEMS);
setTextSize(2); setTextSize(2);
int yStart = (sheight / 2 - PLMITEMHEIGHT / 2) - PLMITEMHEIGHT * (PLMITEMS - 1) / 2 + 3; 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++) { for (byte i = 0; i < PLMITEMS; i++) {
if (i == 4) { if (i == 4) {
//fillRect(0, (sheight / 2 - PLMITEMHEIGHT / 2) - 1, swidth, PLMITEMHEIGHT + 2, TFT_LOGO);
strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1); strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1);
} else { } else {
setTextColor(iclrs[abs(i - 4)-1], TFT_BG); setTextColor(iclrs[abs(i - 4)-1], TFT_BG);
setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT); setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT);
fillRect(0, yStart + i * PLMITEMHEIGHT - 1, swidth, PLMITEMHEIGHT - 2, TFT_BG);
print(utf8Rus(plMenu[i], true)); 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) { void DspCore::drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg) {
if (TFT_FRAMEWDT==0) return; if (TFT_FRAMEWDT==0) return;
fillRect(0, texttop, TFT_FRAMEWDT, textheight, bg);
fillRect(swidth - TFT_FRAMEWDT, 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) { 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) { 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(); yield();
} }
@@ -364,10 +364,9 @@ void DspCore::set_Cursor(int16_t x, int16_t y) {
void DspCore::printText(const char* txt) { void DspCore::printText(const char* txt) {
print(txt); print(txt);
yield();
} }
void DspCore::loop() { void DspCore::loop(bool force) {
} }

View File

@@ -13,8 +13,10 @@
#define TITLE_SIZE1 2 #define TITLE_SIZE1 2
#define TITLE_SIZE2 2 #define TITLE_SIZE2 2
#define SCROLLDELTA 6 #if !defined(SCROLLDELTA) || !defined(SCROLLTIME)
#define SCROLLTIME 83 #define SCROLLDELTA 5
#define SCROLLTIME 50
#endif
#define PLMITEMS 9 #define PLMITEMS 9
#define PLMITEMLENGHT 40 #define PLMITEMLENGHT 40
@@ -53,7 +55,7 @@ class DspCore: public Adafruit_ST7789 {
void rssi(const char* str); void rssi(const char* str);
void ip(const char* str); void ip(const char* str);
void drawPlaylist(uint16_t currentItem, char* currentItemText); void drawPlaylist(uint16_t currentItem, char* currentItemText);
void loop(); void loop(bool force=false);
private: private:
uint16_t swidth, sheight; uint16_t swidth, sheight;
char oldTimeBuf[20]; char oldTimeBuf[20];

View File

@@ -11,17 +11,9 @@
#include "controls.h" #include "controls.h"
#include "mqtt.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() { void setup() {
Serial.begin(115200); Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
//digitalWrite(LED_BUILTIN, LOW);
config.init(); config.init();
display.init(); display.init();
player.init(); player.init();
@@ -34,57 +26,22 @@ void setup() {
netserver.begin(); netserver.begin();
telnet.begin(); telnet.begin();
player.setVol(config.store.volume, true); player.setVol(config.store.volume, true);
if(CORE_FOR_LOOP_CONTROLS == 255){
initControls(); initControls();
display.start(); display.start();
}
#ifdef MQTT_HOST #ifdef MQTT_HOST
mqttInit(); mqttInit();
#endif #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 (config.store.smartstart == 1) player.play(config.store.lastStation);
} }
#if CORE_FOR_LOOP_CONTROLS != 255
void setupCore0(){
initControls();
display.start();
}
void loopCore0( void * pvParameters ){
setupCore0();
for(;;){
micros();
if (network.status == CONNECTED) {
loopControls();
}
display.loop();
vTaskDelay(10);
}
}
#endif
void loop() { void loop() {
if (network.status == CONNECTED) { if (network.status == CONNECTED) {
telnet.loop(); telnet.loop();
player.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(); netserver.loop();
} }