Great! You helped my dream come true. I had once a PIC16F628 and a TSA5512 based tuner from (Mirror of Freddo's Electronics Page). It got damaged accidentally, it's only the HEX data. Now Arduino open source makes it much better to customize. Lots of thanks and best wishes for all Arduino Contributors.
Here I added some luxuries leared from here and there like the RSSI bar in the display. You can get a TA2111 (CD2111) radio or any cheap one with a Stereo led and RSSI led indication and inject the signal via resistor to A0. etc, (For experienced tinkerers and hobbyists not to damage the Arduino)
//updated 25.02.24 Tested with a TA2003 based FM radio Change coils at pins 13 and 15
//Get a good antenna
//"You can dispense with SAW Filters
//It's set for an initial frequency of 107.5MHz.
//To change the intermediate frequency is in the two lines lcd.print(RF*3.2/64-37),
//you can change that at RF =2890, according to the formula in the comment.
//just replace 37 with whatever your IF is."
#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define clk 2 // rotary encoder clk pin
#define dta 3 //rotary encoder dt pin
int CurrentClock =0;
int PreviousClock =0;
uint16_t RF =2890;//3604
uint8_t OSCI =1;
uint8_t lockFlag =0;
void SNTVtuner(uint16_t RF,uint8_t OSCI)
{
uint16_t fpd =0;
Wire.beginTransmission(0x61);
switch (OSCI)
{
case 1 : //Setting for OSCIillator #1 VHF-LO
fpd = (RF + 107) ;
Wire.write(fpd >> 8); //DB1
Wire.write(fpd & 0xFF ); //DB2
Wire.write(0xC0); //CB
Wire.write(0x01); //BB
break;
case 2://Setting for OSCIillator #2 VHF-HI
fpd = (RF + 107) ;
Wire.write(fpd >> 8); //DB1
Wire.write(fpd & 0xFF); //DB2
Wire.write(0xC0); //CB
Wire.write(0x02); //BB
break;
case 3://Setting for OSCIillator #3 UHF
fpd = (RF + 107) ;
Wire.write(fpd >> 8); //DB1
Wire.write(fpd & 0x0FF); //DB2
Wire.write(0xC0); //CB
Wire.write(0x08); //BB
break;
}
Wire.endTransmission();
//delay(10);
Wire.requestFrom(0x61,1); //in-lock flag (FL = 1 when the loop is phase-locked)
while (Wire.available())
{
lockFlag = Wire.read();
}
}
int RSSI_IN = analogRead(A0);
byte ZeroChar[8] =
{
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B11111
};
byte FirstChar[8] =
{
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B11111,
B11111
};
byte SecondChar[8] =
{
B00000,
B00000,
B00000,
B00000,
B00000,
B11111,
B11111,
B11111
};
byte ThirdChar[8] =
{
B00000,
B00000,
B00000,
B00000,
B11111,
B11111,
B11111,
B11111
};
byte FourthChar[8] =
{
B00000,
B00000,
B00000,
B11111,
B11111,
B11111,
B11111,
B11111
};
byte FifthChar[8] =
{
B00000,
B00000,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111
};
byte SixthChar[8] =
{
B00000,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111
};
byte SeventhChar[8] =
{
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111
};
void setup()
{
Wire.begin();
lcd.begin(16,2);
lcd.backlight();
pinMode(clk,INPUT_PULLUP);
pinMode(dta,INPUT_PULLUP);
PreviousClock = digitalRead(clk);
SNTVtuner(RF,OSCI);
lcd.setCursor(0,0);
lcd.print("RF: MHz");
lcd.setCursor(3,0);
lcd.print(RF*3.2/64-37);//DB1+DB2x32/640-IF
lcd.createChar(0, ZeroChar);
lcd.createChar(1, FirstChar);
lcd.createChar(2, SecondChar);
lcd.createChar(3, ThirdChar);
lcd.createChar(4, FourthChar);
lcd.createChar(5, FifthChar);
lcd.createChar(6, SixthChar);
lcd.createChar(7, SeventhChar);
delay(200);
Volume();
}
void loop()
{
// put your main code here, to run repeatedly:
CurrentClock = digitalRead(clk);
if(CurrentClock != PreviousClock){
if(CurrentClock != digitalRead(dta)){
RF--;
SNTVtuner(RF,OSCI);
}
else
{
RF++;
SNTVtuner(RF,OSCI);
}
lcd.setCursor(0,0);
lcd.print("RF:");
lcd.setCursor(3,0);
lcd.print(RF*3.2/64-37);//DB1+DB2x32/640-IF
}
PreviousClock = CurrentClock;
}
void Volume()
{
int RSS_IN = analogRead(0);
RSS_IN = map(RSS_IN, 0, 1023, 0, 8);
lcd.setCursor(0,1);
if(RSS_IN==0)
{
lcd.setCursor(0,1);
lcd.print("RSS:");
lcd.print("-");
lcd.print(" ");
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.print(" ");
lcd.print("+");
}
if(RSS_IN==1){
lcd.setCursor(0,1);
lcd.print("RSS:");
lcd.print("-");
lcd.print(" ");
lcd.write((byte)0);
lcd.write((byte)1);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.print(" ");
lcd.print("+");
}
if(RSS_IN==2){
lcd.setCursor(0,3);
lcd.print("RSS:");
lcd.print("-");
lcd.print(" ");
lcd.write((byte)0);
lcd.write((byte)1);
lcd.write((byte)2);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.print(" ");
lcd.print("+");
}
if(RSS_IN==3){
lcd.setCursor(0,3);
lcd.print("RSS:");
lcd.print("-");
lcd.print(" ");
lcd.write((byte)0);
lcd.write((byte)1);
lcd.write((byte)2);
lcd.write((byte)3);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.print(" ");
lcd.print("+");
}
if(RSS_IN==4){
lcd.setCursor(0,3);
lcd.print("RSS:");
lcd.print("-");
lcd.print(" ");
lcd.write((byte)0);
lcd.write((byte)1);
lcd.write((byte)2);
lcd.write((byte)3);
lcd.write((byte)4);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.print(" ");
lcd.print("+");
}
if(RSS_IN==5){
lcd.setCursor(0,3);
lcd.print("RSS:");
lcd.print("-");
lcd.print(" ");
lcd.write((byte)0);
lcd.write((byte)1);
lcd.write((byte)2);
lcd.write((byte)3);
lcd.write((byte)4);
lcd.write((byte)5);
lcd.write((byte)0);
lcd.write((byte)0);
lcd.print(" ");
lcd.print("+");
}
if(RSS_IN==6){
lcd.setCursor(0,3);
lcd.print("RSS:");
lcd.print("-");
lcd.print(" ");
lcd.write((byte)0);
lcd.write((byte)1);
lcd.write((byte)2);
lcd.write((byte)3);
lcd.write((byte)4);
lcd.write((byte)5);
lcd.write((byte)6);
lcd.write((byte)0);
lcd.print(" ");
lcd.print("+");
}
if(RSS_IN==7){
lcd.setCursor(0,3);
lcd.print("RSS:");
lcd.print("-");
lcd.print(" ");
lcd.write((byte)0);
lcd.write((byte)1);
lcd.write((byte)2);
lcd.write((byte)3);
lcd.write((byte)4);
lcd.write((byte)5);
lcd.write((byte)6);
lcd.write((byte)7);
lcd.print(" ");
lcd.print("+");
}
}