RDA5807M FM RDS radio using the Gecko Segment LCD display. PC serial is used to display the RDS text on a pc terminal program if required (115200 baud). The two press buttons to tune up or down, touch slider to change volume. Top numeric displays frequency, bottom alpha displays station name. Ring segment displays signal level, antenna segment indicates stereo received.

Dependencies:   EFM32_CapSenseSlider EFM32_SegmentLCD RDA5807M mbed-src

main.cpp

Committer:
star297
Date:
2015-06-19
Revision:
4:3bf9d70a48c8
Parent:
3:1220287bcbd7

File content as of revision 4:3bf9d70a48c8:

/*
RDA5807M FM RDS Radio using the EFM32 Gecko Segment LCD
RDS information is displayed using a PC terminal
 
Use:
switches PB0 and PB1 for frequency search
Volume controlled by the Touch Slider
Indicators: 
Signal level - Ring Segement Display
Stereo received - Antenna Segment Display
RDS available - LED0
*/
 
#include "mbed.h"
#include "RDA5807M.h"
#include "EFM32_SegmentLCD.h"
#include "EFM32_CapSenseSlider.h"
 
 
RDA5807M radio(PC4, PC5);   // sda - scl
 
Serial pc(USBTX, USBRX);
 
InterruptIn scan_up(SW1);
InterruptIn scan_down(SW0); 
 
DigitalOut led1(LED1);
DigitalOut led0(LED0);
 
silabs::EFM32_SegmentLCD segmentDisplay;
silabs::EFM32_CapSenseSlider capSlider;
LowPowerTimeout wakeup;
 
Timer t1;
 
int x,n,i,l,wake,signal,lastsignal,volume,laststereo;
float lastfreq;
char Station[10],lastStationName[10],vol[4],lastCT[12];
char RDStxt[70],RDStxt1[70],RDStxt2[70],text1[70],lasttext1[70],text2[70],lasttext2[70];
 
void displayrefresh(),getrds(),RTrefresh();
 
void scan_upIRQ() {
    radio.SeekUp(); 
}  
 
void scan_downIRQ() {
    radio.SeekDown();    
}

void callback(void) {
    wake = 1;
}
 
void slideCallback(void) {
    volume = capSlider.get_position()/3;        
    if(volume > 15){volume = 15;}
    if(volume < 0){volume = 0;}  
    radio.Volume(volume);
    sprintf(vol,"Vol %d", volume);
    segmentDisplay.Write(vol);
    t1.reset();t1.start();  
}  
 
int main() { 
 
    radio.Reset();      // reset and power up radio chip 
    segmentDisplay.Write("RdA5807");
    wait(1); 
    segmentDisplay.Write("RDS FM");
    wait(1);
    segmentDisplay.Write("Radio");    
    capSlider.start();
    capSlider.attach_slide(-1, slideCallback);   
    scan_up.fall(scan_upIRQ);     
    scan_down.rise(scan_downIRQ); 
    wait(1);     
    
    while(1){    
        radio.ProcessData();
        displayrefresh();
        getrds();
        if(t1.read()>3){strcpy(lastStationName," ");t1.stop();} 
        wait_ms(1);
        wakeup.attach(callback, 0.05f);  // MCU average power now 1mA
        wake = 0;
        while(!wake) sleep();        
    }
}
 
void displayrefresh()
{   
    if (strcmp(lastStationName, radio.StationName) != 0){
        if(strlen(radio.StationName)<9){
            n=0;for(i=0;i<(8);i++){ // remove non-printable ASCCi error characters               
                if(radio.StationName[i] > 31){          
                    Station[n] = radio.StationName[i];         
                    n++;
                    }
                }              
            segmentDisplay.Write(Station);
            pc.printf("Station:\n%s\n\n",Station);
            strcpy(lastStationName,radio.StationName);
            }
        }    
    if(lastfreq != radio.freq/1000){lastfreq = radio.freq/1000;
        if(radio.freq<100000){            
            segmentDisplay.Number(radio.freq/10);segmentDisplay.Symbol(LCD_SYMBOL_DP10,1);
            }
            else {segmentDisplay.Number(radio.freq/100);segmentDisplay.Symbol(LCD_SYMBOL_DP10,0);}
            led0=0;
        }
    if(laststereo != radio.stereo){
        if(radio.stereo){segmentDisplay.Symbol(LCD_SYMBOL_ANT,1);}
            else{segmentDisplay.Symbol(LCD_SYMBOL_ANT,0);}
        laststereo = radio.stereo;
        }        
    if(lastsignal != radio.signal){
        signal=radio.signal;
        for (i = 0; i < 8; i++)
            {segmentDisplay.ARing(i, 0);}    
        if(signal>4){segmentDisplay.ARing(0, 1);}
        if(signal>9){segmentDisplay.ARing(1, 1);}
        if(signal>14){segmentDisplay.ARing(2, 1);}
        if(signal>19){segmentDisplay.ARing(3, 1);}
        if(signal>25){segmentDisplay.ARing(4, 1);}
        if(signal>30){segmentDisplay.ARing(5, 1);}
        if(signal>35){segmentDisplay.ARing(6, 1);}
        if(signal>40){segmentDisplay.ARing(7, 1);}        
        lastsignal=radio.signal;       
        }
    if(strcmp(RDStxt1, lasttext1) != 0 || strcmp(RDStxt2, lasttext2) != 0){
        RTrefresh();
        }
    if(strcmp(lastCT, radio.CTtime) !=0){    
        pc.printf("Time: %s\n",radio.CTtime);
        strcpy(lastCT,radio.CTtime);
        if(led0==1){RTrefresh();}
        }       
}

void RTrefresh()
{
        pc.printf("\n-------------------------------------------\n");
        pc.printf("Station:\n%s\n\n",Station);
        pc.printf("RT:\n%s\n",RDStxt1);
        pc.printf("%s\n\n",RDStxt2);
        pc.printf("Time: %s\n",radio.CTtime);    
        memset(lasttext1, '\0', sizeof(lasttext1));strcpy(lasttext1, RDStxt1);           
        memset(lasttext2, '\0', sizeof(lasttext2));strcpy(lasttext2, RDStxt2); 
        led0=1;
}        
 
void getrds()
{    
   if(strlen(radio.RDSText)>3){               
        memset(RDStxt1, '\0', sizeof(RDStxt1));
        memset(RDStxt2, '\0', sizeof(RDStxt2));
                                 
    // format into 2 lines of text seperated by first 'space' after 30 characters
        strcpy(RDStxt1,radio.RDSText);
        n=strlen(RDStxt1);    
        for ( i = 0; i < (n); i++ ){
            if (i>30 && (RDStxt1[i] == ' ') ){              
                RDStxt1 [strlen(RDStxt1) - (n-i)] = '\0';               
                l=strlen(RDStxt1);
                x=1;
                break; // break if more than 30 characters with space 
                }
            if(i>39){
                RDStxt1 [strlen(RDStxt1) - (n-i)] = '\0';
                l=strlen(RDStxt1);
                x=1;
                break; //break if more than 39 characters with no spaces
                }
            }
        if(x==1){           
            strcpy (RDStxt2, radio.RDSText + l);
            while(RDStxt2[0]==' '){
                strcpy (RDStxt2, (RDStxt2 + 1));
            }
            x=0;
        }
    }   
}