How to program the SN761672A

Hello every one,

Using Arduino Uno, I am trying to program a Samsung I2C tuner based on the SN761672A pll synthesizer ic and I need considerable help. I appreciate every bit of view, suggestions, and efforts as I am on crossroads confusion and hope your contributions are rewarded in success and relief. The code shows how far I’ve reached.

I summarize my objectives in setting the tuner to function (plug and play) like analog. The hardware is almost comprehended, but the software is complicated.

  • Be able to write the read/write bytes to control the IC.
  • Correctly setting the bits and bytes of registers.
  • Be able to read the frequency and write it to the tuner.

I understood there are two Read Bytes: the ADB address byte and the SB status byte. I tended to adopt the default suggested in Table 3, page 9.

The Write Bytes are five:

ADV(0xC0: 11000000), DB1(0), DB2(0), CB(0xCA:11001010), and BB different.

Based on my understanding of the explanation and description of symbols in the datasheet, I set these bytes as in the code.

The I2C control part in the SN761672A is in pages 9, 10, 11.

I need some help to configure the divider byte DB1 and DB2. I understood from page 9 table 3 the default value is 0??

Programmable counter set bits N=N14…..N0 is my blackout I need help please!

If I could set the tuner to the VHF_L, read the frequency on power up, write and display the value (set /scan the frequency), then I went far well.

 //Samsung TECC0949PG35A(AA40-00076A) TV\CRT tuner with SN761672A tuner IC . 21.01.2024

  #include <Wire.h>
  //I2C Read mode
  #define ADB 0x60//Address Byte, read 1
  #define SB 0xB8// Status Bit
  //I2C Write mode
  #define ADV 0xC0 //11000000, Address Byte, write 0
  #define DB1 0x0//00000000, 0x0
  #define DB2 0x0//00000000, 0x0
  #define CB 0xCA//11001010

  #define BBL 0x1//00000001, Band Switch, Low
  #define BBH 0x2// 00000100, Band Switch, high
  #define BBU 0x8//00001000, Band Switch, ultra 

  long frequency;//default frequency after power up
  long freq_set;// set or scan +/- increment, decrement
  long IF_freq = 31900000;// IF frequency 31.9MHz
  //VHF_L 48-180MHz BandI
  //VHF_H 160-470MHz BandII
  //UHF 430-860MHz BandIII
  #define L_bandbegin 48;//48 MHz
  #define H_bandbegin 160;//
  #define U_bandbegin 430;//

  #define L_bandend 180;//
  #define H_bandend 470;//
  #define U_bandend 860;//

  int step_rate1 = 1000000;//1MHz steps
  int step_rate2 = 500;//500kHz
  int step_rate3 = 100;//100kHz

  void setup()

  {
  Serial.begin(9600);
  Wire.beginTransmission(0x60);// Address Byte ADB
  Wire.beginTransmission(0xB8);//SB Status bit
  
  Serial.println(0x60);
  delay(200);
  Serial.println(0xB8);
  delay(200);
  Serial.println(" 3_Band Tuner ");
  delay(200); 
  write_data();
  }

  void loop()
  {
    
  }

  void scan_freq()
  {
   //freq_set = up_frequency + 1// increase/ decrease frequency
   // while button + pressed 
   //if freq_set >= H_bandend;
  {
    //freq_set = L_bandbegin;
  }

  }


  void write_data()
    {
    Wire.beginTransmission(0x60);
    Wire.write(ADV);
    Serial.println(ADV);
    Wire.endTransmission();
    }
  



Have you read the data sheet and application notes?

1 Like

Thanks for dropping by, well, reading is not enough, I'm trying to achieve something on my own, you mean having fully understood or been able to decipher some acronyms, figures, equations etc.? unfortunately, no. I haven't found application notes to the IC itself only general to I2C bus, and was about to write to TI but not expecting luck, gave it up!
Anyway, some hours ago, I found a much better source and since you're kindly volunteering here, lots of thanks again, You can perhaps help me in a certain part.

The guy did a great job availing 3 examples one is programming the SN761662, similar to mine. I tried to compare things, I don't understand the setting (calculation) of divider bits DB1 DB2.
I also think the guy swapped DB1 and DB2 bytes as he says: "The third byte(DB2) is the programmable divider, in this byte the first bit is not used 0"
But in the datasheets DB1 starts with 0, whereas DB2 starts with N7.
Trying to understand his procedure of writing the binary equivalent byte for the bits in the (SN761662, pp11, table 1) (don't guess I'm a math dummy!), he says "the second bit is divided by the power of 2^1, the third bit is divided by the power of 2^2 the fourth.. etc."

I am stuck here! I don't know where the bit N14, N13, N12 number that is divided by 2^2, ...etc!
In the datasheet table 2 description: N=N14x2^14. Let's calculate: 14*(2^14)=229376! That wouldn't lead to an 8 bit zeros and ones.

2^N is equivalent shifting a 1 to the left N times, starting from bit 0.

So bit N14 x 2^14 simply sets bit 14 of (say) a 16 bit register. If that is the only bit set in the register, the value is 16384.

2 Likes

Thanks a lot, things seem more complicated than I thought, but I won't give up.
Meanwhile, I'm reading this application: https://www.analog.com/media/en/technical-documentation/app-notes/understanding-the-operation-of--the-frequency-synthesizer-in-maxims-rf-transceivers.pdf

Hoping someone or more might drop by and help me get it to receive at least one station. in the 88-108 band. I updated this post with new editor working code but not in practice.
This code is an adaptation of King Beetle's basic code:

Interestingly there are many PLL chips in different TV tuners but their access data are almost identical: SN761672A, TDA6405, TSA5511, TSA5523, FM1216 tuner and a Temic 3X 7246 tuner, etc. So setting, the bits and bytes and the dividers etc. is similar.
Here's the code to tune to one station simply by choosing a desired frequency, multiplying it by 20 and splitting the binary resulting 16 bits into two high and low bytes:

 //18.02.24
 #include <Wire.h>
 #include <LiquidCrystal_I2C.h>
 LiquidCrystal_I2C lcd(0x27, 16, 2);
 // tuner registers
 byte DB1 = 0x06; //low bite
 byte DB2 =0xE0; //high bite
 byte CB = 0xC8;// 
 byte BB = 0x01;//01 VHF_L
 // byte BB = 0x02;//01 VHF_H
 // byte BB = 0x08;// UHF



 void setup()
  {
   Wire.begin();
   lcd.backlight();
   lcd.begin(16, 2);
   Tuner_init();
  }

  void loop()
  {
  Wire.beginTransmission(0X61);
  Wire.requestFrom(0x61,1);
  }

  void Tuner_init()
   {
    Wire.beginTransmission(0X61);
    Wire.write(DB1);//0x14
    Wire.write(DB2);//0xE0
    Wire.write(CB);//0xC8
    Wire.write(BB);//0x01
    Wire.endTransmission(0X61);

   String dec_freq = String(word(((DB1 << 8) + DB2) / 2 -0)  );// original 
   code -107
   char decimal = dec_freq.charAt(dec_freq.length() - 1);
   dec_freq = "Freq: " + dec_freq + decimal;
   dec_freq.setCharAt(dec_freq.length() - 2,'.');
   lcd.setCursor(0, 0);
   lcd.print(dec_freq);
   } 
 

I used different tuners and even new ones. The connection +5V, +30V, SCL, SDA, AGC are correct. I tweaked the IF filters and the AGC to 10k potentiometer(+5V-) I even tried 12V and potentiometer etc. but no success. I use and Arduino Uno, I wanted to try a pro mini that I have. The I2C data bus wire length between Arduino and the tuner is about 30cm. The I2C bus is pulled up 10k resistor each wire. The I2C scanner detects address 27 (LCD) and 61 which should be the tuner PLL IC.

I am fairly sure what is wrong post an annotated schematic so I can validate my assumption. I do not like to make bad guesses. Be sure it shows all connections, power, ground, and power sources.

1 Like

Thanks a lot, and here is the schematic. I don't hear any reception. The tuner seems to be idle and not responding. I can tell by adding or removing the antenna.

Nice start but parts are missing. You will need to replace the MC34063 putting 30V on it will destroy it. It is designed to monitor the 5V and do a reset when the voltage goes below 4.6 or thereabouts. I expect the I2C scanner will not work correctly, the pull ups should be about 4.7K for each the SCL and SDA connections.

The FM receiver is not connected to anything.

1 Like

The MC34063 is used as a boost converter and is already boosted with an NPN transistor in case of loads although Vtuning doesn't load it, it's powered from the arduino VCC, it supplies +30V (5V in 30 out). The TA2003 receiver gets signal from tuner IF through the SAW filter and a coax cable (sorry not illustrated in the schematic).
The 10k pull up resistors are in fact 4k7 to my surprise and make no difference when added or omitted. I tried the SN761672A tuner and the TDA6405A, the setting is almost similar. I even tried more than tuner with the SN761672A and new ones (I got them very cheap). I have the feeling something in the code, say, the timing or intervals for the bus and the signal to set and rest????!!!!

You are correct, it was my goof I read it as a MC34064 used on another project a few moments before I looked at yours. You have me lost in the radio portion, sorry I cannot be of more help.

Good Luck and let us know how you make out!

1 Like

No problem thanks for your kind interest in helping me. I've powered the tuner and the boost converter from a stabilized +5V seperate supply, but no difference. It calls for a logic analyzer but I'll try it with arduino pro mini who knows and an LCD without I2C!

I think I know what the problem is - you're forgetting the intermediate frequency. If you want to tune to, say, 100Mhz, you have to set the tuner frequency to 131.9 Mhz, or better yet you should use 33 Mhz as the IF since that is the centre frequency of that specific filter, although according to the datasheet pin 2 must be connected to pin 1 for it to work at that frequency.

1 Like

Thanks a lot for helping, It would be a success if my problem were the setting of the IF. Although tuning to get the difference is not critical, I've already tried adding and subtracting, but no success. I tried the setting with an analog tuner and different resonance, glimmer of hope and promise are dazzling no mater how far is the tuning, but these digital tuners are either yes or no! :neutral_face: I think it's the I2C bus not carrying out commands or distorted. I managed to trace the I2C bus to the tuner it's shiny and new or nice and clean. There's no IF signal coming out of the tuner, or may be it's too weak to come out of the SAW filter. I don't have datasheet for it and the TV monitor schematics I get suggested have different tuners. So, hopefully getting IF signal will solve the problem.

Are you sure that's not the problem? Because according to the second code you posted you seem to want to tune to 88Mhz but the code you're sending (0x06 0xE0) is setting the tuner to 88Mhz which means the frequency you'll be receiving is 88-33=55Mhz. If you want to receive 88Mhz you have to tune it to 88+33=121Mhz wich woud be 0x09 0x74.

What you should do is set the tuner to around midway in the FM band (~100Mhz); by tuning the ta2003 you should be able to receive at least two or three stations. I used your code with the same tuner and it worked (of course the frequency displayed in the lcd is incorrect because it doesn't take into account the IF frequency of the tuner) I don't even have the pull up resistors, arduino seems to work fine without them. If that doesn't work, the only thing i can think of is making sure the ta2003 is working at the right frequency (that would be either about 44 or 22Mhz). It would be helpfull if you could post some pictures.

I just noticed that in your tuner 5V goes to BM while in the two that I have it goes to BP while BM is unconnected. That can't be the case with yours since you mentioned that the i2c scanner detects its adress. maybe you have to put 5V on both, i dont know. you'll have to open your tuner to see if BP is unconnected or not.

1 Like

Also, your schematic shows a loudspeaker directly attached to the ta2003 - is that just a simplified drawing or not?, because that chip can't directly drive a loudspeaker.

1 Like

I have tried different frequencies adding and subtracting. Looking for the strong stations, copying their frequency and inserting it to the code but the problem is not that, the VCOs in the tuner don't work. I also connected BP BM together +5V, there's a jumper in a schematic but those things make no difference. I once replaced to trim-poti with 100k instead of 10k I'll reverse that may be after all the modifications some wonder might happen, From my experience in tweaking if there's a signal of a station there's a chance of grasping it through adjusting fiddling here and there. But I have the feeling the Chip inside is not responding.
There's some simplification in the diagram. The TA2003 is a whole modified Chinese radio. I'll post images though they might not give clues as they're "dead bug" constructions.



That's the exact same tuner that i have; the other one is only slightly different but it works the same. I highly doubt the tuner chip is not working, unless you accidentaly put 12 or 30V in some of the pins; either way, since you have several tuners it's just a question of trying the others to see if that's the problem. the potenciometer you use for AGC is irrelevant - you can connect AGC directly to 4V which is the maximum AGC voltage for that tuner.
All I can think of is the basics: checking for short circuits, the stability of the 30V (I just use a separate 24V supply), try bypassing the IF filter and connect the tuner output directly to the radio. How do you know that the ta2003 is tuned to the right frequency?
Also, where did you get the first code you posted from? It has very useful features like the different frequency steps but I can't seem to understand how the frequency is changed

1 Like

It's frustrating! I connected the last tuner I have and I tried all the suggestions you mentioned above but I only get noise. Connecting and disconnecting the antenna doesn't make that difference. May be I should amplify the IF. I need a code that keeps scanning from 88 to 108 MHz to capture something.
I have this code with the benefit of scanning manually with a rotary encoder but I am not sure where I am scanning may be in te KHz spectrum, I get no reception no matter how I keep turning the resonance dial and the rotary encoder!
This guy here has knowledge: TSA5523 Tuner Modules from PC TV Cards · One Transistor
and from here you can be inspired by the code (main)
MekWeb - Mek's personal web page ● Download - FM receiver with TV tuner with digital tuning
and from here:
FM1216_2

//here is the code for SN761672A TV tuner, I'm assuming you using Arduino nano board.
#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 =3604;//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();
}
}
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:");
lcd.setCursor(3,0);
lcd.print(RF/40.96);
lcd.setCursor(0,1);
lcd.print("OSCI:");
lcd.setCursor(5,1);
lcd.print(OSCI);
lcd.setCursor(10,1);
lcd.print("LF:");
lcd.setCursor(13,1);
lcd.print(lockFlag);
}
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/40.96);
lcd.setCursor(0,1);
lcd.print("OSCI:");
lcd.setCursor(5,1);
lcd.print(OSCI);
lcd.setCursor(8,1);
lcd.print("LF");
lcd.setCursor(11,1);
lcd.print(lockFlag);
}
PreviousClock = CurrentClock;
}