Atmel AVR Atmega168 RDS decoder with serial output

I have build a RDS (Radio Data System) decoder with a microcontroller from Atmel.
This decoder is fed by a RDS demodulator IC (or tuner) which has RDDA (data signal) and RDCL (clock signal) outputs.

atmega168_avr_rds_decoder_rs232-rds-demodulator

The microcontrolller is an Atmega168 clocked on the external 4.332MHz crystal from the RDS demodulator.
In my prototype I have used the (I think obsolete) TDA7330B RDS demodulator IC from STMicroelectronics.
The TDA7330B is connected to the Atmega168 with RDDA connected to PD4 (on PORTD) and RDCL to INT0 (PD2).

The tuner I have used is an old Hauppauge WinTV PCI card with FM tuner which I can tune to the Frequency I want with some software.
The tuner module on this card is an FM1216 from Philips.
It has an unmodulated MPX FM signal output (AF sound output) which the RDS demodulator needs.
This is the same signal which is fed into a stereo decoder to produce stereo sound outputs.

The yellow wire on the right is the MPX output:

This is the TDA7330B RDS demodulator, you can see the MPX wire coming from the WinTV tuner.
This board also provides the clock signal for the microcontroller (wire on the crystal) and RDDA and RDCL outputs.

This is the Atmega168 microcontroller which tries to decode the RDDA and RDCL RDS outputs from the demodulator.
When the Atmega168 successfully decodes something it will send the output on its USART port to the PC wich is running a terminal program.
The serial output first goes to the MAX233 to convert the signal to RS232 levels. The speed is 38K4 8N1.

Hauppauge WinTV radio software is used to tune to the correct station:

The serial output from the microcontroller looks like this:

The software in the Atmega168 is able to decode the following RDS data:

  • Programme Identification code (PI: 0x83C7, Detected new station.)
  • Program service name (PS: RADIO538)
  • Programme Type code (PTY: 0x0A, Pop Music.)
  • Traffic Programme Identification code & Traffic announcement code (TP&TA: 0x01 0x00, Traffic announcements available on this station and maybe via EON on another station.)
  • Music Speech switch code (MS: 0x01, Music is being broadcasted or station does not use MS flag.)
  • Decoder-identification control code (DI: 0x01, Stereo, Dynamic PTY.)
  • Alternative frequency codes (AF: 0x98, 102.7MHz.)
  • Linkage Actuator (LA: 0x00)
  • Extended Country Code (ECC: 0xE3)
  • RadioText (RTA: Radio 538 = Randstad (Zuid) 102.7 FM)
  • Clock-time and date (CT: 0x1A53CD844, UTC 2006-07-02 (MJD 53918) 13:33:00 +02:00, TIME 15:33:00)

The software can also output all RDS groups in undecoded form by sending character ‘G’ to the Atmega:

Downloads

20060629-1 HEX file for the Atmage168. Note: low fuse: 0xF0, high fuse: 0xDD.

Released source code for the 20060629-1 version under GPL2 license. Have fun, let me know what you made with it! Send me some
pictures and details of your project.

20060629-1 source for the Atmage168

It is funny to note that when I am developing the software in the Atmega all sorts of radio stations have very crappy RDS encoders installed.

For example:

  • This station does not send correct UTC offset (I live in +2:00 I think):
    PI: 0x83C7, Detected new station.
    PS: RADIO538
    CT: 0x1A53CF740, UTC 2006-07-02 (MJD 53918) 15:29:00 +00:00, TIME 15:29:00

    The UTC time is send in local time.

  • However, some station can do worse:
    PI: 0x8062, Detected new station.
    RTA: Den HaagFM 92.0 Den HaagFM 92.0 Den HaagFM 92.0 Den HaagFM 92.0
    CT: 0x1A53CFD40, UTC 2006-07-02 (MJD 53918) 15:53:00 +00:00, TIME 15:53:00

    This station does not send the correct offset or the correct time, it is 10 minutes in the future.

  • This station does even worse:
    PI: 0x845A, Detected new station.
    RTA: Den Haag:89.8 MHz  Rotterdam:102.2 MHz  e-mail: studio@amorfm.nl
    CT: 0x1A53CE540, UTC 2006-07-02 (MJD 53918) 14:21:00 +00:00, TIME 14:21:00

    The time is 1,5 hours(!) in the past.

  • This station has a bug in its RDS encoder, it is toglling the Music Speech flag very fast (also the DI flag does not make sense):
    PI: 0x8062, Detected new station.
    MS: 0x00, Speech is being broadcasted.
    MS: 0x01, Music is being broadcasted or station does not use MS flag.
    DI: 0x04, Mono, Compressed, Dynamic PTY.
    MS: 0x00, Speech is being broadcasted.
    MS: 0x01, Music is being broadcasted or station does not use MS flag.
    DI: 0x00, Mono, Dynamic PTY.
    MS: 0x00, Speech is being broadcasted.
    MS: 0x01, Music is being broadcasted or station does not use MS flag.
    MS: 0x00, Speech is being broadcasted.
    MS: 0x01, Music is being broadcasted or station does not use MS flag.
    DI: 0x01, Stereo, Dynamic PTY.
    MS: 0x00, Speech is being broadcasted.
    MS: 0x01, Music is being broadcasted or station does not use MS flag.
    DI: 0x00, Mono, Dynamic PTY.
    MS: 0x00, Speech is being broadcasted.
    MS: 0x01, Music is being broadcasted or station does not use MS flag.
    MS: 0x00, Speech is being broadcasted.
    DI: 0x01, Stereo, Dynamic PTY.
    DI: 0x00, Mono, Dynamic PTY.
    MS: 0x00, Speech is being broadcasted.
    MS: 0x01, Music is being broadcasted or station does not use MS flag.
    MS: 0x00, Speech is being broadcasted.
    MS: 0x01, Music is being broadcasted or station does not use MS flag.

Did you like this post? Please give it a thumbs up by sharing it on your social network. Thanks!

5 thoughts on “Atmel AVR Atmega168 RDS decoder with serial output

  1. Vu Minh Tuan

    Dear Sir,

    We are using DTMF encoder and decoder for FM systems in Vietnam, but my customer is asking for RDS. Could you please share the source code to us.

    Thank you,
    Tuan

    Reply
  2. Nelson

    Dear Marc:
    My name is Nelson and i am developing an application that uses RDS information.
    I came across your design using the ATmega168 and the old TDA7330B decoder.
    Have assembled a couple of boards with all the components and the system is working nice and smooth.
    I am impressed with your job indeed !!!!
    It is fantastic.
    I am not a programmer, but can move around…
    I would like to ask you if you can help me to implement in your code the decodification of the Transparent Data block (5A).
    I need to send strings of raw bytes to load Bilboards with information and I think this field is quite good for this application.
    I will be glad to support your efforts accordingly and I am pretty sure it will not a big effort for you as it will be for me…
    Let me know and I look forward to hear from you soon.
    Cheers.

    Reply
    1. marc Post author

      Hi Nelson!

      Thanks!

      Exactly 10 years ago I started this project. I cannot remember the details. But have a look the source code of the decoder.

      I saw that the variables groupType, groupVersion, block1, block2, block3 and block4 are available to decode in this empty if():

      //Type 5 groups: Transparent data channels or ODA
      if (groupType == 5) {

      }

      I have no idea what ODA exactly is. If they are some custom data blocks then you must get a specification of that protocol somewhere.
      My google-fu led me to this document: http://www.nrscstandards.org/RBDS/RDS%20ODA%20AIDs.pdf
      If I understand correctly, ODA block can contain everything from public transportation data to extra TMC data to iTunes tag something.

      Reply
      1. Nelson

        Dear Marc:
        Thank you very much !
        I will work around the original code and add the decodification part for Group 5A. This is the Transparent Data capability of the RDS standard.
        Just made the code run on the Atmega328P (Arduino?).
        Also, I will try the TDA7478 which is easy to find than the TDA7330B. Hope is the same.
        Do you have any other project but for Coding RDS ? I hve the FM transmitter for testing and will be fantastic to have a RDS codifier with its code sorce.
        Let me know and we can keep in touch. nejemia@gmail.com

        Reply

Leave a Reply

Your email address will not be published. Required fields are marked *