Added RDS statistics analyser
This commit is contained in:
+60
-46
@@ -110,6 +110,7 @@ bool NTPupdated;
|
||||
bool optenc;
|
||||
bool rdsflagreset;
|
||||
bool rdsreset;
|
||||
bool rdsstatscreen;
|
||||
bool RDSSPYTCP;
|
||||
bool RDSSPYUSB;
|
||||
bool RDSstatus;
|
||||
@@ -427,6 +428,7 @@ unsigned long afticker;
|
||||
unsigned long aftickerhold;
|
||||
unsigned long aftimer;
|
||||
unsigned long autosquelchtimer;
|
||||
unsigned long blockcounterold[33];
|
||||
unsigned long eonticker;
|
||||
unsigned long eontickerhold;
|
||||
unsigned long flashingtimer;
|
||||
@@ -437,6 +439,7 @@ unsigned long ModulationpreviousMillis;
|
||||
unsigned long ModulationpeakPreviousMillis;
|
||||
unsigned long NTPtimer;
|
||||
unsigned long peakholdmillis;
|
||||
unsigned long processed_rdsblocksold[33];
|
||||
unsigned long pslongticker;
|
||||
unsigned long pslongtickerhold;
|
||||
unsigned long rtplusticker;
|
||||
@@ -1104,7 +1107,7 @@ void loop() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!BWtune && !menu && !afscreen && !scandxmode) {
|
||||
if (!BWtune && !menu && !afscreen && !rdsstatscreen && !scandxmode) {
|
||||
if (af != 0 && dropout && millis() >= aftimer + 1000) {
|
||||
aftimer = millis();
|
||||
if (radio.af_counter == 0) {
|
||||
@@ -1223,7 +1226,7 @@ void loop() {
|
||||
if (seek) Seek(direction);
|
||||
|
||||
if ((SStatus / 10 > LowLevelSet) && !LowLevelInit && !BWtune && !menu && band < BAND_GAP) {
|
||||
if (!screenmute && !advancedRDS && !afscreen) {
|
||||
if (!screenmute && !advancedRDS && !rdsstatscreen && !afscreen) {
|
||||
if (showmodulation) {
|
||||
tftPrint(-1, "10", 24, 144, ActiveColor, ActiveColorSmooth, 16);
|
||||
tftPrint(-1, "30", 54, 144, ActiveColor, ActiveColorSmooth, 16);
|
||||
@@ -1255,7 +1258,7 @@ void loop() {
|
||||
|
||||
if ((SStatus / 10 <= LowLevelSet) && band < BAND_GAP) {
|
||||
if (LowLevelInit && !BWtune && !menu) {
|
||||
if (!screenmute && !afscreen && !advancedRDS) {
|
||||
if (!screenmute && !rdsstatscreen && !afscreen && !advancedRDS) {
|
||||
for (byte segments = 0; segments < 94; segments++) {
|
||||
if (segments > 54) {
|
||||
if (((segments - 53) % 10) == 0) tft.fillRect(16 + (2 * segments), 141, 2, 2, GreyoutColor);
|
||||
@@ -1315,7 +1318,7 @@ void loop() {
|
||||
doSquelch();
|
||||
if (millis() >= tuningtimer + 200) readRds();
|
||||
GetData();
|
||||
if (!screenmute && !afscreen && !advancedRDS) ShowModLevel();
|
||||
if (!screenmute && !rdsstatscreen && !afscreen && !advancedRDS) ShowModLevel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1373,7 +1376,7 @@ void loop() {
|
||||
WakeToSleep(REVERSE);
|
||||
while (digitalRead(ROTARY_BUTTON) == LOW);
|
||||
} else {
|
||||
if (!afscreen) ButtonPress();
|
||||
if (!afscreen && !rdsstatscreen) ButtonPress();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1393,7 +1396,7 @@ void loop() {
|
||||
WakeToSleep(REVERSE);
|
||||
while (digitalRead(BWBUTTON) == LOW);
|
||||
} else {
|
||||
if (!screenmute && !afscreen) BWButtonPress();
|
||||
if (!screenmute) BWButtonPress();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1403,7 +1406,7 @@ void loop() {
|
||||
num = GetNum();
|
||||
if (num != -1)
|
||||
{
|
||||
if (!screenmute && !BWtune && !menu && !advancedRDS && !afscreen)
|
||||
if (!screenmute && !BWtune && !menu && !advancedRDS && !rdsstatscreen && !afscreen)
|
||||
{
|
||||
NumpadProcess(num);
|
||||
}
|
||||
@@ -1414,13 +1417,14 @@ void loop() {
|
||||
}
|
||||
|
||||
void GetData() {
|
||||
if (!afscreen) ShowSignalLevel();
|
||||
if (!BWtune && !menu) showPS();
|
||||
if (!afscreen && !rdsstatscreen) ShowSignalLevel();
|
||||
if (!BWtune && !menu && !rdsstatscreen) showPS();
|
||||
|
||||
if (band < BAND_GAP && !BWtune && !menu) {
|
||||
if (advancedRDS && !afscreen && !screenmute) ShowAdvancedRDS();
|
||||
if (advancedRDS && !afscreen && !rdsstatscreen && !screenmute) ShowAdvancedRDS();
|
||||
if (!advancedRDS && !afscreen && rdsstatscreen && !screenmute) ShowRDSStatistics();
|
||||
if (afscreen && !screenmute) ShowAFEON();
|
||||
if (!afscreen) {
|
||||
if (!afscreen && !rdsstatscreen) {
|
||||
if (!screenmute) ShowErrors();
|
||||
showPTY();
|
||||
showECC();
|
||||
@@ -1870,7 +1874,7 @@ void BANDBUTTONPress() {
|
||||
while (digitalRead(BANDBUTTON) == LOW && counter - counterold <= 1000) counter = millis();
|
||||
|
||||
if (counter - counterold < 1000) {
|
||||
if (afscreen) {
|
||||
if (afscreen || rdsstatscreen) {
|
||||
leave = true;
|
||||
BuildAdvancedRDS();
|
||||
freq_in = 0;
|
||||
@@ -2306,7 +2310,7 @@ void ToggleSWMIBand(bool frequencyup) {
|
||||
}
|
||||
|
||||
void SelectBand() {
|
||||
if (afscreen || advancedRDS) {
|
||||
if (afscreen || advancedRDS || rdsstatscreen) {
|
||||
BuildDisplay();
|
||||
freq_in = 0;
|
||||
}
|
||||
@@ -2429,37 +2433,41 @@ void SelectBand() {
|
||||
void BWButtonPress() {
|
||||
if (seek) radio.setUnMute();
|
||||
seek = false;
|
||||
if (scandxmode) {
|
||||
unsigned long counterold = millis();
|
||||
unsigned long counter = millis();
|
||||
while (digitalRead(BWBUTTON) == LOW && counter - counterold <= 1000) counter = millis();
|
||||
|
||||
if (counter - counterold < 1000) {
|
||||
ShowFreq(5);
|
||||
ShowFreq(0);
|
||||
} else {
|
||||
cancelDXScan();
|
||||
}
|
||||
if (afscreen || rdsstatscreen) {
|
||||
BuildRDSStatScreen();
|
||||
} else {
|
||||
if (!usesquelch) radio.setUnMute();
|
||||
if (!BWtune && !menu) {
|
||||
if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor);
|
||||
if (scandxmode) {
|
||||
unsigned long counterold = millis();
|
||||
unsigned long counter = millis();
|
||||
while (digitalRead(BWBUTTON) == LOW && counter - counterold <= 1000) counter = millis();
|
||||
|
||||
if (counter - counterold < 1000) {
|
||||
BuildBWSelector();
|
||||
freq_in = 0;
|
||||
BWtune = true;
|
||||
BWtemp = BWset;
|
||||
ShowFreq(5);
|
||||
ShowFreq(0);
|
||||
} else {
|
||||
if (band == BAND_FM || band == BAND_OIRT) {
|
||||
doStereoToggle();
|
||||
} else {
|
||||
cancelDXScan();
|
||||
}
|
||||
} else {
|
||||
if (!usesquelch) radio.setUnMute();
|
||||
if (!BWtune && !menu) {
|
||||
if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor);
|
||||
unsigned long counterold = millis();
|
||||
unsigned long counter = millis();
|
||||
while (digitalRead(BWBUTTON) == LOW && counter - counterold <= 1000) counter = millis();
|
||||
|
||||
if (counter - counterold < 1000) {
|
||||
BuildBWSelector();
|
||||
freq_in = 0;
|
||||
BWtune = true;
|
||||
BWtemp = BWset;
|
||||
} else {
|
||||
if (band == BAND_FM || band == BAND_OIRT) {
|
||||
doStereoToggle();
|
||||
} else {
|
||||
BuildBWSelector();
|
||||
freq_in = 0;
|
||||
BWtune = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2506,6 +2514,9 @@ void ModeButtonPress() {
|
||||
if (afpagenr == 1) afpagenr = 2; else if (afpagenr == 2 && afpage) afpagenr = 3; else afpagenr = 1;
|
||||
BuildAFScreen();
|
||||
freq_in = 0;
|
||||
} else if (rdsstatscreen) {
|
||||
BuildAFScreen();
|
||||
freq_in = 0;
|
||||
} else {
|
||||
if (!BWtune && !menu) {
|
||||
if (!screenmute) {
|
||||
@@ -2813,7 +2824,7 @@ void KeyUp() {
|
||||
ShowFreq(5);
|
||||
ShowFreq(0);
|
||||
} else {
|
||||
if (!afscreen) {
|
||||
if (!afscreen && !rdsstatscreen) {
|
||||
if (!BWtune && !menu) {
|
||||
switch (tunemode) {
|
||||
case TUNE_MAN:
|
||||
@@ -2881,7 +2892,7 @@ void KeyDown() {
|
||||
ShowFreq(5);
|
||||
ShowFreq(0);
|
||||
} else {
|
||||
if (!afscreen) {
|
||||
if (!afscreen && !rdsstatscreen) {
|
||||
if (!BWtune && !menu) {
|
||||
switch (tunemode) {
|
||||
case TUNE_MAN:
|
||||
@@ -3226,7 +3237,7 @@ void ShowFreq(int mode) {
|
||||
}
|
||||
tuningtimer = millis();
|
||||
|
||||
if (!rdsflagreset && !screenmute && !afscreen) {
|
||||
if (!rdsflagreset && !screenmute && !afscreen && !rdsstatscreen) {
|
||||
ShowRDSLogo(false);
|
||||
if (!advancedRDS) {
|
||||
FullLineSprite.fillSprite(BackgroundColor);
|
||||
@@ -3652,7 +3663,7 @@ void doSquelch() {
|
||||
if (language == LANGUAGE_CHS) SquelchSprite.loadFont(FONT16_CHS); else SquelchSprite.loadFont(FONT16);
|
||||
|
||||
if (!XDRGTKUSB && !XDRGTKTCP && usesquelch && (!scandxmode || (scandxmode && !scanmute))) {
|
||||
if (!screenmute && usesquelch && !advancedRDS && !afscreen) {
|
||||
if (!screenmute && usesquelch && !advancedRDS && !afscreen && !rdsstatscreen) {
|
||||
if (!BWtune && !menu && (Squelch > Squelchold + 2 || Squelch < Squelchold - 2)) {
|
||||
SquelchSprite.setTextColor(PrimaryColor, PrimaryColorSmooth, false);
|
||||
SquelchSprite.fillSprite(BackgroundColor);
|
||||
@@ -3700,7 +3711,7 @@ void doSquelch() {
|
||||
SQ = true;
|
||||
}
|
||||
}
|
||||
if (!screenmute && usesquelch && !advancedRDS && !afscreen) {
|
||||
if (!screenmute && usesquelch && !advancedRDS && !afscreen && !rdsstatscreen) {
|
||||
if (Squelch != Squelchold) {
|
||||
SquelchSprite.setTextColor(PrimaryColor, PrimaryColorSmooth, false);
|
||||
SquelchSprite.fillSprite(BackgroundColor);
|
||||
@@ -3756,13 +3767,13 @@ void doSquelch() {
|
||||
|
||||
void updateBW() {//todo air
|
||||
if (BWset == 0) {
|
||||
if (!BWtune && !screenmute && !advancedRDS && !afscreen) {
|
||||
if (!BWtune && !screenmute && !advancedRDS && !afscreen && !rdsstatscreen) {
|
||||
tft.fillRoundRect(248, 36, 69, 18, 2, SecondaryColor);
|
||||
tftPrint(0, "AUTO BW", 282, 38, BackgroundColor, SecondaryColor, 16);
|
||||
}
|
||||
radio.setFMABandw();
|
||||
} else {
|
||||
if (!BWtune && !screenmute && !advancedRDS && !afscreen) {
|
||||
if (!BWtune && !screenmute && !advancedRDS && !afscreen && !rdsstatscreen) {
|
||||
tft.fillRoundRect(248, 36, 69, 18, 2, GreyoutColor);
|
||||
tftPrint(0, "AUTO BW", 282, 38, BackgroundColor, GreyoutColor, 16);
|
||||
}
|
||||
@@ -3772,13 +3783,13 @@ void updateBW() {//todo air
|
||||
void updateiMS() {
|
||||
if (band < BAND_GAP) {
|
||||
if (iMSset == 0) {
|
||||
if (!screenmute && !advancedRDS && !afscreen && !BWtune) {
|
||||
if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) {
|
||||
tft.fillRoundRect(249, 57, 30, 18, 2, SecondaryColor);
|
||||
tftPrint(0, "iMS", 265, 59, BackgroundColor, SecondaryColor, 16);
|
||||
}
|
||||
radio.setiMS(1);
|
||||
} else {
|
||||
if (!screenmute && !advancedRDS && !afscreen && !BWtune) {
|
||||
if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) {
|
||||
tft.fillRoundRect(249, 57, 30, 18, 2, GreyoutColor);
|
||||
tftPrint(0, "iMS", 265, 59, BackgroundColor, GreyoutColor, 16);
|
||||
}
|
||||
@@ -3790,13 +3801,13 @@ void updateiMS() {
|
||||
void updateEQ() {
|
||||
if (band < BAND_GAP) {
|
||||
if (EQset == 0) {
|
||||
if (!screenmute && !advancedRDS && !afscreen && !BWtune) {
|
||||
if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) {
|
||||
tft.fillRoundRect(287, 57, 30, 18, 2, SecondaryColor);
|
||||
tftPrint(0, "EQ", 301, 59, BackgroundColor, SecondaryColor, 16);
|
||||
}
|
||||
radio.setEQ(1);
|
||||
} else {
|
||||
if (!screenmute && !advancedRDS && !afscreen && !BWtune) {
|
||||
if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) {
|
||||
tft.fillRoundRect(287, 57, 30, 18, 2, GreyoutColor);
|
||||
tftPrint(0, "EQ", 301, 59, BackgroundColor, GreyoutColor, 16);
|
||||
}
|
||||
@@ -4477,6 +4488,9 @@ void MuteScreen(bool setting) {
|
||||
} else if (advancedRDS) {
|
||||
BuildAdvancedRDS();
|
||||
freq_in = 0;
|
||||
} else if (rdsstatscreen) {
|
||||
BuildRDSStatScreen();
|
||||
freq_in = 0;
|
||||
} else {
|
||||
BuildDisplay();
|
||||
freq_in = 0;
|
||||
@@ -4897,7 +4911,7 @@ void startFMDXScan() {
|
||||
}
|
||||
|
||||
if (menu) endMenu();
|
||||
if (afscreen || advancedRDS) {
|
||||
if (afscreen || advancedRDS || rdsstatscreen) {
|
||||
BuildDisplay();
|
||||
freq_in = 0;
|
||||
}
|
||||
|
||||
@@ -596,6 +596,9 @@ void TEF6686::readRDS(byte showrdserrors) {
|
||||
}
|
||||
|
||||
if (!rds.rdsBerror || showrdserrors == 3) rdsblock = rds.rdsB >> 11; else return;
|
||||
rds.blockcounter[rdsblock]++;
|
||||
processed_rdsblocks++;
|
||||
|
||||
switch (rdsblock) {
|
||||
case RDS_GROUP_0A:
|
||||
case RDS_GROUP_0B:
|
||||
@@ -1783,9 +1786,12 @@ void TEF6686::clearRDS (bool fullsearchrds) {
|
||||
RDSplus2[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 33; i++) rds.blockcounter[i] = 0;
|
||||
|
||||
for (i = 0; i < 10; i++) rds.aid[i] = 0;
|
||||
|
||||
rdsblock = 254;
|
||||
processed_rdsblocks = 0;
|
||||
piold = 0;
|
||||
rds.correctPI = 0;
|
||||
rds.ECC = 254;
|
||||
|
||||
@@ -592,6 +592,7 @@ typedef struct _rds_ {
|
||||
char stationState[3];
|
||||
char dabafeid[5];
|
||||
char dabafchannel[4];
|
||||
unsigned long blockcounter[33];
|
||||
uint16_t rdsA, rdsB, rdsC, rdsD, rdsErr, rdsStat, correctPI, rdsplusTag1, rdsplusTag2, PICTlock = 0;
|
||||
bool ps12error, ps34error, ps56error, ps78error;
|
||||
time_t time;
|
||||
@@ -732,6 +733,7 @@ class TEF6686 {
|
||||
uint8_t eon_counter;
|
||||
uint8_t logbook_counter;
|
||||
uint8_t rdsblock;
|
||||
unsigned long processed_rdsblocks;
|
||||
bool mute;
|
||||
bool afmethodB;
|
||||
byte underscore;
|
||||
|
||||
+89
@@ -478,6 +478,92 @@ void doTheme() { // Use this to put your own colors in: http://www.barth-dev.de
|
||||
}
|
||||
}
|
||||
|
||||
void BuildRDSStatScreen() {
|
||||
// Only build screen if not already active
|
||||
if (!rdsstatscreen) {
|
||||
// Set page flags
|
||||
afscreen = false;
|
||||
advancedRDS = false;
|
||||
rdsstatscreen = true;
|
||||
|
||||
// --- Draw frame and static lines ---
|
||||
tft.fillScreen(BackgroundColor);
|
||||
tft.drawRect(0, 0, 320, 240, FrameColor);
|
||||
tft.drawLine(0, 30, 320, 30, FrameColor);
|
||||
tft.drawLine(0, 218, 320, 218, FrameColor);
|
||||
tft.drawLine(30, 30, 30, 0, FrameColor);
|
||||
tft.drawLine(66, 30, 66, 0, FrameColor);
|
||||
tft.drawLine(105, 30, 105, 0, FrameColor);
|
||||
tft.drawLine(162, 30, 162, 0, FrameColor);
|
||||
tft.drawLine(248, 30, 248, 0, FrameColor);
|
||||
tft.drawLine(0, 50, 320, 50, FrameColor);
|
||||
tft.drawLine(208, 30, 208, 50, FrameColor);
|
||||
tft.drawLine(80, 30, 80, 218, FrameColor);
|
||||
tft.drawLine(160, 30, 160, 218, FrameColor);
|
||||
tft.drawLine(240, 30, 240, 218, FrameColor);
|
||||
|
||||
// --- Column headers ---
|
||||
tftPrint(-1, "kHz", 205, 4, ActiveColor, ActiveColorSmooth, 28);
|
||||
|
||||
// --- Labels above packet columns ---
|
||||
tftPrint(-1, "ERRORS", 3, 34, ActiveColor, ActiveColorSmooth, 16);
|
||||
tftPrint(-1, "A:", 66, 34, ActiveColor, ActiveColorSmooth, 16);
|
||||
tftPrint(-1, "B:", 104, 34, ActiveColor, ActiveColorSmooth, 16);
|
||||
tftPrint(-1, "C:", 142, 34, ActiveColor, ActiveColorSmooth, 16);
|
||||
tftPrint(-1, "D:", 180, 34, ActiveColor, ActiveColorSmooth, 16);
|
||||
tftPrint(-1, "PACKETS", 210, 34, ActiveColor, ActiveColorSmooth, 16);
|
||||
|
||||
// --- Group labels setup ---
|
||||
const uint16_t xcol[4] = {10, 90, 170, 250}; // column X positions
|
||||
const uint16_t rowY[8] = {56, 76, 96, 116, 136, 156, 176, 196}; // row Y positions
|
||||
|
||||
// Labels for each group (A/B)
|
||||
const char* const groups[16][2] = {
|
||||
{"0A", "0B"}, {"1A", "1B"}, {"2A", "2B"}, {"3A", "3B"},
|
||||
{"4A", "4B"}, {"5A", "5B"}, {"6A", "6B"}, {"7A", "7B"},
|
||||
{"8A", "8B"}, {"9A", "9B"}, {"10A", "10B"}, {"11A", "11B"},
|
||||
{"12A", "12B"}, {"13A", "13B"}, {"14A", "14B"}, {"15A", "15B"}
|
||||
};
|
||||
|
||||
// --- Draw group labels in columns with correct Y positions ---
|
||||
for (uint8_t col = 0; col < 4; col++) { // 4 columns
|
||||
for (uint8_t row = 0; row < 4; row++) { // 4 groups per column
|
||||
uint8_t g = col * 4 + row; // group index 0..15
|
||||
tftPrint(-1, groups[g][0], xcol[col], rowY[row * 2], ActiveColor, ActiveColorSmooth, 16); // A
|
||||
tftPrint(-1, groups[g][1], xcol[col], rowY[row * 2 + 1], ActiveColor, ActiveColorSmooth, 16); // B
|
||||
}
|
||||
}
|
||||
|
||||
// --- Draw 0.0 % in four columns ---
|
||||
const uint16_t pctX[4] = {70, 150, 230, 310};
|
||||
for (uint8_t c = 0; c < 4; c++) {
|
||||
for (uint8_t y = 56; y < 216; y += 20) {
|
||||
tftPrint(1, "0.0", pctX[c] - 10, y, GreyoutColor, BackgroundColor, 16); // placeholder value
|
||||
tftPrint(0, "%", pctX[c], y, GreyoutColor, BackgroundColor, 16);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Reset stored states ---
|
||||
RDSstatusold = !RDSstatusold;
|
||||
Stereostatusold = false;
|
||||
BWreset = true;
|
||||
rssiold = 2000;
|
||||
batteryold = 6;
|
||||
batteryVold = 0;
|
||||
vPerold = 0;
|
||||
rds_clockold = "";
|
||||
dropout = false;
|
||||
rdsreset = true;
|
||||
|
||||
// --- Clear previous RDS block counters ---
|
||||
for (int x = 0; x < 33; x++) {
|
||||
processed_rdsblocksold[x] = 0;
|
||||
blockcounterold[x] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BuildAFScreen() {
|
||||
if (!afscreen && RDSstatus) {
|
||||
tft.drawRoundRect(20, 30, 274, 170, 5, ActiveColor);
|
||||
@@ -487,6 +573,7 @@ void BuildAFScreen() {
|
||||
}
|
||||
afscreen = true;
|
||||
advancedRDS = false;
|
||||
rdsstatscreen = false;
|
||||
|
||||
tft.fillScreen(BackgroundColor);
|
||||
tft.drawRect(0, 0, 320, 240, FrameColor);
|
||||
@@ -2850,6 +2937,7 @@ void BuildMenu() {
|
||||
|
||||
void BuildAdvancedRDS() {
|
||||
afscreen = false;
|
||||
rdsstatscreen = false;
|
||||
afpage = false;
|
||||
afpagenr = 1;
|
||||
advancedRDS = true;
|
||||
@@ -2980,6 +3068,7 @@ void BuildAdvancedRDS() {
|
||||
|
||||
void BuildDisplay() {
|
||||
afscreen = false;
|
||||
rdsstatscreen = false;
|
||||
advancedRDS = false;
|
||||
BWtune = false;
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ extern bool mwstepsize;
|
||||
extern bool rdsreset;
|
||||
extern bool RDSstatus;
|
||||
extern bool RDSstatusold;
|
||||
extern bool rdsstatscreen;
|
||||
extern bool rdsstereoold;
|
||||
extern bool usesquelch;
|
||||
extern bool scandxmode;
|
||||
@@ -205,6 +206,8 @@ extern unsigned int mappedfreqold2[20];
|
||||
extern unsigned int mappedfreqold3[20];
|
||||
extern unsigned int memstartfreq;
|
||||
extern unsigned int memstopfreq;
|
||||
extern unsigned long blockcounterold[33];
|
||||
extern unsigned long processed_rdsblocksold[33];
|
||||
extern unsigned long scantimer;
|
||||
extern byte items[10];
|
||||
extern const size_t language_totalnumber;
|
||||
@@ -219,6 +222,7 @@ extern TFT_eSprite PSSprite;
|
||||
extern TFT_eSprite FrequencySprite;
|
||||
|
||||
void BuildAFScreen();
|
||||
void BuildRDSStatScreen();
|
||||
void BuildMenu();
|
||||
void BuildAdvancedRDS();
|
||||
void BuildDisplay();
|
||||
|
||||
+122
-4
@@ -4,6 +4,8 @@
|
||||
#include "constants.h"
|
||||
#include <TimeLib.h>
|
||||
|
||||
String HexStringold;
|
||||
|
||||
int RadiotextWidth, PSLongWidth, AIDWidth, afstringWidth, eonstringWidth, rtplusstringWidth, lengths[7];
|
||||
String afstringold, eonstringold, rtplusstringold, stationNameLongOld, AIDStringold;
|
||||
bool rtABold, ps12errorold, ps34errorold, ps56errorold, ps78errorold;
|
||||
@@ -307,7 +309,7 @@ void readRds() {
|
||||
RDSstatus = radio.rds.hasRDS;
|
||||
ShowRDSLogo(RDSstatus);
|
||||
|
||||
if (!screenmute && !afscreen) {
|
||||
if (!screenmute && !afscreen && !rdsstatscreen) {
|
||||
if (!RDSstatus) {
|
||||
if (radio.rds.correctPI != 0 && !dropout) {
|
||||
if (radio.rds.region == 0) {
|
||||
@@ -553,7 +555,7 @@ void ShowErrors() {
|
||||
|
||||
void showPI() {
|
||||
if ((radio.rds.region != 0 && (String(radio.rds.picode) != PIold || radio.rds.stationIDtext != stationIDold || radio.rds.stationStatetext != stationStateold)) || (radio.rds.region == 0 && String(radio.rds.picode) != PIold)) {
|
||||
if (!afscreen && !radio.rds.rdsAerror && !radio.rds.rdsBerror && !radio.rds.rdsCerror && !radio.rds.rdsDerror && radio.rds.rdsA != radio.rds.correctPI && PIold.length() > 1) {
|
||||
if (!rdsstatscreen && !afscreen && !radio.rds.rdsAerror && !radio.rds.rdsBerror && !radio.rds.rdsCerror && !radio.rds.rdsDerror && radio.rds.rdsA != radio.rds.correctPI && PIold.length() > 1) {
|
||||
radio.clearRDS(fullsearchrds);
|
||||
if (RDSSPYUSB) Serial.print("G:\r\nRESET-------\r\n\r\n");
|
||||
if (RDSSPYTCP) RemoteClient.print("G:\r\nRESET-------\r\n\r\n");
|
||||
@@ -579,7 +581,7 @@ void showPI() {
|
||||
}
|
||||
} else if (afscreen) {
|
||||
tftReplace(-1, PIold, radio.rds.picode, 30, 201, BWAutoColor, BWAutoColorSmooth, BackgroundColor, 16);
|
||||
} else {
|
||||
} else if (!rdsstatscreen) {
|
||||
if (radio.rds.region == 0) {
|
||||
if (!RDSstatus) {
|
||||
tftReplace(0, PIold, radio.rds.picode, 275, 187, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 28);
|
||||
@@ -661,7 +663,7 @@ void showPS() {
|
||||
if (!screenmute) {
|
||||
tftReplace(0, PSold, radio.rds.stationName, 160, 201, BWAutoColor, BWAutoColorSmooth, BackgroundColor, 16);
|
||||
}
|
||||
} else {
|
||||
} else if (!rdsstatscreen) {
|
||||
// Handle long PS display
|
||||
if (radio.rds.hasLongPS && showlongps) {
|
||||
String stationNameLongString = String(radio.rds.stationNameLong) + " "; // Add trailing spaces for scrolling
|
||||
@@ -1230,4 +1232,120 @@ void ShowAFEON() {
|
||||
}
|
||||
}
|
||||
|
||||
void ShowRDSStatistics() {
|
||||
// Only update if RDS is active, blocks processed, and no errors in Block A-D
|
||||
if (RDSstatus && radio.processed_rdsblocks > 0 &&
|
||||
!radio.rds.rdsAerror && !radio.rds.rdsBerror &&
|
||||
!radio.rds.rdsCerror && !radio.rds.rdsDerror) {
|
||||
|
||||
// --- Draw A-D error circles ---
|
||||
const uint8_t xErr[4] = {86, 124, 162, 200}; // X positions for A-D
|
||||
const bool errors[4] = {radio.rds.rdsAerror, radio.rds.rdsBerror,
|
||||
radio.rds.rdsCerror, radio.rds.rdsDerror
|
||||
};
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
tft.fillCircle(xErr[i], 41, 5, errors[i] ? SignificantColor : InsignificantColor);
|
||||
}
|
||||
|
||||
// --- Update total processed RDS blocks if changed ---
|
||||
if (processed_rdsblocksold[32] != radio.processed_rdsblocks) {
|
||||
tftReplace(1, String(processed_rdsblocksold[32]), String(radio.processed_rdsblocks),
|
||||
318, 34, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16);
|
||||
processed_rdsblocksold[32] = radio.processed_rdsblocks;
|
||||
}
|
||||
|
||||
// --- Row Y positions (repeats every 8 groups) ---
|
||||
const uint8_t rdsYpos[] PROGMEM = {56, 76, 96, 116, 136, 156, 176, 196};
|
||||
|
||||
uint8_t rb = radio.rdsblock; // current RDS block
|
||||
|
||||
// --- Determine column X positions based on group range ---
|
||||
uint16_t xpos, xposPct;
|
||||
if (rb <= RDS_GROUP_3B ) {
|
||||
xpos = 60;
|
||||
xposPct = 70;
|
||||
}
|
||||
else if (rb <= RDS_GROUP_7B ) {
|
||||
xpos = 140;
|
||||
xposPct = 150;
|
||||
}
|
||||
else if (rb <= RDS_GROUP_11B) {
|
||||
xpos = 220;
|
||||
xposPct = 230;
|
||||
}
|
||||
else {
|
||||
xpos = 300;
|
||||
xposPct = 310;
|
||||
}
|
||||
|
||||
// --- Determine row Y position (wraps every 8 groups) ---
|
||||
uint8_t row = rb & 0x07; // modulo 8
|
||||
uint8_t ypos = pgm_read_byte(&rdsYpos[row]); // Y position
|
||||
|
||||
// --- Persist last drawn dot between calls ---
|
||||
static int16_t lastX = -1, lastY = -1; // -1 = "none yet"
|
||||
|
||||
// Only update if the block counter has changed
|
||||
if (blockcounterold[rb] != radio.rds.blockcounter[rb]) {
|
||||
// --- Calculate old and new percentage ---
|
||||
float oldPerc = (blockcounterold[rb] * 100.0f) / processed_rdsblocksold[rb];
|
||||
float newPerc = (radio.rds.blockcounter[rb] * 100.0f) / radio.processed_rdsblocks;
|
||||
|
||||
char oldBuf[6], newBuf[6]; // buffers for dtostrf
|
||||
dtostrf(oldPerc, 0, 1, oldBuf);
|
||||
dtostrf(newPerc, 0, 1, newBuf);
|
||||
|
||||
// --- Draw previous position as "Significant" if it exists and is different ---
|
||||
if (lastX >= 0 && (lastX != xpos || lastY != ypos)) {
|
||||
tft.fillCircle(lastX - 55, lastY + 7, 2, SignificantColor);
|
||||
}
|
||||
|
||||
// --- Update percentage display ---
|
||||
tftReplace(1, oldBuf, newBuf, xpos, ypos, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16);
|
||||
tftPrint(0, "%", xposPct, ypos, ActiveColor, ActiveColorSmooth, 16);
|
||||
|
||||
// --- Draw current dot as "Insignificant" ---
|
||||
tft.fillCircle(xpos - 55, ypos + 7, 2, InsignificantColor);
|
||||
|
||||
// --- Save current as last for next update ---
|
||||
lastX = xpos;
|
||||
lastY = ypos;
|
||||
|
||||
// --- Store updated block counters ---
|
||||
blockcounterold[rb] = radio.rds.blockcounter[rb];
|
||||
processed_rdsblocksold[rb] = radio.processed_rdsblocks;
|
||||
}
|
||||
|
||||
String HexString;
|
||||
// Convert 16-bit blocks rdsA..rdsD into 4-digit HEX strings
|
||||
HexString = String(((radio.rds.rdsA >> 12) & 0xF), HEX) +
|
||||
String(((radio.rds.rdsA >> 8) & 0xF), HEX) +
|
||||
String(((radio.rds.rdsA >> 4) & 0xF), HEX) +
|
||||
String(( radio.rds.rdsA & 0xF), HEX) + " ";
|
||||
|
||||
HexString += String(((radio.rds.rdsB >> 12) & 0xF), HEX) +
|
||||
String(((radio.rds.rdsB >> 8) & 0xF), HEX) +
|
||||
String(((radio.rds.rdsB >> 4) & 0xF), HEX) +
|
||||
String(( radio.rds.rdsB & 0xF), HEX) + " ";
|
||||
|
||||
HexString += String(((radio.rds.rdsC >> 12) & 0xF), HEX) +
|
||||
String(((radio.rds.rdsC >> 8) & 0xF), HEX) +
|
||||
String(((radio.rds.rdsC >> 4) & 0xF), HEX) +
|
||||
String(( radio.rds.rdsC & 0xF), HEX) + " ";
|
||||
|
||||
HexString += String(((radio.rds.rdsD >> 12) & 0xF), HEX) +
|
||||
String(((radio.rds.rdsD >> 8) & 0xF), HEX) +
|
||||
String(((radio.rds.rdsD >> 4) & 0xF), HEX) +
|
||||
String(( radio.rds.rdsD & 0xF), HEX);
|
||||
|
||||
// Make uppercase
|
||||
HexString.toUpperCase();
|
||||
|
||||
if (HexString != HexStringold) {
|
||||
tftReplace(0, HexStringold, HexString, 160, 222, ActiveColor, ActiveColorSmooth, BackgroundColor, 16);
|
||||
HexStringold = HexString;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
@@ -33,6 +33,7 @@ extern bool rdsreset;
|
||||
extern bool RDSSPYTCP;
|
||||
extern bool RDSSPYUSB;
|
||||
extern bool RDSstatus;
|
||||
extern bool rdsstatscreen;
|
||||
extern bool rdsstereoold;
|
||||
extern bool rtcset;
|
||||
extern bool screenmute;
|
||||
@@ -123,8 +124,10 @@ extern unsigned int mappedfreqold3[20];
|
||||
extern unsigned long afticker;
|
||||
extern unsigned long aftickerhold;
|
||||
extern unsigned long aftimer;
|
||||
extern unsigned long blockcounterold[33];
|
||||
extern unsigned long eonticker;
|
||||
extern unsigned long eontickerhold;
|
||||
extern unsigned long processed_rdsblocksold[33];
|
||||
extern unsigned long pslongticker;
|
||||
extern unsigned long pslongtickerhold;
|
||||
extern unsigned long rtplusticker;
|
||||
@@ -152,6 +155,7 @@ void showRadioText();
|
||||
void ShowAFEON();
|
||||
void showCT();
|
||||
void ShowErrors();
|
||||
void ShowRDSStatistics();
|
||||
|
||||
extern void ShowRDSLogo(bool RDSstatus);
|
||||
extern void DataPrint(String string);
|
||||
|
||||
Reference in New Issue
Block a user