diff --git a/include/TEF6686.h b/include/TEF6686.h index 4944a30..3aaf952 100644 --- a/include/TEF6686.h +++ b/include/TEF6686.h @@ -21,7 +21,6 @@ enum RDS_GROUPS { // Fixed PI/callsign combinations for Canada static const uint16_t fixedPI[] = {0x4C10, 0x4C11, 0x4C12}; -static const char* fixedCalls[] = {"CBLA", "CBFM", "CBOT"}; static const char* const PTY_EU[] { "None", @@ -433,11 +432,9 @@ const DABFrequencyLabel DABfrequencyTable[] = { {1490624, "LW"} }; -#pragma GCC diagnostic pop - typedef struct _rds_ { byte region; - byte stationTypeCode; + byte PTY; String stationName; String stationText; String stationText32; @@ -480,7 +477,7 @@ typedef struct _rds_ { bool hasLongPS; bool hasRT; bool hasEnhancedRT; - bool hasTP; + bool TP; bool hasTA; bool hasEON; bool hasAID; @@ -490,7 +487,7 @@ typedef struct _rds_ { bool hasPTYN; bool rtAB; bool rtAB32; - bool hasRDSplus; + bool hasRTplus; bool filter; bool rdsreset; bool pierrors; @@ -590,7 +587,7 @@ class TEF6686 { uint8_t af_counter; uint8_t eon_counter; uint8_t logbook_counter; - uint8_t rdsblock; + uint8_t rdsgroup; unsigned long processed_rdsblocks; bool mute; bool afmethodB; diff --git a/include/WC_AP_HTML.h b/include/WC_AP_HTML.h index ceabd50..dd4769e 100644 --- a/include/WC_AP_HTML.h +++ b/include/WC_AP_HTML.h @@ -8,15 +8,15 @@ * GNU General Public License v3.0 licence, all text here must be included in any redistribution and you should receive a copy of the license file. * */ - + #ifndef WC_AP_HTML #define WC_AP_HTML ///< Define to stop re-inclusion /*! \def char AP_HTTP_HEAD[] PROGMEM Start of HTML output */ const char AP_HTTP_HEAD[] PROGMEM = "{v}"; -/*! \def AP_HTTP_STYLE[] PROGMEM -Style for our access point +/*! \def AP_HTTP_STYLE[] PROGMEM +Style for our access point */ const char AP_HTTP_STYLE[] PROGMEM = ""; /** Scripts for our page */ @@ -40,18 +40,18 @@ const char AP_HTTP_SCAN_LINK[] PROGMEM = "
-function doPing() { +function doPing() { //if ( timeout_count > 20 ) { if ( attempt_count > 20 ) { // wait about a minute window.clearInterval(myPinger), document.getElementById("conn_ok").style.display = "block" } - + var o = new XMLHttpRequest; o.onload = function() { console.log(this.responseText), document.getElementById("conn_fail").style.display = "block", window.clearInterval(myPinger) @@ -59,7 +59,7 @@ function doPing() { console.log("Timeout Counter is: " + timeout_count++) }, o.open("GET", "/foo"), o.timeout = 1000, o.send(null), console.log("Ping counter is: " + attempt_count++) } - + attempt_count = 0; timeout_count = 0; var myPinger = window.setInterval(doPing, 3000); diff --git a/include/constants.h b/include/constants.h index 5f9617d..84ea4dd 100644 --- a/include/constants.h +++ b/include/constants.h @@ -1,10 +1,5 @@ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" +#define VERSION "v2.20.5b" -#define VERSION "v2.20.5" - -#define ON 1 -#define OFF 0 #define REVERSE false #define ALEFT -1 @@ -362,13 +357,6 @@ #endif // End of EEPROM index defines -static const char* const unitString[] = {"dBμV", "dBf", "dBm"}; -static const char* const FreqFont[] = {"Classic", "Roubenstil", "Motoya", "Aura2", "Modern"}; -static const char* const Theme[] = {"Essence", "Cyan", "Crimson", "Monochrome", "Volcano", "Dendro", "Sakura", "Whiteout", "Tangerine", "Ocean", "Indigo", "Queer", "GoldBrite", "Bubblegum"}; -static const char* const Skin[] = {"Essential"}; -static const char* BWButtonLabelsFM[] = {"56 kHz", "64 kHz", "72 kHz", "84 kHz", "97 kHz", "114 kHz", "133 kHz", "151 kHz", "168 kHz", "184 kHz", "200 kHz", "217 kHz", "236 kHz", "254 kHz", "287 kHz", "311 kHz", "Auto", "iMS", "EQ"}; -static const char* BWButtonLabelsAM[] = {"3 kHz", "4 kHz", "6 kHz", "8 kHz"}; - // Memory channel database typedef struct { byte bw; @@ -383,24 +371,21 @@ enum LONGBANDBUTTONPRESS { STANDBY = 0, SCREENOFF }; -enum menupage {INDEX, MAINSETTINGS, AUDIOSETTINGS, DISPLAYSETTINGS, RDSSETTINGS, FMSETTINGS, AMSETTINGS, CONNECTIVITY, DXMODE, AUTOMEM - }; +enum menupage {INDEX, MAINSETTINGS, AUDIOSETTINGS, DISPLAYSETTINGS, RDSSETTINGS, FMSETTINGS, AMSETTINGS, CONNECTIVITY, DXMODE, AUTOMEM}; enum AUTOMEMPIMODES { MEMPI_OFF = 0, MEMPI_RANGE, MEMPI_FULL }; enum SCAN_CANCEL { - SCAN_CANCEL = OFF, CORRECTPI, SIGNAL + SCAN_CANCEL = 0, CORRECTPI, SIGNAL }; -// FM band: before BAND_GAP; AM band: after BAND_GAP enum RADIO_BAND { BAND_OIRT = 0, BAND_FM, BAND_GAP, BAND_LW, BAND_MW, BAND_SW, BAND_AIR }; #ifndef HAS_AIR_BAND -// Toggle: LW -> MW -> SW enum RADIO_AM_BAND_SELECTION { AM_BAND_ALL = 0, AM_BAND_LW_MW, AM_BAND_LW_SW, AM_BAND_MW_SW, AM_BAND_LW, AM_BAND_MW, AM_BAND_SW, AM_BAND_NONE, @@ -417,9 +402,8 @@ enum RADIO_AM_BAND_SELECTION { AM_BAND_LW, AM_BAND_MW, AM_BAND_SW, AM_BAND_AIR, AM_BAND_NONE, AM_BAND_CNT }; -#endif /* end of HAS_AIR_BAND */ +#endif -// Toggle: OIRT -> FM enum RADIO_FM_BAND_SELECTION { FM_BAND_ALL = 0, FM_BAND_OIRT, FM_BAND_FM, FM_BAND_NONE, FM_BAND_CNT @@ -792,6 +776,4 @@ static const uint16_t openradiologo[] PROGMEM = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbdf7, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0x39c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x42e6, 0x76ef, 0xa6cf, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x7ecf, 0x5be9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xce59, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xef5d, 0x3186, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc618, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x9492, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5367, 0x76ef, 0x9e6e, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x1962, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x31a6, 0xef7d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xef5d, 0x4228, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad75, 0xf7be, 0xffff, 0xffff, 0xffff, 0xffff, 0xef7d, 0x94b2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2183, 0x5be8, 0x76ef, 0x95ed, 0x9e8f, 0xa6ef, 0xa730, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0x76ef, 0xa730, 0xa6f0, 0x9e8f, 0x962e, 0x76ef, 0x76ef, 0x3aa5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4208, 0xd6ba, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd6ba, 0x2965, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -}; - -#pragma GCC diagnostic pop \ No newline at end of file +}; \ No newline at end of file diff --git a/include/gui.h b/include/gui.h index 6f122d8..dc60d0f 100644 --- a/include/gui.h +++ b/include/gui.h @@ -8,6 +8,13 @@ #include "WiFiConnectParam.h" #include "menugraphics.h" +static const char* const unitString[] = {"dBμV", "dBf", "dBm"}; +static const char* const FreqFont[] = {"Classic", "Roubenstil", "Motoya", "Aura2", "Modern"}; +static const char* const Theme[] = {"Essence", "Cyan", "Crimson", "Monochrome", "Volcano", "Dendro", "Sakura", "Whiteout", "Tangerine", "Ocean", "Indigo", "Queer", "GoldBrite", "Bubblegum"}; +static const char* const Skin[] = {"Essential"}; +static const char* BWButtonLabelsFM[] = {"56 kHz", "64 kHz", "72 kHz", "84 kHz", "97 kHz", "114 kHz", "133 kHz", "151 kHz", "168 kHz", "184 kHz", "200 kHz", "217 kHz", "236 kHz", "254 kHz", "287 kHz", "311 kHz", "Auto", "iMS", "EQ"}; +static const char* BWButtonLabelsAM[] = {"3 kHz", "4 kHz", "6 kHz", "8 kHz"}; + #define SMETERPIN 27 #define CONTRASTPIN 2 diff --git a/lib/Hash/library.json b/lib/Hash/library.json new file mode 100644 index 0000000..4935181 --- /dev/null +++ b/lib/Hash/library.json @@ -0,0 +1,17 @@ +{ + "name": "Hash", + "version": "1.0", + "description": "Generate Hash from data", + "authors": + [ + { + "name": "Markus Sattler", + "maintainer": true + } + ], + "frameworks": "arduino", + "platforms": "espressif8266, espressif32", + "build": { + "flags": ["-Wno-unused-function"] + } +} diff --git a/lib/TFT_eSPI/Processors/TFT_eSPI_ESP32.c b/lib/TFT_eSPI/Processors/TFT_eSPI_ESP32.c index faf3034..d3c3865 100644 --- a/lib/TFT_eSPI/Processors/TFT_eSPI_ESP32.c +++ b/lib/TFT_eSPI/Processors/TFT_eSPI_ESP32.c @@ -793,12 +793,10 @@ bool TFT_eSPI::initDMA(bool ctrl_cs) .sclk_io_num = TFT_SCLK, .quadwp_io_num = -1, .quadhd_io_num = -1, - #ifdef xCONFIG_IDF_TARGET_ESP32S2 - .data4_io_num = -1, - .data5_io_num = -1, - .data6_io_num = -1, - .data7_io_num = -1, - #endif + .data4_io_num = -1, + .data5_io_num = -1, + .data6_io_num = -1, + .data7_io_num = -1, .max_transfer_sz = TFT_WIDTH * TFT_HEIGHT * 2 + 8, // TFT screen size .flags = 0, .intr_flags = 0 diff --git a/platformio.ini b/platformio.ini index 940e1e0..8783d3e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,3 +13,7 @@ platform = espressif32 board = esp32dev framework = arduino board_build.partitions = huge_app.csv +build_flags = + -Wall + -Wextra + -Wno-unknown-pragmas \ No newline at end of file diff --git a/src/TEF6686.cpp b/src/TEF6686.cpp index 6a471cb..94a4143 100644 --- a/src/TEF6686.cpp +++ b/src/TEF6686.cpp @@ -159,7 +159,7 @@ void TEF6686::init(byte TEF) { void TEF6686::getIdentification(uint16_t *device, uint16_t *hw_version, uint16_t *sw_version) { uint8_t buf[6]; - uint16_t r = devTEF_Get_Cmd(TEF_APPL, Cmd_Get_Identification, buf, sizeof(buf)); + devTEF_Get_Cmd(TEF_APPL, Cmd_Get_Identification, buf, sizeof(buf)); *device = Convert8bto16b(buf); *hw_version = Convert8bto16b(buf + 2); @@ -363,10 +363,8 @@ void TEF6686::getStatusAM(int16_t &level, uint16_t &noise, uint16_t &cochannel, } void TEF6686::readRDS(byte showrdserrors) { - uint8_t offset; - if (rds.filter && ps_process) { - devTEF_Radio_Get_RDS_Status(&rds.rdsStat, &rds.rdsA, &rds.rdsB, &rds.rdsC, &rds.rdsD, &rds.rdsErr); - } else { + if (rds.filter && ps_process) devTEF_Radio_Get_RDS_Status(&rds.rdsStat, &rds.rdsA, &rds.rdsB, &rds.rdsC, &rds.rdsD, &rds.rdsErr); + else { if (millis() >= rdstimer + 87) { rdstimer += 87; devTEF_Radio_Get_RDS_Data(&rds.rdsStat, &rds.rdsA, &rds.rdsB, &rds.rdsC, &rds.rdsD, &rds.rdsErr); @@ -378,14 +376,11 @@ void TEF6686::readRDS(byte showrdserrors) { } if (bitRead(rds.rdsStat, 9)) { - rds.hasRDS = true; // RDS decoder synchronized and data available + rds.hasRDS = true; bitStartTime = 0; } else { - if (bitStartTime == 0) { - bitStartTime = millis(); - } else if (millis() - bitStartTime >= 87) { - rds.hasRDS = false; - } + if (bitStartTime == 0) bitStartTime = millis(); + else if (millis() - bitStartTime >= 87) rds.hasRDS = false; } rdsAerrorThreshold = (((rds.rdsErr >> 14) & 0x03) > showrdserrors); @@ -394,12 +389,11 @@ void TEF6686::readRDS(byte showrdserrors) { rdsDerrorThreshold = (((rds.rdsErr >> 8) & 0x03) > showrdserrors); if (bitRead(rds.rdsStat, 9) && (rds.rdsA != previous_rdsA || rds.rdsB != previous_rdsB || rds.rdsC != previous_rdsC || rds.rdsD != previous_rdsD)) { - rds.rdsAerror = (((rds.rdsErr >> 14) & 0x03) > 1); // We have all data to decode... let's go... + rds.rdsAerror = (((rds.rdsErr >> 14) & 0x03) > 1); rds.rdsBerror = (((rds.rdsErr >> 12) & 0x03) > 1); rds.rdsCerror = (((rds.rdsErr >> 10) & 0x03) > 1); rds.rdsDerror = (((rds.rdsErr >> 8) & 0x03) > 1); - //PI decoder if (!rdsAerrorThreshold && afreset) { rds.correctPI = rds.rdsA; afreset = false; @@ -413,11 +407,8 @@ void TEF6686::readRDS(byte showrdserrors) { rds.picode[2] = (rds.rdsA >> 4) & 0xF; rds.picode[3] = rds.rdsA & 0xF; for (int i = 0; i < 4; i++) { - if (rds.picode[i] < 10) { - rds.picode[i] += '0'; - } else { - rds.picode[i] += 'A' - 10; - } + if (rds.picode[i] < 10) rds.picode[i] += '0'; + else rds.picode[i] += 'A' - 10; } } @@ -438,7 +429,6 @@ void TEF6686::readRDS(byte showrdserrors) { if (strncmp(rds.picode, "0000", 4) == 0 && rds.rdsB == 0 && rds.stationName.length() == 0) memset(rds.picode, 0, sizeof(rds.picode)); - // USA Station callsign decoder if ((rds.region == 1 ? ps_process : true) && rds.correctPI != 0 && rds.region > 0 && correctPIold != rds.correctPI) { bool foundMatch = false; @@ -446,27 +436,16 @@ void TEF6686::readRDS(byte showrdserrors) { if (rds.region == 1 && SPIFFS.begin(true)) { delay(5); - if (currentfreq2 < 9000) { - file = SPIFFS.open("/USA_87-90.csv"); - } else if (currentfreq2 > 9000 && currentfreq2 < 9200) { - file = SPIFFS.open("/USA_90-92.csv"); - } else if (currentfreq2 > 9200 && currentfreq2 < 9400) { - file = SPIFFS.open("/USA_92-94.csv"); - } else if (currentfreq2 > 9400 && currentfreq2 < 9600) { - file = SPIFFS.open("/USA_94-96.csv"); - } else if (currentfreq2 > 9600 && currentfreq2 < 9800) { - file = SPIFFS.open("/USA_96-98.csv"); - } else if (currentfreq2 > 9800 && currentfreq2 < 10000) { - file = SPIFFS.open("/USA_98-100.csv"); - } else if (currentfreq2 > 10000 && currentfreq2 < 10200) { - file = SPIFFS.open("/USA_100-102.csv"); - } else if (currentfreq2 > 10200 && currentfreq2 < 10400) { - file = SPIFFS.open("/USA_102-104.csv"); - } else if (currentfreq2 > 10400 && currentfreq2 < 10600) { - file = SPIFFS.open("/USA_104-106.csv"); - } else if (currentfreq2 > 10600) { - file = SPIFFS.open("/USA_106-108.csv"); - } + if (currentfreq2 < 9000) file = SPIFFS.open("/USA_87-90.csv"); + else if (currentfreq2 > 9000 && currentfreq2 < 9200) file = SPIFFS.open("/USA_90-92.csv"); + else if (currentfreq2 > 9200 && currentfreq2 < 9400) file = SPIFFS.open("/USA_92-94.csv"); + else if (currentfreq2 > 9400 && currentfreq2 < 9600) file = SPIFFS.open("/USA_94-96.csv"); + else if (currentfreq2 > 9600 && currentfreq2 < 9800) file = SPIFFS.open("/USA_96-98.csv"); + else if (currentfreq2 > 9800 && currentfreq2 < 10000) file = SPIFFS.open("/USA_98-100.csv"); + else if (currentfreq2 > 10000 && currentfreq2 < 10200) file = SPIFFS.open("/USA_100-102.csv"); + else if (currentfreq2 > 10200 && currentfreq2 < 10400) file = SPIFFS.open("/USA_102-104.csv"); + else if (currentfreq2 > 10400 && currentfreq2 < 10600) file = SPIFFS.open("/USA_104-106.csv"); + else if (currentfreq2 > 10600) file = SPIFFS.open("/USA_106-108.csv"); delay(5); if (file) { @@ -562,43 +541,48 @@ void TEF6686::readRDS(byte showrdserrors) { } } - if (!rds.rdsBerror || showrdserrors == 3) rdsblock = rds.rdsB >> 11; else return; - rds.blockcounter[rdsblock]++; + if(rdsBerrorThreshold) goto end; + + rds.TP = (bitRead(rds.rdsB, 10)); + rds.PTY = (rds.rdsB >> 5) & 0x1F; + strcpy(rds.stationType, rds.region == 0 ? PTY_EU[rds.PTY] : PTY_USA[rds.PTY]); + + if (!rds.rdsBerror || showrdserrors == 3) rdsgroup = rds.rdsB >> 11; else return; + rds.blockcounter[rdsgroup]++; processed_rdsblocks++; - switch (rdsblock) { + switch (rdsgroup) { case RDS_GROUP_0A: case RDS_GROUP_0B: { - //PS decoder - if (showrdserrors == 3 || (!rdsBerrorThreshold && (!rdsDerrorThreshold))) { - offset = rds.rdsB & 0x03; // Let's get the character offset for PS + if (showrdserrors == 3 || !rdsDerrorThreshold) { + uint8_t segment = rds.rdsB & 0x03; - switch (offset) { + switch (segment) { case 0: if (((rds.rdsErr >> 8) & 0x03) > 1) rds.ps12error = true; else rds.ps12error = false; break; case 1: if (((rds.rdsErr >> 8) & 0x03) > 1) rds.ps34error = true; else rds.ps34error = false; break; case 2: if (((rds.rdsErr >> 8) & 0x03) > 1) rds.ps56error = true; else rds.ps56error = false; break; case 3: if (((rds.rdsErr >> 8) & 0x03) > 1) rds.ps78error = true; else rds.ps78error = false; break; } - ps_buffer2[(offset * 2) + 0] = ps_buffer[(offset * 2) + 0]; // Make a copy of the PS buffer - ps_buffer2[(offset * 2) + 1] = ps_buffer[(offset * 2) + 1]; + ps_buffer2[(segment * 2) + 0] = ps_buffer[(segment * 2) + 0]; // Make a copy of the PS buffer + ps_buffer2[(segment * 2) + 1] = ps_buffer[(segment * 2) + 1]; ps_buffer2[8] = '\0'; // Endmarker - ps_buffer[(offset * 2) + 0] = rds.rdsD >> 8; // First character of segment - ps_buffer[(offset * 2) + 1] = rds.rdsD & 0xFF; // Second character of segment + ps_buffer[(segment * 2) + 0] = rds.rdsD >> 8; // First character of segment + ps_buffer[(segment * 2) + 1] = rds.rdsD & 0xFF; // Second character of segment ps_buffer[8] = '\0'; // Endmarker if (ps_process || rds.fastps == 0) { - if (offset == 0) { + if (segment == 0) { packet0 = true; packet1 = false; packet2 = false; packet3 = false; } - if (offset == 1) packet1 = true; - if (offset == 2) packet2 = true; - if (offset == 3) packet3 = true; + if (segment == 1) packet1 = true; + if (segment == 2) packet2 = true; + if (segment == 3) packet3 = true; } if (packet0 && packet1 && packet2 && packet3 && (ps_process || (rds.fastps == 0 && rds.fastps != 2))) { // Last chars are received @@ -615,198 +599,186 @@ void TEF6686::readRDS(byte showrdserrors) { } if ((!ps_process && rds.fastps > 0 && rds.fastps != 2) || rds.fastps == 2) { // Let's get 2 runs of 8 PS characters fast and without refresh - if (offset == 0) packet0 = true; - if (offset == 1) packet1 = true; - if (offset == 2) packet2 = true; - if (offset == 3) packet3 = true; + if (segment == 0) packet0 = true; + if (segment == 1) packet1 = true; + if (segment == 2) packet2 = true; + if (segment == 3) packet3 = true; RDScharConverter(ps_buffer, PStext, sizeof(PStext) / sizeof(wchar_t), (underscore > 0 ? true : false)); // Convert 8 bit ASCII to 16 bit ASCII String utf8String = convertToUTF8(PStext); // Convert RDS characterset to ASCII rds.stationName = extractUTF8Substring(utf8String, 0, 8, (underscore > 0 ? true : false)); if (packet0 && packet1 && packet2 && packet3) ps_process = true; // OK, we had one runs, now let's go the idle PS writing } - if (offset == 0) rds.hasDynamicPTY = bitRead(rds.rdsB, 2) & 0x1F; // Dynamic PTY flag - if (offset == 1) rds.hasCompressed = bitRead(rds.rdsB, 2) & 0x1F; // Compressed flag - if (offset == 2) rds.hasArtificialhead = bitRead(rds.rdsB, 2) & 0x1F; // Artificial head flag - if (offset == 3) rds.hasStereo = bitRead(rds.rdsB, 2) & 0x1F; // Stereo flag + if(segment == 0) rds.hasDynamicPTY = bitRead(rds.rdsB, 2) & 0x1F; + else if(segment == 1) rds.hasCompressed = bitRead(rds.rdsB, 2) & 0x1F; + else if(segment == 2) rds.hasArtificialhead = bitRead(rds.rdsB, 2) & 0x1F; + else if(segment == 3) rds.hasStereo = bitRead(rds.rdsB, 2) & 0x1F; } - if (!rdsBerrorThreshold) { - rds.stationTypeCode = (rds.rdsB >> 5) & 0x1F; // Get 5 PTY bits from Block B - if (rds.region == 0) strcpy(rds.stationType, PTY_EU[rds.stationTypeCode]); else strcpy(rds.stationType, PTY_USA[rds.stationTypeCode]); + rds.hasTA = (bitRead(rds.rdsB, 4)); - rds.hasTA = (bitRead(rds.rdsB, 4)); // Read TA flag - } - - rds.hasTP = (bitRead(rds.rdsB, 10)); // Read TP flag - - if (!rdsCerrorThreshold) { + if (!rdsCerrorThreshold && rdsgroup == RDS_GROUP_0A && rds.rdsC != rdsCold) { //AF decoder - if (rdsblock == 0 && rds.rdsC != rdsCold) { // Only when in GROUP 0A - - if ((rds.rdsC >> 8) > 224 && (rds.rdsC >> 8) < 250) { - afinit = true; // AF detected - rds.hasAF = true; - } - - if (afinit) { - if ((rds.rdsC >> 8) > 224 && (rds.rdsC >> 8) < 250 && ((rds.rdsC & 0xFF) * 10 + 8750) == currentfreq && rds.hasAF) { - if (afmethodBtrigger) afmethodB = true; // Check for AF method B - afmethodBprobe = true; - af_counterb = (rds.rdsC >> 8) - 224; - af_number = (rds.rdsC >> 8) - 224; - af_counterbcheck = 1; - doublecounter = 0; - doubletestfreq = (rds.rdsC & 0xFF) * 10 + 8750; - } else if ((rds.rdsC >> 8) > 224 && (rds.rdsC >> 8) < 250 && ((rds.rdsC & 0xFF) * 10 + 8750) != currentfreq && rds.hasAF) { - afmethodBprobe = false; - afmethodBtrigger = true; - af_counterb = 0; - af_number = (rds.rdsC >> 8) - 224; - af_counterbcheck = 0; - doublecounter = 0; - doubletestfreq = (rds.rdsC & 0xFF) * 10 + 8750; - } - - if (((rds.rdsC >> 8) > 0 && (rds.rdsC >> 8) < 205) && ((rds.rdsC >> 8) > 0 && (rds.rdsC >> 8) < 205)) { - if (afmethodBprobe) af_counterbcheck += 2; - } - - if ((rds.rdsB >> 11) == 0 && af_counter < 50) { - uint16_t buffer0; - uint16_t buffer1; - - if ((rds.rdsC >> 8) > 0 && (rds.rdsC >> 8) < 205) buffer0 = (rds.rdsC >> 8) * 10 + 8750; else buffer0 = 0; - if ((rds.rdsC & 0xFF) > 0 && (rds.rdsC & 0xFF) < 205) buffer1 = (rds.rdsC & 0xFF) * 10 + 8750; else buffer1 = 0; - - if (((rds.rdsC >> 8) > 0 && (rds.rdsC >> 8) < 205) && (buffer0 == doubletestfreq || buffer1 == doubletestfreq)) doublecounter++; - if (doublecounter > (af_number / 2)) afmethodB = true; // If signed frequency also appears more than once in the AF list, AF Method B detected - - if (afmethodBprobe && af_counterbcheck > af_counterb) afmethodBprobe = false; // If more than counter received disable probe flag - - if (afmethodBprobe) { // Check for Reg. flags - if (buffer1 == currentfreq && buffer0 > buffer1) { - for (int x = 0; x < af_counter; x++) { - if (af[x].frequency == buffer0 && !af[x].regional) { - af[x].regional = true; - af_updatecounter++; - break; - } - } - } else if (buffer1 == currentfreq && buffer0 < buffer1) { - for (int x = 0; x < af_counter; x++) { - if (af[x].frequency == buffer0 && !af[x].same) { - af[x].same = true; - af_updatecounter++; - break; - } - } - } - - if (buffer0 == currentfreq && buffer0 > buffer1) { - for (int x = 0; x < af_counter; x++) { - if (af[x].frequency == buffer1 && !af[x].regional) { - af[x].regional = true; - af_updatecounter++; - break; - } - } - } else if (buffer0 == currentfreq && buffer0 < buffer1) { - for (int x = 0; x < af_counter; x++) { - if (af[x].frequency == buffer1 && !af[x].same) { - af[x].same = true; - af_updatecounter++; - break; - } - } - } - } - - if (buffer0 != currentfreq && buffer1 != currentfreq && afmethodB && afmethodBprobe) { - afmethodBprobe = false; // Remove faulty Reg. flags - for (int x = 0; x < af_counter; x++) { - if (af[x].frequency == buffer0 || af[x].frequency == buffer1) { - if (af[x].same) { - af[x].same = false; - af_updatecounter++; - } - if (af[x].regional) { - af[x].regional = false; - af_updatecounter++; - } - } - break; - } - } - - bool isValuePresent = false; - for (int i = 0; i < 50; i++) { // Check if already in list - if ((rds.sortaf && (buffer0 == currentfreq)) || buffer0 == 0 || af[i].frequency == buffer0) { - isValuePresent = true; - break; - } - } - - if (!isValuePresent) { // Add frequency to list - af[af_counter].frequency = buffer0; - if (af_counter < 50) af_counter++; - af_updatecounter++; - } - - isValuePresent = false; - for (int i = 0; i < 50; i++) { // Check if already in list - if ((rds.sortaf && (buffer1 == currentfreq)) || buffer1 == 0 || af[i].frequency == buffer1) { - isValuePresent = true; - break; - } - } - - if (!isValuePresent) { - af[af_counter].frequency = buffer1; // Add frequency to list - if (af_counter < 50) af_counter++; - af_updatecounter++; - } - - if (rds.sortaf) { // Sort AF list (low to high) - for (int i = 0; i < 50; i++) { - for (int j = 0; j < 50 - i; j++) { - if (af[j].frequency == 0) continue; - - if (af[j].frequency > af[j + 1].frequency && af[j + 1].frequency != 0) { - uint16_t temp = af[j].frequency; - bool temp3 = af[j].afvalid; - bool temp4 = af[j].checked; - bool temp5 = af[j].regional; - bool temp6 = af[j].same; - af[j].frequency = af[j + 1].frequency; - af[j].afvalid = af[j + 1].afvalid; - af[j].checked = af[j + 1].checked; - af[j].regional = af[j + 1].regional; - af[j].same = af[j + 1].same; - af[j + 1].frequency = temp; - af[j + 1].afvalid = temp3; - af[j + 1].checked = temp4; - af[j + 1].regional = temp5; - af[j + 1].same = temp6; - } - } - } - } - } - } - rdsCold = rds.rdsC; + if ((rds.rdsC >> 8) > 224 && (rds.rdsC >> 8) < 250) { + afinit = true; // AF detected + rds.hasAF = true; } + + if (afinit) { + if ((rds.rdsC >> 8) > 224 && (rds.rdsC >> 8) < 250 && ((rds.rdsC & 0xFF) * 10 + 8750) == currentfreq && rds.hasAF) { + if (afmethodBtrigger) afmethodB = true; + afmethodBprobe = true; + af_counterb = (rds.rdsC >> 8) - 224; + af_number = (rds.rdsC >> 8) - 224; + af_counterbcheck = 1; + doublecounter = 0; + doubletestfreq = (rds.rdsC & 0xFF) * 10 + 8750; + } else if ((rds.rdsC >> 8) > 224 && (rds.rdsC >> 8) < 250 && ((rds.rdsC & 0xFF) * 10 + 8750) != currentfreq && rds.hasAF) { + afmethodBprobe = false; + afmethodBtrigger = true; + af_counterb = 0; + af_number = (rds.rdsC >> 8) - 224; + af_counterbcheck = 0; + doublecounter = 0; + doubletestfreq = (rds.rdsC & 0xFF) * 10 + 8750; + } + + if (((rds.rdsC >> 8) > 0 && (rds.rdsC >> 8) < 205) && ((rds.rdsC >> 8) > 0 && (rds.rdsC >> 8) < 205)) { + if (afmethodBprobe) af_counterbcheck += 2; + } + + if ((rds.rdsB >> 11) == 0 && af_counter < 50) { + uint16_t buffer0; + uint16_t buffer1; + + if ((rds.rdsC >> 8) > 0 && (rds.rdsC >> 8) < 205) buffer0 = (rds.rdsC >> 8) * 10 + 8750; else buffer0 = 0; + if ((rds.rdsC & 0xFF) > 0 && (rds.rdsC & 0xFF) < 205) buffer1 = (rds.rdsC & 0xFF) * 10 + 8750; else buffer1 = 0; + + if (((rds.rdsC >> 8) > 0 && (rds.rdsC >> 8) < 205) && (buffer0 == doubletestfreq || buffer1 == doubletestfreq)) doublecounter++; + if (doublecounter > (af_number / 2)) afmethodB = true; // If signed frequency also appears more than once in the AF list, AF Method B detected + + if (afmethodBprobe && af_counterbcheck > af_counterb) afmethodBprobe = false; // If more than counter received disable probe flag + + if (afmethodBprobe) { // Check for Reg. flags + if (buffer1 == currentfreq && buffer0 > buffer1) { + for (int x = 0; x < af_counter; x++) { + if (af[x].frequency == buffer0 && !af[x].regional) { + af[x].regional = true; + af_updatecounter++; + break; + } + } + } else if (buffer1 == currentfreq && buffer0 < buffer1) { + for (int x = 0; x < af_counter; x++) { + if (af[x].frequency == buffer0 && !af[x].same) { + af[x].same = true; + af_updatecounter++; + break; + } + } + } + + if (buffer0 == currentfreq && buffer0 > buffer1) { + for (int x = 0; x < af_counter; x++) { + if (af[x].frequency == buffer1 && !af[x].regional) { + af[x].regional = true; + af_updatecounter++; + break; + } + } + } else if (buffer0 == currentfreq && buffer0 < buffer1) { + for (int x = 0; x < af_counter; x++) { + if (af[x].frequency == buffer1 && !af[x].same) { + af[x].same = true; + af_updatecounter++; + break; + } + } + } + } + + if (buffer0 != currentfreq && buffer1 != currentfreq && afmethodB && afmethodBprobe) { + afmethodBprobe = false; // Remove faulty Reg. flags + for (int x = 0; x < af_counter; x++) { + if (af[x].frequency == buffer0 || af[x].frequency == buffer1) { + if (af[x].same) { + af[x].same = false; + af_updatecounter++; + } + if (af[x].regional) { + af[x].regional = false; + af_updatecounter++; + } + } + break; + } + } + + bool isValuePresent = false; + for (int i = 0; i < 50; i++) { // Check if already in list + if ((rds.sortaf && (buffer0 == currentfreq)) || buffer0 == 0 || af[i].frequency == buffer0) { + isValuePresent = true; + break; + } + } + + if (!isValuePresent) { // Add frequency to list + af[af_counter].frequency = buffer0; + if (af_counter < 50) af_counter++; + af_updatecounter++; + } + + isValuePresent = false; + for (int i = 0; i < 50; i++) { // Check if already in list + if ((rds.sortaf && (buffer1 == currentfreq)) || buffer1 == 0 || af[i].frequency == buffer1) { + isValuePresent = true; + break; + } + } + + if (!isValuePresent) { + af[af_counter].frequency = buffer1; // Add frequency to list + if (af_counter < 50) af_counter++; + af_updatecounter++; + } + + if (rds.sortaf) { // Sort AF list (low to high) + for (int i = 0; i < 50; i++) { + for (int j = 0; j < 50 - i; j++) { + if (af[j].frequency == 0) continue; + + if (af[j].frequency > af[j + 1].frequency && af[j + 1].frequency != 0) { + uint16_t temp = af[j].frequency; + bool temp3 = af[j].afvalid; + bool temp4 = af[j].checked; + bool temp5 = af[j].regional; + bool temp6 = af[j].same; + af[j].frequency = af[j + 1].frequency; + af[j].afvalid = af[j + 1].afvalid; + af[j].checked = af[j + 1].checked; + af[j].regional = af[j + 1].regional; + af[j].same = af[j + 1].same; + af[j + 1].frequency = temp; + af[j + 1].afvalid = temp3; + af[j + 1].checked = temp4; + af[j + 1].regional = temp5; + af[j + 1].same = temp6; + } + } + } + } + } + } + rdsCold = rds.rdsC; } - } break; + } break; - case RDS_GROUP_1A: - case RDS_GROUP_1B: { - if (!rdsCerrorThreshold) { - if (((rds.rdsC >> 12) & 0x07) == 0 && rdsblock == RDS_GROUP_1A) { // ECC code readout - rds.ECC = rds.rdsC & 0xff; - rds.hasECC = true; + case RDS_GROUP_1A: { + if (!rdsCerrorThreshold && ((rds.rdsC >> 12) & 0x07) == 0) { + rds.ECC = rds.rdsC & 0xff; + rds.hasECC = true; - switch (rds.picode[0]) { + switch (rds.picode[0]) { case '1': { if (rds.ECC == 160) rds.ECCtext = ECCtext[226]; if (rds.ECC == 162) rds.ECCtext = ECCtext[129]; @@ -1114,17 +1086,13 @@ void TEF6686::readRDS(byte showrdserrors) { break; } } - } } - - if (rds.rdsC >> 12 == 1 && rdsblock == RDS_GROUP_1A) rds.hasTMC = true; // TMC flag - } break; + } break; case RDS_GROUP_2A: { - if (showrdserrors == 3 || (!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold)) { - // RT decoder (64 characters) + if (showrdserrors == 3 || !(rdsCerrorThreshold && rdsDerrorThreshold)) { rds.hasRT = true; - rds.rtAB = (bitRead(rds.rdsB, 4)); // Get AB flag + rds.rtAB = (bitRead(rds.rdsB, 4)); if (initab) { rtABold = rds.rtAB; @@ -1139,19 +1107,16 @@ void TEF6686::readRDS(byte showrdserrors) { } } - if (rds.rtAB != rtABold) { // Erase old RT, because of AB change + if (rds.rtAB != rtABold) { initrt = false; if (rds.rtbuffer) { char rt_buffer_temp[129]; - bool found = false; strcpy(rt_buffer_temp, rt_buffer); for (int i = 0; i < 129; i++) { - if (rt_buffer_temp[i] == 0x0D) { - found = true; - } - if (found) { + if (rt_buffer_temp[i] == '\r') { rt_buffer_temp[i] = '\0'; + break; } } @@ -1162,31 +1127,25 @@ void TEF6686::readRDS(byte showrdserrors) { rds.stationText = trimTrailingSpaces(rds.stationText); // Trim empty spaces at the end } - for (byte i = 0; i < 64; i++) { - rt_buffer[i] = 0x20; - } + for (byte i = 0; i < 64; i++) rt_buffer[i] = 0x20; rt_buffer[64] = '\0'; rtABold = rds.rtAB; } - offset = (rds.rdsB & 0xf) * 4; // Get RT character segment - rt_buffer[offset + 0] = rds.rdsC >> 8; // First character of segment - rt_buffer[offset + 1] = rds.rdsC & 0xff; // Second character of segment - rt_buffer[offset + 2] = rds.rdsD >> 8; // Thirth character of segment - rt_buffer[offset + 3] = rds.rdsD & 0xff; // Fourth character of segment - + uint8_t segment = (rds.rdsB & 0xf) * 4; + rt_buffer[segment + 0] = rds.rdsC >> 8; + rt_buffer[segment + 1] = rds.rdsC & 0xff; + rt_buffer[segment + 2] = rds.rdsD >> 8; + rt_buffer[segment + 3] = rds.rdsD & 0xff; if (initrt || !rds.rtbuffer) { char rt_buffer_temp[129]; - bool found = false; strcpy(rt_buffer_temp, rt_buffer); for (int i = 0; i < 129; i++) { - if (rt_buffer_temp[i] == 0x0D) { - found = true; - } - if (found) { + if (rt_buffer_temp[i] == '\r') { rt_buffer_temp[i] = '\0'; + break; } } @@ -1199,7 +1158,7 @@ void TEF6686::readRDS(byte showrdserrors) { for (int i = 0; i < 64; i++) rt_buffer2[i] = rt_buffer[i]; } - } break; + } break; case RDS_GROUP_2B: { if (showrdserrors == 3 || (!rdsBerrorThreshold && !rdsDerrorThreshold)) { @@ -1215,9 +1174,9 @@ void TEF6686::readRDS(byte showrdserrors) { rtAB32old = rds.rtAB32; } - offset = (rds.rdsB & 0xf) * 2; // Get RT character segment - rt_buffer32[offset + 0] = rds.rdsD >> 8; // First character of segment - rt_buffer32[offset + 1] = rds.rdsD & 0xff; // Second character of segment + uint16_t segment = (rds.rdsB & 0xf) * 2; // Get RT character segment + rt_buffer32[segment + 0] = rds.rdsD >> 8; // First character of segment + rt_buffer32[segment + 1] = rds.rdsD & 0xff; // Second character of segment byte endmarkerRT32 = 32; for (byte i = 0; i < endmarkerRT32; i++) { @@ -1229,15 +1188,12 @@ void TEF6686::readRDS(byte showrdserrors) { char rt_buffer_temp[129]; - bool found = false; strcpy(rt_buffer_temp, rt_buffer32); for (int i = 0; i < 129; i++) { - if (rt_buffer_temp[i] == 0x0D) { - found = true; - } - if (found) { + if (rt_buffer_temp[i] == '\r') { rt_buffer_temp[i] = '\0'; + break; } } @@ -1266,25 +1222,22 @@ void TEF6686::readRDS(byte showrdserrors) { rds.aid_counter++; } - if (rds.rdsD == 0xCD46) { // Check for TMC application - rds.hasTMC = true; // TMC flag + if (rds.rdsD == 0xCD46) rds.hasTMC = true; + + if (rds.rdsD == 0x4BD7) { + rds.hasRTplus = true; + rtplusblock = ((rds.rdsB & 0x1F) >> 1) * 2; } - // RT+ init - if (rds.rdsD == 0x4BD7) { // Check for RT+ application - rds.hasRDSplus = true; // Set flag - rtplusblock = ((rds.rdsB & 0x1F) >> 1) * 2; // Get RT+ Block + if (rds.rdsD == 0x0093) { + rds.hasDABAF = true; + DABAFblock = ((rds.rdsB & 0x1F) >> 1) * 2; } - if (rds.rdsD == 0x0093) { // Check for DAB+ AF application - rds.hasDABAF = true; // Set flag - DABAFblock = ((rds.rdsB & 0x1F) >> 1) * 2; // Get DAB AF Block - } - - if (rds.rdsD == 0x6552) { // Check for Enhanced RT application - _hasEnhancedRT = true; // Set flag - eRTblock = ((rds.rdsB & 0x1F) >> 1) * 2; // Get eRT block - eRTcoding = bitRead(rds.rdsC, 0); // 0 = UCS-2, 1 = UTF-8 + if (rds.rdsD == 0x6552) { + _hasEnhancedRT = true; + eRTblock = ((rds.rdsB & 0x1F) >> 1) * 2; + eRTcoding = bitRead(rds.rdsC, 0); } } } break; @@ -1292,11 +1245,8 @@ void TEF6686::readRDS(byte showrdserrors) { case RDS_GROUP_4A: { if (!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold && rds.ctupdate && (rds.PICTlock == rds.rdsA || rds.PICTlock == 0)) { // CT - uint32_t mjd; - mjd = (rds.rdsB & 0x03); - mjd <<= 15; - mjd += ((rds.rdsC >> 1) & 0x7FFF); - uint16_t hour, minute, day = 1, month = 1, year = 2020; // Set default values for day, month, and year + uint32_t mjd = (rds.rdsB & 0x03) << 15 | ((rds.rdsC >> 1) & 0x7FFF);; + uint16_t hour, minute, day = 5, month = 1, year = 2026; int32_t timeoffset; long J, C, Y, M; @@ -1313,14 +1263,13 @@ void TEF6686::readRDS(byte showrdserrors) { if ((M + 2 - (12 * J)) < 13) month = M + 2 - (12 * J); if ((100 * (C - 49) + Y + J) > 2022) year = 100 * (C - 49) + Y + J; - hour = ((rds.rdsD >> 12) & 0x000f); - hour += ((rds.rdsC << 4) & 0x0010); + hour = ((rds.rdsD >> 12) & 0xf) | ((rds.rdsC << 4) & 0x10); timeoffset = rds.rdsD & 0x001f; if (bitRead(rds.rdsD, 5)) timeoffset *= -1; timeoffset *= 1800; minute = (rds.rdsD & 0x0fc0) >> 6; - if (year < 2024 || hour > 23 || minute > 59 || timeoffset > 55800 || timeoffset < -55800) break; + if (year < 2026 || hour > 23 || minute > 59 || timeoffset > 55800 || timeoffset < -55800) break; struct tm tm; tm.tm_year = year - 1900; @@ -1340,9 +1289,7 @@ void TEF6686::readRDS(byte showrdserrors) { rds.hasCT = true; rds.time = rdstime; rds.offset = timeoffset; - } else { - rds.hasCT = false; - } + } else rds.hasCT = false; lastrdstime = rdstime; lasttimeoffset = timeoffset; } @@ -1351,16 +1298,16 @@ void TEF6686::readRDS(byte showrdserrors) { case RDS_GROUP_10A: { if (!rdsCerrorThreshold && !rdsDerrorThreshold) { // PTYN - offset = bitRead(rds.rdsB, 0); // Get char offset + uint8_t segment = bitRead(rds.rdsB, 0); if (rds.rdsC != 0 && rds.rdsD != 0) { - ptyn_buffer[(offset * 4) + 0] = rds.rdsC >> 8; // Get position 1 and 5 - ptyn_buffer[(offset * 4) + 1] = rds.rdsC & 0xFF; // Get position 2 and 6 - ptyn_buffer[(offset * 4) + 2] = rds.rdsD >> 8; // Get position 3 and 7 - ptyn_buffer[(offset * 4) + 3] = rds.rdsD & 0xFF; // Get position 4 and 8 + ptyn_buffer[(segment * 4) + 0] = rds.rdsC >> 8; + ptyn_buffer[(segment * 4) + 1] = rds.rdsC & 0xFF; + ptyn_buffer[(segment * 4) + 2] = rds.rdsD >> 8; + ptyn_buffer[(segment * 4) + 3] = rds.rdsD & 0xFF; for (byte i = 0; i < 8; i++) PTYNtext[i] = L'\0'; - RDScharConverter(ptyn_buffer, PTYNtext, sizeof(PTYNtext) / sizeof(wchar_t), false); // Convert 8 bit ASCII to 16 bit ASCII - String utf8String = convertToUTF8(PTYNtext); // Convert RDS characterset to ASCII - rds.PTYN = extractUTF8Substring(utf8String, 0, 8, false); // Make sure text is not longer than 8 chars + RDScharConverter(ptyn_buffer, PTYNtext, sizeof(PTYNtext) / sizeof(wchar_t), false); + String utf8String = convertToUTF8(PTYNtext); + rds.PTYN = extractUTF8Substring(utf8String, 0, 8, false); rds.hasPTYN = true; } } @@ -1373,9 +1320,9 @@ void TEF6686::readRDS(byte showrdserrors) { case RDS_GROUP_9A: case RDS_GROUP_11A: case RDS_GROUP_12A: - case RDS_GROUP_13A: { + case RDS_GROUP_13A: { // RT+ decoding - if ((!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold) && rtplusblock == rdsblock && rds.hasRDSplus) { + if ((!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold) && rtplusblock == rdsgroup && rds.hasRTplus) { rds.rdsplusTag1 = ((rds.rdsB & 0x07) << 3) + (rds.rdsC >> 13); // Are we in the right RT+ block and is all ok to go? rds.rdsplusTag2 = ((rds.rdsC & 0x01) << 5) + (rds.rdsD >> 11); uint16_t start_marker_1 = (rds.rdsC >> 7) & 0x3F; @@ -1428,8 +1375,8 @@ void TEF6686::readRDS(byte showrdserrors) { } // eRT decoding - if ((!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold) && eRTblock == rdsblock && _hasEnhancedRT) { - offset = (rds.rdsB & 0x1f) * 4; + if ((!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold) && eRTblock == rdsgroup && _hasEnhancedRT) { + uint8_t offset = (rds.rdsB & 0x1f) * 4; eRT_buffer[offset + 0] = rds.rdsC >> 8; // First character of segment eRT_buffer[offset + 1] = rds.rdsC & 0xff; // Second character of segment eRT_buffer[offset + 2] = rds.rdsD >> 8; // Thirth character of segment @@ -1454,9 +1401,9 @@ void TEF6686::readRDS(byte showrdserrors) { } - if (!rdsBerrorThreshold && rdsblock == 16 && (bitRead(rds.rdsB, 15))) rds.hasTMC = true; // TMC flag + if (!rdsBerrorThreshold && rdsgroup == 16 && (bitRead(rds.rdsB, 15))) rds.hasTMC = true; // TMC flag - if ((!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold) && DABAFblock == rdsblock && rds.hasDABAF) { + if ((!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold) && DABAFblock == rdsgroup && rds.hasDABAF) { rds.dabaffreq = (rds.rdsC * 16); for (size_t i = 0; i < sizeof(DABfrequencyTable) / sizeof(DABfrequencyTable[0]); ++i) { @@ -1468,11 +1415,8 @@ void TEF6686::readRDS(byte showrdserrors) { rds.dabafeid[2] = (rds.rdsD >> 4) & 0xF; rds.dabafeid[3] = rds.rdsD & 0xF; for (int i = 0; i < 4; i++) { - if (rds.dabafeid[i] < 10) { - rds.dabafeid[i] += '0'; // Add ASCII offset for decimal digits - } else { - rds.dabafeid[i] += 'A' - 10; // Add ASCII offset for hexadecimal letters A-F - } + if (rds.dabafeid[i] < 10) rds.dabafeid[i] += '0'; + else rds.dabafeid[i] += 'A' - 10; } rds.dabafeid[4] = 0; } @@ -1501,21 +1445,16 @@ void TEF6686::readRDS(byte showrdserrors) { eon[eon_counter].picode[2] = (rds.rdsD >> 4) & 0xF; eon[eon_counter].picode[3] = rds.rdsD & 0xF; for (int j = 0; j < 4; j++) { - if (eon[eon_counter].picode[j] < 10) { - eon[eon_counter].picode[j] += '0'; // Add ASCII offset for decimal digits - } else { - eon[eon_counter].picode[j] += 'A' - 10; // Add ASCII offset for hexadecimal letters A-F - } + if (eon[eon_counter].picode[j] < 10) eon[eon_counter].picode[j] += '0'; + else eon[eon_counter].picode[j] += 'A' - 10; } eon[eon_counter].pi = rds.rdsD; // Store PI on next array if (eon_counter < 20) eon_counter++; eonIndex = eon_counter - 1; - } else { - eonIndex = i; - } + } else eonIndex = i; - offset = rds.rdsB & 0x0F; // Read offset + uint8_t offset = rds.rdsB & 0x0F; // Read offset if (offset < 4 && eon[eonIndex].pi == rds.rdsD) { eon_buffer[eonIndex][(offset * 2) + 0] = rds.rdsC >> 8; // First character of segment @@ -1583,7 +1522,7 @@ void TEF6686::readRDS(byte showrdserrors) { case RDS_GROUP_15A: { if (showrdserrors == 3 || (!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold)) { if (pslong_process && rds.stationNameLong.length() > 0) rds.hasLongPS = true; - offset = (rds.rdsB & 0xf) * 4; // Get Long PS character segment + uint8_t offset = (rds.rdsB & 0xf) * 4; // Get Long PS character segment pslong_buffer2[offset + 0] = pslong_buffer[offset + 0]; // Copy PS long buffer pslong_buffer2[offset + 1] = pslong_buffer[offset + 1]; @@ -1630,6 +1569,7 @@ void TEF6686::readRDS(byte showrdserrors) { } break; } + end: previous_rdsA = rds.rdsA; previous_rdsB = rds.rdsB; previous_rdsC = rds.rdsC; @@ -1737,17 +1677,17 @@ void TEF6686::clearRDS(bool fullsearchrds) { for (i = 0; i < 10; i++) rds.aid[i] = 0; - rdsblock = 254; + rdsgroup = 254; processed_rdsblocks = 0; piold = 0; rds.correctPI = 0; rds.ECC = 254; - rds.stationTypeCode = 32; + rds.PTY = 32; rds.dabaffreq = 0; rds.hasECC = false; rds.hasRT = false; rds.hasRDS = false; - rds.hasTP = false; + rds.TP = false; rds.hasAF = false; rds.hasTA = false; rds.hasEON = false; @@ -1756,7 +1696,7 @@ void TEF6686::clearRDS(bool fullsearchrds) { rds.hasAID = false; rds.hasPTYN = false; rds.hasLongPS = false; - rds.hasRDSplus = false; + rds.hasRTplus = false; rds.hasDABAF = false; rds.hasEnhancedRT = false; rt_process = false; @@ -2040,6 +1980,7 @@ String TEF6686::ucs2ToUtf8(const char* ucs2Input) { return utf8Output; } +static const char* fixedCalls[] = {"CBLA", "CBFM", "CBOT"}; bool TEF6686::isFixedCallsign(uint16_t stationID, char* stationIDStr) { for (int i = 0; i < sizeof(fixedPI) / sizeof(fixedPI[0]); i++) { if (stationID == fixedPI[i]) { diff --git a/src/gui.cpp b/src/gui.cpp index 999ff12..ac54fe0 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -1296,7 +1296,7 @@ void ShowOneLine(byte position, byte item, bool selected) { FullLineSprite.setTextDatum(TR_DATUM); FullLineSprite.setTextColor(PrimaryColor, PrimaryColorSmooth, false); switch (scancancel) { - case OFF: FullLineSprite.drawString(textUI(30), 298, 2); break; + case SCAN_CANCEL: FullLineSprite.drawString(textUI(30), 298, 2); break; case CORRECTPI: FullLineSprite.drawString(textUI(220), 298, 2); break; case SIGNAL: FullLineSprite.drawString(textUI(221), 298, 2); break; } @@ -2408,7 +2408,7 @@ void ShowOneButton(byte position, byte item, bool selected) { PSSprite.setTextColor(PrimaryColor, PrimaryColorSmooth, false); switch (scancancel) { - case OFF: PSSprite.drawString(textUI(30), 75, 15); break; + case 0: PSSprite.drawString(textUI(30), 75, 15); break; case CORRECTPI: PSSprite.drawString(textUI(220), 75, 15); break; case SIGNAL: PSSprite.drawString(textUI(221), 75, 15); break; } @@ -4375,7 +4375,7 @@ void MenuUpDown(bool dir) { } switch (scancancel) { - case OFF: OneBigLineSprite.drawString(textUI(30), 135, 0); break; + case SCAN_CANCEL: OneBigLineSprite.drawString(textUI(30), 135, 0); break; case CORRECTPI: OneBigLineSprite.drawString(textUI(220), 135, 0); break; case SIGNAL: OneBigLineSprite.drawString(textUI(221), 135, 0); break; } @@ -4657,7 +4657,8 @@ void DoMenu() { tftPrint(ARIGHT, "marsel90-1", 145, 185, PrimaryColor, PrimaryColorSmooth, 16); tftPrint(ALEFT, "lawendel", 155, 185, PrimaryColor, PrimaryColorSmooth, 16); tftPrint(ARIGHT, "KB8U", 145, 200, PrimaryColor, PrimaryColorSmooth, 16); - tftPrint(ACENTER, "github.com/PE5PVB/TEF6686_ESP32", 155, 215, ActiveColor, ActiveColorSmooth, 16); + tftPrint(ALEFT, "KubaPro010", 155, 200, PrimaryColor, PrimaryColorSmooth, 16); + tftPrint(ACENTER, "github.com/KubaPro010/TEF6686_ESP32", 155, 215, ActiveColor, ActiveColorSmooth, 16); if (hardwaremodel == PORTABLE_TOUCH_ILI9341) { tft.fillRoundRect(240, 36, 60, 40, 6, FrameColor); tft.drawRoundRect(240, 36, 60, 40, 6, ActiveColor); @@ -5470,7 +5471,7 @@ void DoMenu() { Infoboxprint(textUI(219)); switch (scancancel) { - case OFF: OneBigLineSprite.drawString(textUI(30), 135, 0); break; + case SCAN_CANCEL: OneBigLineSprite.drawString(textUI(30), 135, 0); break; case CORRECTPI: OneBigLineSprite.drawString(textUI(220), 135, 0); break; case SIGNAL: OneBigLineSprite.drawString(textUI(221), 135, 0); break; } diff --git a/src/logbook.cpp b/src/logbook.cpp index b45b9f7..a31dc6d 100644 --- a/src/logbook.cpp +++ b/src/logbook.cpp @@ -15,7 +15,6 @@ void handleRoot() { html += ""; html += ""; - // Add CSS styling html += ""; html += ""; - // Add logo as a clickable link html += ""; html += "\"FMDX"; html += ""; @@ -130,7 +128,6 @@ void handleRoot() { if (endIndex == -1) endIndex = line.length(); String cell = line.substring(startIndex, endIndex); - // Extract PI code and Frequency if (columnIndex == piCodeIndex) piCode = cell; if (columnIndex == frequencyIndex) frequency = cell; @@ -139,23 +136,17 @@ void handleRoot() { columnIndex++; } - // Remove " MHz" from Frequency frequency.replace(" MHz", ""); - // Make row clickable html += "🌐"; html += ""; } } file.close(); - } else { - html += "" + String(textUI(299)) + ""; - } + } else html += "" + String(textUI(299)) + ""; - if (!hasData) { - html += "" + String(textUI(288)) + ""; - } + if (!hasData) html += "" + String(textUI(288)) + ""; html += ""; html += ""; @@ -164,45 +155,30 @@ void handleRoot() { } void handleDownloadCSV() { - // Attempt to open the CSV file from SPIFFS in read mode fs::File file = SPIFFS.open("/logbook.csv", "r"); - // Check if the file was successfully opened if (!file) { - // If the file could not be opened, send an error response webserver.send(500, "text/plain", "Failed to open logbook for download"); - return; // Exit the function if the file cannot be opened + return; } - // Set the headers to specify that the response will be a CSV file for download - webserver.sendHeader("Content-Type", "text/csv"); // Set MIME type for CSV files - webserver.sendHeader("Content-Disposition", "attachment; filename=logbook.csv"); // Suggests the file name for download + webserver.sendHeader("Content-Type", "text/csv"); + webserver.sendHeader("Content-Disposition", "attachment; filename=logbook.csv"); - // Stream the CSV file content directly to the browser webserver.streamFile(file, "text/csv"); - // Close the file after streaming the content to release resources file.close(); } bool handleCreateNewLogbook() { - // Check if the file "logbook.csv" already exists if (SPIFFS.exists("/logbook.csv")) { - // If it exists, delete the file - if (!SPIFFS.remove("/logbook.csv")) { - return false; - } + if (!SPIFFS.remove("/logbook.csv")) return false; } - // Create a new "logbook.csv" file in write mode fs::File file = SPIFFS.open("/logbook.csv", "w"); - if (!file) { - return false; - } + if (!file) return false; - // Write the header to the new CSV file - String header = "Date,Time,Frequency,PI,Signal,Stereo,TA,TP,PTY,ECC,PS,Radiotext\n"; - file.print(header); + file.print("Date,Time,Frequency,PI,Signal,Stereo,TA,TP,PTY,ECC,PS,Radiotext\n"); file.flush(); file.close(); @@ -215,33 +191,18 @@ bool handleCreateNewLogbook() { } byte addRowToCSV() { - // Ensure there is at least 150 bytes of free space in SPIFFS before proceeding - if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < 150 || logcounter > 1500) { - return 2; // Return 2 if insufficient free space is available - } + if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < 150 || logcounter > 1500) return 2; - // Open the "logbook.csv" file in append mode fs::File file = SPIFFS.open("/logbook.csv", "a"); - // Check if the file could not be opened - if (!file) { - return 1; // Return 1 if the file cannot be opened - } + if (!file) return 1; - // Fetch the current date and time as a string String currentDateTime = getCurrentDateTime(false); + if (currentDateTime == "") currentDateTime = "-,-"; - // Use a placeholder ("-,-") if the date and time could not be retrieved - if (currentDateTime == "") { - currentDateTime = "-,-"; - } - - // Prepare the frequency in a formatted string (e.g., "XX.XX MHz") int freqInt = (band == BAND_OIRT) ? (int)frequency_OIRT : (int)frequency; int adjustedFreq = freqInt + (band != BAND_OIRT ? ConverterSet * 100 : 0); - String frequencyFormatted = String(adjustedFreq / 100) + "." + - ((adjustedFreq % 100 < 10) ? "0" : "") + - String(adjustedFreq % 100) + " MHz"; + String frequencyFormatted = String(adjustedFreq / 100) + "." + ((adjustedFreq % 100 < 10) ? "0" : "") + String(adjustedFreq % 100) + " MHz"; // Calculate signal strength based on the selected unit int SStatusPrint = 0; @@ -249,126 +210,87 @@ byte addRowToCSV() { else if (unit == 1) SStatusPrint = ((SStatus * 100) + 10875) / 100; // dBf else if (unit == 2) SStatusPrint = round((float(SStatus) / 10.0 - 10.0 * log10(75) - 90.0) * 10.0); // dBm - // Format the signal strength with appropriate decimal places and unit String signal = String(SStatusPrint / 10) + "." + String(abs(SStatusPrint % 10)); if (unit == 0) signal += " dBμV"; else if (unit == 1) signal += " dBf"; else if (unit == 2) signal += " dBm"; - // Prepare the radio text with station information, including enhanced options if available String radioText = String(radio.rds.stationText + " " + radio.rds.stationText32); - if (radio.rds.hasEnhancedRT) { - radioText += " eRT: " + String(radio.rds.enhancedRTtext); - } + if (radio.rds.hasEnhancedRT) radioText += " eRT: " + String(radio.rds.enhancedRTtext); - // Replace commas in the station name and radio text to avoid CSV conflicts String stationName = radio.rds.stationName; String radioTextModified = (scanhold > 4 ? radioText : ""); - stationName.replace(",", " "); // Replace commas in station name - radioTextModified.replace(",", " "); // Replace commas in radio text + stationName.replace(",", " "); + radioTextModified.replace(",", " "); - // Handle ECC, PTY, TA, TP, and Stereo flag String TA = radio.rds.hasTA ? "•" : " "; - String TP = radio.rds.hasTP ? "•" : " "; + String TP = radio.rds.TP ? "•" : " "; String Stereo = radio.getStereoStatus() ? "•" : " "; - String pty = String(radio.rds.stationTypeCode); + String pty = String(radio.rds.PTY); String ECC = "--"; if (radio.rds.hasECC) { - char eccBuffer[3]; // Buffer to hold 2-digit hex value + null terminator + char eccBuffer[3]; snprintf(eccBuffer, sizeof(eccBuffer), "%02X", radio.rds.ECC); // Format ECC as uppercase 2-digit hex ECC = String(eccBuffer); } - // Construct the CSV row data - String row = currentDateTime + "," + - frequencyFormatted + "," + - String(radio.rds.picode).substring(0, 4) + "," + - signal + "," + - Stereo + "," + - TA + "," + - TP + "," + - pty + "," + - ECC + "," + - stationName + "," + - radioTextModified + "\n"; + String row = currentDateTime + "," + frequencyFormatted + "," + String(radio.rds.picode).substring(0, 4) + "," + signal + "," + Stereo + "," + TA + "," + TP + "," + pty + "," + ECC + "," + stationName + "," + radioTextModified + "\n"; - // Write the row to the file and close it if (file.print(row)) { - file.close(); // Successfully wrote to the file + file.close(); logcounter++; EEPROM.writeUInt(EE_UINT16_LOGCOUNTER, logcounter); EEPROM.commit(); - return 0; // Return 0 to indicate success + return 0; } else { - file.close(); // Close the file if writing fails - return 1; // Return 1 to indicate failure + file.close(); + return 1; } } String getCurrentDateTime(bool inUTC) { - // Check if the RTC has been set - if (!rtcset) { - return "-,-"; // Return placeholder when the RTC is not set - } + if (!rtcset) return "-,-"; - // Use the ESP32's time functions to retrieve the current time struct tm timeInfo; - if (!getLocalTime(&timeInfo)) { - return "-,-"; // Return placeholder if local time is unavailable - } + if (!getLocalTime(&timeInfo)) return "-,-"; - // Convert struct tm to time_t format time_t currentEpoch = mktime(&timeInfo); - - // Determine UTC offset as a number int utcOffsetHours = 0; if (!inUTC) { - // Adjust for time zone offset and DST if not in UTC currentEpoch += (NTPupdated ? NTPoffset * 3600 : radio.rds.offset); // Apply GMT offset if NTPupdated, else RDS offset - // Apply DST adjustment if NTPupdated and autoDST are true if (NTPupdated && autoDST) { struct tm tempTimeInfo; - localtime_r(¤tEpoch, &tempTimeInfo); // Convert to struct tm for DST calculation - if (isDST(mktime(&tempTimeInfo))) { // Check if DST is in effect - currentEpoch += 3600; // Add 1-hour DST offset - } + localtime_r(¤tEpoch, &tempTimeInfo); + if (isDST(mktime(&tempTimeInfo))) currentEpoch += 3600; } } else utcOffsetHours = (NTPupdated ? NTPoffset : radio.rds.offset / 3600); - // Convert adjusted (or original) time back to struct tm format localtime_r(¤tEpoch, &timeInfo); - // Buffer for formatted date-time string char buf[20]; if (clockampm) { - // USA format: MM/DD/YYYY, HH:MM:SS AM/PM - strftime(buf, sizeof(buf), "%m/%d/%Y", &timeInfo); // Format as MM/DD/YYYY + strftime(buf, sizeof(buf), "%m/%d/%Y", &timeInfo); - // Format time in 12-hour format with AM/PM int hour = timeInfo.tm_hour; - String ampm = (hour >= 12) ? "PM" : "AM"; // Determine AM or PM - if (hour == 0) hour = 12; // Convert 0 hour to 12 AM - else if (hour > 12) hour -= 12; // Convert to 12-hour format for PM + String ampm = (hour >= 12) ? "PM" : "AM"; + if (hour == 0) hour = 12; + else if (hour > 12) hour -= 12; String timeWithAMPM = String(hour) + ":" + (timeInfo.tm_min < 10 ? "0" : "") + String(timeInfo.tm_min) + ":" + (timeInfo.tm_sec < 10 ? "0" : "") + String(timeInfo.tm_sec) + " " + ampm; - // Append UTC offset if inUTC if (inUTC) { String utcOffsetStr = ", " + String(utcOffsetHours) + ","; return String(buf) + "," + timeWithAMPM + utcOffsetStr; } - // Return the final formatted date and time for the USA region return String(buf) + "," + timeWithAMPM; } else { - // European format: DD-MM-YYYY, HH:MM:SS - strftime(buf, sizeof(buf), "%d-%m-%Y", &timeInfo); // Format as DD-MM-YYYY + strftime(buf, sizeof(buf), "%d-%m-%Y", &timeInfo); String timeEuropean = String(timeInfo.tm_hour) + ":" + (timeInfo.tm_min < 10 ? "0" : "") + String(timeInfo.tm_min) + ":" + (timeInfo.tm_sec < 10 ? "0" : "") + String(timeInfo.tm_sec); // Format time with leading zero if needed - // Append UTC offset if inUTC if (inUTC) { String utcOffsetStr = ", " + String(utcOffsetHours) + ","; return String(buf) + "," + timeEuropean + utcOffsetStr; @@ -380,33 +302,24 @@ String getCurrentDateTime(bool inUTC) { bool isDST(time_t t) { struct tm timeInfo; - localtime_r(&t, &timeInfo); // Convert time_t to struct tm + localtime_r(&t, &timeInfo); - int month = timeInfo.tm_mon + 1; // tm_mon is 0-based, so add 1 - int day = timeInfo.tm_mday; // tm_mday is the day of the month - int hour = timeInfo.tm_hour; // tm_hour is the hour of the day - int weekday = timeInfo.tm_wday; // tm_wday is the day of the week (0 = Sunday) + int month = timeInfo.tm_mon + 1; + int day = timeInfo.tm_mday; + int hour = timeInfo.tm_hour; + int weekday = timeInfo.tm_wday; - // DST starts last Sunday in March at 2:00 AM if (month == 3) { int lastSunday = 31 - ((weekday + 31 - day) % 7); - if (day > lastSunday || (day == lastSunday && hour >= 2)) { - return true; - } + if (day > lastSunday || (day == lastSunday && hour >= 2)) return true; } - // DST ends last Sunday in October at 3:00 AM if (month == 10) { int lastSunday = 31 - ((weekday + 31 - day) % 7); - if (day < lastSunday || (day == lastSunday && hour < 3)) { - return false; - } + if (day < lastSunday || (day == lastSunday && hour < 3)) return false; } - // DST is active from April to September - if (month > 3 && month < 10) { - return true; - } + if (month > 3 && month < 10) return true; return false; } @@ -422,48 +335,34 @@ void handleLogo() { } void printLogbookCSV() { - // Attempt to open the CSV file stored in SPIFFS fs::File file = SPIFFS.open("/logbook.csv", "r"); - // Check if the file was successfully opened if (!file) { Serial.println("Failed to open logbook!"); return; } - // Print a message indicating the start of the file content Serial.println("===== Start of logbook.csv ====="); - // Read and print the contents of the file line by line while (file.available()) { - String line = file.readStringUntil('\n'); // Read one line at a time - Serial.println(line); // Print the line to the Serial Monitor + String line = file.readStringUntil('\n'); + Serial.println(line); } - // Close the file after reading file.close(); - // Print a message indicating the end of the file content Serial.println("===== End of logbook.csv ====="); } void sendUDPlog() { - // Get the current date and time as a string String currentDateTime = getCurrentDateTime(true); - // Use a placeholder if the date and time could not be retrieved - if (currentDateTime == "") { - currentDateTime = "-,-"; - } + if (currentDateTime == "") currentDateTime = "-,-"; - // Format the frequency, adjusting based on the band and converter settings int freqInt = (band == BAND_OIRT) ? (int)frequency_OIRT : (int)frequency; int adjustedFreq = freqInt + (band != BAND_OIRT ? ConverterSet * 100 : 0); - String frequencyFormatted = String(adjustedFreq / 100) + "." + - ((adjustedFreq % 100 < 10) ? "0" : "") + - String(adjustedFreq % 100); + String frequencyFormatted = String(adjustedFreq / 100) + "." + ((adjustedFreq % 100 < 10) ? "0" : "") + String(adjustedFreq % 100); - // Calculate signal strength and format it with the selected unit int SStatusPrint = 0; if (unit == 0) SStatusPrint = SStatus; // dBμV else if (unit == 1) SStatusPrint = ((SStatus * 100) + 10875) / 100; // dBf @@ -474,19 +373,14 @@ void sendUDPlog() { else if (unit == 1) signal += " dBf"; else if (unit == 2) signal += " dBm"; - // Prepare the radio text with RDS station information and enhanced options String radioText = String(radio.rds.stationText + " " + radio.rds.stationText32); - if (radio.rds.hasEnhancedRT) { - radioText += " eRT: " + String(radio.rds.enhancedRTtext); - } + if (radio.rds.hasEnhancedRT) radioText += " eRT: " + String(radio.rds.enhancedRTtext); - // Replace commas in the station name and radio text to avoid conflicts in the CSV format String stationName = radio.rds.stationName; stationName.replace(",", " "); String radioTextModified = radioText; radioTextModified.replace(",", " "); - // Extract and format ECC (Extended Country Code) if available String ECC = ""; if (radio.rds.hasECC) { char eccBuffer[3]; @@ -494,16 +388,13 @@ void sendUDPlog() { ECC = String(eccBuffer); } - // Format the list of Alternative Frequencies (AF) if available String AF = ""; if (radio.rds.hasAF && radio.af_counter > 0) { for (byte i = 0; i < radio.af_counter; i++) { - AF += String(radio.af[i].frequency / 100) + "." + String((radio.af[i].frequency % 100) / 10) + - (i == radio.af_counter - 1 ? "" : ";"); + AF += String(radio.af[i].frequency / 100) + "." + String((radio.af[i].frequency % 100) / 10) + (i == radio.af_counter - 1 ? "" : ";"); } } - // Format Enhanced Other Networks (EON) data if available String EON = ""; if (radio.eon_counter > 0) { for (byte i = 0; i < radio.eon_counter; i++) { @@ -516,7 +407,6 @@ void sendUDPlog() { } } - // set Chipmodel String CHIP = ""; switch (chipmodel) { case 0: CHIP = "TEF6686"; break; @@ -525,11 +415,8 @@ void sendUDPlog() { case 3: CHIP = "TEF6689"; break; } - // Extract RT+ (RadioText Plus) content if available String RTPLUS = ""; - if (radio.rds.hasRDSplus) { - RTPLUS += radio.rds.RTContent1 + ";" + radio.rds.RTContent2; - } + if (radio.rds.hasRTplus) RTPLUS += radio.rds.RTContent1 + ";" + radio.rds.RTContent2; // Construct the data row to send via UDP String row = CHIP + "," + @@ -541,9 +428,9 @@ void sendUDPlog() { signal + "," + String(radio.getStereoStatus()) + "," + String(radio.rds.hasTA) + "," + - String(radio.rds.hasTP) + "," + + String(radio.rds.TP) + "," + String(radio.rds.hasTMC) + "," + - String(radio.rds.stationTypeCode) + "," + + String(radio.rds.PTY) + "," + ECC + "," + stationName + "," + radioTextModified + "," + diff --git a/src/main.cpp b/src/main.cpp index ebee6fe..68de6cd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5110,17 +5110,12 @@ void StoreMemoryPos(uint8_t _pos) { EEPROM.writeByte(_pos + EE_PRESETS_BAND_START, band); EEPROM.writeByte(_pos + EE_PRESET_BW_START, BWset); EEPROM.writeByte(_pos + EE_PRESET_MS_START, StereoToggle); - if (band == BAND_FM) {//todo air - EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency); - } else if (band == BAND_OIRT) { - EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_OIRT); - } else if (band == BAND_LW) { - EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_LW); - } else if (band == BAND_MW) { - EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_MW); - } else { - EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_SW); - } + + if (band == BAND_FM) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency); + else if (band == BAND_OIRT) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_OIRT); + else if (band == BAND_LW) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_LW); + else if (band == BAND_MW) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_MW); + else EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_SW); presets[_pos].band = band; presets[_pos].bw = BWset; @@ -5144,17 +5139,11 @@ void StoreMemoryPos(uint8_t _pos) { EEPROM.commit(); - if (band == BAND_FM) {//todo air - presets[_pos].frequency = frequency; - } else if (band == BAND_OIRT) { - presets[_pos].frequency = frequency_OIRT; - } else if (band == BAND_LW) { - presets[_pos].frequency = frequency_LW; - } else if (band == BAND_MW) { - presets[_pos].frequency = frequency_MW; - } else { - presets[_pos].frequency = frequency_SW; - } + if (band == BAND_FM) presets[_pos].frequency = frequency; + else if (band == BAND_OIRT) presets[_pos].frequency = frequency_OIRT; + else if (band == BAND_LW) presets[_pos].frequency = frequency_LW; + else if (band == BAND_MW) presets[_pos].frequency = frequency_MW; + else presets[_pos].frequency = frequency_SW; } void ClearMemoryRange(uint8_t start, uint8_t stop) { @@ -5180,9 +5169,7 @@ void ClearMemoryRange(uint8_t start, uint8_t stop) { } } -byte numval[16] = { - 2, 3, 127, 5, 6, 0, 9, 13, 8, 7, 4, 1, 0, 0, 0, 0 -}; +byte numval[16] = {2, 3, 127, 5, 6, 0, 9, 13, 8, 7, 4, 1, 0, 0, 0, 0}; int GetNum() { int16_t temp; @@ -5201,12 +5188,11 @@ int GetNum() { for (int i = 0; i < 16; i++) { if ((temp & 0x01) == 0) { num = numval[i]; - cnt ++; + cnt++; } temp >>= 1; } - if (cnt == 1) - return num; + if (cnt == 1) return num; } return -1; diff --git a/src/rds.cpp b/src/rds.cpp index fd6701f..366e13a 100644 --- a/src/rds.cpp +++ b/src/rds.cpp @@ -132,12 +132,12 @@ void ShowAdvancedRDS() { } String rtplusstring; - if (radio.rds.hasRDSplus) rtplusstring = (radio.rds.rdsplusTag1 != 169 ? String(textUI(radio.rds.rdsplusTag1)) + ": " + String(radio.rds.RTContent1) : "") + (radio.rds.rdsplusTag2 != 169 ? " - " + String(textUI(radio.rds.rdsplusTag2)) + ": " + String(radio.rds.RTContent2) : "") + " "; else rtplusstring = textUI(89); - if (hasrtplusold != radio.rds.hasRDSplus) { + if (radio.rds.hasRTplus) rtplusstring = (radio.rds.rdsplusTag1 != 169 ? String(textUI(radio.rds.rdsplusTag1)) + ": " + String(radio.rds.RTContent1) : "") + (radio.rds.rdsplusTag2 != 169 ? " - " + String(textUI(radio.rds.rdsplusTag2)) + ": " + String(radio.rds.RTContent2) : "") + " "; else rtplusstring = textUI(89); + if (hasrtplusold != radio.rds.hasRTplus) { if (!screenmute) { - if (radio.rds.hasRDSplus) tftPrint(ALEFT, "RT+", 123, 51, RDSColor, RDSColorSmooth, 16); else tftPrint(ALEFT, "RT+", 123, 51, GreyoutColor, BackgroundColor, 16); + if (radio.rds.hasRTplus) tftPrint(ALEFT, "RT+", 123, 51, RDSColor, RDSColorSmooth, 16); else tftPrint(ALEFT, "RT+", 123, 51, GreyoutColor, BackgroundColor, 16); } - hasrtplusold = radio.rds.hasRDSplus; + hasrtplusold = radio.rds.hasRTplus; } if (rtplusstring != rtplusstringold) { @@ -172,11 +172,11 @@ void ShowAdvancedRDS() { } } - if (TPold != radio.rds.hasTP) { + if (TPold != radio.rds.TP) { if (!screenmute) { - if (radio.rds.hasTP) tftPrint(ALEFT, "TP", 2, 51, RDSColor, RDSColorSmooth, 16); else tftPrint(ALEFT, "TP", 2, 51, GreyoutColor, BackgroundColor, 16); + if (radio.rds.TP) tftPrint(ALEFT, "TP", 2, 51, RDSColor, RDSColorSmooth, 16); else tftPrint(ALEFT, "TP", 2, 51, GreyoutColor, BackgroundColor, 16); } - TPold = radio.rds.hasTP; + TPold = radio.rds.TP; } if (TAold != radio.rds.hasTA) { @@ -193,10 +193,10 @@ void ShowAdvancedRDS() { afmethodBold = radio.afmethodB; } - if (rdsblockold != radio.rdsblock) { + if (rdsblockold != radio.rdsgroup) { if (rdsblockold < 33) tft.fillCircle((6 * rdsblockold) + 10, 133, 2, SignificantColor); - if (radio.rdsblock < 33) tft.fillCircle((6 * radio.rdsblock) + 10, 133, 2, InsignificantColor); - rdsblockold = radio.rdsblock; + if (radio.rdsgroup < 33) tft.fillCircle((6 * radio.rdsgroup) + 10, 133, 2, InsignificantColor); + rdsblockold = radio.rdsgroup; } if (hastmcold != radio.rds.hasTMC) { @@ -527,9 +527,9 @@ void showPI() { void showPTY() { if (strcmp(radio.rds.stationType, programTypePrevious)) { - String PTYString = String(radio.rds.stationTypeCode) + "/" + (radio.rds.region != 0 ? radio.rds.stationType : textUI(228 + radio.rds.stationTypeCode)); + String PTYString = String(radio.rds.PTY) + "/" + (radio.rds.region != 0 ? radio.rds.stationType : textUI(228 + radio.rds.PTY)); - if (radio.rds.stationTypeCode == 32) PTYString = ""; + if (radio.rds.PTY == 32) PTYString = ""; if (!screenmute) { if (advancedRDS) { @@ -545,7 +545,7 @@ void showPTY() { if (wifi) { Udp.beginPacket(remoteip, 9030); Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";PTY="); - Udp.print(String(radio.rds.stationTypeCode, HEX)); + Udp.print(String(radio.rds.PTY, HEX)); Udp.endPacket(); } strcpy(programTypePrevious, radio.rds.stationType); @@ -1015,7 +1015,7 @@ void ShowRDSStatistics() { const uint8_t rdsYpos[] PROGMEM = {56, 76, 96, 116, 136, 156, 176, 196}; - uint8_t rb = radio.rdsblock; + uint8_t rb = radio.rdsgroup; uint16_t xpos, xposPct; if(rb <= RDS_GROUP_3B) {