Project showcase
Make Radio with touch control by RDA5807M

Make Radio with touch control by RDA5807M © LGPL

Make FM Radio full function by RDA5807M and arduino nano. Control by touch button

  • 4,518 views
  • 3 comments
  • 8 respects

Components and supplies

Ard nano
Arduino Nano R3
×1
RDA5807M
×1
PAM8403 amplifier module
×1
LCD 1602 module
×1
Adafruit industries ada1314 image
Speaker: 3W, 4 ohms
×1
Touch sensor module TTP223
×1
variable resistor 10k
×1
4415447 jg5sklyzsj
Resistor 220 ohm
×1
Micro USB to DIP PCBA
Use to power the radio by phone charger
×1
4797683
Wire, Flexivolt-E
×1

Necessary tools and machines

09507 01
Soldering iron (generic)

About this project

Just to make some fun with Radio by Arduino. This make a touch control radio and few function of a radio that some one may need for fun!

System Start Up state: Initializing RDA5807M chip.

- If found the chip after Initializing, will check the pre-save channel list and play.

I loaded Vietnam channel in default. You can change it in code.

InFMplaying:

  • Press Next will play next channel in ROM, Press Prev will play previous channel.
  • Press mute for muting and un-muting.
  • Press and hold Vol- or Vol+ for volume adjustment.
  • Press and hold Menu will display channel info (RSSI, channel status)
  • Press and hold Seek to auto seek and found next channel
  • Press Menu for Menu selection and choose function by F1, F2 according to display

InSeekingmode:

  • ress Next will play next channel in ROM, Press Prev will play previous channel.
  • Press mute for muting and un-muting.
  • Press and hold Vol- or Vol+ for volume adjustment.
  • Press and hold Menu will display channel info (RSSI, channel status)
  • Press and hold Seek to auto seek and found next channel
  • Press Save to save the channel to ROM, input Name of station by Up, down, Enter

InPlaybyfrequencymode:

  • Press up and down for frequency change.
  • Press and hold Enter for change frequency by x10 or x1 change
  • Press save to save frequency to ROM

Others functionsin Menu.

Code

NANOFMRADIO.inoArduino
/*
 * FM CHANNEL AT HO CHI MINH CITY - VIET NAM
 * VOHKT  87.7 
 * VOV89  89
 * VOVGT  91
 * BINHD  92.5
 * VOV1   94
 * VOHGT  95.6
 * VOV2   96.5
 * DONGN  97.5
 * VOHFM    99.9
 * TA247  104
 * VOV3   104.5
 * VOV5   105.7
 */





#include <Wire.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>
#include <RADIO_RDA5807M.h>


//Define byte of custom char in LCD
#define DSignalchar     byte(0) 
#define DSignal100      byte(1) 
#define DSignal80       byte(2)
#define DSignal60       byte(3)
#define DSignal40       byte(4)
#define DSignal20       byte(5)
#define DSignal0        byte(6)
#define DPlaysign       byte(7)

//Define button Pin No
#define BMenu   2
#define BEnter  3
#define BDown   4
#define BUp     5
#define LCDBackLight     6

//Define Buton active level
#define ACTIVE_LOW 0
#define ACTIVE_HIGH 1

//define State of device
#define NO_RADIO_FOUND          0
#define NO_CHANNEL_FOUND        1
#define FIRST_SETUP_SELECT      2
#define DONE_LOAD_VN_CHANNEL    3
#define PLAYING                 4
#define SEEKING                 5
#define SAVE_CHANNEL_SEEK       6
#define MENU_PAGE1              7
#define MENU_PAGE2              8
#define MENU_PAGE3              9
#define PLAY_BY_FREQ            10
#define EDIT_CHANNEL            11
#define REMOVE_CHANNEL          12
#define ERASE_ALL               13
#define REMOVE_CHANNEL_DONE     14
#define LCD_BACKLIGHT           15  
#define DONE_ERASE_ALL          16
#define DATA_ERASING            17
#define DISPLAY_CHANNEL_INFO    18
#define SAVE_CHANNEL_FREQ       19
#define LOAD_DEFAULT_DATA       20
#define SET_BACKLIGHT           21



//define ButtonState
#define NO_BUTTON_PRESS     0
#define MENU_LONG_PRESS     1
#define MENU_SHORT_PRESS    2
#define UP_LONG_PRESS       3
#define UP_SHORT_PRESS      4
#define DOWN_LONG_PRESS     5
#define DOWN_SHORT_PRESS    6
#define ENTER_LONG_PRESS    7
#define ENTER_SHORT_PRESS   8

//Define BackLight macro
#define ONLCDLED digitalWrite(LCDBackLight, LOW)
#define OFFLCDLED digitalWrite(LCDBackLight, HIGH)

struct RadioChannelInfo
{
 uint8_t ChannelIndex;
 char ChannelName[5];
 unsigned int ChannelFreq;
};


LiquidCrystal LCDDISPLAY(12, 11, 10, 9, 8, 7);

byte SignalChar[8] = {31,14,4,4,4,4,4,0};
byte Signal100[8]= {1,3,7,15,31,0,31,0};
byte Signal80[8]= {0,2,6,14,30,0,31,0};
byte Signal60[8]= {0,0,4,12,28,0,31,0};
byte Signal40[8]= {0,0,0,8,24,0,31,0};
byte Signal20[8]= {0,0,0,0,16,0,31,0};
byte Signal0[8]= {17,10,4,10,17,0,31,0};
byte Playsign[8]= {16,24,28,30,30,28,24,16};

const byte DefaultROMDataVietnamChannel[]= {1,'V','O','H','K','T',0x22,0x42,
                                            2,'V','O','V','8','9',0x22,0xC4,
                                            3,'V','O','V','G','T',0x23,0x8C,
                                            4,'B','I','N','H','D',0x24,0x22,                                  
                                            5,'V','O','V','1',0,0x24,0xB8,                                  
                                            6,'V','O','H','G','T',0x25,0x58,                                  
                                            7,'V','O','V','2',0,0x25,0xB2,                                  
                                            8,'D','O','N','G','N',0x26,0x16,                                  
                                            9,'V','O','H','F','M',0x27,0x06,                                 
                                            10,'T','A','2','4',0,0x28,0xA0,                                  
                                            11,'V','O','V','3',0,0x28,0xD2,                                  
                                            12,'V','O','V','5',0,0x29,0x4A                                 
                                                                              };



byte SignalLevel;
byte CurrentState;
byte LastState;
RadioChannelInfo CurrentChannelInfo;
byte CurrentChannelIndex;
byte CurrentVolume;
byte MuteVolume=1;
unsigned int CurrentFreq;
bool FreqMode10x;

byte CurrentBacklightLife=5;
unsigned int BackLighOnpoint;

RDA5807M MyRadio;
bool RadioFound;
bool ChannelDefined;
byte ROMData;
byte NumofChannel;
byte CurrentCharacter=0;
byte CurrentCharacterIndex=0;
char SaveChannelName[5];


bool ButtonHolding=false;

byte ReadCurrentBackLightLife()
{
  byte ReturnBacklightLife;
  ReturnBacklightLife=EEPROM.read(0x03);
  return  ReturnBacklightLife;
}

void WriteCurrentBackLightLife(byte LifeSecond)
{
  EEPROM.write(0x03,LifeSecond);
}

void SaveChanneltoROM(RadioChannelInfo ChannelDataSave)
{
   byte RomAddress;
   byte FreqData;
   RomAddress=((ChannelDataSave.ChannelIndex-1)*8)+10;
   EEPROM.write(RomAddress,ChannelDataSave.ChannelIndex);
   EEPROM.write(RomAddress+1,ChannelDataSave.ChannelName[0]);
   EEPROM.write(RomAddress+2,ChannelDataSave.ChannelName[1]);
   EEPROM.write(RomAddress+3,ChannelDataSave.ChannelName[2]);
   EEPROM.write(RomAddress+4,ChannelDataSave.ChannelName[3]);
   EEPROM.write(RomAddress+5,ChannelDataSave.ChannelName[4]);
   FreqData=highByte(ChannelDataSave.ChannelFreq);
   EEPROM.write(RomAddress+6,FreqData);
   FreqData=lowByte(ChannelDataSave.ChannelFreq);
   EEPROM.write(RomAddress+7,FreqData);
}

void SaveRadioParametertoROM()
{
  EEPROM.write(0,NumofChannel);
  EEPROM.write(1,CurrentChannelIndex);
  if(CurrentVolume==0) CurrentVolume = 8; //Prevent from saving mute
  EEPROM.write(2,CurrentVolume);
}
void EraseAllChannelInROM()
{
  unsigned int RomAddress;
   EEPROM.write(0,0xFF);//Num of channel
   EEPROM.write(1,0);//current channel
   EEPROM.write(2,8);//Current volume
   for(RomAddress=3;RomAddress<400;RomAddress++)
  {
    EEPROM.write(RomAddress,0xFF);
  }
  
}

void RemoveChannelfromROM(byte RemoveChannelIndex)
{
  byte ChannelIndexMoving;
  RadioChannelInfo ChannelInArray;
  for(ChannelIndexMoving=RemoveChannelIndex+1;ChannelIndexMoving<=NumofChannel;ChannelIndexMoving++)// re-arrange the channel array (shift left)
  {
    ChannelInArray=GetChannelROM(ChannelIndexMoving);
    ChannelInArray.ChannelIndex=ChannelInArray.ChannelIndex-1;
    SaveChanneltoROM(ChannelInArray);
  }
  NumofChannel=NumofChannel-1;
  SaveRadioParametertoROM();
}

void LoadDefaultChannel()
{
  byte RomAddress;
  byte DataArrayIndex;
  DataArrayIndex=0;
  EEPROM.write(0x00,12); // save number of channel
  EEPROM.write(0x01,1);  // save Current channel index
  EEPROM.write(0x02,8);  // save Current volume
  EEPROM.write(0x03,5);  // save Current backlight life second
  for(RomAddress=10;RomAddress<106;RomAddress++)
  {
    EEPROM.write(RomAddress,DefaultROMDataVietnamChannel[DataArrayIndex]);
    DataArrayIndex++;
  }
  NumofChannel=12;
  CurrentChannelIndex=1;
  CurrentVolume=8;
}

RadioChannelInfo GetChannelROM(byte ChannelIndex)
{
 byte ROMAddress;
 uint16_t ROMChannelFreq;
 RadioChannelInfo ReturnChannel;

 ROMAddress=(ChannelIndex-1)*8 + 10;// 10 is ROm slot use for Num of channel, curent channel,LED backlight time and volume storage, user storage
 ReturnChannel.ChannelIndex=EEPROM.read(ROMAddress);
 ReturnChannel.ChannelName[0]=EEPROM.read(ROMAddress+1);
 ReturnChannel.ChannelName[1]=EEPROM.read(ROMAddress+2);
 ReturnChannel.ChannelName[2]=EEPROM.read(ROMAddress+3);
 ReturnChannel.ChannelName[3]=EEPROM.read(ROMAddress+4);
 ReturnChannel.ChannelName[4]=EEPROM.read(ROMAddress+5);
 ROMChannelFreq=EEPROM.read(ROMAddress+6);
 ROMChannelFreq=ROMChannelFreq<<8;
 ROMChannelFreq=ROMChannelFreq+EEPROM.read(ROMAddress+7);
 ReturnChannel.ChannelFreq=ROMChannelFreq;
 return ReturnChannel;
}

void GetLastPlayingToCurrent()
{
  NumofChannel=EEPROM.read(0x0000);
  CurrentChannelIndex=EEPROM.read(0x0001);
  CurrentVolume=EEPROM.read(0x0002);
}




void DisplayWelCome() {
  LCDDISPLAY.setCursor(4, 0);
  LCDDISPLAY.print("RADIO FM");
  LCDDISPLAY.setCursor(14, 0);
  LCDDISPLAY.write(DSignalchar);
  LCDDISPLAY.setCursor(0, 1);
  LCDDISPLAY.print("Have fun time!!!");
  delay(1000);
}


void Displaysignal(byte SignalLevelDisplay)
{
 LCDDISPLAY.setCursor(14, 0);
 LCDDISPLAY.write(DSignalchar);
 SignalLevelDisplay=SignalLevelDisplay/20;
 switch(SignalLevelDisplay)
 {
   case 0:
   {
     LCDDISPLAY.write(DSignal0);
     break;
   }
   case 1:
   {
     LCDDISPLAY.write(DSignal20);
     break;
   }
   case 2:
   {
     LCDDISPLAY.write(DSignal40);
     break;
   }
   case 3:
   {
     LCDDISPLAY.write(DSignal60);
     break;
   }
    case 4:
   {
     LCDDISPLAY.write(DSignal80);
     break;
   }
    case 5:
   {
     LCDDISPLAY.write(DSignal100);
     break;
   }
 }
}

void DisplayPlayInfo(RadioChannelInfo ChannelData,byte Voldata)
{
 byte Voldisplay;
 byte FreqDisplay;
 byte FMInfoData; //yzzzzzzz bit y=1: is station found,  zzzzzzz: RSSI data
 unsigned int RSSIData;
 byte RSSILevel;
 
 LCDDISPLAY.setCursor(0, 0);
 if(ChannelData.ChannelIndex==0xFF) LCDDISPLAY.print("SEK");
 else
   {
      LCDDISPLAY.print(ChannelData.ChannelIndex/10);
      LCDDISPLAY.print(ChannelData.ChannelIndex%10);
   }
 if(MuteVolume!=0)
 {
     Voldata=Voldata/2;  // Vol level on RDA5708M is 16 level, display in 8 level
     LCDDISPLAY.setCursor(4, 0);
     for(Voldisplay=0;Voldisplay<Voldata;Voldisplay++)
     {
        LCDDISPLAY.print("=");
     }
     for(Voldisplay=Voldata;Voldisplay<8;Voldisplay++)
     {
        LCDDISPLAY.print(" ");
     }
 }
 else
 {
  LCDDISPLAY.setCursor(4, 0);
  for(Voldisplay=0;Voldisplay<8;Voldisplay++)
     {
      LCDDISPLAY.print(" ");
     }
   LCDDISPLAY.setCursor(5, 0);
   LCDDISPLAY.print("Muted");
 }
 
  LCDDISPLAY.setCursor(0, 1);
 if(ChannelData.ChannelName[0]!=0) LCDDISPLAY.print(ChannelData.ChannelName[0]);
 else LCDDISPLAY.print(" ");
 if(ChannelData.ChannelName[1]!=0) LCDDISPLAY.print(ChannelData.ChannelName[1]);
 else LCDDISPLAY.print(" ");
 if(ChannelData.ChannelName[2]!=0) LCDDISPLAY.print(ChannelData.ChannelName[2]);
 else LCDDISPLAY.print(" ");
 if(ChannelData.ChannelName[3]!=0) LCDDISPLAY.print(ChannelData.ChannelName[3]);
 else LCDDISPLAY.print(" ");
 if(ChannelData.ChannelName[4]!=0) LCDDISPLAY.print(ChannelData.ChannelName[4]);
 else LCDDISPLAY.print(" ");
 LCDDISPLAY.print(" ");
 FreqDisplay=ChannelData.ChannelFreq/10000;
 if(FreqDisplay!=0) LCDDISPLAY.print(FreqDisplay);
 else LCDDISPLAY.print(" ");
 FreqDisplay=(ChannelData.ChannelFreq%10000)/1000;
 LCDDISPLAY.print(FreqDisplay);
 FreqDisplay=(ChannelData.ChannelFreq%1000)/100;
 LCDDISPLAY.print(FreqDisplay);
 LCDDISPLAY.print(".");
 FreqDisplay=(ChannelData.ChannelFreq%100)/10;
 LCDDISPLAY.print(FreqDisplay);
 LCDDISPLAY.noBlink();

  FMInfoData = MyRadio.GetRSSI_FMInfo();
  FMInfoData=FMInfoData & 0x7F;
  RSSIData = FMInfoData*100/127;
  RSSILevel= (byte) RSSIData;
  Displaysignal(RSSILevel);

}
  

void LCDDisplay(byte DisplayMode)
{
 switch(DisplayMode)
 {
    case NO_RADIO_FOUND:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(4, 0);
      LCDDISPLAY.print("RADIO FM");
      LCDDISPLAY.setCursor(14, 0);
      LCDDISPLAY.write(DSignalchar);
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("Cannot found RDA");
      break;
    }
    case NO_CHANNEL_FOUND:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("No Channel set");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("Pls Press Menu");
      Displaysignal(SignalLevel);
      break;
    }
    case FIRST_SETUP_SELECT:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("F1>AUTO SCAN");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("F2>LOAD VN CHAN");
      Displaysignal(SignalLevel);
      break;
    }
    case DONE_LOAD_VN_CHANNEL:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("DATA LOADED");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("Pls Press Exit");
      Displaysignal(SignalLevel);
      break;
    }
    case PLAYING:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(3, 0);
      LCDDISPLAY.print("[");
      LCDDISPLAY.setCursor(12, 0);
      LCDDISPLAY.print("]");
      LCDDISPLAY.setCursor(12, 1);
      LCDDISPLAY.print("Mhz");
      Displaysignal(SignalLevel);
      break;
    }
    case MENU_PAGE1:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("F1>PLAY by Freq");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("F2>Edit Channel");
      break;
    }
    
    case MENU_PAGE2:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("F1>Del Channel");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("F2>EraseAll Data");
      break;
    }
    
    case MENU_PAGE3:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("F1>LCD BackLight");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("F2>ReLoad VNchannel");
      break;
    }

    case ERASE_ALL:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("Erase All Data?");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("Enter to confirm");
      break;
    }
    case DONE_ERASE_ALL:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("All Data clear");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("Exit to return");
      break;
    }
     case DATA_ERASING:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("Data erasing");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("Please wait...");
      break;
    }
    case DISPLAY_CHANNEL_INFO:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("STATION FOUND: _");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("___._Mhz RS:   %");
      break;
    }

    case PLAY_BY_FREQ:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("PlayFRQ:___._Mhz");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("Vol:__ RS:   % *");
      break;
    }
    case EDIT_CHANNEL:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("Channel __ edit");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("       ___._ Mhz");
      break;
    }
    case REMOVE_CHANNEL:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("Del Channel __ ?");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("_____  ___._ Mhz");
      break;
    }
    case REMOVE_CHANNEL_DONE:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("Del Channel Done");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("Pls Press Exit");
      break;
    }
     case LOAD_DEFAULT_DATA:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("LoadDefalt Data?");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("Old Data erase?");
      break;
    }
    case SET_BACKLIGHT:
    {
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(0, 0);
      LCDDISPLAY.print("LCD Backlight __");
      LCDDISPLAY.setCursor(0, 1);
      LCDDISPLAY.print("0 sec = Alway ON");
      break;
    }
  }
}


void InceaseCharacter()
{
 if(SaveChannelName[CurrentCharacterIndex]==0) CurrentCharacter='@';
 else CurrentCharacter=SaveChannelName[CurrentCharacterIndex];
  CurrentCharacter++;
  if(CurrentCharacter=='[') CurrentCharacter=' ';
  else if(CurrentCharacter=='!') CurrentCharacter='0';
  else if(CurrentCharacter==':') CurrentCharacter='A';
  LCDDISPLAY.setCursor(CurrentCharacterIndex, 1);
  LCDDISPLAY.write(CurrentCharacter);
  LCDDISPLAY.setCursor(CurrentCharacterIndex, 1);
  SaveChannelName[CurrentCharacterIndex]=CurrentCharacter;
}

void DecreaseCharacter()
{
  if(SaveChannelName[CurrentCharacterIndex]==0) CurrentCharacter='B';
  else CurrentCharacter=SaveChannelName[CurrentCharacterIndex];
  CurrentCharacter--;
  if(CurrentCharacter=='/') CurrentCharacter=' ';
  else if(CurrentCharacter==31) CurrentCharacter='Z';
  else if(CurrentCharacter=='@') CurrentCharacter='9';
  LCDDISPLAY.setCursor(CurrentCharacterIndex, 1);
  LCDDISPLAY.write(CurrentCharacter);
  LCDDISPLAY.setCursor(CurrentCharacterIndex, 1);
  SaveChannelName[CurrentCharacterIndex]=CurrentCharacter;
}

void DisplaySaveChannel()
{
 byte SaveChannelIndex;
 SaveChannelIndex=NumofChannel+1;
 
 LCDDISPLAY.setCursor(0, 0);
 LCDDISPLAY.print("   ");
 LCDDISPLAY.setCursor(0, 0);
 LCDDISPLAY.print(SaveChannelIndex/10);
 LCDDISPLAY.print(SaveChannelIndex%10);
 LCDDISPLAY.setCursor(CurrentCharacterIndex, 1);
 LCDDISPLAY.blink();
 InceaseCharacter();
}


void PlayFM(RadioChannelInfo RadioData,byte VolumeData)
{

  CurrentState=PLAYING;
  LCDDISPLAY.clear();
  CurrentVolume=VolumeData;
  LCDDisplay(CurrentState);
  //Play Freq command here
  MyRadio.SetFrequency(RadioData.ChannelFreq,CurrentVolume-1);
  DisplayPlayInfo(RadioData,VolumeData);
}

void PlaybyFreq(unsigned FreqPlay) // ussing for play by Freq
{
   byte FreqDisplay;
   byte FMInfoData; //yzzzzzzz bit y=1: is station found,  zzzzzzz: RSSI data
   unsigned int RSSIData;
   byte RSSILevel;
   MyRadio.SetFrequency(FreqPlay,CurrentVolume-1);
   delay(100);
   FMInfoData = MyRadio.GetRSSI_FMInfo();
   
   LCDDISPLAY.setCursor(4, 1);
   LCDDISPLAY.print(CurrentVolume/10);
   LCDDISPLAY.print(CurrentVolume%10);

   LCDDISPLAY.setCursor(15, 1);
   if(bitRead(FMInfoData,7)==0) LCDDISPLAY.print(" ");
   else LCDDISPLAY.print("*");
  
   FMInfoData=FMInfoData & 0x7F;
   RSSIData = FMInfoData*100/127;
   RSSILevel= (byte) RSSIData;
   if(RSSILevel>99) LCDDISPLAY.setCursor(10, 1);
   else LCDDISPLAY.setCursor(11, 1);
   LCDDISPLAY.print(RSSILevel);
   
   LCDDISPLAY.setCursor(8, 0);
   FreqDisplay=FreqPlay/10000;
   if(FreqDisplay!=0) LCDDISPLAY.print(FreqDisplay);
   else LCDDISPLAY.print(" ");
   FreqDisplay=(FreqPlay%10000)/1000;
   LCDDISPLAY.print(FreqDisplay);
   FreqDisplay=(FreqPlay%1000)/100;
   LCDDISPLAY.print(FreqDisplay);
   LCDDISPLAY.print(".");
   FreqDisplay=(FreqPlay%100)/10;
   LCDDISPLAY.print(FreqDisplay);
   
   if(FreqMode10x==true)
   {
     LCDDISPLAY.setCursor(10, 0);
     LCDDISPLAY.blink();
   }
   else
   {
     LCDDISPLAY.setCursor(12, 0);
     LCDDISPLAY.blink();
   }
}

void  DisplaySaveFrequency()
{ 
      byte FreqDisplay;
      LCDDISPLAY.clear();
      LCDDISPLAY.setCursor(3, 0);
      LCDDISPLAY.print("Save Channel  ");
      LCDDISPLAY.setCursor(12, 1);
      LCDDISPLAY.print(" Mhz");
      LCDDISPLAY.setCursor(7, 1);
       FreqDisplay=CurrentFreq/10000;
       if(FreqDisplay!=0) LCDDISPLAY.print(FreqDisplay);
       else LCDDISPLAY.print(" ");
       FreqDisplay=(CurrentFreq%10000)/1000;
       LCDDISPLAY.print(FreqDisplay);
       FreqDisplay=(CurrentFreq%1000)/100;
       LCDDISPLAY.print(FreqDisplay);
       LCDDISPLAY.print(".");
       FreqDisplay=(CurrentFreq%100)/10;
       LCDDISPLAY.print(FreqDisplay);
  
}

void IncreaseFreqPlay() // ussing for play by Freq
{
  if(FreqMode10x==true) CurrentFreq=CurrentFreq+100;
  else CurrentFreq=CurrentFreq+10;
  if(CurrentFreq>MyRadio.MaxFreq) CurrentFreq=MyRadio.MaxFreq;
  PlaybyFreq(CurrentFreq);
}


void DecreaseFreqPlay() // ussing for play by Freq
{
  if(FreqMode10x==true) CurrentFreq=CurrentFreq-100;
  else CurrentFreq=CurrentFreq-10;
  if(CurrentFreq<MyRadio.MinFreq) CurrentFreq=MyRadio.MinFreq;
  PlaybyFreq(CurrentFreq);
}

void ChangeFreqTurn()
{
  if(FreqMode10x==true)
  {
    FreqMode10x=false;
    LCDDISPLAY.setCursor(12, 0);
  }
  else
  {
    FreqMode10x=true;
    LCDDISPLAY.setCursor(10, 0); 
  }
}


void StopPlayFM()
{
  // Stop play FM here
  MyRadio.ResetChip();
}

void DisplayFMInfo()
{
 byte FMInfoData; //yzzzzzzz bit y=1: is station found,  zzzzzzz: RSSI data
 unsigned int RSSIData;
 byte RSSILevel;
 byte FreqDisplay;
 unsigned int FreqData;
 FMInfoData = MyRadio.GetRSSI_FMInfo();
 FreqData = MyRadio.GetFrequency();
 
 LCDDISPLAY.setCursor(15, 0);
 if(bitRead(FMInfoData,7)==0) LCDDISPLAY.print("N");
 else LCDDISPLAY.print("Y");

 FMInfoData=FMInfoData & 0x7F;
 RSSIData = FMInfoData*100/127;
 RSSILevel= (byte) RSSIData;
 if(RSSILevel>99) LCDDISPLAY.setCursor(12, 1);
 else LCDDISPLAY.setCursor(13, 1);
 LCDDISPLAY.print(RSSILevel);

 
 LCDDISPLAY.setCursor(0, 1);
 FreqDisplay=FreqData/10000;
 if(FreqDisplay!=0) LCDDISPLAY.print(FreqDisplay);
 else LCDDISPLAY.print(" ");
 FreqDisplay=(FreqData%10000)/1000;
 LCDDISPLAY.print(FreqDisplay);
 FreqDisplay=(FreqData%1000)/100;
 LCDDISPLAY.print(FreqDisplay);
 LCDDISPLAY.print(".");
 FreqDisplay=(FreqData%100)/10;
 LCDDISPLAY.print(FreqDisplay);
 LCDDISPLAY.noBlink();
   
}

void PlayNextChannel()
{
  if(NumofChannel>0)
  {
   CurrentChannelIndex++;
   if(CurrentChannelIndex>NumofChannel) CurrentChannelIndex =1;
   CurrentChannelInfo=GetChannelROM(CurrentChannelIndex);
   PlayFM(CurrentChannelInfo,CurrentVolume);
   SaveRadioParametertoROM();
  }
}

void PlayPrevChannel()
{
  if(NumofChannel>0)
  {
   CurrentChannelIndex--;
   if(CurrentChannelIndex<1) CurrentChannelIndex = NumofChannel;
   CurrentChannelInfo=GetChannelROM(CurrentChannelIndex);
   PlayFM(CurrentChannelInfo,CurrentVolume);
   SaveRadioParametertoROM();
  }
}

void IncVol()
{
  CurrentVolume++;
  if(CurrentVolume>16) CurrentVolume=16;
  MuteVolume=CurrentVolume; // unmute if muted
  SaveRadioParametertoROM();
  // Increase volume here
  MyRadio.SetVolume(CurrentVolume-1);
  if(CurrentState==PLAY_BY_FREQ) // when play by Freq
  {
    LCDDISPLAY.setCursor(4, 1);
    LCDDISPLAY.print(CurrentVolume/10);
    LCDDISPLAY.print(CurrentVolume%10);
    if(FreqMode10x==true) LCDDISPLAY.setCursor(10, 0);
    else LCDDISPLAY.setCursor(12, 0);
  }
  else
  {
     DisplayPlayInfo(CurrentChannelInfo,CurrentVolume); // when play by SEEK, CHANNEL
  }

  
}
void DecVol()
{
  CurrentVolume--;
  if(CurrentVolume<1) CurrentVolume=1;
  MuteVolume=CurrentVolume;//unmute if muted
  SaveRadioParametertoROM();
  // Decrease volume here
  MyRadio.SetVolume(CurrentVolume-1);

   if(CurrentState==PLAY_BY_FREQ)  // when play by Freq
  {
    LCDDISPLAY.setCursor(4, 1);
    LCDDISPLAY.print(CurrentVolume/10);
    LCDDISPLAY.print(CurrentVolume%10);
    if(FreqMode10x==true) LCDDISPLAY.setCursor(10, 0);
    else LCDDISPLAY.setCursor(12, 0);
  }
  
  else // when play by SEEK, CHANNEL
  {
     DisplayPlayInfo(CurrentChannelInfo,CurrentVolume);
  }
}

void Mute_Unmute()
{

 if(CurrentState==PLAY_BY_FREQ) // when play by Freq
 {
      if(MuteVolume==0)
      {
        MuteVolume=CurrentVolume;
        MyRadio.SetMute(false);
        LCDDISPLAY.setCursor(4, 1);
        LCDDISPLAY.print(CurrentVolume/10);
        LCDDISPLAY.print(CurrentVolume%10);
        if(FreqMode10x==true) LCDDISPLAY.setCursor(10, 0);
        else LCDDISPLAY.setCursor(12, 0);

      }
      else
      {
        MuteVolume=0;
        MyRadio.SetMute(true);
        LCDDISPLAY.setCursor(4, 1);
        LCDDISPLAY.print("--");
        if(FreqMode10x==true) LCDDISPLAY.setCursor(10, 0);
        else LCDDISPLAY.setCursor(12, 0);
      }
      
 }
 else // when play by SEEK, CHANNEL
 {
  if(MuteVolume==0)
      {
        MuteVolume=CurrentVolume;
        DisplayPlayInfo(CurrentChannelInfo,CurrentVolume);
        //Set mute here
        MyRadio.SetMute(false);
      }
      else
      {
        MuteVolume=0;
        DisplayPlayInfo(CurrentChannelInfo,CurrentVolume);
        //Set unmute here
        MyRadio.SetMute(true);
      }
 }

 
}

void SeekChannel()
{
  unsigned int GetFreq;
  CurrentChannelInfo.ChannelIndex=0xFF;
  CurrentChannelInfo.ChannelName[0]='_';
  CurrentChannelInfo.ChannelName[1]='_';
  CurrentChannelInfo.ChannelName[2]='_';
  CurrentChannelInfo.ChannelName[3]='_';
  CurrentChannelInfo.ChannelName[4]='_';
  //Seek up channel here
  MyRadio.SeekUp();
  GetFreq=MyRadio.GetFrequency();
  CurrentChannelInfo.ChannelFreq=GetFreq;
  CurrentFreq=CurrentChannelInfo.ChannelFreq;
  DisplayPlayInfo(CurrentChannelInfo,CurrentVolume);
  LCDDISPLAY.noBlink();
}


void SaveChannel()
{
  CurrentChannelInfo.ChannelIndex=NumofChannel;
  NumofChannel++;
  CurrentChannelIndex=NumofChannel;
  CurrentChannelInfo.ChannelIndex=NumofChannel;
  CurrentChannelInfo.ChannelName[0]=SaveChannelName[0];
  CurrentChannelInfo.ChannelName[1]=SaveChannelName[1];
  CurrentChannelInfo.ChannelName[2]=SaveChannelName[2];
  CurrentChannelInfo.ChannelName[3]=SaveChannelName[3];
  CurrentChannelInfo.ChannelName[4]=SaveChannelName[4];
  CurrentChannelInfo.ChannelFreq=CurrentFreq;
  SaveChanneltoROM(CurrentChannelInfo);
  SaveRadioParametertoROM();
}

void UpdateChannel()
{
 CurrentChannelInfo.ChannelIndex=CurrentChannelIndex;
 CurrentChannelInfo.ChannelName[0]=SaveChannelName[0];
 CurrentChannelInfo.ChannelName[1]=SaveChannelName[1];
 CurrentChannelInfo.ChannelName[2]=SaveChannelName[2];
 CurrentChannelInfo.ChannelName[3]=SaveChannelName[3];
 CurrentChannelInfo.ChannelName[4]=SaveChannelName[4];
 CurrentChannelInfo.ChannelFreq=CurrentFreq;
 SaveChanneltoROM(CurrentChannelInfo);
 SaveRadioParametertoROM();
  
}

void EditChannel()
{
  byte FreqDisplay;
 RadioChannelInfo ChannelInfo;
 
 ChannelInfo = GetChannelROM(CurrentChannelIndex);
 SaveChannelName[0]=ChannelInfo.ChannelName[0];
 SaveChannelName[1]=ChannelInfo.ChannelName[1];
 SaveChannelName[2]=ChannelInfo.ChannelName[2];
 SaveChannelName[3]=ChannelInfo.ChannelName[3];
 SaveChannelName[4]=ChannelInfo.ChannelName[4];
 
 
 LCDDISPLAY.setCursor(8, 0);
 LCDDISPLAY.print(CurrentChannelIndex/10);
 LCDDISPLAY.print(CurrentChannelIndex%10);
 LCDDISPLAY.setCursor(0, 1);
 LCDDISPLAY.print(SaveChannelName);
 
 LCDDISPLAY.setCursor(7, 1);
 CurrentFreq=ChannelInfo.ChannelFreq;
 FreqDisplay=CurrentFreq/10000;
 if(FreqDisplay!=0) LCDDISPLAY.print(FreqDisplay);
 else LCDDISPLAY.print(" ");
 FreqDisplay=(CurrentFreq%10000)/1000;
 LCDDISPLAY.print(FreqDisplay);
 FreqDisplay=(CurrentFreq%1000)/100;
 LCDDISPLAY.print(FreqDisplay);
 LCDDISPLAY.print(".");
 FreqDisplay=(CurrentFreq%100)/10;
 LCDDISPLAY.print(FreqDisplay);

 LCDDISPLAY.setCursor(0, 1);
 LCDDISPLAY.blink();
 CurrentCharacterIndex=0;
 CurrentCharacter=SaveChannelName[CurrentCharacterIndex];
}

void DisplayRemoveChannel()
{
      byte FreqDisplay;
      CurrentChannelInfo=GetChannelROM(CurrentChannelIndex);
      LCDDISPLAY.setCursor(12, 0);
      LCDDISPLAY.print(CurrentChannelIndex/10);
      LCDDISPLAY.print(CurrentChannelIndex%10);
      LCDDISPLAY.setCursor(0, 1);
       if(CurrentChannelInfo.ChannelName[0]!=0) LCDDISPLAY.print(CurrentChannelInfo.ChannelName[0]);
       else LCDDISPLAY.print(" ");
       if(CurrentChannelInfo.ChannelName[1]!=0) LCDDISPLAY.print(CurrentChannelInfo.ChannelName[1]);
       else LCDDISPLAY.print(" ");
       if(CurrentChannelInfo.ChannelName[2]!=0) LCDDISPLAY.print(CurrentChannelInfo.ChannelName[2]);
       else LCDDISPLAY.print(" ");
       if(CurrentChannelInfo.ChannelName[3]!=0) LCDDISPLAY.print(CurrentChannelInfo.ChannelName[3]);
       else LCDDISPLAY.print(" ");
       if(CurrentChannelInfo.ChannelName[4]!=0) LCDDISPLAY.print(CurrentChannelInfo.ChannelName[4]);
       else LCDDISPLAY.print(" ");
       LCDDISPLAY.print(" ");

       LCDDISPLAY.setCursor(7, 1);
       CurrentFreq=CurrentChannelInfo.ChannelFreq;
       FreqDisplay=CurrentFreq/10000;
       if(FreqDisplay!=0) LCDDISPLAY.print(FreqDisplay);
       else LCDDISPLAY.print(" ");
       FreqDisplay=(CurrentFreq%10000)/1000;
       LCDDISPLAY.print(FreqDisplay);
       FreqDisplay=(CurrentFreq%1000)/100;
       LCDDISPLAY.print(FreqDisplay);
       LCDDISPLAY.print(".");
       FreqDisplay=(CurrentFreq%100)/10;
       LCDDISPLAY.print(FreqDisplay);

      LCDDISPLAY.setCursor(13, 0);
      LCDDISPLAY.blink();
}

void DisplaySetBackLight()
{
      
      LCDDISPLAY.setCursor(14, 0);
      LCDDISPLAY.print(CurrentBacklightLife/10);
      LCDDISPLAY.print(CurrentBacklightLife%10);
      LCDDISPLAY.setCursor(15, 0);
      LCDDISPLAY.blink();
}



byte CheckButton(bool ActiveLevel)
{
 unsigned long CurrentTimecount;
 unsigned long PreviousTimecount;
 const unsigned long Buttonholdtime=500;
 byte Checkresult;
 bool TimeOver;
 Checkresult = NO_BUTTON_PRESS;

 if(digitalRead(BMenu)==ActiveLevel) // Button was press.
 {
    ActiveBackLight();   
    delay(200); // debounce button
    PreviousTimecount=millis();
    TimeOver=false;
    while(digitalRead(BMenu)==ActiveLevel && TimeOver==false)// Wait until button release
    {
    CurrentTimecount=millis();
    if(CurrentTimecount-PreviousTimecount>Buttonholdtime)  TimeOver=true;
    }
    if(TimeOver==true)
    { 
      Checkresult = MENU_LONG_PRESS; 
      ButtonHolding=true;
    }
    else if(ButtonHolding==false) Checkresult = MENU_SHORT_PRESS; // First press after release
    
 }
 else if(digitalRead(BUp)==ActiveLevel) // Button was press.
 {
    ActiveBackLight();
    delay(200); // debounce button
    PreviousTimecount=millis();
    TimeOver=false;
    while(digitalRead(BUp)==ActiveLevel && TimeOver==false)// Wait until button release
    {
        CurrentTimecount=millis();
        if(CurrentTimecount-PreviousTimecount>Buttonholdtime)  TimeOver=true;
    }
    if(TimeOver==true)
    { 
      Checkresult = UP_LONG_PRESS; 
      ButtonHolding=true;
    }
    else if(ButtonHolding==false) Checkresult = UP_SHORT_PRESS; // First press after release
 }
 else if(digitalRead(BDown)==ActiveLevel) // Button was press.
 {
    ActiveBackLight();
    delay(200); // debounce button
    PreviousTimecount=millis();
    TimeOver=false;
    while(digitalRead(BDown)==ActiveLevel && TimeOver==false)// Wait until button release
    {
        CurrentTimecount=millis();
        if(CurrentTimecount-PreviousTimecount>Buttonholdtime)  TimeOver=true;
    }
    if(TimeOver==true)
    { 
       Checkresult = DOWN_LONG_PRESS; 
       ButtonHolding=true;
    }
    else if(ButtonHolding==false) Checkresult = DOWN_SHORT_PRESS; // First press after release
  }
 else if(digitalRead(BEnter)==ActiveLevel) // Button was press.
 {
    ActiveBackLight();
    delay(200); // debounce button
    PreviousTimecount=millis();
    TimeOver=false;
    while(digitalRead(BEnter)==ActiveLevel && TimeOver==false)// Wait until button release
    {
      CurrentTimecount=millis();
      if(CurrentTimecount-PreviousTimecount>Buttonholdtime)  TimeOver=true;
    }
    if(TimeOver==true)
    { 
      Checkresult = ENTER_LONG_PRESS; 
      ButtonHolding=true;
    }
    else if(ButtonHolding==false) Checkresult = ENTER_SHORT_PRESS; // First press after release
 }
 else ButtonHolding=false; // No button pressed. release holding variable
 return Checkresult;
}



void ProcessButton(byte ButtonData,byte CurrentStateData)
{
  
   switch(ButtonData)
   {
     case MENU_SHORT_PRESS:
     {
      switch(CurrentStateData)
      {
        case NO_CHANNEL_FOUND:
        {
          CurrentState=FIRST_SETUP_SELECT;
          LCDDisplay(CurrentState);
          break;
        }
        case DONE_LOAD_VN_CHANNEL: case REMOVE_CHANNEL_DONE:
        {
          CurrentChannelInfo=GetChannelROM(CurrentChannelIndex);
          PlayFM(CurrentChannelInfo,CurrentVolume);
          break;
        }
        
        case SEEKING:
        {
         CurrentState=SAVE_CHANNEL_SEEK;
         CurrentCharacterIndex=0;
         SaveChannelName[0]=0;
         SaveChannelName[1]=0;
         SaveChannelName[2]=0;
         SaveChannelName[3]=0;
         SaveChannelName[4]=0;
         DisplaySaveChannel();
         break;
        }
        case PLAY_BY_FREQ:
        {
           DisplaySaveFrequency();
           CurrentState=SAVE_CHANNEL_FREQ;
           CurrentCharacterIndex=0;
           SaveChannelName[0]=0;
           SaveChannelName[1]=0;
           SaveChannelName[2]=0;
           SaveChannelName[3]=0;
           SaveChannelName[4]=0;
           DisplaySaveChannel();
          break;
        }
         case SAVE_CHANNEL_SEEK: case SAVE_CHANNEL_FREQ:
        {
         SaveChannel();
         CurrentState=PLAYING;
         CurrentChannelIndex--;
         PlayNextChannel();
         break;
        }
        case EDIT_CHANNEL:
        {
           UpdateChannel();
           CurrentState=PLAYING;
           CurrentChannelIndex--;
           PlayNextChannel();
          break;
        }
        case PLAYING:
        {
          StopPlayFM();
          CurrentState=MENU_PAGE1;
          LCDDisplay(CurrentState);
          break;
        }
         case MENU_PAGE1:
        {
          CurrentState=MENU_PAGE2;
          LCDDisplay(CurrentState);
          break;
        }

        case MENU_PAGE2:
        {
          CurrentState=MENU_PAGE3;
          LCDDisplay(CurrentState);
          break;
        }

        case MENU_PAGE3:
        {
          CurrentState=PLAYING;
          CurrentChannelIndex--;
          PlayNextChannel();
          break;
        }
        case DONE_ERASE_ALL:
        {
          CurrentState=NO_CHANNEL_FOUND;
          LCDDisplay(CurrentState);
          break;
        }
      }
      break;
     }
     
     case MENU_LONG_PRESS:
     {
        switch(CurrentStateData)
      {
        case SAVE_CHANNEL_SEEK:
        {
        DisplayPlayInfo(CurrentChannelInfo,CurrentVolume);
        LCDDISPLAY.noBlink();
        CurrentState=SEEKING;
        break;
        }
        case SAVE_CHANNEL_FREQ:
        {
          CurrentState=PLAY_BY_FREQ;
          LCDDisplay(CurrentState);
          PlaybyFreq(CurrentFreq);
          break;
        }
        case EDIT_CHANNEL:
        {
           CurrentState=PLAYING;
           CurrentChannelIndex--;
           PlayNextChannel();
           break;
        }
        case MENU_PAGE1: case MENU_PAGE2: case MENU_PAGE3: case LOAD_DEFAULT_DATA: case SET_BACKLIGHT:
        {
          PlayFM(CurrentChannelInfo,CurrentVolume);
          CurrentState=PLAYING;
          break;
        }
        case PLAYING: case SEEKING:
        {
          LastState=CurrentState;
          CurrentState=DISPLAY_CHANNEL_INFO;
          LCDDisplay(CurrentState);
          DisplayFMInfo();
          break;
        }
        case DISPLAY_CHANNEL_INFO:
        {
          CurrentState=LastState;
          LCDDisplay(PLAYING);
          DisplayPlayInfo(CurrentChannelInfo,CurrentVolume);
          break;
        }
        case PLAY_BY_FREQ:
        {
          CurrentChannelIndex--;
          PlayNextChannel();
          break;
        }
      }
      break;
     }
     
     case UP_SHORT_PRESS:
     {
      switch(CurrentStateData)
      {
        case FIRST_SETUP_SELECT:
        {
          CurrentState=PLAYING;
          CurrentVolume=8;
          NumofChannel=0;
          CurrentChannelIndex=0;
          SaveRadioParametertoROM();
          LCDDisplay(CurrentState);
          CurrentState=SEEKING;
          SeekChannel();
          break;
        }
       case PLAYING: case SEEKING:
        {
          PlayNextChannel();
          break;
        }

        case SAVE_CHANNEL_SEEK: case EDIT_CHANNEL: case SAVE_CHANNEL_FREQ:
        {
          InceaseCharacter();
          break;
        }
        case MENU_PAGE1:
        {
          CurrentState = PLAY_BY_FREQ;
          FreqMode10x=false;
          LCDDisplay(CurrentState);
          CurrentFreq=MyRadio.MinFreq;// Lowest FM Freq
          PlaybyFreq(CurrentFreq);
          
          break;
        }
        
        case MENU_PAGE2:
        {
          CurrentState = REMOVE_CHANNEL;
          LCDDisplay(CurrentState);
          DisplayRemoveChannel();
          
          break;
        }
        case MENU_PAGE3:
        {
          CurrentState = SET_BACKLIGHT;
          LCDDisplay(CurrentState);
          DisplaySetBackLight();
          break;
        }
   
        case PLAY_BY_FREQ:
        {
          IncreaseFreqPlay();
          break;
        }

        case REMOVE_CHANNEL:
        {
          CurrentChannelIndex++;
          if(CurrentChannelIndex>NumofChannel) CurrentChannelIndex=1;
          DisplayRemoveChannel();
          break;
        }
        case SET_BACKLIGHT:
        {
          CurrentBacklightLife++;
          if(CurrentBacklightLife>15) CurrentBacklightLife=15;
          DisplaySetBackLight();
          break;
        }
      }
      break;
     }
     
     case UP_LONG_PRESS:
     {
      switch(CurrentStateData)
      {
        case PLAYING: case SEEKING: case PLAY_BY_FREQ:
        {
          IncVol();
          break;
        }
      }
      break;
     }

     case DOWN_SHORT_PRESS:
     {
      switch(CurrentStateData)
      {
       case FIRST_SETUP_SELECT:
        {
          LoadDefaultChannel();
          CurrentState=DONE_LOAD_VN_CHANNEL;
          LCDDisplay(CurrentState);
          break;
        }
        case PLAYING: case SEEKING:
        {
          PlayPrevChannel();
          break;
        }
        case SAVE_CHANNEL_SEEK: case EDIT_CHANNEL: case SAVE_CHANNEL_FREQ:
        {
          DecreaseCharacter();
          break;
        }
         case MENU_PAGE1:
        {
          CurrentState=EDIT_CHANNEL;
          LCDDisplay(CurrentState);
          CurrentCharacterIndex=0;
          EditChannel();
          break;
        }
        case MENU_PAGE2:
        {
          CurrentState=ERASE_ALL;
          LCDDisplay(CurrentState);
          break;
        }

        case MENU_PAGE3:
        {
           CurrentState=LOAD_DEFAULT_DATA;
           LCDDisplay(CurrentState);
           break;
        }

        case PLAY_BY_FREQ:
        {
          DecreaseFreqPlay();
          break;
        }

         case REMOVE_CHANNEL:
        {
          CurrentChannelIndex--;
          if(CurrentChannelIndex==0) CurrentChannelIndex=NumofChannel;
          DisplayRemoveChannel();
          break;
        }

        case SET_BACKLIGHT:
        {
          CurrentBacklightLife--;
          if(CurrentBacklightLife==255) CurrentBacklightLife=0;
          DisplaySetBackLight();
          break;
        } 
      }
      break;
     }

     case DOWN_LONG_PRESS:
     {
      switch(CurrentStateData)
      {
       case PLAYING: case SEEKING: case PLAY_BY_FREQ:
        {
          DecVol();
          break;
        }
      }
      break;
     }

     case ENTER_SHORT_PRESS:
     {
      switch(CurrentStateData)
      {
        case PLAYING: case SEEKING: case PLAY_BY_FREQ: 
        {
          Mute_Unmute();
          break;
        }
        case SAVE_CHANNEL_SEEK: 
        {
          CurrentCharacterIndex++;
          if(CurrentCharacterIndex==5) CurrentCharacterIndex=0;
          DisplaySaveChannel();
          break;
        }
        case EDIT_CHANNEL: case SAVE_CHANNEL_FREQ:
        {
          CurrentCharacterIndex++;
          if(CurrentCharacterIndex==5) CurrentCharacterIndex=0;
          LCDDISPLAY.setCursor(CurrentCharacterIndex, 1);
          break;
        }
        case ERASE_ALL:
        {
          CurrentState=DATA_ERASING;
          LCDDisplay(CurrentState);
          EraseAllChannelInROM();
          CurrentState=DONE_ERASE_ALL;
          LCDDisplay(CurrentState);
          break;
        }
        case REMOVE_CHANNEL:
        {
          RemoveChannelfromROM(CurrentChannelIndex);
          CurrentState=REMOVE_CHANNEL_DONE;
          LCDDisplay(CurrentState);
          CurrentChannelIndex--;
          break;
        }
        case LOAD_DEFAULT_DATA:
        {
          LoadDefaultChannel();
          CurrentState=DONE_LOAD_VN_CHANNEL;
          LCDDisplay(CurrentState);
          break;
        }
        case SET_BACKLIGHT:
        {
          WriteCurrentBackLightLife(CurrentBacklightLife);
          PlayFM(CurrentChannelInfo,CurrentVolume);
          CurrentState=PLAYING;
          break;
        }
      }
      break;
     }

     case ENTER_LONG_PRESS:
     {
      switch(CurrentStateData)
      {
        case PLAYING: case SAVE_CHANNEL_SEEK: case SEEKING:
        {
          CurrentState=SEEKING;
          SeekChannel();
          break;
        }
        case PLAY_BY_FREQ:
        {
          ChangeFreqTurn();
          break;
        }
      }
      break;
     }
   }
}
void ActiveBackLight()
{
  ONLCDLED;
  BackLighOnpoint=millis();
}

void CheckBackLightLife()
{
  unsigned int CurrentTimePoint;
  if(CurrentBacklightLife>0)
  {
    CurrentTimePoint=millis();
    if(CurrentTimePoint-BackLighOnpoint>(CurrentBacklightLife*1000))
    {
      OFFLCDLED;
    }
  }
}


void setup() {
  pinMode(BMenu,INPUT_PULLUP);
  pinMode(BEnter,INPUT_PULLUP);
  pinMode(BUp,INPUT_PULLUP);
  pinMode(BDown,INPUT_PULLUP);
  pinMode(LCDBackLight,OUTPUT);
  ONLCDLED;
  BackLighOnpoint=millis();
  
  LCDDISPLAY.createChar(0, SignalChar);
  LCDDISPLAY.createChar(1, Signal100);
  LCDDISPLAY.createChar(2, Signal80);
  LCDDISPLAY.createChar(3, Signal60);
  LCDDISPLAY.createChar(4, Signal40);
  LCDDISPLAY.createChar(5, Signal20);
  LCDDISPLAY.createChar(6, Signal0);
  LCDDISPLAY.createChar(7, Playsign);
  LCDDISPLAY.begin(16,2);
  Serial.begin(9600);
  DisplayWelCome();
  ButtonHolding=false;
  MuteVolume=1;
  RadioFound = MyRadio.Radioinit(); // Return to true if found RDA5807M chips. else, return false.
  if(RadioFound==false)
  {
    CurrentState=NO_RADIO_FOUND;
    LCDDisplay(CurrentState);
   }
  else
  {
    //EEPROM.write(0x0000,0xFF);
    NumofChannel=EEPROM.read(0x0000);
    if(NumofChannel>200 or NumofChannel==0) // Max storage is 200 channel. if greater than 200 mean no data
     {
      ChannelDefined=false; // not yet found channel save in ROM.
      CurrentState=NO_CHANNEL_FOUND;
      LCDDisplay(CurrentState);
      }
    else 
    {
      ChannelDefined=true; //Found channel as found number of channel at 0x0000 ROM
      GetLastPlayingToCurrent();
      CurrentChannelInfo=GetChannelROM(CurrentChannelIndex);
      PlayFM(CurrentChannelInfo,CurrentVolume);
    }
  }

  CurrentBacklightLife=ReadCurrentBackLightLife();
  if(CurrentBacklightLife>15) 
  {CurrentBacklightLife=5;
   WriteCurrentBackLightLife(CurrentBacklightLife);
  }
}

void loop() 
{
   byte CheckButtonResult;
   CheckButtonResult=CheckButton(ACTIVE_HIGH);
   ProcessButton(CheckButtonResult,CurrentState);
   CheckBackLightLife();
 }
 
RADIO_RDA5807M_VN.zipC/C++
Library for RDA5807M
No preview (download only).

Schematics

Schematic
Radio fm nano bb 8ot1qsswiy

Comments

Similar projects you might like

Touch Less Touch Switch - A touch alternative UI

Project tutorial by Jithesh Thulasidharan

  • 2,863 views
  • 2 comments
  • 7 respects

JeePioneer Radio Control

Project tutorial by Scott Paul

  • 3,216 views
  • 2 comments
  • 5 respects

Control TV Using A Touch Remote

Project tutorial by Rahul Khanna D

  • 2,524 views
  • 2 comments
  • 9 respects

Servo Control with TV Remote Control

Project showcase by eldo85

  • 23,450 views
  • 8 comments
  • 46 respects

A Remote Controlled Stereo Volume Control

Project showcase by Keith Walker

  • 14,146 views
  • 1 comment
  • 12 respects

DIY Si4730 All Band Radio (LW, MW, SW, FM)

Project tutorial by Mirko Pavleski

  • 51,021 views
  • 12 comments
  • 80 respects
Add projectSign up / Login