Arduino Mad Scientist Laboratory EP#8 TEA5767 FM radio with LCD, Rotary Encoder, Presets & 30w AMP

Today we will be trying to take over the world by building our own Arduino controlled TEA5767 FM radio with LCD display, rotary encoder tuning, presets and an optional 30 watt stereo amplifier.

 

Check us out on Facebook!

 

How to set up and use a 1602 I2C serial LCD with your ARDUINO

Parts List:

affiliate links

ARDUINO Pro Mini

I2C LCD

TEA5767 FM Radio

Rotary Encoder

Push Buttons

2N2222 NPN Transistor

amplifier

Schematic:

Library’s:

LCD Library Download

TEA5767 Library can be found in your ARDUINO Manage library’s tab.

ARDUINO Code:

#include <Wire.h>
#include <TEA5767Radio.h>
TEA5767Radio radio = TEA5767Radio();
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
#define lcdLight 5 // lcd backlight on off pin
#define encoderPinA 2 // right
#define encoderPinB 3 // left
#define lcdButton 8 // lcd backlight switch button
#define ps1Button 10 // preset buttons
#define ps2Button 11
#define ps3Button 12
float encoderPos = 100; // a counter for the dial
unsigned int lastReportedPos = 1; // change management
static boolean rotating = false; // debounce management
boolean A_set = false;
boolean B_set = false;
int state = 0; // lcd on or off state

void setup() {

Wire.begin();

pinMode(encoderPinA, INPUT_PULLUP); //enabling pullups
pinMode(encoderPinB, INPUT_PULLUP);
pinMode(lcdButton, INPUT_PULLUP);
pinMode(ps1Button, INPUT_PULLUP);
pinMode(ps2Button, INPUT_PULLUP);
pinMode(ps3Button, INPUT_PULLUP);
pinMode(lcdLight, OUTPUT);

attachInterrupt(0, doEncoderA, CHANGE); //pin 2
attachInterrupt(1, doEncoderB, CHANGE); //pin 3

digitalWrite(lcdLight, HIGH);
lcd.begin(16, 2); // initialize the lcd for 16 chars 2 lines, turn on backlight
lcd.clear();
}

void loop() {

rotating = true; // reset the debouncer

if (lastReportedPos != encoderPos) {
encoderPos = constrain(encoderPos, 87.5, 107.9);
radio.setFrequency(encoderPos);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print(“Z-HUT FM RADIO”);
lcd.setCursor(5, 1);
lcd.print(encoderPos);
lastReportedPos = encoderPos;

}
if (digitalRead(lcdButton) == LOW ) // LCD light on & off
{
if (state == 0)
{
digitalWrite(lcdLight, HIGH);
state = 1;
delay(500);
}
else if (state == 1)
{
digitalWrite(lcdLight, LOW);
state = 0;
delay(500);
}
}

// preset buttons ////////////////////////// add more as needed

if (digitalRead(ps1Button) == LOW ) // preset #1
{
encoderPos = 93.7;
}
if (digitalRead(ps2Button) == LOW ) // Preset #2
{
encoderPos = 101.7;
}
if (digitalRead(ps3Button) == LOW ) // preset #3
{
encoderPos = 104.7;
}
}

// Interrupt on A changing state
void doEncoderA() {
// debounce
if ( rotating ) delay (1); // wait a little until the bouncing is done

// Test transition, did things really change?
if ( digitalRead(encoderPinA) != A_set ) { // debounce once more
A_set = !A_set;
// adjust counter + if A leads B
if ( A_set && !B_set )
encoderPos += .1;

rotating = false; // no more debouncing until loop() hits again
}
}

// Interrupt on B changing state
void doEncoderB() {
if ( rotating ) delay (1);
if ( digitalRead(encoderPinB) != B_set ) {
B_set = !B_set;
// adjust counter – 1 if B leads A
if ( B_set && !A_set )
encoderPos -= .1;

rotating = false;
}
}