RDA5807M FM Radio library with RDS.
Dependents: RDA5807M-FM-Radio EFM32 RDA5807M RDS Radio
Example program here:
https://developer.mbed.org/users/star297/code/RDA5807M-FM-Radio/
Diff: RDA5807M.cpp
- Revision:
- 3:bdd691977de4
- Parent:
- 1:2c8a64e71afd
- Child:
- 4:3e7968bd455d
--- a/RDA5807M.cpp Sun Apr 12 16:26:11 2015 +0000 +++ b/RDA5807M.cpp Thu Jun 11 20:17:16 2015 +0000 @@ -173,7 +173,7 @@ WriteAll(); } -void RDA5807M::Read(){ +void RDA5807M::Readregisters(){ int i; char rcv[12]; i2c.read(0x20, rcv,12); // read 12 bytes for reg 0x0A .. reg 0x0F @@ -200,117 +200,118 @@ //11= 6+ errors or error in checkword, correction not possible. } - void RDA5807M::RDSinit() { + strcpy(StationName, " "); + strcpy(PSName, " "); strcpy(PSName1, " "); - strcpy(PSName2, PSName1); - strcpy(StationName, " "); + strcpy(PSName2, " "); memset(RDSText, '\0', sizeof(RDSText)); + memset(RDSTxt, '\0', sizeof(RDSTxt)); lastTextIDX = 0; + mins=0; + sprintf(CTtime, "CT --:--"); } -void RDA5807M::processData() +void RDA5807M::ProcessData() { - char c1, c2; - int idx; // index of rdsText - int mins; // RDS time in minutes - int offset; // RDS time offset and sign - Read(); - if (block1==0) { - // reset all the RDS info. - RDSinit(); - // Send out empty data - if (sendServiceName) sendServiceName(StationName); - if (sendText) sendText(""); - return; - } - + Readregisters(); + if (rdssynchro != 0x1000){ // reset all the RDS info. + RDSinit(); + return; + } // analyzing Block 2 - rdsGroupType = 0x0A | ((block2 & 0xF000) >> 8) | ((block2 & 0x0800) >> 11); - rdsTP = (block2 & 0x0400); - rdsPTY = (block2 & 0x0400); + rdsGroupType = 0x0A | ((block2 & 0xF000) >> 8) | ((block2 & 0x0800) >> 11); + rdsTP = (block2 & 0x0400); + rdsPTY = (block2 & 0x0400); - switch (rdsGroupType) { - case 0x0A: - case 0x0B: - // The data received is part of the Service Station Name - - idx = 2 * (block2 & 0x0003); - // new data is 2 chars from block 4 - c1 = block4 >> 8; - c2 = block4 & 0x00FF; - // check that the data was received successfully twice - // before publishing the station name - if ((PSName1[idx] == c1) && (PSName1[idx + 1] == c2)) { - // retrieved the text a second time: store to _PSName2 - PSName2[idx] = c1; - PSName2[idx + 1] = c2; - PSName2[8] = '\0'; - if ((idx == 6) && strcmp(PSName1, PSName2) == 0) { - if (strcmp(PSName2, StationName) != 0) { - // publish station name - if(strlen(PSName2)<9){strcpy(StationName, PSName2);} - if (sendServiceName) - sendServiceName(StationName); + switch (rdsGroupType) { + case 0x0A: + case 0x0B: + // The data received is part of the Service Station Name + idx = 2 * (block2 & 0x0003); + // new data is 2 chars from block 4 + c1 = block4 >> 8; + c2 = block4 & 0x00FF; + // check that the data was received successfully twice + // before sending the station name + if ((PSName1[idx] == c1) && (PSName1[idx + 1] == c2)) { + // retrieve the text a second time: store to _PSName2 + PSName2[idx] = c1; + PSName2[idx + 1] = c2; + PSName2[8] = '\0'; + if (strcmp(PSName1, PSName2) == 0) { + // publish station name + n=0; + for(i=0;i<(8);i++){ // remove non-printable error ASCCi characters + if(PSName2[i] > 31 && PSName2[i] < 127){ + StationName[n] = PSName2[i]; + n++; + } + } + } + } + if ((PSName1[idx] != c1) || (PSName1[idx + 1] != c2)) { + PSName1[idx] = c1; + PSName1[idx + 1] = c2; + PSName1[8] = '\0'; } - } - } - if ((PSName1[idx] != c1) || (PSName1[idx + 1] != c2)) { - PSName1[idx] = c1; - PSName1[idx + 1] = c2; - PSName1[8] = '\0'; - } break; - case 0x2A: - // RDS text - // if(rdsblockerror > 1){memset(RDSText, '\0', sizeof(RDSText));lastTextIDX = 0;} - // The data received is part of the RDS Text. + case 0x2A: + // RDS text + // The data received is part of the RDS Text. textAB = (block2 & 0x0010); idx = 4 * (block2 & 0x000F); - + if(idx>64){memset(RDSTxt, '\0', sizeof(RDSTxt));idx=0;} if (idx < lastTextIDX) { // the existing text might be complete because the index is starting at the beginning again. // now send it to the possible listener. - if (sendText) - sendText(RDSText); - } + n=0; + for(i=0;i<64;i++){ + if(RDSTxt[i] > 31 && RDSTxt[i] < 127){ // remove any non printable error charcters + RDSText[n] = RDSTxt[i]; + n++; + } + } + } lastTextIDX = idx; - if (textAB != lasttextAB) { // when this bit is toggled the whole buffer should be cleared. lasttextAB = textAB; - } - // new data is 2 chars from block 3 - RDSText[idx] = (block3 >> 8); idx++; - RDSText[idx] = (block3 & 0x00FF); idx++; - - // new data is 2 chars from block 4 - RDSText[idx] = (block4 >> 8); idx++; - RDSText[idx] = (block4 & 0x00FF); idx++; - + memset(RDSTxt, 0, sizeof(RDSTxt)); + memset(RDSText, '\0', sizeof(RDSText)); + } + if(rdsblockerror < 4){ + // new data is 2 chars from block 3 + RDSTxt[idx] = (block3 >> 8); idx++; + RDSTxt[idx] = (block3 & 0x00FF); idx++; + // new data is 2 chars from block 4 + RDSTxt[idx] = (block4 >> 8); idx++; + RDSTxt[idx] = (block4 & 0x00FF); idx++; + } break; case 0x4A: // Clock time and date - offset = (block4) & 0x3F; // 6 bits - mins = (block4 >> 6) & 0x3F; // 6 bits - mins += 60 * (((block3 & 0x0001) << 4) | ((block4 >> 12) & 0x0F)); - + if(rdsblockerror ==0){ // allow no RDS data errors as we have no correctioin code + offset = (block4) & 0x3F; // 6 bits + mins = (block4 >> 6) & 0x3F; // 6 bits + mins += 60 * (((block3 & 0x0001) << 4) | ((block4 >> 12) & 0x0F)); + } // adjust offset if (offset & 0x20) { mins -= 30 * (offset & 0x1F); } else { mins += 30 * (offset & 0x1F); - } - -// Serial.print(" >>"); Serial.print(mins/60); Serial.print(':'); Serial.println(mins % 60); - - //if ((sendTime) && (mins != _lastRDSMinutes)) { - CTtime = mins; - // sendTime(mins / 60, mins % 60); - // } + } + if(mins == lastmins+1){ // get CT time twice before sending time + minutes=mins;} + lastmins=mins; + if(rdssynchro == 0x1000){ + if(minutes>0 && minutes<1500){sprintf(CTtime, "CT %2d:%02d",(minutes/60),(minutes%60));} + } + else{minutes=0;sprintf(CTtime, "CT --:--");} // CT time formatted string break; case 0x6A: @@ -334,7 +335,8 @@ break; default: - // Serial.print("RDS_GRP:"); Serial.println(rdsGroupType, HEX); + break; } -} +} +