Use tuners from PCI TV cards for video and FM radio reception with Arduino or other I2C interface
Since I had some old TV tuner cards that were no longer compatible with my PC or had poor performance, I decided to take the tuners out of them. To my surprise, different tuners from different manufacturers looked pretty much the same on the inside. All of them used the same integrated circuits. The tuners I found are actually complete receivers, with included demodulator. This means you can get analog audio and video straight from the module pins. There are also modules with FM support, with stereo decoder.
In the photo below, you can see two tuners. The top one has FM radio support. You can see that it's similar to the other, but the rightmost compartment has some additional filters for FM IF.
![]() |
Tuners from TV cards |
![]() |
Functional modules of the TV tuner |
![]() |
Pinout of TV tuner module TCL2002MB-33F |
Basic connection requires SCL and SDA to be connected to an I2C interface of a microcontroller, CVBS and AF to be connected to a capture card inputs via RCA jacks. All that's left is to power up the module.
According to datasheet, I2C address of TSA5523 is 0xC2 is AS pin is left floating. The IC has 4 write registers and 1 read register. Here is an overview.
![]() |
Overview of TSA5523 registers (refer to datasheet) |
Read register contains some important bits. FL is 1 when tuner is locked to frequency. I1 reads mono/stereo status (1 means stereo). A2, A1 and A0 represent ADC readout.
Let's write some Arduino compatible code. First, for tuning TV channels. Control byte is set to 0xCA. This means CP=1 (higher chargepump current, recommended in TV mode) and RSA=0; RSB=1 (resulting in 31.25kHz frequency step). Ports bytes is set according to the band in which the frequency fits. To set frequency of local oscillator, IF is added to receiving frequency and the sum is divided by tuning step (31.25 in this configuration). The number 1245 in freq_khz formula comes from IF frequency 38900 divided by 31.25.
#define TSA5523_ADDR (0xC2 >> 1) // tuner registers byte db1, db2, cb, pb; void tsa5523_setTVFrequency(uint32_t freq_khz) { // band bits if (freq_khz < 168000) pb = 0xA0; // band A, VHF-Lo else if (freq_khz < 448000) pb = 0x90; // band B, VHF-Hi else pb = 0x30; // band C, UHF // control cb = 0xCA; freq_khz = freq_khz / 31.25 + 1245; db1 = (freq_khz >> 8) & 0x7F; db2 = freq_khz & 0xFF; Wire.beginTransmission(TSA5523_ADDR); Wire.write(db1); Wire.write(db2); Wire.write(cb); Wire.write(pb); Wire.endTransmission(); }In FM mode, we're always in band A. Chargepump can use lower current to improve SNR (set CP=0) and tuning step needs to be 50kHz to cover all channels. RSA and RSB are both 0. Some changes are required for ports byte. Band A (which includes FM) requires P7 and P5 to be set. P2 also needs to be 1. IF frequency is 10.7MHz now. The sum is divided by 50 (tuning step).
#define TSA5523_ADDR (0xC2 >> 1) // tuner registers byte db1, db2, cb, pb; void tsa5523_setFMFrequency(uint32_t freq_khz) { pb = 0xa4; // band A only cb = 0x88; freq_khz += 10700; freq_khz /= 50; db1 = (freq_khz >> 8) & 0x7F; db2 = freq_khz & 0xFF; Wire.beginTransmission(TSA5523_ADDR); Wire.write(db1); Wire.write(db2); Wire.write(cb); Wire.write(pb); Wire.endTransmission(); }To get tuner status, read one byte from the read address. If this status byte (SB) has bit 6 set, tuner is locked (SB & 0x40). Then you can assess bit 4 for stereo (SB & 0x10) and compute ADC readout (SB & 0x07). Note that ADC reads what you configured it with the ports byte.
Due to the capability of tuning to frequencies between 45 to 860 MHz, programming a button based user interface for Arduino is rather difficult. A future post will show a programming example of Windows application that uses CH341A to control this tuner.
Thank you very much, Cornelius. This was very usefull.
ReplyDeletemuch appreciated,just what iwas looking for!
ReplyDeleteHi;
ReplyDeleteI have tried your project and it is working, thank you. So how can we listen to narrow bands?
It's difficult, but not impossible to listen to narrow band broadcasts or any other signals. You have to build a detector (demodulator) and connect its input at the output of the SAW filter. Obviously, the detector must be able to demodulate the frequency that passes through the filter.
Delete