You've already forked TEF6686_ESP32
this code was written by clowns? No it was AI
This commit is contained in:
@@ -1,6 +1,4 @@
|
|||||||
#ifndef NTP_H
|
#pragma once
|
||||||
#define NTP_H
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <WiFiClient.h>
|
#include <WiFiClient.h>
|
||||||
@@ -11,7 +9,7 @@
|
|||||||
|
|
||||||
static const char ntpServerName[] = "0.pool.ntp.org";
|
static const char ntpServerName[] = "0.pool.ntp.org";
|
||||||
static const int localPort = 8944;
|
static const int localPort = 8944;
|
||||||
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
|
const int NTP_PACKET_SIZE = 48;
|
||||||
|
|
||||||
extern ESP32Time rtc;
|
extern ESP32Time rtc;
|
||||||
extern WiFiClient RemoteClient;
|
extern WiFiClient RemoteClient;
|
||||||
@@ -25,4 +23,3 @@ extern bool rtcset;
|
|||||||
void sendNTPpacket(IPAddress &address);
|
void sendNTPpacket(IPAddress &address);
|
||||||
void NTPupdate();
|
void NTPupdate();
|
||||||
time_t getNtpTime();
|
time_t getNtpTime();
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -6,8 +6,7 @@
|
|||||||
class RdsPiBuffer
|
class RdsPiBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum State : uint8_t
|
enum State : uint8_t {
|
||||||
{
|
|
||||||
STATE_CORRECT = 0,
|
STATE_CORRECT = 0,
|
||||||
STATE_VERY_LIKELY = 1,
|
STATE_VERY_LIKELY = 1,
|
||||||
STATE_LIKELY = 2,
|
STATE_LIKELY = 2,
|
||||||
@@ -20,7 +19,6 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* BUFF_SIZE must be a multiple of 8 */
|
|
||||||
static constexpr uint8_t BUFF_SIZE = 64;
|
static constexpr uint8_t BUFF_SIZE = 64;
|
||||||
uint16_t buff[BUFF_SIZE];
|
uint16_t buff[BUFF_SIZE];
|
||||||
uint8_t errorBuff[BUFF_SIZE/8];
|
uint8_t errorBuff[BUFF_SIZE/8];
|
||||||
|
|||||||
@@ -547,7 +547,7 @@ class TEF6686 {
|
|||||||
void getProcessing(uint16_t &highcut, uint16_t &stereo, uint16_t &sthiblend, uint8_t &stband_1, uint8_t &stband_2, uint8_t &stband_3, uint8_t &stband_4);
|
void getProcessing(uint16_t &highcut, uint16_t &stereo, uint16_t &sthiblend, uint8_t &stband_1, uint8_t &stband_2, uint8_t &stband_3, uint8_t &stband_4);
|
||||||
void getStatus(int16_t &level, uint16_t &USN, uint16_t &WAM, int16_t &offset, uint16_t &bandwidth, uint16_t &modulation, int8_t &snr);
|
void getStatus(int16_t &level, uint16_t &USN, uint16_t &WAM, int16_t &offset, uint16_t &bandwidth, uint16_t &modulation, int8_t &snr);
|
||||||
void getStatusAM(int16_t &level, uint16_t &noise, uint16_t &cochannel, int16_t &offset, uint16_t &bandwidth, uint16_t &modulation, int8_t &snr);
|
void getStatusAM(int16_t &level, uint16_t &noise, uint16_t &cochannel, int16_t &offset, uint16_t &bandwidth, uint16_t &modulation, int8_t &snr);
|
||||||
void getIdentification(uint16_t &device, uint16_t &hw_version, uint16_t &sw_version);
|
void getIdentification(uint16_t *device, uint16_t *hw_version, uint16_t *sw_version);
|
||||||
void I2Sin(bool mode);
|
void I2Sin(bool mode);
|
||||||
void setSoftmuteFM(uint8_t mode);
|
void setSoftmuteFM(uint8_t mode);
|
||||||
void setSoftmuteAM(uint8_t mode);
|
void setSoftmuteAM(uint8_t mode);
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#ifndef TUNER_DRV_LITHIO_H
|
#pragma once
|
||||||
#define TUNER_DRV_LITHIO_H
|
|
||||||
|
#define High_16bto8b(a) ((uint8_t)((a) >> 8))
|
||||||
|
#define Low_16bto8b(a) ((uint8_t)(a ))
|
||||||
|
#define Convert8bto16b(a) ((uint16_t)(((uint16_t)(*(a))) << 8 |((uint16_t)(*(a+1)))))
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TEF_FM = 32,
|
TEF_FM = 32,
|
||||||
@@ -63,16 +66,15 @@ typedef enum {
|
|||||||
} TEF_APPL_COMMAND;
|
} TEF_APPL_COMMAND;
|
||||||
|
|
||||||
void devTEF_Set_Cmd(TEF_MODULE module, uint8_t cmd, uint16_t len, ...);
|
void devTEF_Set_Cmd(TEF_MODULE module, uint8_t cmd, uint16_t len, ...);
|
||||||
|
bool devTEF_Get_Cmd(TEF_MODULE module, uint8_t cmd, uint8_t *receive, uint16_t len);
|
||||||
void devTEF_Radio_Set_Noiseblanker_AM(uint8_t mode, uint16_t start);
|
void devTEF_Radio_Set_Noiseblanker_AM(uint8_t mode, uint16_t start);
|
||||||
void devTEF_Radio_Set_Wavegen(bool mode, int16_t amplitude, uint16_t freq);
|
void devTEF_Radio_Set_Wavegen(bool mode, int16_t amplitude, uint16_t freq);
|
||||||
void devTEF_Radio_Set_GPIO(uint8_t mode);
|
void devTEF_Radio_Set_GPIO(uint8_t mode);
|
||||||
|
|
||||||
bool devTEF_Radio_Get_Identification (uint16_t *device, uint16_t *hw_version, uint16_t *sw_version);
|
|
||||||
bool devTEF_Radio_Get_Quality_Status (uint16_t *status, int16_t *level, uint16_t *usn, uint16_t *wam, int16_t *offset, uint16_t *bandwidth, uint16_t *mod, int8_t *snr);
|
bool devTEF_Radio_Get_Quality_Status (uint16_t *status, int16_t *level, uint16_t *usn, uint16_t *wam, int16_t *offset, uint16_t *bandwidth, uint16_t *mod, int8_t *snr);
|
||||||
bool devTEF_Radio_Get_Processing_Status (uint16_t *highcut, uint16_t *stereo, uint16_t *sthiblend, uint8_t *stband_1, uint8_t *stband_2, uint8_t *stband_3, uint8_t *stband_4);
|
bool devTEF_Radio_Get_Processing_Status (uint16_t *highcut, uint16_t *stereo, uint16_t *sthiblend, uint8_t *stband_1, uint8_t *stband_2, uint8_t *stband_3, uint8_t *stband_4);
|
||||||
bool devTEF_Radio_Get_Quality_Status_AM (int16_t *level, uint16_t *noise, uint16_t *cochannel, int16_t *offset, uint16_t *bandwidth, uint16_t *mod, int8_t *snr);
|
bool devTEF_Radio_Get_Quality_Status_AM (int16_t *level, uint16_t *noise, uint16_t *cochannel, int16_t *offset, uint16_t *bandwidth, uint16_t *mod, int8_t *snr);
|
||||||
bool devTEF_APPL_Get_Operation_Status(uint8_t *bootstatus);
|
bool devTEF_APPL_Get_Operation_Status(uint8_t *bootstatus);
|
||||||
bool devTEF_Radio_Get_Stereo_Status(uint16_t *status);
|
bool devTEF_Radio_Get_Stereo_Status(uint16_t *status);
|
||||||
bool devTEF_Radio_Get_RDS_Status(uint16_t *status, uint16_t *A_block, uint16_t *B_block, uint16_t *C_block, uint16_t *D_block, uint16_t *dec_error);
|
bool devTEF_Radio_Get_RDS_Status(uint16_t *status, uint16_t *A_block, uint16_t *B_block, uint16_t *C_block, uint16_t *D_block, uint16_t *dec_error);
|
||||||
bool devTEF_Radio_Get_RDS_Data(uint16_t *status, uint16_t *A_block, uint16_t *B_block, uint16_t *C_block, uint16_t *D_block, uint16_t *dec_error);
|
bool devTEF_Radio_Get_RDS_Data(uint16_t *status, uint16_t *A_block, uint16_t *B_block, uint16_t *C_block, uint16_t *D_block, uint16_t *dec_error);
|
||||||
#endif
|
|
||||||
@@ -141,7 +141,6 @@ extern void doBW();
|
|||||||
extern void BuildDisplay();
|
extern void BuildDisplay();
|
||||||
extern void BuildAdvancedRDS();
|
extern void BuildAdvancedRDS();
|
||||||
extern void ModeButtonPress();
|
extern void ModeButtonPress();
|
||||||
//extern void ScreensaverTimerReopen();
|
|
||||||
extern void Seek(bool mode);
|
extern void Seek(bool mode);
|
||||||
extern void doStereoToggle();
|
extern void doStereoToggle();
|
||||||
extern void MuteScreen(bool setting);
|
extern void MuteScreen(bool setting);
|
||||||
|
|||||||
@@ -1,83 +1,64 @@
|
|||||||
#include "NTPupdate.h"
|
#include "NTPupdate.h"
|
||||||
|
|
||||||
// Sends an NTP request packet to the specified server address
|
|
||||||
void sendNTPpacket(IPAddress &address) {
|
void sendNTPpacket(IPAddress &address) {
|
||||||
byte packetBuffer[NTP_PACKET_SIZE] = {0}; // Initialize buffer with zeros
|
byte packetBuffer[NTP_PACKET_SIZE] = {0}; // Initialize buffer with zeros
|
||||||
|
|
||||||
// Set NTP packet header fields as per NTP protocol
|
|
||||||
packetBuffer[0] = 0b11100011; // LI, Version, Mode
|
packetBuffer[0] = 0b11100011; // LI, Version, Mode
|
||||||
packetBuffer[2] = 6; // Polling interval
|
packetBuffer[2] = 6; // Polling interval
|
||||||
packetBuffer[3] = 0xEC; // Peer clock precision
|
packetBuffer[3] = 0xEC; // Peer clock precision
|
||||||
|
|
||||||
// Root Delay & Root Dispersion fields
|
|
||||||
packetBuffer[12] = 49;
|
packetBuffer[12] = 49;
|
||||||
packetBuffer[13] = 0x4E;
|
packetBuffer[13] = 0x4E;
|
||||||
packetBuffer[14] = 49;
|
packetBuffer[14] = 49;
|
||||||
packetBuffer[15] = 52;
|
packetBuffer[15] = 52;
|
||||||
|
|
||||||
// Send the NTP request to port 123 (NTP standard port)
|
|
||||||
Udp.beginPacket(address, 123);
|
Udp.beginPacket(address, 123);
|
||||||
Udp.write(packetBuffer, NTP_PACKET_SIZE);
|
Udp.write(packetBuffer, NTP_PACKET_SIZE);
|
||||||
Udp.endPacket();
|
Udp.endPacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves the current time from an NTP server
|
|
||||||
time_t getNtpTime() {
|
time_t getNtpTime() {
|
||||||
IPAddress ntpServerIP;
|
IPAddress ntpServerIP;
|
||||||
byte packetBuffer[NTP_PACKET_SIZE];
|
byte packetBuffer[NTP_PACKET_SIZE];
|
||||||
|
|
||||||
// Clear any previously received UDP packets
|
|
||||||
while (Udp.parsePacket() > 0);
|
while (Udp.parsePacket() > 0);
|
||||||
|
|
||||||
// Resolve the NTP server's hostname to its IP address
|
if (!WiFi.hostByName(ntpServerName, ntpServerIP)) return 0;
|
||||||
if (!WiFi.hostByName(ntpServerName, ntpServerIP)) {
|
|
||||||
return 0; // Return 0 if hostname resolution fails
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send an NTP request
|
|
||||||
sendNTPpacket(ntpServerIP);
|
sendNTPpacket(ntpServerIP);
|
||||||
|
|
||||||
// Wait for a response with a 1500ms timeout
|
|
||||||
uint32_t startWait = millis();
|
uint32_t startWait = millis();
|
||||||
while (millis() - startWait < 1500) {
|
while (millis() - startWait < 1500) {
|
||||||
if (Udp.parsePacket() >= NTP_PACKET_SIZE) { // Check if a valid packet is received
|
if (Udp.parsePacket() >= NTP_PACKET_SIZE) {
|
||||||
Udp.read(packetBuffer, NTP_PACKET_SIZE);
|
Udp.read(packetBuffer, NTP_PACKET_SIZE);
|
||||||
|
|
||||||
// Extract "seconds since 1900" from the packet (bytes 40-43)
|
|
||||||
unsigned long secsSince1900 =
|
unsigned long secsSince1900 =
|
||||||
((unsigned long)packetBuffer[40] << 24) |
|
((unsigned long)packetBuffer[40] << 24) |
|
||||||
((unsigned long)packetBuffer[41] << 16) |
|
((unsigned long)packetBuffer[41] << 16) |
|
||||||
((unsigned long)packetBuffer[42] << 8) |
|
((unsigned long)packetBuffer[42] << 8) |
|
||||||
(unsigned long)packetBuffer[43];
|
(unsigned long)packetBuffer[43];
|
||||||
|
|
||||||
// Convert to UNIX epoch time (seconds since 1970)
|
|
||||||
return secsSince1900 - 2208988800UL;
|
return secsSince1900 - 2208988800UL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return 0 if no valid response is received
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates the RTC with the time from an NTP server
|
|
||||||
void NTPupdate() {
|
void NTPupdate() {
|
||||||
// Abort if Wi-Fi is not connected
|
|
||||||
if (!wifi) {
|
if (!wifi) {
|
||||||
NTPupdated = false;
|
NTPupdated = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the current time from the NTP server
|
|
||||||
time_t currentTime = getNtpTime();
|
time_t currentTime = getNtpTime();
|
||||||
|
|
||||||
if (currentTime) {
|
if (currentTime) {
|
||||||
// Set the RTC if valid time is received
|
|
||||||
rtc.setTime(currentTime);
|
rtc.setTime(currentTime);
|
||||||
rtcset = true;
|
rtcset = true;
|
||||||
NTPupdated = true;
|
NTPupdated = true;
|
||||||
radio.rds.ctupdate = false;
|
radio.rds.ctupdate = false;
|
||||||
} else {
|
} else {
|
||||||
// Indicate that the update failed
|
|
||||||
NTPupdated = false;
|
NTPupdated = false;
|
||||||
radio.rds.ctupdate = true;
|
radio.rds.ctupdate = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +1,30 @@
|
|||||||
#include "RdsPiBuffer.hpp"
|
#include "RdsPiBuffer.hpp"
|
||||||
|
|
||||||
RdsPiBuffer::RdsPiBuffer()
|
RdsPiBuffer::RdsPiBuffer() {
|
||||||
{
|
|
||||||
this->clear();
|
this->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
RdsPiBuffer::State
|
RdsPiBuffer::State RdsPiBuffer::add(uint16_t value, bool error) {
|
||||||
RdsPiBuffer::add(uint16_t value,
|
|
||||||
bool error)
|
|
||||||
{
|
|
||||||
this->pos = (this->pos + 1) % BUFF_SIZE;
|
this->pos = (this->pos + 1) % BUFF_SIZE;
|
||||||
this->buff[this->pos] = value;
|
this->buff[this->pos] = value;
|
||||||
|
|
||||||
const uint8_t errorPos = this->pos / 8;
|
const uint8_t errorPos = this->pos / 8;
|
||||||
const uint8_t errorBitPos = this->pos % 8;
|
const uint8_t errorBitPos = this->pos % 8;
|
||||||
|
|
||||||
if (error)
|
if (error) this->errorBuff[errorPos] |= (1 << errorBitPos);
|
||||||
{
|
else this->errorBuff[errorPos] &= ~(1 << errorBitPos);
|
||||||
this->errorBuff[errorPos] |= (1 << errorBitPos);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->errorBuff[errorPos] &= ~(1 << errorBitPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->fill < BUFF_SIZE)
|
if (this->fill < BUFF_SIZE) this->fill++;
|
||||||
{
|
|
||||||
this->fill++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->getState(value);
|
return this->getState(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void RdsPiBuffer::clear(){
|
||||||
RdsPiBuffer::clear()
|
|
||||||
{
|
|
||||||
this->fill = 0;
|
this->fill = 0;
|
||||||
this->pos = (uint8_t)-1;
|
this->pos = (uint8_t)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
RdsPiBuffer::State
|
RdsPiBuffer::State RdsPiBuffer::getState(uint16_t value) {
|
||||||
RdsPiBuffer::getState(uint16_t value)
|
|
||||||
{
|
|
||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
uint8_t correctCount = 0;
|
uint8_t correctCount = 0;
|
||||||
|
|
||||||
@@ -50,29 +33,14 @@ RdsPiBuffer::getState(uint16_t value)
|
|||||||
if (this->buff[i] == value)
|
if (this->buff[i] == value)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
if ((this->errorBuff[i / 8] & (1 << (i % 8))) == 0)
|
if ((this->errorBuff[i / 8] & (1 << (i % 8))) == 0) correctCount++;
|
||||||
{
|
|
||||||
correctCount++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (correctCount >= 2)
|
if (correctCount >= 2) return STATE_CORRECT;
|
||||||
{
|
else if (count >= 2 && correctCount) return STATE_VERY_LIKELY;
|
||||||
return STATE_CORRECT;
|
else if (count >= 3) return STATE_LIKELY;
|
||||||
}
|
else if (count == 2 || correctCount) return STATE_UNLIKELY;
|
||||||
else if (count >= 2 && correctCount)
|
|
||||||
{
|
|
||||||
return STATE_VERY_LIKELY;
|
|
||||||
}
|
|
||||||
else if (count >= 3)
|
|
||||||
{
|
|
||||||
return STATE_LIKELY;
|
|
||||||
}
|
|
||||||
else if (count == 2 || correctCount)
|
|
||||||
{
|
|
||||||
return STATE_UNLIKELY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATE_INVALID;
|
return STATE_INVALID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,8 +157,13 @@ void TEF6686::init(byte TEF) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TEF6686::getIdentification(uint16_t &device, uint16_t &hw_version, uint16_t &sw_version) {
|
void TEF6686::getIdentification(uint16_t *device, uint16_t *hw_version, uint16_t *sw_version) {
|
||||||
devTEF_Radio_Get_Identification(&device, &hw_version, &sw_version);
|
uint8_t buf[6];
|
||||||
|
uint16_t r = devTEF_Get_Cmd(TEF_APPL, Cmd_Get_Identification, buf, sizeof(buf));
|
||||||
|
|
||||||
|
*device = Convert8bto16b(buf);
|
||||||
|
*hw_version = Convert8bto16b(buf + 2);
|
||||||
|
*sw_version = Convert8bto16b(buf + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TEF6686::power(bool mode) {
|
void TEF6686::power(bool mode) {
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
#include "TEF6686.h"
|
#include "TEF6686.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#define High_16bto8b(a) ((uint8_t)((a) >> 8))
|
|
||||||
#define Low_16bto8b(a) ((uint8_t)(a ))
|
|
||||||
#define Convert8bto16b(a) ((uint16_t)(((uint16_t)(*(a))) << 8 |((uint16_t)(*(a+1)))))
|
|
||||||
|
|
||||||
void devTEF_Set_Cmd(TEF_MODULE module, uint8_t cmd, uint16_t len, ...) {
|
void devTEF_Set_Cmd(TEF_MODULE module, uint8_t cmd, uint16_t len, ...) {
|
||||||
uint16_t i, temp;
|
uint16_t i, temp;
|
||||||
uint8_t buf[20];
|
uint8_t buf[20];
|
||||||
@@ -126,16 +122,6 @@ bool devTEF_Radio_Get_Stereo_Status(uint16_t *status) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool devTEF_Radio_Get_Identification (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));
|
|
||||||
|
|
||||||
*device = Convert8bto16b(buf);
|
|
||||||
*hw_version = Convert8bto16b(buf + 2);
|
|
||||||
*sw_version = Convert8bto16b(buf + 4);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void devTEF_Radio_Set_Wavegen(bool mode, int16_t amplitude, uint16_t freq) {
|
void devTEF_Radio_Set_Wavegen(bool mode, int16_t amplitude, uint16_t freq) {
|
||||||
devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Input, 5, mode ? 240 : 0);
|
devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Input, 5, mode ? 240 : 0);
|
||||||
if (mode) devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_WaveGen, 15, 5, 0, amplitude * 10, freq, amplitude * 10, freq);
|
if (mode) devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_WaveGen, 15, 5, 0, amplitude * 10, freq, amplitude * 10, freq);
|
||||||
|
|||||||
@@ -90,9 +90,7 @@ bool Tuner_Table_Write(const unsigned char *tab) {
|
|||||||
if (tab[1] == 0xff) {
|
if (tab[1] == 0xff) {
|
||||||
delay(tab[2]);
|
delay(tab[2]);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else return Tuner_WriteBuffer((unsigned char *)&tab[1], tab[0]);
|
||||||
return Tuner_WriteBuffer((unsigned char *)&tab[1], tab[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tuner_Reset(void) {
|
void Tuner_Reset(void) {
|
||||||
@@ -123,7 +121,6 @@ void Tuner_Patch(byte TEF) {
|
|||||||
case 102:
|
case 102:
|
||||||
Tuner_Patch_Load(pPatchBytes102, PatchSize102);
|
Tuner_Patch_Load(pPatchBytes102, PatchSize102);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 205:
|
case 205:
|
||||||
Tuner_Patch_Load(pPatchBytes205, PatchSize205);
|
Tuner_Patch_Load(pPatchBytes205, PatchSize205);
|
||||||
break;
|
break;
|
||||||
@@ -143,7 +140,6 @@ void Tuner_Patch(byte TEF) {
|
|||||||
case 102:
|
case 102:
|
||||||
Tuner_Patch_Load(pLutBytes102, LutSize102);
|
Tuner_Patch_Load(pLutBytes102, LutSize102);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 205:
|
case 205:
|
||||||
Tuner_Patch_Load(pLutBytes205, LutSize205);
|
Tuner_Patch_Load(pLutBytes205, LutSize205);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -909,8 +909,8 @@ void XDRGTKRoutine() {
|
|||||||
if (millis() >= signalstatustimer + 66) {
|
if (millis() >= signalstatustimer + 66) {
|
||||||
if (band > BAND_GAP) DataPrint("Sm");
|
if (band > BAND_GAP) DataPrint("Sm");
|
||||||
else {
|
else {
|
||||||
if (!StereoToggle) DataPrint("SM");
|
if(!StereoToggle) DataPrint("SM");
|
||||||
else if (Stereostatus) DataPrint("Ss");
|
else if(Stereostatus) DataPrint("Ss");
|
||||||
else DataPrint("Sm");
|
else DataPrint("Sm");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -335,10 +335,7 @@ String getCurrentDateTime(bool inUTC) {
|
|||||||
currentEpoch += 3600; // Add 1-hour DST offset
|
currentEpoch += 3600; // Add 1-hour DST offset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else utcOffsetHours = (NTPupdated ? NTPoffset : radio.rds.offset / 3600);
|
||||||
// Calculate UTC offset in hours when inUTC is true
|
|
||||||
utcOffsetHours = (NTPupdated ? NTPoffset : radio.rds.offset / 3600);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert adjusted (or original) time back to struct tm format
|
// Convert adjusted (or original) time back to struct tm format
|
||||||
localtime_r(¤tEpoch, &timeInfo);
|
localtime_r(¤tEpoch, &timeInfo);
|
||||||
|
|||||||
41
src/main.cpp
41
src/main.cpp
@@ -69,22 +69,14 @@ bool dynamicPTYold, edgebeep, externaltune;
|
|||||||
bool findMemoryAF;
|
bool findMemoryAF;
|
||||||
bool firstTouchHandled = false;
|
bool firstTouchHandled = false;
|
||||||
bool flashing;
|
bool flashing;
|
||||||
bool fmsi;
|
bool fmsi, fullsearchrds;
|
||||||
bool fullsearchrds;
|
bool hasafold, hasCTold, haseonold;
|
||||||
bool hasafold;
|
bool hasrtplusold, hastmcold;
|
||||||
bool hasCTold;
|
bool initdxscan, invertdisplay, leave;
|
||||||
bool haseonold;
|
|
||||||
bool hasrtplusold;
|
|
||||||
bool hastmcold;
|
|
||||||
bool initdxscan;
|
|
||||||
bool invertdisplay;
|
|
||||||
bool leave;
|
|
||||||
bool LowLevelInit;
|
bool LowLevelInit;
|
||||||
bool memorystore;
|
bool memorystore;
|
||||||
bool memreset;
|
bool memreset, memtune;
|
||||||
bool memtune;
|
bool menu, menuopen;
|
||||||
bool menu;
|
|
||||||
bool menuopen;
|
|
||||||
bool mwstepsize;
|
bool mwstepsize;
|
||||||
#ifdef HAS_AIR_BAND
|
#ifdef HAS_AIR_BAND
|
||||||
bool airstepsize;
|
bool airstepsize;
|
||||||
@@ -95,10 +87,8 @@ bool optenc;
|
|||||||
bool rdsflagreset;
|
bool rdsflagreset;
|
||||||
bool rdsreset;
|
bool rdsreset;
|
||||||
bool rdsstatscreen;
|
bool rdsstatscreen;
|
||||||
bool RDSSPYTCP;
|
bool RDSSPYTCP, RDSSPYUSB;
|
||||||
bool RDSSPYUSB;
|
bool RDSstatus, RDSstatusold;
|
||||||
bool RDSstatus;
|
|
||||||
bool RDSstatusold;
|
|
||||||
bool rdsstereoold;
|
bool rdsstereoold;
|
||||||
bool rotaryaccelerate = true;
|
bool rotaryaccelerate = true;
|
||||||
bool rtcset;
|
bool rtcset;
|
||||||
@@ -122,8 +112,7 @@ bool SQ;
|
|||||||
bool Stereostatusold;
|
bool Stereostatusold;
|
||||||
bool StereoToggle;
|
bool StereoToggle;
|
||||||
bool store;
|
bool store;
|
||||||
bool TAold;
|
bool TAold, TPold;
|
||||||
bool TPold;
|
|
||||||
bool touchrepeat = false;
|
bool touchrepeat = false;
|
||||||
bool touch_detect;
|
bool touch_detect;
|
||||||
bool tuned;
|
bool tuned;
|
||||||
@@ -1087,11 +1076,9 @@ void setup() {
|
|||||||
if (TEF != 102 && TEF != 205) SetTunerPatch();
|
if (TEF != 102 && TEF != 205) SetTunerPatch();
|
||||||
|
|
||||||
radio.init(TEF);
|
radio.init(TEF);
|
||||||
uint16_t device;
|
uint16_t device, hw, sw;
|
||||||
uint16_t hw;
|
|
||||||
uint16_t sw;
|
|
||||||
|
|
||||||
radio.getIdentification(device, hw, sw);
|
radio.getIdentification(&device, &hw, &sw);
|
||||||
if (TEF != (highByte(hw) * 100 + highByte(sw))) SetTunerPatch();
|
if (TEF != (highByte(hw) * 100 + highByte(sw))) SetTunerPatch();
|
||||||
|
|
||||||
if (lowByte(device) == 14) {
|
if (lowByte(device) == 14) {
|
||||||
@@ -4404,10 +4391,8 @@ void Seek(bool mode) {
|
|||||||
void SetTunerPatch() {
|
void SetTunerPatch() {
|
||||||
if (TEF != 102 && TEF != 205) {
|
if (TEF != 102 && TEF != 205) {
|
||||||
radio.init(102);
|
radio.init(102);
|
||||||
uint16_t device;
|
uint16_t device, hw, sw;
|
||||||
uint16_t hw;
|
radio.getIdentification(&device, &hw, &sw);
|
||||||
uint16_t sw;
|
|
||||||
radio.getIdentification(device, hw, sw);
|
|
||||||
TEF = highByte(hw) * 100 + highByte(sw);
|
TEF = highByte(hw) * 100 + highByte(sw);
|
||||||
tft.fillScreen(BackgroundColor);
|
tft.fillScreen(BackgroundColor);
|
||||||
analogWrite(CONTRASTPIN, map(ContrastSet, 0, 100, 15, 255));
|
analogWrite(CONTRASTPIN, map(ContrastSet, 0, 100, 15, 255));
|
||||||
|
|||||||
410
src/rds.cpp
410
src/rds.cpp
@@ -1,5 +1,3 @@
|
|||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wbool-compare"
|
|
||||||
#include "rds.h"
|
#include "rds.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include <TimeLib.h>
|
#include <TimeLib.h>
|
||||||
@@ -76,11 +74,11 @@ void ShowAdvancedRDS() {
|
|||||||
if (xPos2 < -afstringWidth) xPos2 = 0;
|
if (xPos2 < -afstringWidth) xPos2 = 0;
|
||||||
if (xPos2 == 0) {
|
if (xPos2 == 0) {
|
||||||
if (millis() - aftickerhold >= 2000) {
|
if (millis() - aftickerhold >= 2000) {
|
||||||
xPos2 --;
|
xPos2--;
|
||||||
aftickerhold = millis();
|
aftickerhold = millis();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xPos2 --;
|
xPos2--;
|
||||||
aftickerhold = millis();
|
aftickerhold = millis();
|
||||||
}
|
}
|
||||||
RDSSprite.fillSprite(BackgroundColor);
|
RDSSprite.fillSprite(BackgroundColor);
|
||||||
@@ -219,9 +217,7 @@ void doAF() {
|
|||||||
|
|
||||||
for (byte af_scan = 0; af_scan < radio.af_counter; af_scan++) {
|
for (byte af_scan = 0; af_scan < radio.af_counter; af_scan++) {
|
||||||
if (wifi) {
|
if (wifi) {
|
||||||
if ((radio.af[af_scan].frequency - 8750) / 10 < 0x10) {
|
if ((radio.af[af_scan].frequency - 8750) / 10 < 0x10) Udp.print("0");
|
||||||
Udp.print("0");
|
|
||||||
}
|
|
||||||
Udp.print(String((radio.af[af_scan].frequency - 8750) / 10, HEX));
|
Udp.print(String((radio.af[af_scan].frequency - 8750) / 10, HEX));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,10 +255,8 @@ void showECC() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void readRds() {
|
void readRds() {
|
||||||
// Only process RDS on FM bands
|
|
||||||
if (band >= BAND_GAP) return;
|
if (band >= BAND_GAP) return;
|
||||||
|
|
||||||
// Read RDS data from tuner
|
|
||||||
radio.readRDS(showrdserrors);
|
radio.readRDS(showrdserrors);
|
||||||
RDSstatus = radio.rds.hasRDS;
|
RDSstatus = radio.rds.hasRDS;
|
||||||
ShowRDSLogo(RDSstatus);
|
ShowRDSLogo(RDSstatus);
|
||||||
@@ -273,16 +267,11 @@ void readRds() {
|
|||||||
// --- RDS dropout (lost signal) ---
|
// --- RDS dropout (lost signal) ---
|
||||||
if (radio.rds.correctPI != 0 && !dropout) {
|
if (radio.rds.correctPI != 0 && !dropout) {
|
||||||
if (!rdsstatscreen) {
|
if (!rdsstatscreen) {
|
||||||
if (radio.rds.region == 0) {
|
if (radio.rds.region == 0) tftPrint(ACENTER, PIold, 275, advancedRDS ? 75 : 187, RDSDropoutColor, RDSDropoutColorSmooth, 28);
|
||||||
tftPrint(ACENTER, PIold, 275, advancedRDS ? 75 : 187,
|
else {
|
||||||
RDSDropoutColor, RDSDropoutColorSmooth, 28);
|
tftPrint(ALEFT, PIold, 240, advancedRDS ? 72 : 184, RDSDropoutColor, RDSDropoutColorSmooth, 16);
|
||||||
} else {
|
tftPrint(ALEFT, stationIDold, 240, advancedRDS ? 89 : 201, RDSDropoutColor, RDSDropoutColorSmooth, 16);
|
||||||
tftPrint(ALEFT, PIold, 240, advancedRDS ? 72 : 184,
|
tftPrint( 1, stationStateold, 318, advancedRDS ? 89 : 201, RDSDropoutColor, RDSDropoutColorSmooth, 16);
|
||||||
RDSDropoutColor, RDSDropoutColorSmooth, 16);
|
|
||||||
tftPrint(ALEFT, stationIDold, 240, advancedRDS ? 89 : 201,
|
|
||||||
RDSDropoutColor, RDSDropoutColorSmooth, 16);
|
|
||||||
tftPrint( 1, stationStateold, 318, advancedRDS ? 89 : 201,
|
|
||||||
RDSDropoutColor, RDSDropoutColorSmooth, 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!radio.rds.hasLongPS) {
|
if (!radio.rds.hasLongPS) {
|
||||||
@@ -292,14 +281,11 @@ void readRds() {
|
|||||||
PSSprite.pushSprite(36, advancedRDS ? 72 : 185);
|
PSSprite.pushSprite(36, advancedRDS ? 72 : 185);
|
||||||
}
|
}
|
||||||
|
|
||||||
tftPrint(ALEFT, PTYold, 34, advancedRDS ? 109 : 163,
|
tftPrint(ALEFT, PTYold, 34, advancedRDS ? 109 : 163, RDSDropoutColor, RDSDropoutColorSmooth, 16);
|
||||||
RDSDropoutColor, RDSDropoutColorSmooth, 16);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rdsstatscreen && berPercentold != 100) {
|
if (rdsstatscreen && berPercentold != 100) {
|
||||||
tftReplace(ARIGHT, String(berPercentold) + "%", "100%",
|
tftReplace(ARIGHT, String(berPercentold) + "%", "100%", 318, 34, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16);
|
||||||
318, 34, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16);
|
|
||||||
berPercentold = 100;
|
berPercentold = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,43 +301,29 @@ void readRds() {
|
|||||||
// --- RDS recovery or memory reset ---
|
// --- RDS recovery or memory reset ---
|
||||||
if (dropout || memreset) {
|
if (dropout || memreset) {
|
||||||
if (!rdsstatscreen) {
|
if (!rdsstatscreen) {
|
||||||
if (radio.rds.region == 0) {
|
if (radio.rds.region == 0) tftPrint(ACENTER, PIold, 275, advancedRDS ? 75 : 187, RDSColor, RDSColorSmooth, 28);
|
||||||
tftPrint(ACENTER, PIold, 275, advancedRDS ? 75 : 187,
|
else {
|
||||||
RDSColor, RDSColorSmooth, 28);
|
tftPrint(ALEFT, PIold, 240, advancedRDS ? 72 : 184, RDSColor, RDSColorSmooth, 16);
|
||||||
} else {
|
tftPrint(ALEFT, stationIDold, 240, advancedRDS ? 89 : 201, RDSColor, RDSColorSmooth, 16);
|
||||||
tftPrint(ALEFT, PIold, 240, advancedRDS ? 72 : 184,
|
tftPrint( 1, stationStateold, 318, advancedRDS ? 89 : 201, advancedRDS ? RDSColor : RDSDropoutColor, advancedRDS ? RDSColorSmooth : RDSDropoutColorSmooth, 16);
|
||||||
RDSColor, RDSColorSmooth, 16);
|
|
||||||
tftPrint(ALEFT, stationIDold, 240, advancedRDS ? 89 : 201,
|
|
||||||
RDSColor, RDSColorSmooth, 16);
|
|
||||||
tftPrint( 1, stationStateold, 318, advancedRDS ? 89 : 201,
|
|
||||||
advancedRDS ? RDSColor : RDSDropoutColor,
|
|
||||||
advancedRDS ? RDSColorSmooth : RDSDropoutColorSmooth, 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PS handling
|
|
||||||
if (!radio.rds.hasLongPS) {
|
if (!radio.rds.hasLongPS) {
|
||||||
PSSprite.fillSprite(BackgroundColor);
|
PSSprite.fillSprite(BackgroundColor);
|
||||||
if ((ps12errorold || ps34errorold || ps56errorold || ps78errorold) && radio.ps_process) {
|
if ((ps12errorold || ps34errorold || ps56errorold || ps78errorold) && radio.ps_process) {
|
||||||
// Mark partial errors
|
|
||||||
for (uint8_t i = 0; i < 7; i++) {
|
for (uint8_t i = 0; i < 7; i++) {
|
||||||
bool error = (i < 2 && ps12errorold) ||
|
bool error = (i < 2 && ps12errorold) || (i < 4 && ps34errorold) || (i < 6 && ps56errorold) || ps78errorold;
|
||||||
(i < 4 && ps34errorold) ||
|
PSSprite.setTextColor(error ? RDSDropoutColor : RDSColor, RDSColorSmooth, false);
|
||||||
(i < 6 && ps56errorold) || ps78errorold;
|
PSSprite.drawString(radio.rds.stationName.substring(i, i + 1), i == 0 ? 0 : lengths[i - 1], 2);
|
||||||
PSSprite.setTextColor(error ? RDSDropoutColor : RDSColor,
|
|
||||||
RDSColorSmooth, false);
|
|
||||||
PSSprite.drawString(radio.rds.stationName.substring(i, i + 1),
|
|
||||||
i == 0 ? 0 : lengths[i - 1], 2);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Print clean PS
|
|
||||||
PSSprite.setTextColor(RDSColor, RDSColorSmooth, false);
|
PSSprite.setTextColor(RDSColor, RDSColorSmooth, false);
|
||||||
PSSprite.drawString(PSold, 0, 2);
|
PSSprite.drawString(PSold, 0, 2);
|
||||||
}
|
}
|
||||||
PSSprite.pushSprite(36, advancedRDS ? 72 : 185);
|
PSSprite.pushSprite(36, advancedRDS ? 72 : 185);
|
||||||
}
|
}
|
||||||
|
|
||||||
tftPrint(ALEFT, PTYold, 34, advancedRDS ? 109 : 163,
|
tftPrint(ALEFT, PTYold, 34, advancedRDS ? 109 : 163, RDSColor, RDSColorSmooth, 16);
|
||||||
RDSColor, RDSColorSmooth, 16);
|
|
||||||
|
|
||||||
tft.fillCircle(314, 223, 2, GreyoutColor);
|
tft.fillCircle(314, 223, 2, GreyoutColor);
|
||||||
tft.fillCircle(314, 234, 2, GreyoutColor);
|
tft.fillCircle(314, 234, 2, GreyoutColor);
|
||||||
@@ -369,17 +341,12 @@ void readRds() {
|
|||||||
// RDS Spy output
|
// RDS Spy output
|
||||||
if (RDSstatus && (RDSSPYUSB || RDSSPYTCP)) {
|
if (RDSstatus && (RDSSPYUSB || RDSSPYTCP)) {
|
||||||
RDSSPYRDS = F("G:\r\n");
|
RDSSPYRDS = F("G:\r\n");
|
||||||
uint16_t blocks[4] = {radio.rds.rdsA, radio.rds.rdsB,
|
uint16_t blocks[4] = {radio.rds.rdsA, radio.rds.rdsB, radio.rds.rdsC, radio.rds.rdsD};
|
||||||
radio.rds.rdsC, radio.rds.rdsD
|
bool errors[4] = {radio.rds.rdsAerror, radio.rds.rdsBerror, radio.rds.rdsCerror, radio.rds.rdsDerror};
|
||||||
};
|
|
||||||
bool errors[4] = {radio.rds.rdsAerror, radio.rds.rdsBerror,
|
|
||||||
radio.rds.rdsCerror, radio.rds.rdsDerror
|
|
||||||
};
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
if (errors[i]) {
|
if (errors[i]) RDSSPYRDS += F("----");
|
||||||
RDSSPYRDS += F("----");
|
else {
|
||||||
} else {
|
|
||||||
sprintf(hexbuf, "%04X", blocks[i]); // format word into HEX
|
sprintf(hexbuf, "%04X", blocks[i]); // format word into HEX
|
||||||
RDSSPYRDS += hexbuf;
|
RDSSPYRDS += hexbuf;
|
||||||
}
|
}
|
||||||
@@ -387,23 +354,18 @@ void readRds() {
|
|||||||
RDSSPYRDS += F("\r\n\r\n");
|
RDSSPYRDS += F("\r\n\r\n");
|
||||||
|
|
||||||
if (RDSSPYRDS != RDSSPYRDSold) {
|
if (RDSSPYRDS != RDSSPYRDSold) {
|
||||||
if (RDSSPYUSB) {
|
if (RDSSPYUSB) Serial.print(RDSSPYRDS);
|
||||||
Serial.print(RDSSPYRDS);
|
else RemoteClient.print(RDSSPYRDS);
|
||||||
} else {
|
|
||||||
RemoteClient.print(RDSSPYRDS);
|
|
||||||
}
|
|
||||||
RDSSPYRDSold = RDSSPYRDS;
|
RDSSPYRDSold = RDSSPYRDS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XDRGTK output
|
|
||||||
if (RDSstatus && (XDRGTKUSB || XDRGTKTCP)) {
|
if (RDSstatus && (XDRGTKUSB || XDRGTKTCP)) {
|
||||||
XDRGTKRDS = F("R");
|
XDRGTKRDS = F("R");
|
||||||
sprintf(hexbuf, "%04X", radio.rds.rdsB); XDRGTKRDS += hexbuf;
|
sprintf(hexbuf, "%04X", radio.rds.rdsB); XDRGTKRDS += hexbuf;
|
||||||
sprintf(hexbuf, "%04X", radio.rds.rdsC); XDRGTKRDS += hexbuf;
|
sprintf(hexbuf, "%04X", radio.rds.rdsC); XDRGTKRDS += hexbuf;
|
||||||
sprintf(hexbuf, "%04X", radio.rds.rdsD); XDRGTKRDS += hexbuf;
|
sprintf(hexbuf, "%04X", radio.rds.rdsD); XDRGTKRDS += hexbuf;
|
||||||
|
|
||||||
// Pack error bits
|
|
||||||
uint8_t erroutput = 0;
|
uint8_t erroutput = 0;
|
||||||
erroutput |= ((radio.rds.rdsErr >> 8) & B00110000) >> 4;
|
erroutput |= ((radio.rds.rdsErr >> 8) & B00110000) >> 4;
|
||||||
erroutput |= ((radio.rds.rdsErr >> 8) & B00001100);
|
erroutput |= ((radio.rds.rdsErr >> 8) & B00001100);
|
||||||
@@ -518,11 +480,8 @@ void showPI() {
|
|||||||
if (!screenmute) {
|
if (!screenmute) {
|
||||||
if (advancedRDS) {
|
if (advancedRDS) {
|
||||||
if (radio.rds.region == 0) {
|
if (radio.rds.region == 0) {
|
||||||
if (!RDSstatus) {
|
if (!RDSstatus) tftReplace(ACENTER, PIold, radio.rds.picode, 275, 75, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 28);
|
||||||
tftReplace(ACENTER, PIold, radio.rds.picode, 275, 75, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 28);
|
else tftReplace(ACENTER, PIold, radio.rds.picode, 275, 75, RDSColor, RDSColorSmooth, BackgroundColor, 28);
|
||||||
} else {
|
|
||||||
tftReplace(ACENTER, PIold, radio.rds.picode, 275, 75, RDSColor, RDSColorSmooth, BackgroundColor, 28);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!RDSstatus) {
|
if (!RDSstatus) {
|
||||||
if (String(radio.rds.picode) != PIold) tftReplace(ALEFT, PIold, radio.rds.picode, 240, 72, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16);
|
if (String(radio.rds.picode) != PIold) tftReplace(ALEFT, PIold, radio.rds.picode, 240, 72, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16);
|
||||||
@@ -533,15 +492,11 @@ void showPI() {
|
|||||||
}
|
}
|
||||||
tftReplace(ARIGHT, stationStateold, radio.rds.stationStatetext, 318, 89, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16);
|
tftReplace(ARIGHT, stationStateold, radio.rds.stationStatetext, 318, 89, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16);
|
||||||
}
|
}
|
||||||
} else if (afscreen) {
|
} else if (afscreen) tftReplace(ALEFT, PIold, radio.rds.picode, 30, 201, BWAutoColor, BWAutoColorSmooth, BackgroundColor, 16);
|
||||||
tftReplace(ALEFT, PIold, radio.rds.picode, 30, 201, BWAutoColor, BWAutoColorSmooth, BackgroundColor, 16);
|
else if (!rdsstatscreen) {
|
||||||
} else if (!rdsstatscreen) {
|
|
||||||
if (radio.rds.region == 0) {
|
if (radio.rds.region == 0) {
|
||||||
if (!RDSstatus) {
|
if (!RDSstatus) tftReplace(ACENTER, PIold, radio.rds.picode, 275, 187, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 28);
|
||||||
tftReplace(ACENTER, PIold, radio.rds.picode, 275, 187, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 28);
|
else tftReplace(ACENTER, PIold, radio.rds.picode, 275, 187, RDSColor, RDSColorSmooth, BackgroundColor, 28);
|
||||||
} else {
|
|
||||||
tftReplace(ACENTER, PIold, radio.rds.picode, 275, 187, RDSColor, RDSColorSmooth, BackgroundColor, 28);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!RDSstatus) {
|
if (!RDSstatus) {
|
||||||
if (String(radio.rds.picode) != PIold || radio.rds.stationIDtext != stationIDold) {
|
if (String(radio.rds.picode) != PIold || radio.rds.stationIDtext != stationIDold) {
|
||||||
@@ -578,17 +533,11 @@ void showPTY() {
|
|||||||
|
|
||||||
if (!screenmute) {
|
if (!screenmute) {
|
||||||
if (advancedRDS) {
|
if (advancedRDS) {
|
||||||
if (!RDSstatus) {
|
if (!RDSstatus) tftReplace(ALEFT, PTYold, PTYString, 34, 109, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16);
|
||||||
tftReplace(ALEFT, PTYold, PTYString, 34, 109, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16);
|
else tftReplace(ALEFT, PTYold, PTYString, 34, 109, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
||||||
} else {
|
|
||||||
tftReplace(ALEFT, PTYold, PTYString, 34, 109, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!RDSstatus) {
|
if (!RDSstatus) tftReplace(ALEFT, PTYold, PTYString, 34, 163, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16);
|
||||||
tftReplace(ALEFT, PTYold, PTYString, 34, 163, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16);
|
else tftReplace(ALEFT, PTYold, PTYString, 34, 163, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
||||||
} else {
|
|
||||||
tftReplace(ALEFT, PTYold, PTYString, 34, 163, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PTYold = PTYString;
|
PTYold = PTYString;
|
||||||
@@ -604,23 +553,12 @@ void showPTY() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void showPS() {
|
void showPS() {
|
||||||
// Check if station name or errors have changed, or long PS should be displayed
|
if ((radio.rds.stationName != PSold) || (RDSstatus && !(ps12errorold == radio.rds.ps12error || ps34errorold == radio.rds.ps34error || ps56errorold == radio.rds.ps56error || ps78errorold == radio.rds.ps78error)) || (radio.rds.hasLongPS && showlongps)) {
|
||||||
if ((radio.rds.stationName != PSold) ||
|
|
||||||
(RDSstatus && !(ps12errorold == radio.rds.ps12error ||
|
|
||||||
ps34errorold == radio.rds.ps34error ||
|
|
||||||
ps56errorold == radio.rds.ps56error ||
|
|
||||||
ps78errorold == radio.rds.ps78error)) ||
|
|
||||||
(radio.rds.hasLongPS && showlongps)) {
|
|
||||||
|
|
||||||
// Handle AF screen update
|
|
||||||
if (afscreen) {
|
if (afscreen) {
|
||||||
if (!screenmute) {
|
if (!screenmute) tftReplace(ACENTER, PSold, radio.rds.stationName, 160, 201, BWAutoColor, BWAutoColorSmooth, BackgroundColor, 16);
|
||||||
tftReplace(ACENTER, PSold, radio.rds.stationName, 160, 201, BWAutoColor, BWAutoColorSmooth, BackgroundColor, 16);
|
|
||||||
}
|
|
||||||
} else if (!rdsstatscreen) {
|
} else if (!rdsstatscreen) {
|
||||||
// Handle long PS display
|
|
||||||
if (radio.rds.hasLongPS && showlongps) {
|
if (radio.rds.hasLongPS && showlongps) {
|
||||||
String stationNameLongString = String(radio.rds.stationNameLong) + " "; // Add trailing spaces for scrolling
|
String stationNameLongString = String(radio.rds.stationNameLong) + " ";
|
||||||
if (stationNameLongString != stationNameLongOld) {
|
if (stationNameLongString != stationNameLongOld) {
|
||||||
PSLongWidth = PSSprite.textWidth(stationNameLongString); // Measure new width
|
PSLongWidth = PSSprite.textWidth(stationNameLongString); // Measure new width
|
||||||
stationNameLongOld = stationNameLongString;
|
stationNameLongOld = stationNameLongString;
|
||||||
@@ -638,12 +576,9 @@ void showPS() {
|
|||||||
if (xPos5 == 0 && millis() - pslongtickerhold >= 2000) {
|
if (xPos5 == 0 && millis() - pslongtickerhold >= 2000) {
|
||||||
xPos5--; // Hold position for 2 seconds before scrolling
|
xPos5--; // Hold position for 2 seconds before scrolling
|
||||||
pslongtickerhold = millis();
|
pslongtickerhold = millis();
|
||||||
} else {
|
} else xPos5--;
|
||||||
xPos5--; // Scroll
|
|
||||||
}
|
|
||||||
pslongticker = millis();
|
pslongticker = millis();
|
||||||
|
|
||||||
// Draw scrolling PS
|
|
||||||
PSSprite.fillSprite(BackgroundColor);
|
PSSprite.fillSprite(BackgroundColor);
|
||||||
PSSprite.setTextColor(RDSstatus ? RDSColor : RDSDropoutColor, RDSstatus ? RDSColorSmooth : RDSDropoutColorSmooth, false);
|
PSSprite.setTextColor(RDSstatus ? RDSColor : RDSDropoutColor, RDSstatus ? RDSColorSmooth : RDSDropoutColorSmooth, false);
|
||||||
PSSprite.drawString(stationNameLongString, xPos5, 2);
|
PSSprite.drawString(stationNameLongString, xPos5, 2);
|
||||||
@@ -651,34 +586,25 @@ void showPS() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Handle normal PS display
|
|
||||||
xPos5 = 0;
|
xPos5 = 0;
|
||||||
PSSprite.fillSprite(BackgroundColor);
|
PSSprite.fillSprite(BackgroundColor);
|
||||||
|
|
||||||
// Calculate widths for individual characters (ensures proper spacing)
|
|
||||||
for (int i = 0; i < 7; i++) {
|
for (int i = 0; i < 7; i++) {
|
||||||
lengths[i] = PSSprite.textWidth(radio.rds.stationName.substring(0, i + 1));
|
lengths[i] = PSSprite.textWidth(radio.rds.stationName.substring(0, i + 1));
|
||||||
if (i > 0 && lengths[i] <= lengths[i - 1]) {
|
if (i > 0 && lengths[i] <= lengths[i - 1]) lengths[i] = lengths[i - 1] + 23;
|
||||||
lengths[i] = lengths[i - 1] + 23; // Ensure consistent spacing
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update error states only when their respective flags are true
|
|
||||||
if (ps12errorold) ps12errorold = radio.rds.ps12error;
|
if (ps12errorold) ps12errorold = radio.rds.ps12error;
|
||||||
if (ps34errorold) ps34errorold = radio.rds.ps34error;
|
if (ps34errorold) ps34errorold = radio.rds.ps34error;
|
||||||
if (ps56errorold) ps56errorold = radio.rds.ps56error;
|
if (ps56errorold) ps56errorold = radio.rds.ps56error;
|
||||||
if (ps78errorold) ps78errorold = radio.rds.ps78error;
|
if (ps78errorold) ps78errorold = radio.rds.ps78error;
|
||||||
|
|
||||||
// Set text color based on RDS status and error state
|
|
||||||
if (!RDSstatus || band > BAND_GAP) {
|
if (!RDSstatus || band > BAND_GAP) {
|
||||||
PSSprite.setTextColor(RDSDropoutColor, RDSDropoutColorSmooth, false);
|
PSSprite.setTextColor(RDSDropoutColor, RDSDropoutColorSmooth, false);
|
||||||
PSSprite.drawString(radio.rds.stationName, 0, 2);
|
PSSprite.drawString(radio.rds.stationName, 0, 2);
|
||||||
} else if ((ps12errorold || ps34errorold || ps56errorold || ps78errorold) && radio.ps_process) {
|
} else if ((ps12errorold || ps34errorold || ps56errorold || ps78errorold) && radio.ps_process) {
|
||||||
for (int i = 0; i < 7; i++) {
|
for (int i = 0; i < 7; i++) {
|
||||||
PSSprite.setTextColor((i < 2 && ps12errorold) || (i < 4 && ps34errorold) ||
|
PSSprite.setTextColor((i < 2 && ps12errorold) || (i < 4 && ps34errorold) || (i < 6 && ps56errorold) || ps78errorold ? RDSDropoutColor : RDSColor, RDSColorSmooth, false);
|
||||||
(i < 6 && ps56errorold) || ps78errorold ?
|
|
||||||
RDSDropoutColor : RDSColor,
|
|
||||||
RDSColorSmooth, false);
|
|
||||||
PSSprite.drawString(radio.rds.stationName.substring(i, i + 1), i == 0 ? 0 : lengths[i - 1], 2);
|
PSSprite.drawString(radio.rds.stationName.substring(i, i + 1), i == 0 ? 0 : lengths[i - 1], 2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -686,18 +612,11 @@ void showPS() {
|
|||||||
PSSprite.drawString(radio.rds.stationName, 0, 2);
|
PSSprite.drawString(radio.rds.stationName, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset PS error flags if the station name changes
|
if (PSold != radio.rds.stationName) ps12errorold = ps34errorold = ps56errorold = ps78errorold = true;
|
||||||
if (PSold != radio.rds.stationName) {
|
|
||||||
ps12errorold = ps34errorold = ps56errorold = ps78errorold = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push updated sprite to screen
|
if (!screenmute) PSSprite.pushSprite(36, advancedRDS ? 72 : 185);
|
||||||
if (!screenmute) {
|
|
||||||
PSSprite.pushSprite(36, advancedRDS ? 72 : 185);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle WiFi update if PS has changed
|
|
||||||
if (wifi && radio.rds.stationName.length() > 0 && PSold != radio.rds.stationName) {
|
if (wifi && radio.rds.stationName.length() > 0 && PSold != radio.rds.stationName) {
|
||||||
Udp.beginPacket(remoteip, 9030);
|
Udp.beginPacket(remoteip, 9030);
|
||||||
Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";PS=");
|
Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";PS=");
|
||||||
@@ -712,87 +631,57 @@ void showPS() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the updated station name
|
|
||||||
PSold = radio.rds.stationName;
|
PSold = radio.rds.stationName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showCT() {
|
void showCT() {
|
||||||
// Temporary string buffers for time and date formatting
|
char timeStr[16];
|
||||||
char timeStr[16]; // Increased buffer size to 16
|
char dateStr[9];
|
||||||
char dateStr[9]; // DD-MM-YY
|
|
||||||
time_t t;
|
time_t t;
|
||||||
|
|
||||||
// Determine the current time source
|
if (radio.rds.hasCT && !dropout && !NTPupdated) t = radio.rds.time + radio.rds.offset;
|
||||||
if (radio.rds.hasCT && !dropout && !NTPupdated) {
|
else {
|
||||||
t = radio.rds.time + radio.rds.offset;
|
|
||||||
} else {
|
|
||||||
t = rtc.getEpoch() + (NTPupdated ? 0 : radio.rds.offset);
|
t = rtc.getEpoch() + (NTPupdated ? 0 : radio.rds.offset);
|
||||||
|
|
||||||
// Update RDS time during dropout
|
// Update RDS time during dropout
|
||||||
if (dropout) {
|
if (dropout) radio.rds.time = static_cast<time_t>(rtc.getEpoch());
|
||||||
radio.rds.time = static_cast<time_t>(rtc.getEpoch());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the GMT offset only if NTPupdated is true
|
|
||||||
if (NTPupdated) {
|
if (NTPupdated) {
|
||||||
t += NTPoffset * 3600; // Convert offset from hours to seconds
|
t += NTPoffset * 3600; // Convert offset from hours to seconds
|
||||||
|
if (autoDST && isDST(t)) t += 3600;
|
||||||
// Apply DST adjustment if autoDST is enabled
|
|
||||||
if (autoDST && isDST(t)) {
|
|
||||||
t += 3600; // Add 1 hour for DST
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format the time based on region
|
|
||||||
if (clockampm) { // USA region: 12-hour AM/PM format
|
if (clockampm) { // USA region: 12-hour AM/PM format
|
||||||
int hour = localtime(&t)->tm_hour;
|
int hour = localtime(&t)->tm_hour;
|
||||||
|
|
||||||
// Ensure the hour is valid (between 1-12)
|
|
||||||
if (hour < 1 || hour > 12) {
|
if (hour < 1 || hour > 12) {
|
||||||
if (hour == 0) {
|
if (hour == 0) hour = 12;
|
||||||
hour = 12; // Midnight case
|
else if (hour > 12) hour -= 12;
|
||||||
} else if (hour > 12) {
|
|
||||||
hour -= 12; // Convert PM hours
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String ampm = (localtime(&t)->tm_hour >= 12) ? "PM" : "AM";
|
String ampm = (localtime(&t)->tm_hour >= 12) ? "PM" : "AM";
|
||||||
snprintf(timeStr, sizeof(timeStr), "%d:%02d %s", hour, localtime(&t)->tm_min, ampm.c_str());
|
snprintf(timeStr, sizeof(timeStr), "%d:%02d %s", hour, localtime(&t)->tm_min, ampm.c_str());
|
||||||
} else { // Other regions: 24-hour format
|
} else {
|
||||||
int hour = localtime(&t)->tm_hour;
|
int hour = localtime(&t)->tm_hour;
|
||||||
|
if (hour < 0 || hour > 23) hour = 0;
|
||||||
// Ensure the hour is valid (between 0-23)
|
|
||||||
if (hour < 0 || hour > 23) {
|
|
||||||
hour = 0; // Invalid hour, reset to 0
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(timeStr, sizeof(timeStr), "%02d:%02d", hour, localtime(&t)->tm_min);
|
snprintf(timeStr, sizeof(timeStr), "%02d:%02d", hour, localtime(&t)->tm_min);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store formatted time in rds_clock
|
|
||||||
rds_clock = String(timeStr);
|
rds_clock = String(timeStr);
|
||||||
|
|
||||||
// Format the date as DD-MM-YY
|
if (clockampm) strftime(dateStr, sizeof(dateStr), "%m-%d-%y", localtime(&t));
|
||||||
if (clockampm) {
|
else strftime(dateStr, sizeof(dateStr), "%d-%m-%y", localtime(&t));
|
||||||
strftime(dateStr, sizeof(dateStr), "%m-%d-%y", localtime(&t));
|
|
||||||
} else {
|
|
||||||
strftime(dateStr, sizeof(dateStr), "%d-%m-%y", localtime(&t));
|
|
||||||
}
|
|
||||||
rds_date = String(dateStr);
|
rds_date = String(dateStr);
|
||||||
|
|
||||||
// Check if the clock or RDS CT status has changed
|
|
||||||
if (!screenmute && showclock && (rds_clock != rds_clockold || rds_date != rds_dateold || hasCTold != radio.rds.hasCT)) {
|
if (!screenmute && showclock && (rds_clock != rds_clockold || rds_date != rds_dateold || hasCTold != radio.rds.hasCT)) {
|
||||||
|
|
||||||
// Update RTC if RDS CT is available or NTP was updated
|
|
||||||
if ((radio.rds.hasCT && RDSstatus) || NTPupdated) {
|
if ((radio.rds.hasCT && RDSstatus) || NTPupdated) {
|
||||||
rtcset = true;
|
rtcset = true;
|
||||||
if (!NTPupdated) {
|
if (!NTPupdated) rtc.setTime(radio.rds.time);
|
||||||
rtc.setTime(radio.rds.time);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the updated time and date
|
|
||||||
tftReplace(ACENTER, rds_clockold, rds_clock, 134, 1, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
tftReplace(ACENTER, rds_clockold, rds_clock, 134, 1, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
||||||
tftReplace(ACENTER, rds_dateold, rds_date, 134, 15, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
tftReplace(ACENTER, rds_dateold, rds_date, 134, 15, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
||||||
} else { // Handle dropout scenarios
|
} else { // Handle dropout scenarios
|
||||||
@@ -808,21 +697,13 @@ void showCT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update previous clock, date, and RDS CT status
|
|
||||||
rds_clockold = rds_clock;
|
rds_clockold = rds_clock;
|
||||||
rds_dateold = rds_date;
|
rds_dateold = rds_date;
|
||||||
hasCTold = radio.rds.hasCT;
|
hasCTold = radio.rds.hasCT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void showRadioText() {
|
void showRadioText() {
|
||||||
// Build the radio text string
|
String RTString = String(radio.rds.stationText + (radio.rds.stationText.length() > 0 ? " " : "") + radio.rds.stationText32 + (radio.rds.hasEnhancedRT ? " eRT: " + String(radio.rds.enhancedRTtext) : "") + " ");
|
||||||
String RTString = String(
|
|
||||||
radio.rds.stationText +
|
|
||||||
(radio.rds.stationText.length() > 0 ? " " : "") +
|
|
||||||
radio.rds.stationText32 +
|
|
||||||
(radio.rds.hasEnhancedRT ? " eRT: " + String(radio.rds.enhancedRTtext) : "") +
|
|
||||||
" "
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check if RT has changed
|
// Check if RT has changed
|
||||||
if (radio.rds.hasRT && radio.rds.rtAB != rtABold) {
|
if (radio.rds.hasRT && radio.rds.rtAB != rtABold) {
|
||||||
@@ -891,7 +772,6 @@ void showRadioText() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update RTold and RadiotextWidth if the string has changed
|
|
||||||
if (RTold != RTString) {
|
if (RTold != RTString) {
|
||||||
RadiotextWidth = FullLineSprite.textWidth(RTString);
|
RadiotextWidth = FullLineSprite.textWidth(RTString);
|
||||||
|
|
||||||
@@ -935,13 +815,9 @@ void ShowAFEON() {
|
|||||||
tft.fillRect(2, 48, 316, 150, BackgroundColor);
|
tft.fillRect(2, 48, 316, 150, BackgroundColor);
|
||||||
for (byte i = 0; i < radio.af_counter; i++) {
|
for (byte i = 0; i < radio.af_counter; i++) {
|
||||||
tftPrint(ALEFT, (radio.afmethodB && !radio.af[i].regional && radio.af[i].same) ? "S " : (radio.afmethodB && radio.af[i].regional && radio.af[i].same) ? "M " : (radio.afmethodB && radio.af[i].regional && !radio.af[i].same) ? "R " : "", 10 + (i > 9 ? 54 : 0) + (i > 19 ? 54 : 0) + (i > 29 ? 54 : 0) + (i > 39 ? 54 : 0), 48 + (15 * i) - (i > 9 ? 150 : 0) - (i > 19 ? 150 : 0) - (i > 29 ? 150 : 0) - (i > 39 ? 150 : 0), ActiveColor, ActiveColorSmooth, 16);
|
tftPrint(ALEFT, (radio.afmethodB && !radio.af[i].regional && radio.af[i].same) ? "S " : (radio.afmethodB && radio.af[i].regional && radio.af[i].same) ? "M " : (radio.afmethodB && radio.af[i].regional && !radio.af[i].same) ? "R " : "", 10 + (i > 9 ? 54 : 0) + (i > 19 ? 54 : 0) + (i > 29 ? 54 : 0) + (i > 39 ? 54 : 0), 48 + (15 * i) - (i > 9 ? 150 : 0) - (i > 19 ? 150 : 0) - (i > 29 ? 150 : 0) - (i > 39 ? 150 : 0), ActiveColor, ActiveColorSmooth, 16);
|
||||||
if (radio.af[i].checked) {
|
if (radio.af[i].checked) tftPrint(ARIGHT, String(radio.af[i].frequency / 100) + "." + String((radio.af[i].frequency % 100) / 10), 55 + (i > 9 ? 54 : 0) + (i > 19 ? 54 : 0) + (i > 29 ? 54 : 0) + (i > 39 ? 54 : 0), 48 + (15 * i) - (i > 9 ? 150 : 0) - (i > 19 ? 150 : 0) - (i > 29 ? 150 : 0) - (i > 39 ? 150 : 0), InsignificantColor, InsignificantColorSmooth, 16);
|
||||||
tftPrint(ARIGHT, String(radio.af[i].frequency / 100) + "." + String((radio.af[i].frequency % 100) / 10), 55 + (i > 9 ? 54 : 0) + (i > 19 ? 54 : 0) + (i > 29 ? 54 : 0) + (i > 39 ? 54 : 0), 48 + (15 * i) - (i > 9 ? 150 : 0) - (i > 19 ? 150 : 0) - (i > 29 ? 150 : 0) - (i > 39 ? 150 : 0), InsignificantColor, InsignificantColorSmooth, 16);
|
else if (!radio.af[i].afvalid) tftPrint(ARIGHT, String(radio.af[i].frequency / 100) + "." + String((radio.af[i].frequency % 100) / 10), 55 + (i > 9 ? 54 : 0) + (i > 19 ? 54 : 0) + (i > 29 ? 54 : 0) + (i > 39 ? 54 : 0), 48 + (15 * i) - (i > 9 ? 150 : 0) - (i > 19 ? 150 : 0) - (i > 29 ? 150 : 0) - (i > 39 ? 150 : 0), SignificantColor, SignificantColorSmooth, 16);
|
||||||
} else if (!radio.af[i].afvalid) {
|
else tftPrint(ARIGHT, String(radio.af[i].frequency / 100) + "." + String((radio.af[i].frequency % 100) / 10), 55 + (i > 9 ? 54 : 0) + (i > 19 ? 54 : 0) + (i > 29 ? 54 : 0) + (i > 39 ? 54 : 0), 48 + (15 * i) - (i > 9 ? 150 : 0) - (i > 19 ? 150 : 0) - (i > 29 ? 150 : 0) - (i > 39 ? 150 : 0), RDSColor, RDSColorSmooth, 16);
|
||||||
tftPrint(ARIGHT, String(radio.af[i].frequency / 100) + "." + String((radio.af[i].frequency % 100) / 10), 55 + (i > 9 ? 54 : 0) + (i > 19 ? 54 : 0) + (i > 29 ? 54 : 0) + (i > 39 ? 54 : 0), 48 + (15 * i) - (i > 9 ? 150 : 0) - (i > 19 ? 150 : 0) - (i > 29 ? 150 : 0) - (i > 39 ? 150 : 0), SignificantColor, SignificantColorSmooth, 16);
|
|
||||||
} else {
|
|
||||||
tftPrint(ARIGHT, String(radio.af[i].frequency / 100) + "." + String((radio.af[i].frequency % 100) / 10), 55 + (i > 9 ? 54 : 0) + (i > 19 ? 54 : 0) + (i > 29 ? 54 : 0) + (i > 39 ? 54 : 0), 48 + (15 * i) - (i > 9 ? 150 : 0) - (i > 19 ? 150 : 0) - (i > 29 ? 150 : 0) - (i > 39 ? 150 : 0), RDSColor, RDSColorSmooth, 16);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (radio.af_counter > 10) tft.drawLine(59, 54, 59, 191, SecondaryColor);
|
if (radio.af_counter > 10) tft.drawLine(59, 54, 59, 191, SecondaryColor);
|
||||||
if (radio.af_counter > 20) tft.drawLine(113, 54, 113, 191, SecondaryColor);
|
if (radio.af_counter > 20) tft.drawLine(113, 54, 113, 191, SecondaryColor);
|
||||||
@@ -969,48 +845,27 @@ void ShowAFEON() {
|
|||||||
byte eon_numbers;
|
byte eon_numbers;
|
||||||
if (afpagenr != 3) {
|
if (afpagenr != 3) {
|
||||||
if (radio.eon_counter > 9) eon_numbers = 10; else eon_numbers = radio.eon_counter;
|
if (radio.eon_counter > 9) eon_numbers = 10; else eon_numbers = radio.eon_counter;
|
||||||
} else {
|
} else eon_numbers = radio.eon_counter - 10;
|
||||||
eon_numbers = radio.eon_counter - 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (byte i = 0; i < eon_numbers; i++) {
|
for (byte i = 0; i < eon_numbers; i++) {
|
||||||
if (eonpicodeold[i + y] == nullptr) {
|
if (eonpicodeold[i + y] == nullptr) strcpy(eonpicodeold[i + y], "");
|
||||||
strcpy(eonpicodeold[i + y], "");
|
if (eonpsold[i + y] == nullptr) eonpsold[i + y] = "";
|
||||||
}
|
if (mappedfreqold[i + y] == 0) mappedfreqold[i + y] = 0;
|
||||||
if (eonpsold[i + y] == nullptr) {
|
if (mappedfreqold2[i + y] == 0) mappedfreqold2[i + y] = 0;
|
||||||
eonpsold[i + y] = "";
|
if (mappedfreqold3[i + y] == 0) mappedfreqold3[i + y] = 0;
|
||||||
}
|
if (eonptyold[i + y] == 0) eonptyold[i + y] = 0;
|
||||||
if (mappedfreqold[i + y] == 0) {
|
|
||||||
mappedfreqold[i + y] = 0;
|
|
||||||
}
|
|
||||||
if (mappedfreqold2[i + y] == 0) {
|
|
||||||
mappedfreqold2[i + y] = 0;
|
|
||||||
}
|
|
||||||
if (mappedfreqold3[i + y] == 0) {
|
|
||||||
mappedfreqold3[i + y] = 0;
|
|
||||||
}
|
|
||||||
if (eonptyold[i + y] == 0) {
|
|
||||||
eonptyold[i + y] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(eonpicodeold[i + y], radio.eon[i + y].picode) != 0) {
|
if (strcmp(eonpicodeold[i + y], radio.eon[i + y].picode) != 0) tftPrint(ALEFT, eonpicodeold[i + y], 4, 48 + (15 * i), BackgroundColor, BackgroundColor, 16);
|
||||||
tftPrint(ALEFT, eonpicodeold[i + y], 4, 48 + (15 * i), BackgroundColor, BackgroundColor, 16);
|
|
||||||
}
|
|
||||||
tftPrint(ALEFT, radio.eon[i + y].picode, 4, 48 + (15 * i), RDSColor, RDSColorSmooth, 16);
|
tftPrint(ALEFT, radio.eon[i + y].picode, 4, 48 + (15 * i), RDSColor, RDSColorSmooth, 16);
|
||||||
strcpy(eonpicodeold[i + y], radio.eon[i + y].picode);
|
strcpy(eonpicodeold[i + y], radio.eon[i + y].picode);
|
||||||
|
|
||||||
if (radio.eon[i + y].ps.length() > 0) {
|
if (radio.eon[i + y].ps.length() > 0) {
|
||||||
tftPrint(ALEFT, "PS", 46, 32, ActiveColor, ActiveColorSmooth, 16);
|
tftPrint(ALEFT, "PS", 46, 32, ActiveColor, ActiveColorSmooth, 16);
|
||||||
|
|
||||||
if (strcmp(radio.eon[i + y].ps.c_str(), eonpsold[i + y].c_str()) != 0) {
|
if (strcmp(radio.eon[i + y].ps.c_str(), eonpsold[i + y].c_str()) != 0) tftPrint(ALEFT, eonpsold[i + y].c_str(), 46, 48 + (15 * i), BackgroundColor, BackgroundColor, 16);
|
||||||
tftPrint(ALEFT, eonpsold[i + y].c_str(), 46, 48 + (15 * i), BackgroundColor, BackgroundColor, 16);
|
|
||||||
}
|
|
||||||
tftPrint(ALEFT, radio.eon[i + y].ps.c_str(), 46, 48 + (15 * i), RDSDropoutColor, RDSDropoutColorSmooth, 16);
|
tftPrint(ALEFT, radio.eon[i + y].ps.c_str(), 46, 48 + (15 * i), RDSDropoutColor, RDSDropoutColorSmooth, 16);
|
||||||
eonpsold[i + y] = radio.eon[i + y].ps;
|
eonpsold[i + y] = radio.eon[i + y].ps;
|
||||||
} else {
|
} else tftPrint(ALEFT, eonpsold[i + y].c_str(), 46, 48 + (15 * i), BackgroundColor, BackgroundColor, 16);
|
||||||
tftPrint(ALEFT, eonpsold[i + y].c_str(), 46, 48 + (15 * i), BackgroundColor, BackgroundColor, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (radio.eon[i + y].mappedfreq > 0) {
|
if (radio.eon[i + y].mappedfreq > 0) {
|
||||||
tftPrint(ALEFT, "MF", 119, 32, ActiveColor, ActiveColorSmooth, 16);
|
tftPrint(ALEFT, "MF", 119, 32, ActiveColor, ActiveColorSmooth, 16);
|
||||||
@@ -1070,9 +925,7 @@ void ShowAFEON() {
|
|||||||
if (eonptyold[i + y] != radio.eon[i + y].pty) tft.fillRect(290, 48 + (15 * i), 29, 16, BackgroundColor);
|
if (eonptyold[i + y] != radio.eon[i + y].pty) tft.fillRect(290, 48 + (15 * i), 29, 16, BackgroundColor);
|
||||||
if (radio.eon[i + y].pty != 254) tftPrint(ARIGHT, String(radio.eon[i + y].pty), 310, 48 + (15 * i), RDSColor, RDSColorSmooth, 16);
|
if (radio.eon[i + y].pty != 254) tftPrint(ARIGHT, String(radio.eon[i + y].pty), 310, 48 + (15 * i), RDSColor, RDSColorSmooth, 16);
|
||||||
eonptyold[i + y] = radio.eon[i + y].pty;
|
eonptyold[i + y] = radio.eon[i + y].pty;
|
||||||
} else {
|
} else tft.fillRect(290, 48 + (15 * i), 29, 16, BackgroundColor);
|
||||||
tft.fillRect(290, 48 + (15 * i), 29, 16, BackgroundColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (radio.eon[i + y].ta) tftPrint(ACENTER, "O", 250, 48 + (15 * i), RDSColor, RDSColorSmooth, 16); else tftPrint(ACENTER, "O", 250, 48 + (15 * i), BackgroundColor, BackgroundColor, 16);
|
if (radio.eon[i + y].ta) tftPrint(ACENTER, "O", 250, 48 + (15 * i), RDSColor, RDSColorSmooth, 16); else tftPrint(ACENTER, "O", 250, 48 + (15 * i), BackgroundColor, BackgroundColor, 16);
|
||||||
if (radio.eon[i + y].tp) tftPrint(ACENTER, "O", 276, 48 + (15 * i), RDSColor, RDSColorSmooth, 16); else tftPrint(ACENTER, "O", 276, 48 + (15 * i), BackgroundColor, BackgroundColor, 16);
|
if (radio.eon[i + y].tp) tftPrint(ACENTER, "O", 276, 48 + (15 * i), RDSColor, RDSColorSmooth, 16); else tftPrint(ACENTER, "O", 276, 48 + (15 * i), BackgroundColor, BackgroundColor, 16);
|
||||||
@@ -1093,11 +946,8 @@ void ShowAFEON() {
|
|||||||
if (!aidProcessed) {
|
if (!aidProcessed) {
|
||||||
for (int z = 0; z < 4; z++) {
|
for (int z = 0; z < 4; z++) {
|
||||||
uint8_t nibble = (radio.rds.aid[y] >> (4 * (3 - z))) & 0xF;
|
uint8_t nibble = (radio.rds.aid[y] >> (4 * (3 - z))) & 0xF;
|
||||||
if (nibble < 10) {
|
if (nibble < 10) id[z] = nibble + '0';
|
||||||
id[z] = nibble + '0';
|
else id[z] = nibble - 10 + 'A';
|
||||||
} else {
|
|
||||||
id[z] = nibble - 10 + 'A';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
id[4] = '\0';
|
id[4] = '\0';
|
||||||
|
|
||||||
@@ -1111,9 +961,7 @@ void ShowAFEON() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aidProcessed && y < radio.rds.aid_counter - 1) {
|
if (aidProcessed && y < radio.rds.aid_counter - 1) AIDStringTemp += " | ";
|
||||||
AIDStringTemp += " | ";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
aid_counterold = radio.rds.aid_counter;
|
aid_counterold = radio.rds.aid_counter;
|
||||||
|
|
||||||
@@ -1156,52 +1004,40 @@ void ShowAFEON() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ShowRDSStatistics() {
|
void ShowRDSStatistics() {
|
||||||
// --- Only update if RDS is active, blocks processed, and no block A-D errors ---
|
|
||||||
if (RDSstatus && radio.processed_rdsblocks > 0 &&
|
if (RDSstatus && radio.processed_rdsblocks > 0 &&
|
||||||
!radio.rds.rdsAerror && !radio.rds.rdsBerror &&
|
!radio.rds.rdsAerror && !radio.rds.rdsBerror &&
|
||||||
!radio.rds.rdsCerror && !radio.rds.rdsDerror) {
|
!radio.rds.rdsCerror && !radio.rds.rdsDerror) {
|
||||||
|
|
||||||
// --- Update total processed RDS blocks if changed ---
|
|
||||||
if (processed_rdsblocksold[32] != radio.processed_rdsblocks) {
|
if (processed_rdsblocksold[32] != radio.processed_rdsblocks) {
|
||||||
tftReplace(ARIGHT, String(processed_rdsblocksold[32]), String(radio.processed_rdsblocks),
|
tftReplace(ARIGHT, String(processed_rdsblocksold[32]), String(radio.processed_rdsblocks), 318, 222, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16);
|
||||||
318, 222, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16);
|
|
||||||
processed_rdsblocksold[32] = radio.processed_rdsblocks;
|
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};
|
const uint8_t rdsYpos[] PROGMEM = {56, 76, 96, 116, 136, 156, 176, 196};
|
||||||
|
|
||||||
uint8_t rb = radio.rdsblock; // current RDS block index
|
uint8_t rb = radio.rdsblock;
|
||||||
|
|
||||||
// --- Determine X column positions based on group range ---
|
|
||||||
uint16_t xpos, xposPct;
|
uint16_t xpos, xposPct;
|
||||||
if (rb <= RDS_GROUP_3B ) {
|
if(rb <= RDS_GROUP_3B) {
|
||||||
xpos = 60;
|
xpos = 60;
|
||||||
xposPct = 70;
|
xposPct = 70;
|
||||||
}
|
} else if(rb <= RDS_GROUP_7B) {
|
||||||
else if (rb <= RDS_GROUP_7B ) {
|
|
||||||
xpos = 140;
|
xpos = 140;
|
||||||
xposPct = 150;
|
xposPct = 150;
|
||||||
}
|
} else if(rb <= RDS_GROUP_11B) {
|
||||||
else if (rb <= RDS_GROUP_11B) {
|
|
||||||
xpos = 220;
|
xpos = 220;
|
||||||
xposPct = 230;
|
xposPct = 230;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
xpos = 300;
|
xpos = 300;
|
||||||
xposPct = 310;
|
xposPct = 310;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Determine Y row position (wraps every 8 groups) ---
|
uint8_t row = rb & 0x07;
|
||||||
uint8_t row = rb & 0x07; // modulo 8
|
uint8_t ypos = pgm_read_byte(&rdsYpos[row]);
|
||||||
uint8_t ypos = pgm_read_byte(&rdsYpos[row]); // Y position
|
|
||||||
|
|
||||||
// --- Persist last drawn dot between calls ---
|
static int16_t lastX = -1, lastY = -1;
|
||||||
static int16_t lastX = -1, lastY = -1; // -1 = "none yet"
|
|
||||||
|
|
||||||
// --- Update only if block counter has changed ---
|
|
||||||
if (blockcounterold[rb] != radio.rds.blockcounter[rb]) {
|
if (blockcounterold[rb] != radio.rds.blockcounter[rb]) {
|
||||||
// Calculate old and new percentages
|
|
||||||
float oldPerc = (blockcounterold[rb] * 100.0f) / processed_rdsblocksold[rb];
|
float oldPerc = (blockcounterold[rb] * 100.0f) / processed_rdsblocksold[rb];
|
||||||
float newPerc = (radio.rds.blockcounter[rb] * 100.0f) / radio.processed_rdsblocks;
|
float newPerc = (radio.rds.blockcounter[rb] * 100.0f) / radio.processed_rdsblocks;
|
||||||
|
|
||||||
@@ -1209,58 +1045,33 @@ void ShowRDSStatistics() {
|
|||||||
dtostrf(oldPerc, 0, 1, oldBuf);
|
dtostrf(oldPerc, 0, 1, oldBuf);
|
||||||
dtostrf(newPerc, 0, 1, newBuf);
|
dtostrf(newPerc, 0, 1, newBuf);
|
||||||
|
|
||||||
// Draw previous position as "Significant" if different
|
if (lastX >= 0 && (lastX != xpos || lastY != ypos)) tft.fillCircle(lastX - 55, lastY + 7, 2, SignificantColor);
|
||||||
if (lastX >= 0 && (lastX != xpos || lastY != ypos)) {
|
|
||||||
tft.fillCircle(lastX - 55, lastY + 7, 2, SignificantColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update percentage display
|
tftReplace(ARIGHT, oldBuf, newBuf, xpos, ypos, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16);
|
||||||
tftReplace(ARIGHT, oldBuf, newBuf, xpos, ypos,
|
tftPrint(ACENTER, "%", xposPct, ypos, ActiveColor, ActiveColorSmooth, 16);
|
||||||
PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16);
|
|
||||||
tftPrint(ACENTER, "%", xposPct, ypos,
|
|
||||||
ActiveColor, ActiveColorSmooth, 16);
|
|
||||||
|
|
||||||
// Draw current dot as "Insignificant"
|
|
||||||
tft.fillCircle(xpos - 55, ypos + 7, 2, InsignificantColor);
|
tft.fillCircle(xpos - 55, ypos + 7, 2, InsignificantColor);
|
||||||
|
|
||||||
// Save current dot for next update
|
|
||||||
lastX = xpos;
|
lastX = xpos;
|
||||||
lastY = ypos;
|
lastY = ypos;
|
||||||
|
|
||||||
// Store updated block counters
|
blockcounterold[rb] = radio.rds.blockcounter[rb];
|
||||||
blockcounterold[rb] = radio.rds.blockcounter[rb];
|
|
||||||
processed_rdsblocksold[rb] = radio.processed_rdsblocks;
|
processed_rdsblocksold[rb] = radio.processed_rdsblocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Build HEX string from 16-bit RDS blocks A..D ---
|
|
||||||
String HexString;
|
String HexString;
|
||||||
HexString = String(((radio.rds.rdsA >> 12) & 0xF), HEX) +
|
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);
|
||||||
String(((radio.rds.rdsA >> 8) & 0xF), HEX) +
|
HexString += " ";
|
||||||
String(((radio.rds.rdsA >> 4) & 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);
|
||||||
String(( radio.rds.rdsA & 0xF), HEX) + " ";
|
HexString += " ";
|
||||||
|
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 += " ";
|
||||||
|
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);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Uppercase HEX string
|
|
||||||
HexString.toUpperCase();
|
HexString.toUpperCase();
|
||||||
|
|
||||||
// Update display if string changed
|
|
||||||
if (HexString != HexStringold) {
|
if (HexString != HexStringold) {
|
||||||
tftReplace(ACENTER, HexStringold, HexString,
|
tftReplace(ACENTER, HexStringold, HexString, 160, 222, ActiveColor, ActiveColorSmooth, BackgroundColor, 16);
|
||||||
160, 222, ActiveColor, ActiveColorSmooth, BackgroundColor, 16);
|
|
||||||
HexStringold = HexString;
|
HexStringold = HexString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1269,20 +1080,14 @@ void ShowRDSStatistics() {
|
|||||||
if (radio.processed_rdsblocks > 0 && !dropout) {
|
if (radio.processed_rdsblocks > 0 && !dropout) {
|
||||||
// Draw A-D error circles (simple error flags)
|
// Draw A-D error circles (simple error flags)
|
||||||
const uint8_t xErr[4] = {86, 124, 162, 200};
|
const uint8_t xErr[4] = {86, 124, 162, 200};
|
||||||
const bool errors[4] = {radio.rds.rdsAerror, radio.rds.rdsBerror,
|
const bool errors[4] = {radio.rds.rdsAerror, radio.rds.rdsBerror, radio.rds.rdsCerror, radio.rds.rdsDerror};
|
||||||
radio.rds.rdsCerror, radio.rds.rdsDerror
|
|
||||||
};
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) tft.fillCircle(xErr[i], 41, 5, errors[i] ? SignificantColor : InsignificantColor);
|
||||||
tft.fillCircle(xErr[i], 41, 5,
|
|
||||||
errors[i] ? SignificantColor : InsignificantColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Advanced error levels (0=clean, 1=small, 2=medium, 3=big) ---
|
|
||||||
int errA = (radio.rds.rdsErr >> 14) & 0x03;
|
int errA = (radio.rds.rdsErr >> 14) & 0x03;
|
||||||
int errB = ((radio.rds.rdsErr >> 8) & B00110000) >> 4;
|
int errB = ((radio.rds.rdsErr >> 8) & 48) >> 4;
|
||||||
int errC = ((radio.rds.rdsErr >> 8) & B00001100) >> 2;
|
int errC = ((radio.rds.rdsErr >> 8) & 12) >> 2;
|
||||||
int errD = (radio.rds.rdsErr & B00000011);
|
int errD = (radio.rds.rdsErr & 3);
|
||||||
|
|
||||||
// Aggressive weights per error level
|
// Aggressive weights per error level
|
||||||
const int weights[4] = {0, 2, 6, 12};
|
const int weights[4] = {0, 2, 6, 12};
|
||||||
@@ -1291,25 +1096,18 @@ void ShowRDSStatistics() {
|
|||||||
int errorBits = weights[errA] + weights[errB] + weights[errC] + weights[errD];
|
int errorBits = weights[errA] + weights[errB] + weights[errC] + weights[errD];
|
||||||
int totalBits = 4 * 26; // 104 data bits per RDS group
|
int totalBits = 4 * 26; // 104 data bits per RDS group
|
||||||
|
|
||||||
// Raw BER estimate
|
|
||||||
float ber = (float)errorBits / (float)totalBits;
|
float ber = (float)errorBits / (float)totalBits;
|
||||||
|
|
||||||
// Non-linear boost (sqrt makes small errors show stronger)
|
|
||||||
ber = sqrt(ber);
|
ber = sqrt(ber);
|
||||||
if (ber > 1.0) ber = 1.0; // clamp to 100%
|
if (ber > 1.0) ber = 1.0;
|
||||||
|
|
||||||
// Smooth exponential filter
|
|
||||||
float alpha = 0.05;
|
float alpha = 0.05;
|
||||||
smoothBER = (1.0 - alpha) * smoothBER + alpha * ber;
|
smoothBER = (1.0 - alpha) * smoothBER + alpha * ber;
|
||||||
|
|
||||||
int berPercent = (int)(smoothBER * 100.0);
|
int berPercent = (int)(smoothBER * 100.0);
|
||||||
|
|
||||||
// Update BER display only if value changed
|
|
||||||
if (berPercentold != berPercent) {
|
if (berPercentold != berPercent) {
|
||||||
tftReplace(ARIGHT, String(berPercentold) + "%", String(berPercent) + "%",
|
tftReplace(ARIGHT, String(berPercentold) + "%", String(berPercent) + "%", 318, 34, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16);
|
||||||
318, 34, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16);
|
|
||||||
berPercentold = berPercent;
|
berPercentold = berPercent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
Reference in New Issue
Block a user