Friday, September 16, 2011

New Arduino Library for Sparkfun Si4703 FM Receiver Breakout Board

The Sparkfun Si4703 FM Receiver Breakout Board is a great little FM radio, complete with RDS and a 100mW stereo amp.

There is example code for using it and top marks to Nathan Seidle from Sparkfun for working out how to use the pesky thing from the largely opaque datasheet for the receiver chip.

I have been making myself the 'ultimate' FM receiver. Arduino-based and using nice controls, solar-charging of battery with charging data and an LCD display for the RDS data. I will post on this when its finished.

The software engineer in me railed at just hacking away at Nathan's example. So I put his code in a library and also fixed some of the problems with RDS and did a bit of tidying.

You can download it from here. Continuing Nathan's licensing arrangement, I also offer it as 'Beer-ware'. If you are feeling extremely grateful then by all means buy one of my books (see right panel).

Here is an example app, just connect up the three pins at the top of the sketch but remember Vcc for the breakout board is 3.3V NOT 5V. 5V will kill it:

#include <Si4703_Breakout.h>
#include <Wire.h>

int resetPin = 2;
int SDIO = A4;
int SCLK = A5;

Si4703_Breakout radio(resetPin, SDIO, SCLK);
int channel;
int volume;
char rdsBuffer[10];

void setup()
  Serial.println("\n\nSi4703_Breakout Test Sketch");
  Serial.println("a b     Favourite stations");
  Serial.println("+ -     Volume (max 15)");
  Serial.println("u d     Seek up / down");
  Serial.println("r       Listen for RDS Data (15 sec timeout)");
  Serial.println("Send me a command letter.");


void loop()
  if (Serial.available())
    char ch = Serial.read();
    if (ch == 'u') 
      channel = radio.seekUp();
    else if (ch == 'd') 
      channel = radio.seekDown();
    else if (ch == '+') 
      volume ++;
      if (volume == 16) volume = 15;
    else if (ch == '-') 
      volume --;
      if (volume < 0) volume = 0;
    else if (ch == 'a')
      channel = 930; // Rock FM
    else if (ch == 'b')
      channel = 974; // BBC R4
    else if (ch == 'r')
      Serial.println("RDS listening");
      radio.readRDS(rdsBuffer, 15000);
      Serial.print("RDS heard:");

void displayInfo()
   Serial.print("Channel:"); Serial.print(channel); 
   Serial.print(" Volume:"); Serial.println(volume); 

Here is the public part of the class definition.

class Si4703_Breakout
    Si4703_Breakout(int resetPin, int sdioPin, int sclkPin);
    void powerOn(); // call in setup
void setChannel(int channel);   // 3 digit channel number
int seekUp(); // returns the tuned channel or 0
int seekDown();
void setVolume(int volume); // 0 to 15
void readRDS(char* message, long timeout);
// message should be at least 9 chars
// result will be null terminated
// timeout in milliseconds

About the Author
These are my books. Click on the image below to find out more about them.


Vincenzo said...

Hi, Simon, please can you confirm me the schematics? If is correct can you explain the inusual lcd connection? Many thanks!

Anonymous said...

Many thanks for your code. Up and running on my Arduino. Great to hear actual radio:-)


acidice333 said...

Any more updates on the library? particularly the RDS part?

Matti said...

Nice Library but i have a question. If i would like to use the radio in Japan (76 - 108 MHz) wich byte should i write and how should i change the code?

BBORNCR said...

Hello, your code is working fine for me. I am an owner of your "30 Arduino Projects for the Evil Genius" and have learned a lot from it. I have been studying your library and the Application Notes for the si4703 and can't understand how to extract the TMC data from the RDS. Do you have any tips on how to understand the formatting of the blocks, group types, etc.

Gurjit Singh Khehra said...

Thanks Dear. Very Informative Article.

Simon Monk said...

TMC data - I'm aftraid I had enough difficulty getting RDS to work! sorry.

Simon Monk said...

@Matti - sorry no idea about changing the band - you will probably need to look in the datasheet.

Tanooki2003 said...

Hi Simon, I am recently new to the world of Arduino and learning / experimenting. What drew me to Arduino was that I am in the process of making my own modernized audio components using Arduino. So far I created an MP3 reader using SD or USB from my last kit now I wanted to try to tackle an Arduino way of creating a FM stereo tuner. I was wondering if you had any information on how to interface an LCD and external buttons to control the tuner like you did in your pic?

Tanooki2003 said...

Hi Simon, I am somewhat new to the world of Arduino and have been building / experimenting with certain projects. I am currently building portable and home stereo components using modern Arduino kits. I was wondering if you have any information on interfacing an LCD display and using external buttons for controls much like you did? Any information you can give will be greatly appreciated.

florindgis said...

when I verify the sketch it gives me some errors ("Si4703_Breakout" does not name a type, "radio" was not declared in this scope,and so on...)
I use IDE 1.0.3.
Should I use an older version or what?

Winthea Lynch said...

Hi, I have been trying to get the SI4735 to work for a few months now and have finally given up. If i switch to SI4703 will i need to use a level shifter when connecting to Arduino?

TheFug said...

Just don't give it 5 volts of power, 3,3 volt is fine.
@Simon: the RDS library (AN243)for the Si4703 is now available.

Francois Steyn said...

I am sorry but I can't get this lib to work. I've spent hours and hours debugging and I keep getting weird errors like 'class TwoWire' has no member named 'send' etc. The code from sparkfun's site works but for the life of me i can't find any code that has RDS working.

Hannibal said...

The Sparkfun Si4703 FM Receiver Breakout Board is a great little FM ... sreceivers.blogspot.com