Remote-controlled Arduino FM radio

Finding TV Remote Codes

We used a small program (Listing 2) to find the IR (infrared) codes from our TV remote. For our program, we used the volume up, volume down, channel up, and channel down keys. Different TV remotes will have different codes, so you will have to find the codes that work with your remote. To use this test program, you'll need to include the IRremote.h infrared library. This library provides the irrecv commands you see through the program.

Listing 2

IR1_simple.ino – Find IR Codes

01  /*
02 IR TEST PROGRAM
03
04   PINOUTS:
05   LEFT = DATA PIN
06   MIDDLE = GND
07   RIGHT = 3.3 volts
08
09 */
10 #include <IRremote.h>
11
12 int RECV_PIN = 11;
13 IRrecv irrecv(RECV_PIN);
14 decode_results results;
15
16 void setup()
17 {
18   Serial.begin(9600);
19   irrecv.enableIRIn(); // Start the receiver
20   Serial.println("Setup Complete");
21 }
22
23 void loop()
24 {
25   if (irrecv.decode(&results))
26     {
27      Serial.println(results.value, HEX);
28      irrecv.resume(); // Receive the next value
29      delay(500);
30     }
31 }

A word of caution: Be careful when wiring the IR receiver. We destroyed two of them. Luckily, they are quite inexpensive.

When our IR test program was running, we used the Arduino monitor window to display the different key codes (Figure 3). To use multiple TV remotes, all you need to do is record the different key codes. For example, if you wanted to use two remotes, the key codes might be:

Figure 3: Finding the remote IR codes.
  • volume up = 0xE0E0E01F or 0x68733A46
  • volume down = 0xE0E0D02F or 0x83B19366
  • channel up = 0xE0E048B7 or 0x5F12E8C4
  • channel down = 0xE0E008F7 or 0x189D7928

We tested a number of different TV remotes, but to keep the final code simple, we only used one. The case statements in Listing 3 (lines 32, 39, 46, and 53) catch the IR codes.

Listing 3

radio_ir.ino

001 // RDA5807M Radio controlled with a TV Remote
002 //
003 #include <Wire.h>
004 #include <IRremote.h>
005
006 int RECV_PIN = 11;  // Connect the IR data pin in 11
007 IRrecv irrecv(RECV_PIN);
008 decode_results results;
009
010 int volume = 0;  // start with the volume low
011 int channellist[]= {999,1029,1021,1079}; // Define some radio stations
012 int maxc = 4;    // Define the number of radio stations used
013 int channel = 2; // Start with a favorite station
014
015 void setup()
016 {
017   Wire.begin();
018
019   Serial.begin(9600);
020
021   irrecv.enableIRIn(); // Start the receiver
022
023   radio_init();
024   setfreq(channellist[channel]);
025   setvolume(volume);
026 }
027
028 void loop() {
029   if (irrecv.decode(&results)) {
030
031     switch (results.value) {
032      case 0xE0E0E01F:
033        Serial.println("vol up");
034        if (volume < 15) {
035          volume++;
036          setvolume(volume);
037        }
038        break;
039      case 0xE0E0D02F:
040        Serial.println("vol down");
041        if (volume > 0) {
042          volume--;
043          setvolume(volume);
044        }
045        break;
046      case 0xE0E048B7:
047        Serial.println("chan up");
048        if (channel < maxc) {
049          channel++;
050          setfreq(channellist[channel]);
051        }
052        break;
053      case 0xE0E008F7:
054        Serial.println("chan down");
055        if (channel > 0) {
056          channel--;
057          setfreq(channellist[channel]);
058        }
059        break;
060      default:
061        Serial.println(results.value, HEX);
062     }
063     irrecv.resume(); // Receive the next value
064   }
065   delay(100);
066 }
067 //===============================
068 void setvolume(int thevolume)
069 {
070   byte volbyte;
071
072   volbyte = thevolume + 0xD0;
073   Wire.beginTransmission(0x11);
074   Wire.write(0x05);
075   Wire.write(0x84); Wire.write(volbyte);
076   Wire.endTransmission();
077   delay(500);
078 }
079 //===============================
080 void setfreq(int thefreq)
081 {
082   int freqB;
083   byte freqH, freqL;
084
085   freqB = thefreq - 870;
086   freqH = freqB >> 2;
087   freqL = (freqB & 3) <<6;
088
089   Wire.beginTransmission(0x11);
090   Wire.write(0x03);
091   Wire.write(freqH);                   // write frequency into bits 15:6, set tune bit
092   Wire.write(freqL + 0x10);
093   Wire.endTransmission();
094   delay(500);
095 }
096 //================================
097 void radio_init()
098 {
099   Wire.beginTransmission(0x11);        // Device address 0x11 (random access)
100   Wire.write(0x02);                    // Register address 0x02
101   Wire.write(0xC0); Wire.write(0x03);  // Initialize the settings
102   Wire.endTransmission();
103   delay(500);                          // wait 500ms to finalize setup
104
105   Wire.beginTransmission(0x11);        // Device address 0x11 (random access)
106   Wire.write(0x02);
107   Wire.write(0xC0); Wire.write(0x0D);  // Set up radio settings
108   Wire.endTransmission();
109   delay(500);                          // wait 500ms to finalize settings
110 }

Using a TV Remote

Our goal was to use a TV remote to change the FM station and to adjust the volume. A number of websites can find nearby radio stations for you; a good one is the RadioLocator.com database kept by Theodric Technologies [10].

Our program (Listing 3) defines four FM stations (line 11) that we cycle through using the channel up and channel down buttons on the TV remote. The volume up and down buttons, on the other hand, change the radio's volume. Remember to change the IR codes to match your TV remote and the choice of FM stations for your area. Lines 15 to 26 initialize the serial connection to 9600 (line 19), start the FM radio receiver, and initialize the radio stations and volume.

The IR remote portion of our program (Listing 3, lines 28-66) looks for button presses from the TV remote and calls the appropriate routine to set the volume or radio frequency. The next two sections of code, setvolume() (lines 68-78) and setfreq(), we described earlier in the text. The final section, radio_init() (lines 97-110), is the FM module initialization called in line 23.

Buy this article as PDF

Express-Checkout as PDF

Pages: 8

Price $2.95
(incl. VAT)

Buy Raspberry Pi Geek

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content