/*--------------------------------------------------------------
TEA5767 FM Radio
By Chris Rouse Jan 2016
Radio Functions:
preset station selection
mute/unmute radio
select favourite station
shows if station is being received in Stereo or Mono
shows signal strength
Keys required on IR controller::
presetUP - next preset station
presetDOWN - next preset station down
radioON_OFF - turns radio ON or OFF
favoutiteSTATION - select your favourite station
scan - scans through FM spectrum looking for stations
finetuneUP - increments frequency up by 0.1mHz
finetuneDOWN - lowers frequency by 0.1mHz increments
Using Arduino Uno
Up to 6 preset stations can be selected although this can easily be increased
SELECT switches to your favourite station
Tuning is in 0.01mHz intervals to allow for fine tuning of presets
There are 4 pins to connect, SDA to Arduino Pin A4, SCL to Arduino pin A5 and Vcc to 5 volts, Gnd to Gnd
or if using Arduino Mega SDA (pin 20), SCL (pin 21), 5volts and Gnd (power available on end socket). Plug the LCD Shield
---------------------------------------------------------------*/
/*--------------------------------------------------------------
Setup OLED Display
---------------------------------------------------------------*/
#include "U8glib.h"
#include <SPI.h>
// setup u8g object
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // I2C
//
/*--------------------------------------------------------------
Setup Radio
---------------------------------------------------------------*/
#include <Wire.h>
//#include <TEA5767N.h>
// Init radio object
//TEA5767N radio = TEA5767N();
/*-------------------------------------------------------------
Setup IR Receiver
---------------------------------------------------------------*/
#include <IRremote.h>
int RECV_PIN = 2;
int LED_PIN = 13;
IRrecv irrecv(RECV_PIN);
decode_results results;
// these are the values for the IR contro; buttons
// alter to suit your IR setup, these are DECIMAL values
//
const double radioON_OFF = 16580863;
const double favouriteSTATION = 16597183;
const double presetUP = 16613503;
const double presetDOWN = 16617583;
const double finetuneUP = 16601263;
const double finetuneDOWN = 16584943;
//
/*--------------------------------------------------------------------------------------
Variables
--------------------------------------------------------------------------------------*/
double frequency = 88.00; // frequency in mHz
double topFrequency = 110.00;
double bottomFrequency = 88.00;
double intervalFreq = 0.01; // could be changed to 1 for coarse tuning
// alter to add more or less presets
int maxPresets; // maximum number of presets used
double stationsMHZ[7]; // allow for 6 preset stations
String stations[7]; // station names
//
int presetCounter = 0; //pointer to preset stations
int favourite; // pressing SELECT will select this one
int sl; // signal level 0 - 10
boolean mute = true;
String stringFrequency;
String stringStation;
String stringSignal;
boolean stereo = false;
String rawData;
boolean IRsignal = false;
int a;
boolean stationName = true; // display the station name
/*--------------------------------------------------------------------------------------
Setup
--------------------------------------------------------------------------------------*/
void setup()
{
Wire.begin();
Serial.begin(9600);
irrecv.enableIRIn(); // Start the IR receiver
//radio.selectFrequency(bottomFrequency); // set radio initially to lowest frequency
pinMode(3, INPUT_PULLUP); // this pin controls the setup screen
digitalWrite(3, HIGH);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
// setup preset list of stations
// for the character set used
// names must be less than 21 characters
stationsMHZ[1] = 88.58;
stations[1] = "BBC Radio 2";
stationsMHZ[2] = 96.10;
stations[2] = "Radio Solent";
stationsMHZ[3] = 97.50;
stations[3] = "Heart Solent";
stationsMHZ[4] = 98.20;
stations[4] = "BBC Radio 1";
stationsMHZ[5] = 103.20;
stations[5] = "Capital FM";
stationsMHZ[6] = 102.00;
stations[6] = "Isle of Wight Radio";
//
maxPresets = 6; // number of stations in list, change this as required
favourite = 6; // select your own favourite
// ensure radio starts with favourite
presetCounter = favourite;
selectStation();
}
/*--------------------------------------------------------------------------------------
Main Loop
--------------------------------------------------------------------------------------*/
void loop() {
// if pin 3 is connected to the Gnd pin then just display output from IR Receiver
if (digitalRead(3) == 0) {
// picture loop
u8g.firstPage();
do {
drawSetupCalibrate();
} while ( u8g.nextPage() );
calibrateIR();
}
//otherwise we are in the Radio receiver mode
// Decode commands from the IR Remote
if (irrecv.decode(&results)) {
digitalWrite(LED_PIN, HIGH);
// this selects the next radio station
if (results.value == presetUP) {
presetCounter = presetCounter + 1;
if (presetCounter > maxPresets) {
presetCounter = 1; // loop counter round
}
stationName = true;
selectStation();
}
// this selects the last preset radio station
if (results.value == presetDOWN) {
presetCounter = presetCounter - 1;
if (presetCounter < 1) {
presetCounter = maxPresets; // loop counter round
}
stationName = true;
selectStation();
}
// this selects your favourite radio station
if (results.value == favouriteSTATION) {
if (favourite > 0 and favourite < maxPresets + 1) {
presetCounter = favourite;
frequency = stationsMHZ[presetCounter];
stationName = true;
selectStation();
}
}
// this section mutes or unmutes the radio
if (results.value == radioON_OFF) {
if (mute) {
//radio.mute();
//radio.setStandByOff();
}
else {
//radio.turnTheSoundBackOn();
}
mute = !mute;
}
// this section increases the frequency to allow fine tuning
if (results.value == finetuneUP) {
frequency = frequency + intervalFreq;
if (frequency > topFrequency) {
frequency = bottomFrequency; // reset to lowest frequency
}
stationName = false; // dont display the station name
selectStation2();
}
// this section decreases the frequency to allow fine tuning
if (results.value == finetuneDOWN) {
frequency = frequency - intervalFreq;
if (frequency < bottomFrequency) {
frequency = topFrequency; // reset to highest frequency
}
stationName = false; // dont display the station name
selectStation2();
}
// end of button press checks
//
irrecv.resume(); // Receive the next value
digitalWrite(LED_PIN, LOW); // turn off onboard LED
//
}
// get Stereo status and signal strength
printStereoStatus();
// picture loop
u8g.firstPage();
do {
draw();
} while ( u8g.nextPage() );
} // end Main loop
/*--------------------------------------------------------------------------------------
Get frequency for a station in the preset list
--------------------------------------------------------------------------------------*/
void selectStation() {
frequency = stationsMHZ[presetCounter];
//radio.mute();
//radio.selectFrequency(frequency); // set radio frequency
//radio.turnTheSoundBackOn();
}
/*--------------------------------------------------------------------------------------
Send a frequency to the TEA 5767
--------------------------------------------------------------------------------------*/
void selectStation2() {
//radio.mute();
//radio.selectFrequency(frequency); // set radio frequency
//radio.turnTheSoundBackOn();
}
/*--------------------------------------------------------------------------------------
Get Stereo Status
--------------------------------------------------------------------------------------*/
void printStereoStatus()
{
/*
sl = radio.getSignalLevel();
if (radio.isStereo()) {
stereo = true;
} else {
stereo = false;
}
*/
}
/*--------------------------------------------------------------------------------------
Draw display
--------------------------------------------------------------------------------------*/
void draw(void) {
u8g.setFont(u8g_font_profont12);
u8g.drawStr(40, 8, "FM Radio");
if (mute) { // radio is muted
// display station frequency
//stringFrequency = String(radio.readFrequencyInMHz()); // display actual frequency
stringFrequency = stringFrequency + "mhz";
a = stringFrequency.length();
a = 18 - a;
a = a * 7; // width in pixels of empty space
a = (a / 2) + 1; // start for string to make it centre
const char* newFrequency = (const char*) stringFrequency.c_str();
u8g.setFont(u8g_font_profont15);
u8g.drawStr(a, 30, newFrequency);
// display station title
u8g.setFont(u8g_font_profont12);
if (stationName) {
stringStation = stations[presetCounter];
}
else {
stringStation = "fine tune";
}
a = stringStation.length();
a = 21 - a;
a = a * 6; // width in pixels of empty space
a = (a / 2) + 1; // start for string to make it centre
const char* newStation = (const char*) stringStation.c_str();
u8g.drawStr(a, 42, newStation);
// display signal strength and Stereo/Mono
if (stereo) {
u8g.drawStr(5, 17, "Stereo");
}
else {
u8g.drawStr(5, 17, "Mono");
}
if (sl < 10) {
stringSignal = "Signal: " + String(sl);
const char* newSignal = (const char*) stringSignal.c_str();
u8g.drawStr(70, 17, newSignal);
}
// now draw frequency line
u8g.drawLine(4, 58, 124, 58);
for (int f = 4; f < 128; f = f + 40) {
u8g.drawLine(f, 52, f, 58);
}
for (int f = 4; f < 128; f = f + 8) {
u8g.drawLine(f, 55, f, 58);
}
u8g.drawLine(((frequency - 80) * 4) + 4, 53, ((frequency - 80) * 4) + 4, 63);
u8g.setFont(u8g_font_profont10);
u8g.drawStr(0, 52, "80");
u8g.drawStr(40, 52, "90");
u8g.drawStr(78, 52, "100");
u8g.drawStr(114, 52, "110");
}
else {
u8g.drawStr(23, 30, "Radio is muted");
}
}
/*--------------------------------------------------------------------------------------
display the values sent by the IR control
--------------------------------------------------------------------------------------*/
void calibrateIR() {
// just display values sent by the IR control
while (digitalRead(3) == 0) {
if (irrecv.decode(&results)) {
digitalWrite(LED_PIN, HIGH); // onboard LED shows IR signal received
// picture loop
u8g.firstPage();
do {
drawSetup();
} while ( u8g.nextPage() );
}
delay(500);
digitalWrite(LED_PIN, LOW);
}
}
/*--------------------------------------------------------------------------------------
Draw display to show data from IR controller
--------------------------------------------------------------------------------------*/
void drawSetup()
{
//radio.mute(); // turn off the radio to reduce noise
u8g.setFont(u8g_font_profont12);
u8g.drawStr(15, 8, "Codes sent by IR");
u8g.drawLine(0, 15, 128, 15);
u8g.drawLine(0, 55, 128, 55);
// now print code
rawData = String(results.value);
const char* newRawData = (const char*) rawData.c_str();
u8g.setFont(u8g_font_profont15);
u8g.drawStr(35, 40, newRawData);
irrecv.resume(); // Receive the next value
}
void drawSetupCalibrate()
{
u8g.setFont(u8g_font_profont12);
u8g.drawStr(15, 8, "Codes sent by IR");
u8g.drawStr(20, 40, "Wating for Data");
u8g.drawLine(0, 15, 128, 15);
u8g.drawLine(0, 55, 128, 55);
}
/*--------------------------------------------------------------------------------------*/