CesarSound
Published © GPL3+

LW/MW/SW Stereo FM with RDS - DSP Radio Receiver V2.5

This is a project of Radio Receiver LW/MW/SW Stereo FM with RDS, using Arduino Nano, Si473x Radio IC and 1.8in TFT color display ST7735.

IntermediateWork in progress117,212
LW/MW/SW Stereo FM with RDS - DSP Radio Receiver V2.5

Things used in this project

Hardware components

BOM: see the parts in the schematics and in the text.
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Audio amp LM386 DIY Schematics

Audio amp LM386 DIY Schematics

Audio amp LM386 DIY PCB layout

It is not necessary to resize the PCB designs, they are already in the 1: 1 scale and you do not need to mirror them.

Audio amp LM386 DIY PCB top mask

Audio amp LM386 DIY PCB top mask

Code

DSP Radio Receiver Code Rev. 2.5

C/C++
Just load it to Arduino Nano
/*********************************************************************************************************************************************************
  Si473x LW/MW/SW/CB AM/FM Stereo RDS Radio Receiver w/ ST7735 TFT Display and Arduino Nano/Uno - AM 150kHz To 30MHz - FM 64 to 108MHz Stereo with RDS.
  Please see the schematics for wiring connections and install all needed libraries that are located in the "INSTALL THESE LIBRARIES" folder.
  By J.CesarSound - ver 2.5 - Mar/2021.
**********************************************************************************************************************************************************/

//Libraries
#include <EEPROM.h>     //IDE Standard 
#include <SPI.h>        //IDE Standard
#include "Wire.h"       //IDE Standard
#include <TFT_ST7735.h> //BODMER graphics and font library for ST7735 TFT display
#include <Si4735.h>     //Michael Kennedy SI4735 I2C library modified by J.CesarSound
#include <Rotary.h>     //Ben Buxton https://github.com/brianlow/Rotary

//User preferences
//-------------------------------------------------------------------------------------------------------------------------------------------
#define SI7435_ADDRESS 0x63  //Si473x I2C address (0x11 = sen pin to GND or 0x63 = sen pin to 3v3), module PL102BA-S V2 uses 0x63
#define pb_0           A0    //AM mode and AM Band selector: short press AM / UP band, long press DOWN band
#define pb_1           A1    //Save current frequency, band, theme to EEPROM and Tuning Step selector: short press SAVE, long press Tstep
#define pb_2           A2    //Bandwidth IF Filter selector for AM and FM
#define pb_3           A3    //FM mode, RDS program type and color theme selector: short press FM / RDS type, long press switch color theme
//--------------------------------------------------------------------------------------------------------------------------------------------

TFT_ST7735 tft = TFT_ST7735();
Rotary r = Rotary(2, 3);
Si4735 radio;

unsigned int freq, fstep, freqold;
unsigned int freq_eeprom_am, freq_eeprom_fm;
int sm, sm_old, mx, sn, texsw = 0;
int stp = 2;
int mode = 2;
byte fr_eeprom_h, fr_eeprom_l, sts_am_fm, sts_theme;
byte encoder = 1, push_count = 0;
byte count, ctr;
byte filter = 0x03;
byte fil = 4;
byte fr_h;
byte fr_l;
byte ssb_m = 0x00;
byte mw_sw = 0x00;
byte am_fm;
bool hasRun = false, hasRun1 = false, hasRun2 = false, hasRun3 = false, rds_t = false;
unsigned int period = 0;
unsigned long time_now = 0;
unsigned int period_rds = 500;
unsigned long time_now_rds = 0;
unsigned int ca, cb, cc, cd, ce, cf, cg, ch;
bool buttonActive_0 = false, buttonActive_1 = false, longPressActive = false;
unsigned int longPressTime = 600;
unsigned long buttonTimer = 0;

void setup() {
  tft.init();
  tft.setRotation(3);
  Wire.begin();
  start_msg();
  tft.fillScreen(ca);

  pinMode(pb_0, INPUT_PULLUP);
  pinMode(pb_1, INPUT_PULLUP);
  pinMode(pb_2, INPUT_PULLUP);
  pinMode(pb_3, INPUT_PULLUP);

  if (digitalRead(A1) == LOW) {
    tft.fillScreen(TFT_BLUE); tft.setTextColor(TFT_WHITE, TFT_BLUE); tft.drawString("* DEFAULT VALUES *", 12, 58, 2);
    delay(500);
    am_fm = 0x20;
    freq = 10050;
    EEPROM.write(5, 6);
    eeprom_write();
  }

  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei();

  eeprom_read(); sts_theme = EEPROM.read(6);
  if (sts_theme == false) blue_theme(); else black_theme();
  if (sts_am_fm == false) am_init(); else fm_init();
}

void loop() {
  if (freqold != freq) {
    freqold = freq;
    tune_freq();
    frequency();
    if (am_fm != 0x20) band_ind();
  }

  if (digitalRead(pb_0) == LOW) {
    delay(100);
    if (buttonActive_0 == false) {
      buttonActive_0 = true;
      buttonTimer = millis();
    }
    if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {
      longPressActive = true;
      dec_preset();
    }
  } else {
    if (buttonActive_0 == true) {
      if (longPressActive == true) {
        longPressActive = false;
      } else {
        inc_preset();
      }
      buttonActive_0 = false;
    }
  }

  if (digitalRead(pb_1) == LOW) {
    delay(100);
    if (buttonActive_1 == false) {
      buttonActive_1 = true;
      buttonTimer = millis();
    }
    if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {
      longPressActive = true;
      if (am_fm != 0x20) inc_step();
      if (am_fm == 0x20) setstepFM();
    }
  } else {
    if (buttonActive_1 == true) {
      if (longPressActive == true) {
        longPressActive = false;
      } else {
        eeprom_write();
      }
      buttonActive_1 = false;
    }
  }

  if ((digitalRead(pb_2)) == LOW) {
    delay(200);
    if (am_fm != 0x20) filterAM();
    if (am_fm == 0x20) filterFM();
    while (digitalRead(pb_2) == LOW);
  }

  if (digitalRead(pb_3) == LOW) {
    delay(500);
    if (am_fm != 0x20) {
      fm_init();
    } else rds_t = !rds_t;
    tft.drawString("                         ", 0, 74, 2);

    push_count++;
    if (push_count > 2) {
      sw_theme();
      while (digitalRead(pb_3) == LOW);
    }
  } else push_count = 0;

  if (millis() > time_now + period) {
    time_now = millis();
    rsq();
    smeter();
    snmeter();
    if (am_fm == 0x20) pilot();
  }

  if (am_fm == 0x20) {
    if (millis() > time_now_rds + period_rds) {
      time_now_rds = millis();
      rds();
    }
  }
}

ISR(PCINT2_vect) {
  char result = r.process();
  if (result == DIR_CW) set_frequency(1);
  else if (result == DIR_CCW) set_frequency(-1);
}

void set_frequency(short dir) {
  if (encoder == 1) {
    if (dir == 1) freq = freq + fstep;
    if (freq >= 30000) freq = 30000;
    if (dir == -1) freq = freq - fstep;
    if (freq <= 150) freq = 150;
  }
  if (encoder == 2) {
    if (dir == 1) freq = freq + fstep;
    if (freq >= 10810) freq = 10810;
    if (dir == -1) freq = freq - fstep;
    if (freq <= 6410) freq = 6410;
  }
}

void inc_preset() {
  count++;
  if (count > 14) count = 1;
  bandpresets();
}

void dec_preset() {
  count--;
  if (count < 1) count = 14;
  bandpresets();
}

void bandpresets() {
  tft.setTextSize(1); tft.setTextColor(cb, ca); tft.drawString("        ", 30, 57, 2);
  switch (count)  {
    case 1:
      freq = 198;
      stp = 1;
      setstep();
      break;
    case 2:
      freq = 522;
      stp = 4;
      setstep();
      break;
    case 3:
      freq = 520;
      stp = 3;
      setstep();
      break;
    case 4:
      freq = 3700;
      stp = 2;
      setstep();
      break;
    case 5:
      freq = 5000;
      stp = 2;
      setstep();
      break;
    case 6:
      freq = 6100;
      stp = 2;
      setstep();
      break;
    case 7:
      freq = 7200;
      stp = 2;
      setstep();
      break;
    case 8:
      freq = 10000;
      stp = 2;
      setstep();
      break;
    case 9:
      freq = 11940;
      stp = 2;
      setstep();
      break;
    case 10:
      freq = 13790;
      stp = 2;
      setstep();
      break;
    case 11:
      freq = 15400;
      stp = 2;
      setstep();
      break;
    case 12:
      freq = 17780;
      stp = 2;
      setstep();
      break;
    case 13:
      freq = 21525;
      stp = 2;
      setstep();
      break;
    case 14:
      freq = 27015;
      stp = 2;
      setstep();
      break;
  }
  if (hasRun2 == false) {
    am_init(); hasRun2 = true;
  }
  if (count >= 1 && count <= 4) period = 4000; else period = 500; band_ind();
}

void filterAM() {
  tft.setTextSize(1);
  tft.setTextColor(cb, ca);
  switch (fil) {
    case 0:
      fil = 1;
      filter = 0x00; tft.drawString("6k ", 135, 92, 2);
      break;
    case 1:
      fil = 2;
      filter = 0x01; tft.drawString("4k ", 135, 92, 2);
      break;
    case 2:
      fil = 3;
      filter = 0x02; tft.drawString("3k ", 135, 92, 2);
      break;
    case 3:
      fil = 4;
      filter = 0x06; tft.drawString("2k5", 135, 92, 2);
      break;
    case 4:
      fil = 5;
      filter = 0x03; tft.drawString("2k ", 135, 92, 2);
      break;
    case 5:
      fil = 6;
      filter = 0x05; tft.drawString("1k8", 135, 92, 2);
      break;
    case 6:
      fil = 0;
      filter = 0x04; tft.drawString("1k ", 135, 92, 2);
      break;
  }
  property_filter_AM();
}

void filterFM() {
  tft.setTextSize(1);
  tft.setTextColor(cb, ca);
  switch (fil) {
    case 0:
      fil = 1;
      filter = 0x00; tft.drawString("Aut", 135, 92, 2);
      break;
    case 1:
      fil = 2;
      filter = 0x01; tft.drawString("110", 134, 92, 2);
      break;
    case 2:
      fil = 3;
      filter = 0x02; tft.drawString("84k", 135, 92, 2);
      break;
    case 3:
      fil = 4;
      filter = 0x03; tft.drawString("60k", 135, 92, 2);
      break;
    case 4:
      fil = 0;
      filter = 0x04; tft.drawString("40k", 135, 92, 2);
      break;
  }
  fm_command();
}

void inc_step() {
  ctr++; if (ctr > 3) ctr = 1;
  byte eu[3] = {1, 4, 1}; byte us[3] = {1, 2, 3};
  if (count == 2) stp = eu[ctr];
  if (count != 2) stp = us[ctr];
  setstep();
}

void setstep() {
  tft.setTextSize(1);
  tft.setTextColor(cb, ca);
  switch (stp) {
    case 1:
      fstep = 1;
      tft.drawString(" 1k", 100, 57, 2);
      break;
    case 2:
      fstep = 5;
      tft.drawString(" 5k", 100, 57, 2);
      break;
    case 3:
      fstep = 10;
      tft.drawString("10k", 100, 57, 2);
      break;
    case 4:
      fstep = 9;
      tft.drawString(" 9k", 100, 57, 2);
      break;
  }
}

void setstepFM() {
  tft.setTextSize(1);
  tft.setTextColor(cb, ca);
  switch (stp) {
    case 0:
      stp = 1;
      fstep = 10;    // 100kHz
      tft.drawString(" x1 ", 100, 57, 2);
      break;
    case 1:
      stp = 0;
      fstep = 20;    // 200kHz
      tft.drawString(" x2 ", 100, 57, 2);
      break;
  }
}

void frequency() {
  tft.setTextColor(cg, ca);
  if (freq >= 10000) tft.drawNumber(freq, 0, 1, 7); if (freq < 10000 && freq >= 1000) tft.drawNumber(freq, 32, 1, 7);
  if (freq < 1000 && freq >= 100) tft.drawNumber(freq, 64, 1, 7); if (freq < 100 && freq >= 10) tft.drawNumber(freq, 96, 1, 7);
  if (freq < 10) tft.drawNumber(freq, 128, 1, 7); if (freq < 10000) tft.fillRect (2, 1, 28, 48, ca);
  if (freq < 1000) tft.fillRect (34, 1, 28, 48, ca);

  if (am_fm == 0x40 && freq >= 1000) tft.fillCircle(63, 51, 2, cg); else  tft.fillCircle(63, 51, 2, ca);
  if (am_fm == 0x20) tft.fillCircle(95, 51, 2, cg);  else tft.fillCircle(95, 51, 2, ca);
}

void snmeter() {
  if (sn > 42) sn = 42;
  byte range; if (am_fm == 0x20) range = 42; else range = 28;
  byte sn_g = map(sn, 0, range, 0, 65);
  tft.fillRect(31, 95, sn_g, 11, ce);
  tft.fillRect(31 + sn_g, 95, 65 - sn_g, 11, cf);
}

void smeter() {
  if (sm > 90) sm = 90; mx = sm;
  tft.fillRect(31, 113, sm, 11, cd);
  tft.fillRect(31 + sm, 113, 90 - sm, 11, cf);

  tft.setTextSize(1);
  tft.setTextColor(cb, ca);
  if (mx < 1) tft.drawString(" S0", 130, 111, 2);
  if ((mx >= 1) && (mx < 10)) tft.drawString(" S1", 130, 111, 2);
  if ((mx >= 10) && (mx < 25)) tft.drawString(" S3", 130, 111, 2);
  if ((mx >= 25) && (mx < 35)) tft.drawString(" S5", 130, 111, 2);
  if ((mx >= 35) && (mx < 50)) tft.drawString(" S7", 130, 111, 2);
  if ((mx >= 50) && (mx < 60)) tft.drawString(" S9", 130, 111, 2);
  if ((mx >= 60) && (mx < 70)) tft.drawString("+10", 130, 111, 2);
  if ((mx >= 70) && (mx < 75)) tft.drawString("+20", 130, 111, 2);
  if ((mx >= 75) && (mx < 80)) tft.drawString("+40", 130, 111, 2);
  if (mx >= 80) tft.drawString("+60", 130, 111, 2);
}

void layout() {
  tft.setTextColor(TFT_WHITE, TFT_BLUE);
  tft.drawFastHLine(0, 56, 160, cc);
  tft.drawFastVLine(125, 59, 12, cc);
  tft.drawFastHLine(0, 73, 160, cc);
  tft.drawFastHLine(0, 91, 160, cc);
  tft.drawFastHLine(0, 109, 160, cc);

  tft.drawFastHLine(30, 106, 67, cc); tft.drawFastHLine(30, 124, 92, cc);
  tft.drawFastVLine(30, 95, 11, cc); tft.drawFastVLine(30, 113, 11, cc);
  tft.drawFastVLine(96, 102, 4, cc); tft.drawFastVLine(121, 120, 4, cc);

  tft.setTextSize(1);
  tft.setTextColor(cb, ca);
  tft.drawString("Ts", 85, 57, 2);
  tft.drawString("S/N", 3, 92, 2);
  tft.drawString("BWF", 105, 92, 2);
  tft.drawString("SIG", 3, 111, 2);
}

void start_msg() {
  tft.fillScreen(TFT_BLACK);
  tft.setTextSize(1);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.drawString("JCR RADIO", 48, 20, 2);
  tft.drawString("AM/FM RDS Receiver", 15, 50, 2);
  tft.drawString("VER 2.5 - MAR/2021", 15, 80, 2);
  delay(1600);
}

void band_ind() {
  tft.setTextSize(1); tft.setTextColor(cb, ca);
  if (freq >= 1800 && freq <= 2000) tft.drawString("160m  ", 30, 57, 2); if (freq >= 2300 && freq <= 2495) tft.drawString("120m", 30, 57, 2);
  if (freq >= 3200 && freq <= 3400) tft.drawString("90m  ", 30, 57, 2); if (freq >= 3500 && freq <= 3800) tft.drawString("80m", 30, 57, 2);
  if (freq >= 3900 && freq <= 4000) tft.drawString("75m", 30, 57, 2); if (freq >= 4750 && freq <= 5500) tft.drawString("60m", 30, 57, 2);
  if (freq >= 5700 && freq <= 6200) tft.drawString("49m", 30, 57, 2); if (freq >= 7000 && freq <= 7299) tft.drawString("40m", 30, 57, 2);
  if (freq >= 7300 && freq <= 7600) tft.drawString("41m", 30, 57, 2); if (freq >= 9400 && freq <= 10000) tft.drawString("31m", 30, 57, 2);
  if (freq >= 10100 && freq <= 10150) tft.drawString("30m", 30, 57, 2); if (freq >= 11600 && freq <= 12100) tft.drawString("25m", 30, 57, 2);
  if (freq >= 13570 && freq <= 13870) tft.drawString("22m", 30, 57, 2); if (freq >= 14000 && freq <= 14350) tft.drawString("20m", 30, 57, 2);
  if (freq >= 15100 && freq <= 15830) tft.drawString("19m", 30, 57, 2); if (freq >= 18068 && freq <= 18168) tft.drawString("17m", 30, 57, 2);
  if (freq >= 17480 && freq <= 17900) tft.drawString("16m", 30, 57, 2); if (freq >= 21000 && freq <= 21450) tft.drawString("15m", 30, 57, 2);
  if (freq >= 21451 && freq <= 21850) tft.drawString("13m", 30, 57, 2); if (freq >= 24890 && freq <= 24990) tft.drawString("12m", 30, 57, 2);
  if (freq >= 25670 && freq <= 27999) tft.drawString("11m", 30, 57, 2); if (freq >= 28000 && freq <= 29700) tft.drawString("10m", 30, 57, 2);
  if (freq >= 150 && freq <= 515) tft.drawString("LW     ", 30, 57, 2);
  if (freq >= 520 && freq <= 1710 && count == 3) tft.drawString("MW US", 30, 57, 2);
  if (freq >= 522 && freq <= 1728 && count == 2) tft.drawString("MW EU", 30, 57, 2);
}

void tune_freq() {
  fr_h = (freq) >> 8;
  fr_l = (freq) & 0x00FF;
  if ((freq) < 1800) mw_sw = 0x00; else (mw_sw = 0x01);
  tune();
}

void rsq() {
  RSQMetrics rsq;
  radio.getRSQ(&rsq);
  sm = (rsq.RSSI);
  sn = (rsq.SNR) * 0.5 + sn * 0.5;
}

void pilot() {
  RSQMetrics rsq;
  radio.getRSQ(&rsq);
  tft.setTextSize(1);

  if (rsq.stereo == 1 && hasRun1 == false) {
    tft.setTextColor(TFT_WHITE, ca); tft.drawString(" Stereo ", 30, 57, 2); hasRun1 = true;
  }
  if (rsq.stereo == 0 && hasRun1 == true) {
    tft.setTextColor(TFT_DARKGREY, ca); tft.drawString(" Stereo ", 30, 57, 2); hasRun1 = false;
  }
}

void rds() {
  radio.getRDS();

  if (rds_t == false) {
    if (radio.rds.RDSSignal) {
      texsw++; if (texsw > 60) texsw = 1;
      tft.setTextSize(1); tft.setTextColor(cb, ca);
      if (hasRun == false) {
        tft.drawString("                         ", 0, 74, 2);
        hasRun = true;
      }
      tft.drawString("RDS ", 3, 74, 2);
      if (texsw > 0 && texsw < 41) tft.drawString(radio.rds.programService, 60, 74, 2);
      if (texsw == 41) tft.drawString("                        ", 33, 74, 2);
      if (texsw > 40 && texsw < 61) tft.drawString(radio.rds.radioText, 33, 74, 2);
      if (texsw == 1) tft.drawString("                        ", 33, 74, 2);
      hasRun3 = false;
    } else {
      radio.clearStationInfo();
      tft.setTextColor(cb, ca); tft.fillRect (0, 75, 3, 15, ca);
      if (hasRun3 == false) {
        tft.drawString("RDS   No Information      ", 3, 74, 2);
        hasRun3 = true;
      }
      hasRun = false;
    }
  }

  if (rds_t == true) {
    if (radio.rds.RDSSignal) {
      texsw += 8; if (texsw > 296) texsw = 0;
      tft.setTextSize(1); tft.setTextColor(cb, ca);
      if (hasRun == false) {
        tft.drawString("                         ", 0, 74, 2);
        hasRun = true;
      }
      tft.drawString(radio.rds.radioText, 20 - texsw, 74, 2); tft.fillRect (156, 75, 4, 15, ca);
      if (texsw == 296) tft.drawString("                             ", 0, 74, 2);
      hasRun3 = false;
    } else {
      radio.clearStationInfo(); texsw = 0;
      tft.setTextColor(cb, ca); tft.fillRect (0, 75, 3, 15, ca);
      if (hasRun3 == false) {
        tft.drawString("RDS   No Information        ", 3, 74, 2);
        hasRun3 = true;
      }
      hasRun = false;
    }
  }
}

void am_init() {
  encoder = 1;
  radio.begin(0, SI7435_ADDRESS);
  power_down();
  power_up_norm();
  delay(400);
  am_fm = 0x40;
  ssb_m = 0x00;
  eeprom_read();
  freq = freq_eeprom_am;
  if (count == 2) stp = 4; else stp = 2; setstep();
  tune();
  am_command();
  filter = 0x03; layout(); frequency(); if (count >= 1 && count <= 4) period = 4000; else period = 500;
  tft.setTextColor(cg, ca); tft.drawString("kHz ", 132, 57, 2); tft.setTextColor(cb, ca); tft.drawString("AM ", 3, 57, 2);
  tft.drawString("  AM/FM RDS Receiver  ", 0, 74, 2); tft.drawString("2k ", 135, 92, 2);
  tft.drawString("        ", 30, 57, 2);
}

void fm_init() {
  encoder = 2;
  radio.begin(0, SI7435_ADDRESS);
  power_down();
  power_up_FM();
  delay(400);
  am_fm = 0x20;
  ssb_m = 0x00;
  eeprom_read();
  freq = freq_eeprom_fm;
  tune(); pilot();
  radio.setMode(FM);
  fil = 0; filterFM();
  stp = 0; setstepFM(); fm_command();
  hasRun2 = false; count--; layout(); frequency(); period = 2000;
  tft.setTextColor(cg, ca); tft.drawString("MHz", 132, 57, 2); tft.setTextColor(cb, ca); tft.drawString("FM ", 3, 57, 2);
  tft.setTextColor(TFT_DARKGREY, ca); tft.drawString(" Stereo ", 30, 57, 2);
}

void sw_theme() {
  sts_theme = !sts_theme;
  if (sts_theme == false) blue_theme(); else black_theme();
  tft.fillScreen(ca); tft.setTextColor(cb, ca);
  hasRun1 = !hasRun1;
  fm_init();
  if (am_fm != 0x20) {
    fil = 4; filterAM();
  }
  if (am_fm == 0x20) {
    fil = 0; filterFM();
  }
}

void blue_theme() {
  ca = TFT_BLUE;       //Screen background
  cb = TFT_WHITE;      //Texts
  cc = TFT_LIGHTGREY;  //Lines
  cd = TFT_GREEN;      //S-Meter bargraph
  ce = TFT_MAGENTA;    //S/N bargraph
  cf = TFT_BLUE;       //Bargraph background
  cg = TFT_WHITE;      //Frequency and kHz MHz
  ch = TFT_CYAN;       //Reserved
  tft.fillScreen(ca);
}

void black_theme() {
  ca = TFT_BLACK;      //Screen background
  cb = TFT_WHITE;      //Texts
  cc = TFT_LIGHTGREY;  //Lines
  cd = TFT_GREEN;      //S-Meter bargraph
  ce = TFT_MAGENTA;    //S/N bargraph
  cf = TFT_BLACK;      //Bargraph background
  cg = TFT_CYAN;       //Frequency and kHz MHz
  ch = TFT_RED;        //Reserved
  tft.fillScreen(ca);
}

void am_command() {
  radio.setProperty(PROP_AM_SOFT_MUTE_MAX_ATTENUATION, 1); // 0 (OFF) - 63
  radio.setProperty(PROP_AM_AUTOMATIC_VOLUME_CONTROL_MAX_GAIN, 0x32C8); // 0x1000 - 0x7800
  radio.setProperty(PROP_AM_AGC_ATTACK_RATE, 4); // 4–248
  radio.setProperty(PROP_AM_AGC_RELEASE_RATE, 4); // 4–248
}

void fm_command() {
  radio.setProperty(PROP_FM_DEEMPHASIS, 0x0001); // 02 = 75 μs;  01 = 50 μs
  radio.setProperty(PROP_FM_CHANNEL_FILTER, filter); // 0 = automat; 1 = 110kHz; 4 = 40kHz
  radio.setProperty(PROP_FM_SOFT_MUTE_MAX_ATTENUATION, 0); // 0 = disable; 31 = max
  radio.setProperty(PROP_FM_BLEND_STEREO_THRESHOLD, 0); // 0 = stereo; 127 = mono
  radio.setProperty(PROP_FM_BLEND_MONO_THRESHOLD, 0); // 0 = stereo; 127 = mono
}

void power_down() {
  Wire.beginTransmission(SI7435_ADDRESS);
  Wire.write(0x11);
  Wire.endTransmission();
  delay(1);
}

void power_up_norm() {
  Wire.beginTransmission(SI7435_ADDRESS);
  Wire.write(0x01);
  Wire.write(0x11);
  Wire.write(0x05);
  Wire.endTransmission();
  delay(1);
}

void power_up_FM() {
  Wire.beginTransmission(SI7435_ADDRESS);
  Wire.write(0x01);
  Wire.write(0x10);
  Wire.write(0x05);
  Wire.endTransmission();
  delay(1);
}

void tune() {
  Wire.beginTransmission(SI7435_ADDRESS);
  Wire.write(am_fm);
  Wire.write(ssb_m);
  Wire.write(fr_h);
  Wire.write(fr_l);
  Wire.write(0x00);
  Wire.write(mw_sw);
  Wire.endTransmission();
  delay(1);
}

void property_filter_AM() {
  Wire.beginTransmission(SI7435_ADDRESS);
  Wire.write(0x12);
  Wire.write(0x00);
  Wire.write(0x31);
  Wire.write(0x02);
  Wire.write(0x00);
  Wire.write(filter);
  Wire.endTransmission();
  delay(1);
}

void eeprom_write() {
  if (am_fm == 0x20) {
    fr_eeprom_h = (freq) >> 8;
    fr_eeprom_l = (freq) & 0x00FF;
    EEPROM.write(0, fr_eeprom_l);
    EEPROM.write(1, fr_eeprom_h);
    EEPROM.write(2, 1);
  }
  if (am_fm != 0x20) {
    fr_eeprom_h = (freq) >> 8;
    fr_eeprom_l = (freq) & 0x00FF;
    EEPROM.write(3, fr_eeprom_l);
    EEPROM.write(4, fr_eeprom_h);
    EEPROM.write(2, 0);
    EEPROM.write(5, count);
  }
  EEPROM.write(6, sts_theme);
  tft.setTextColor(TFT_WHITE, TFT_MAGENTA); tft.drawString("SAVE", 126, 111, 2);
  delay(1500);
  tft.setTextColor(cb, ca); tft.drawString("     ", 126, 111, 2);
  delay(300);
}

void eeprom_read() {
  if (am_fm == 0x20) {
    fr_eeprom_l = EEPROM.read(0);
    fr_eeprom_h = EEPROM.read(1);
    freq_eeprom_fm = (fr_eeprom_h << 8U) | fr_eeprom_l;
  }
  if (am_fm != 0x20) {
    fr_eeprom_l = EEPROM.read(3);
    fr_eeprom_h = EEPROM.read(4);
    freq_eeprom_am = (fr_eeprom_h << 8U) | fr_eeprom_l;
    count = EEPROM.read(5);
  }
  sts_am_fm = EEPROM.read(2);
}

Credits

CesarSound

CesarSound

6 projects • 182 followers

Comments