Hackster is hosting Impact Spotlights highlighting smart energy storage. Start streaming on Thursday!Stream Impact Spotlights on Thursday!
xuansangdanggalaxy
Published © LGPL

Make Radio with touch control by RDA5807M

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

IntermediateShowcase (no instructions)13,727
Make Radio with touch control by RDA5807M

Things used in this project

Hardware components

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

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Schematic

Code

NANOFMRADIO.ino

Arduino
/*
 * 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.zip

C/C++
Library for RDA5807M
No preview (download only).

Credits

xuansangdanggalaxy

xuansangdanggalaxy

0 projects • 0 followers

Comments