Hello guys, today we are going to have a look on, How I made an Arduino based FM and then turn its circuit into a fully functional PCB. In this tutorial you will learn, basic FM working, Arduino code for this FM, range, speakers, antenna and amplifiers used in this circuit. This type of digital circuits has a very big importance over any analog based circuits. It will reduce the circuitry and tuning methods.
Features:
1) Based on digital method
2) Needs very less components
3) Stereo channel availability
4) Easy to tune
5) Onboard volume control
6) Large bandwidth (50MHz to 115MHz)
7) No coils, no variable capacitors
8) Low power consumption
Fm working in brief:
Frequency Modulation (FM) is the encoding of information in a carrier wave by changing the instantaneous frequency of the wave. FM technology is widely used in the fields of computing, telecommunications, and signal processing.
RDA5807 FM:
The RDA5807M series is the newest generation single-chip broadcast FM stereo radio tuner with fully integrated synthesizer, IF selectivity, RDS/RBDS and MPX decoder. The tuner uses the CMOS process, support multi-interface and require the least external component. All these make it very suitable for portable devices.
The RDA5807M series has a powerful low-IF digital audio processor, this make it have optimum sound quality with varying reception conditions. The RDA5807M series support frequency range is from 50MHz to 115MHz.
And this small module comes with a lot of features:
· CMOS single-chip fully-integrated FM tuner
· Low power consumption -Total current consumption lower than 20mA at 3.0V power supply when under normal situation
· Support worldwide frequency band 50 -115 MHz
· Support flexible channel spacing mode – 100KHz, 200KHz, 50KHz and 25KHz
· Support RDS/RBDS
· Digital low-IF tuner
· Image-reject down-converter
· High performance A/D converter
· IF selectivity performed internally
· Fully integrated digital frequency synthesizer
· Fully integrated on-chip RF and IF VCO
· Fully integrated on-chip loop filter
· Autonomous search tuning
· Support 32.768KHz crystal oscillator
· Digital auto gain control (AGC)
· Digital adaptive noise cancellation
· Soft mute
· Programmable de-emphasis (50/75 ms)
· Receive signal strength indicator (RSSI) and SNR
· Bass boost
· Volume control and mute
· Line-level analog output voltage
· Find more info from Datasheet from here, because I think this small module is full of features and that’s what the technology. Changed the whole circuitry, coils, resistors and tuning capacitors into a small 0.2g 8pin SMD chip.
Breadboard circuit:
This is the circuit diagram for people, want to use Arduino nano.
Here in this circuit LM386 is used to amplify the signal, to tune the frequency 100k potentiometer is needed. 10k potentiometer is for volume. If you use custom PCB then no need to do all of this. By the way, you may try this circuit on breadboard to develop your own ideas.
All the ceramic capacitors used in this circuit are 100nf, for resistors color code is given, all the electrolytic capacitor is 1000uf.
Lm386 amplifier does not support stereo channel, this is mono channel 3W ic.
Breadboard software:
Here is our new schematics designer tool “Cirkit Designer” which is totally free to all and having a plenty of extra features over any other.
And I think cirkit designer is best software to make breadboard schematics presentation also gives you ability to view the next diagram and BOM (bill of materials). So accordingly, that you can make an estimate and present yourself good as an electronics student or hobbyist. And we are launching the simulation program this month so stay tuned.
Cirkit Designer (link to www.cirkitdesigner.com) is a one-stop-shop desktop application for designing and documenting circuits and electronics projects. With Cirkit Designer, you can lay out realistic circuit diagrams that are linked to a bill-of-materials so that you can seamlessly order the parts to your circuit.
In the next release, Cirkit Designer is adding a code IDE with full support for compiling and programming Arduino boards, as well as a library of reference circuit designs (circuit templates including documentation, components and wiring, and code). Cirkit Designer will become the one-stop-shop to help you progress from concept to fully working breadboard prototypes.
This PCB is designed in EasyEDA, I ordered this with purple solder mask. All the main components will be soldered front side and the speaker out terminals, tuning terminals, power and ICSP headers for programming is placed backside of this board.
Video & assembling:
Working of circuit:
The custom PCB has PAM8403 audio amplifier, which is a stereo amplifier and has 3+3watts output. Microcontroller atmega328p has a 16Mhz smd crystal rasonator. RDA5807 Fm and other small controlling circuitry which you can see in the circuit schematics given above. Here I am using PAM class D audio amplifier because it is low power, dual channel and 5v supported. A 50k stereo potentiometer to set the volume level.
there is no any type of programmer IC on board but ICSP is provided for programming directly using Arduino or any other MCU. C-type usb jack is only to power the FM. To tune the FM to different channels, a 100k potentiometer can be soldered on 3-pins of tune section. Which gives ability to set any channel manually.
A small slide switch is only to switch on and off the whole system. If you want to try this thing first on breadboard using simple breakout modules then go for it, circuit diagram for breadboard is given above. Testing and other instructions are provided in video.
Code:
#include <Wire.h>
/* Select the frequency we want to tune to by way
* of selecting the channel for the desired frequency
*/
uint16_t channel = 187;
/*
* assuming band starts at 87.0MHz (per settings below)
* and channel spacing of 100kHz (0.1MHz) (per settings below)
* then channel can be derived as follows:
*
* channel = (<desired freq in MHz> - 87.0) / 0.1
*
* which is the same as:
* <10 x desired freq in MHz> - 870
*/
#define RDA5807M_ADDRESS 0b0010000 // 0x10
#define BOOT_CONFIG_LEN 12
#define TUNE_CONFIG_LEN 4
/*
* These bytes set our initial configuration
* We don't bother to tune to a channel at this stage.
* But instead initiate a reset.
*/
uint8_t boot_config[] = {
/* register 0x02 */
0b11000001,
/*
* DHIZ audio output high-z disable
* 1 = normal operation
*
* DMUTE mute disable
* 1 = normal operation
*
* MONO mono select
* 0 = stereo
*
* BASS bass boost
* 0 = disabled
*
* RCLK NON-CALIBRATE MODE
* 0 = RCLK is always supplied
*
* RCLK DIRECT INPUT MODE
* 0 = ??? not certain what this does
*
* SEEKUP
* 0 = seek in down direction
*
* SEEK
* 0 = disable / stop seek (i.e. don't seek)
*/
0b00000011,
/*
* SKMODE seek mode:
* 0 = wrap at upper or lower band limit and contiue seeking
*
* CLK_MODE clock mode
* 000 = 32.768kHZ clock rate (match the watch cystal on the module)
*
* RDS_EN radio data system enable
* 0 = disable radio data system
*
* NEW_METHOD use new demodulate method for improved sensitivity
* 0 = presumably disabled
*
* SOFT_RESET
* 1 = perform a reset
*
* ENABLE power up enable:
* 1 = enabled
*/
/* register 0x03 */
/* Don't bother to tune to a channel at this stage*/
0b00000000,
/*
* CHAN channel select 8 most significant bits of 10 in total
* 0000 0000 = don't boher to program a channel at this time
*/
0b00000000,
/*
* CHAN two least significant bits of 10 in total
* 00 = don't bother to program a channel at this time
*
* DIRECT MODE used only when test
* 0 = presumably disabled
*
* TUNE commence tune operation
* 0 = disable (i.e. don't tune to selected channel)
*
* BAND band select
* 00 = select the 87-108MHz band
*
* SPACE channel spacing
* 00 = select spacing of 100kHz between channels
*/
/* register 0x04 */
0b00001010,
/*
* RESERVED 15
* 0
*
* PRESUMABLY RESERVED 14
* 0
*
* RESERVED 13:12
* 00
*
* DE de-emphasis:
* 1 = 50us de-emphasis as used in Australia
*
* RESERVED
* 0
*
* SOFTMUTE_EN
* 1 = soft mute enabled
*
* AFCD AFC disable
* 0 = AFC enabled
*/
0b00000000,
/*
* Bits 7-0 are not specified, so assume all 0's
* 0000 0000
*/
/* register 0x05 */
0b10001000,
/*
* INT_MODE
* 1 = interrupt last until read reg 0x0C
*
* RESERVED 14:12
* 000
*
* SEEKTH seek signal to noise ratio threshold
* 1000 = suggested default
*/
0b00001111,
/*
* PRESUMABLY RESERVED 7:6
* 00
*
* RESERVED 5:4
* 00
*
* VOLUME
* 1111 = loudest volume
*/
/* register 0x06 */
0b00000000,
/*
* RESERVED 15
* 0
*
* OPEN_MODE open reserved registers mode
* 00 = suggested default
*
* Bits 12:8 are not specified, so assume all 0's
* 00000
*/
0b00000000,
/*
* Bits 7:0 are not specified, so assume all 0's
* 00000000
*/
/* register 0x07 */
0b01000010,
/*
* RESERVED 15
* 0
*
* TH_SOFRBLEND threshhold for noise soft blend setting
* 10000 = using default value
*
* 65M_50M MODE
* 1 = only applies to BAND setting of 0b11, so could probably use 0 here too
*
* RESERVED 8
* 0
*/
0b00000010,
/*
* SEEK_TH_OLD seek threshold for old seek mode
* 000000
*
* SOFTBLEND_EN soft blend enable
* 1 = using default value
*
* FREQ_MODE
* 0 = using defualt value
*/
};
/* After reset, we can tune the device
* We only need program the first 4 bytes in order to do this
*/
uint8_t tune_config[] = {
/* register 0x02 */
0b11000000,
/*
* DHIZ audio output high-z disable
* 1 = normal operation
*
* DMUTE mute disable
* 1 = normal operation
*
* MONO mono select
* 0 = mono
*
* BASS bass boost
* 0 = disabled
*
* RCLK NON-CALIBRATE MODE
* 0 = RCLK is always supplied
*
* RCLK DIRECT INPUT MODE
* 0 = ??? not certain what this does
*
* SEEKUP
* 0 = seek in down direction
*
* SEEK
* 0 = disable / stop seek (i.e. don't seek)
*/
0b00000001,
/*
* SKMODE seek mode:
* 0 = wrap at upper or lower band limit and contiue seeking
*
* CLK_MODE clock mode
* 000 = 32.768kHZ clock rate (match the watch cystal on the module)
*
* RDS_EN radio data system enable
* 0 = disable radio data system
*
* NEW_METHOD use new demodulate method for improved sensitivity
* 0 = presumably disabled
*
* SOFT_RESET
* 0 = don't reset this time around
*
* ENABLE power up enable:
* 1 = enabled
*/
/* register 0x03 */
/* Here's where we set the frequency we want to tune to */
(channel >> 2),
/* CHAN channel select 8 most significant bits of 10 in total */
((channel & 0b11) << 6 ) | 0b00010000
/*
* CHAN two least significant bits of 10 in total
*
* DIRECT MODE used only when test
* 0 = presumably disabled
*
* TUNE commence tune operation
* 1 = enable (i.e. tune to selected channel)
*
* BAND band select
* 00 = select the 87-108MHz band
*
* SPACE channel spacing
* 00 = select spacing of 100kHz between channels
*/
};
void setup()
{
Serial.begin(9600);
pinMode(A0,INPUT);
Wire.begin();
Wire.beginTransmission(RDA5807M_ADDRESS);
Wire.write(boot_config, BOOT_CONFIG_LEN);
Wire.endTransmission();
Wire.beginTransmission(RDA5807M_ADDRESS);
Wire.write(tune_config, TUNE_CONFIG_LEN);
Wire.endTransmission();
}//setup end
void loop()
{
int channel1 =90,newA;
static int oldA = 0; // set the oldA as HIGH
int result = 0;
newA = analogRead(A0);
if ((newA - oldA) > 10 || (oldA - newA) > 10){
Serial.println(newA);
if(newA!= oldA){
channel = channel1+(newA/10);
myChangeChannel(channel);
oldA=newA;
}
}
uint16_t frequency = channel+870;
uint16_t num1 = (frequency / 1000) % 10;
uint16_t num2 = (frequency / 100) % 10;
uint16_t num3 = (frequency / 10) % 10;
uint16_t num4 = frequency % 10;
Serial.print(num1);
Serial.print(num2);
Serial.print(num3);
Serial.print(num4);
Serial.print("--");
Serial.println(channel+870);
}//loop end
/*
* Function to change channel on radio RDA5807
* Example: channel = 191
*/
void myChangeChannel(int channel){ /* void if nothing is returned else int */
/*
* first write new channel to tune_config massive
*/
tune_config[2] = (channel >> 2);
tune_config[3] = ((channel & 0b11) << 6 ) | 0b00010000;
Wire.begin();
Wire.beginTransmission(RDA5807M_ADDRESS);
Wire.write(tune_config, TUNE_CONFIG_LEN);
Wire.endTransmission();
}
JLCPCB:
JLCPCB is the one of the most popular PCB makers. Price is just $2 for 2, 4 and 6 layer PCB. They just launched new purple solder mask, aluminum Pcb and 3d printing service in very low cost. Pcb quality is not compromised at any cost. Check them out right now from Here.
JLCPCB Is also providing new user coupons and sign-up rewards of up to $30. So, check them out from here. Register using this link to get Free PCB assembly service coupons. Get your 2 layer to 6-layer PCB’s just in $2, stencil and PCB assembly service in just $7.
Sagar Saini, an electronics engineer from Kurukshetra, Haryana, developing skills in microcontrollers, PCB designing, circuit design, and embedded system development. I will always try to deliver high-quality solutions and contribute to cutting-edge projects.
It is very easy to calculate the hexadecimal equivalent to a decimal number using dividing by 167 method. But this method is very long and sometimes very confusing when comes to large numbers. here I have a Arduino based decimal to hexadecimal converter. But let’s know more about hexadecimal number system and why it was…
Batteries are the heart of any electronic circuit, the impossibilities of making a wireless circuit without batteries is now eliminated by this DFrobot mini generator based Rf circuit. Remote controllers can be seen everywhere, and most of them are inseparable from the battery. However, we often encounter problems when using the battery, for instance, it…
Previously, I designed an esp8266 shield. And today we will about to know that how to program this esp8266. Because our shield has the same pinout as it is in ESP breakout. Now we will see how to do make all the connections and how to setup Arduino IDE for esp8266 boards. I ordered SMT…
Previously, I made some tutorials regarding current measurements using shunt resistor. Basically, shunt is small known resistance which is in series with the load. And by measuring the voltage drop across the resistor we can find the value of current flowing in the circuit. All credit goes to Ohm’s law: V=IR, by knowing the two…
I need a big RGB stripe for my gaming room, so that I can stick that on my setup. But I need one with better durability and brighter LEDs with Good heat dissipation. The WS2812 RGB neo pixels may do the fine job but these strips come with flex PCB. Which I would not recommend…
hello guys, today we are going to make a smart talking voltmeter. This one is built on Arduino and gives the reading by speaking itself. This function is cool and attractive because when we are working on circuits, we have to see again and again the readings and then switch the voltmeter leads to measure…