tiistai 2. huhtikuuta 2019

Modifying an FM radio

TL;DR I tried to modify an FM radio that only goes up to 108 MHz to receive weather satellites at 138 MHz. That failed, but I learned thing or two on the way.

Introduction

I read about receiving weather satellites with PC sound card and a modified radio many years ago, and since that time I've always wanted to do that. Today it is rather simple to do with very inexpensive software defined radios (SDRs), but using pre-built components is only half the fun.

The weather satellites I talk about transmit at 137 to 138 MHz using FM modulation. The easy way to receive that is to use a radio scanner and connect it to PC using the sound card line input and the software in previous link decodes to images. A powerful antenna may be needed, but that is just details ;)

Radio scanners tend to be quite expensive compared to normal FM radio receivers. Where I live, the FM radio band goes from about 88 MHz to 108 MHz, so quite close to what I needed. I decided to try and modify an existing radio to reach the required band.


Selecting a radio

I looked at the most inexpensive receivers and especially one that looked to have an analog tuning mechanism. I thought that one with analog tuning would have some LC tuning circuit, which I could modify to an upper frequency to extend the band upwards. I assumed that ones with digital tuning (e.g. buttons to tune up and down) might be hard to modify.

I ended up buying a Prego FM/AM radio which had analog potentiometer style tuning and volume. Below is a picture of what the radio looks like.


 

Opening it up

I opened the radio and looked at the PCB. There was no obvious tuning circuit (coils and capacitors) or even crystal oscillators visible on the board.

On the top side there was few IC circuits and on the bottom side just one. The bottom side one was a power amplifier driving the speaker, so what I wanted was one on the top side.

On the top side there was some regulators and interestingly a EEPROM of type L24C02B. This turned out to be important but I didn't know it yet.

The radio chip was under some plastic, protecting it from the mains transformer. The type of the radio receiver is KTmicro KT0922. Luckily I found datasheet for it.


Analysis of the FM receiver

The KT0922 chip is a monolithic AM/FM receiver that goes from 30 MHz to 110 MHz in the FM band. So not directly tunable as high as I would have wanted. There is an internal 32.768 kHz oscillator, which can be used instead of an external one, and that was used here. So no easy way to change the crystal either.

However the chip can be configured during startup from an external EEPROM! There can be up to 3 FM bands, which can be selected with resistors (switch changing a resistor divider) and the bands can be configured, starting and ending frequency. Also the oscillator frequency can be written in the EEPROM, in case external one is used.

So I figured there could be two ways to stretch the band. One is to simply write a higher frequencies to one of the band registers and see if the chip will tune there. The second way is to change the value in the oscillator register so that the chip thinks the oscillator is of a lower frequency, and thus cheat the chip to tune higher up than normally possible.

But first I needed to dump the EEPROM and be able to write it.

Dumping the EEPROM

The KT0922 and the EEPROM communicates via I2C.  What I did first was to sniff the communication between those two to see how the memory is read. I used a Raspberry PI Zero W for this since as a Linux computer it is quite easy to use and program.

The built-in I2C seems to only support I2C master mode, but I wanted one that can sniff the communication instead of sending messages. I found a rather simple I2C sniffer written in python and used that one.

First I soldered some jumper wires to the SCL (clock) and SDA (data) line as well as to ground.Connecting those to the Raspberry PI and running the sniffer while turning on the radio provided me with few lines of data:
[FF-[A0+00+[A1+00+01+00+01+04+1B+24+B0+....

This turned out to be exactly what I wanted. The first FF is some error in signal lines during power up of the radio. Then the A0 is the EEPROM I2C address for write and 00 is the memory address. This means that the host requests write or read starting from zero. + means that the slave or master has received the data.

A1 is the read address of the EEPROM. After that, all bytes are contents of the memory, dumped one after one until the whole 256 bytes of memory is read. That's it. Very simple protocol and I immediately got the whole memory dumped, and the contents matched the datasheet.

I uploaded the source files for both Raspberry Pi and Tiva to Github.

Modifying the EEPROM

What I did next was to desolder one side of the EEPROM to disconnect it from the radio and I solderd wires to I2C pins as well as power and ground. I again connected these to Raspberry PI, but this time to the I2C master pins.

I wrote a simple script to read the memory, just to verify the contents I got earlier. The dump was identical. Beginning of the dump is below. First is the start address, then 8 hex bytes
0000: 00 01 00 01 04 17 24 b0
0008: 3c 27 70 10 30 1e 62 8d
0010: 00 af bc 01 00 22 1c 00
0018: 64 40 00 00 00 79 00 00

... 

Next I wrote a simple script, following the datasheet instructions, to write the memory. I changed the FM frequency bands from 1 to 2 (so that I can change between normal and extended band with a switch) and made the band 2 to goup to 138 MHz. Changes in the EEPROM are following, first bullet is the register address, then EEPROM addresses with original value and changed value.
  • 0x02 MANUAL, set FM band number from 1 to 2
    • 0x0004: 4  => 4
    • 0x0005: 17 => 1B
  • 0x38 BANDCFG, change FM2 bandwidth to 50 kHz
    • 0x0070: C1 => C1
    • 0x0071: 16 => 1A
  • 0x3B FM2_CHAN_LOW, change to 137 MHz
    • 0x0076: 5  => A
    • 0x0077: DC => B4
  • 0x3C FM2_CHAN_NUM, change to 138 MHz (137 MHz + 20 times 50 kHz band = 138 MHz)
    • 0x0078: 0  => 0
    • 0x0079: A0 => 14
I wrote these changes to the EEPROM and re-soldered the chip. Then I added a switch to select the FM resistor either 47 kOhm or 82 kOhm so I could change between FM bands 1 and 2.

First testing

I got to test the radio with a nice function generator, Tektronix AFG3000C series one that goes up to 240 MHz and supports FM modulation. I used for example following parameters in the generator:
  • Frequency e.g. 105 MHz or other un-used frequency. This is the frequency where the radio will be tuned
  • FM frequency e.g. 440 Hz (modulation frequency). This sets the tone that will be heard. 440 Hz is A note for example.
  • Deviation 20 kHz, this sets the volume of the tone that will be heard.
  •  Amplitude 50 mVp-p. This affects the transmission power. 50 mVp-p was minimum and still was enough.
With even the very low amplitude, it was enough to have a 10 cm wire hanging from the output BNC connector and the radio picked the signal up clearly.

This test was not a success, the radio could not pick up signals at the desired frequency. I assumed (maybe wrongly) that there is some kind of limit in the chip, so I decided to try the other option, changing the clock frequency.

Changing the clock

Again I desoldered the EEPROM, but I was not carefull enough and broke the chip while trying to lift it, one leg got disconnected from the IC and it took part of the case with it!

Since I didn't have any suitable EEPROMs around I thought about using the Raspberry PI as I2C slave, however I could not figure out how to make Raspberry PI to reply to continuous read requests... So I needed something else.

Next idea was to use TI's Tiva Launchpad which I have multiple of. It supports I2C slave directly, and I found a nice example on how to use it, which I modified for my use. That allowed me to easily change the EEPROM contents on PC and re-flash the microcontroller (via USB) and then try things. One thing to note though was that the PC (at least not the mains adapter) should not be connected or there is too much interference to get a good reception on the radio....

I decreased the clock indicated frequency to about 78.6 % which would make 108.5 MHz to be 138 MHz. Also the standard FM band would need to be changed, so that the original 87.3 ... 108.5 MHz is written as 68.65 ... 85.3 MHz. The original clock was 32768 Hz, and I changed that parameter to be 25761. This makes the tuning to be 127.2 % higher than the indicated values.
  • 0x15 SYSCLK_CFGA, change to 25761 Hz
    • 0x0044: 0x80 => 0x64
    • 0x0045: 0x00 => 0xA1
  • 0x39 FM1_LOW_CHAN, set to 68.65 MHz / 50 kHz = 1373
    • 0x0074: 0x06 => 0x05
    • 0x0075: 0xD2 => 0x5D
  • 0x40 FM1_CHAN_NUM, set to (85.3 - 68.65) MHz / 50 kHz = 333
    • 0x0076: 0x01 => 0x01
    • 0x0078: 0xA8 => 0x4D
I made the firmware for the Tiva so that with buttons I could select the 0x41 FM2_LOW_CHAN and 0x42 FM2_CHAN_NUM differently, from about 100 MHz to 120 MHz or from 120 MHz to 140 MHz or from 137 MHz to 138 MHz. This helped in testing what is the actual limits of the hardware.

Second testing

I retried with this new firmware. Now it was easy to first set the band to 100 MHz to 120 MHz and tune up the signal generator. I could hear the tone at full scale up to 120 MHz, great so far!

Changing the band to 120 MHz to 140 MHz, the signal was lost at 130 MHz! The radio tuned properly to that frequency, then nothing, like a wall. I assume there must be some very steep hardware filter done with passive components, so that the software changes do not help.

Conclusion

In the end I now have method to tune the radio from at least 30 MHz to about 130 MHz (I did not try the low end). While this cannot be used for receiving weather satellites, there might be some other uses for a wide frequency band receiver; I'm thinking about replacing the EEPROM with Attiny85 or similar, and use some switches to select the bands; that way the radio would become a cheap radio scanner.

Ei kommentteja:

Lähetä kommentti