#include <TouchScreen.h>
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <DS3231.h>
#include <SparkFunSi4703.h>
MCUFRIEND_kbv tft; // hard-wired for UNO shields anyway.
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define rtcAddress 0x68
#define SI4703Address 0x57
int resetPin = 2;
int SDIO = A4;
int SCLK = A5;
uint8_t YP = A1; // must be an analog pin, use "An" notation!
uint8_t XM = A2; // must be an analog pin, use "An" notation!
uint8_t YM = 7; // can be a digital pin
uint8_t XP = 6; // can be a digital pin
uint16_t TS_LEFT = 950;
uint16_t TS_RT = 170;
uint16_t TS_TOP = 950;
uint16_t TS_BOT = 170;
#define SENSITIVITY 100
#define MINPRESSURE 10
#define MAXPRESSURE 1000
uint16_t identifier;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, SENSITIVITY);
TSPoint tp;
// Assign human-readable names to some common 16-bit color values:
#define BLACK 0x0000
#define BLUE 0x01fA
#define LBLUE 0x057F
#define L2BLUE 0x06FF
#define RED 0xD000
#define RED2 0xE000
#define ORANGE 0xFD00
#define ORANGE2 0xF9E0
#define GREEN 0x07E0
#define CYAN 0x07FF
#define CYAN2 0x06FF
#define MAGENTA 0x4008
#define MAGENTA2 0x8008
#define YELLOW 0xFE00
#define WHITE 0xFFFF
#define GRAY 0x2965
#define GRAY2 0x0861
#define LGRAY 0x8410
#define GREEN2 0x0180
int backColor = 0;
int screen = 0;
DS3231 Clock;
bool Century = false;
bool h12;
bool PM;
float temperature;
int Seconds = 57;
int Minutes = 15;
int Hours = 23;
int Mday = 05;
int Month = 01;
int Year = 22;
bool tone1 = false;
int alarm = 0;
bool alarmon = false;
bool alarmset = false;
int alarmHours = 8;
int alarmMinutes = 10;
bool radio_al = true;
bool tone_al = false;
int setHours = 0;
int setMinutes = 0;
int setSeconds = 0;
int setMonthDay = 1;
int setMonth = 1;
int setYear = 22;
bool disekto = false; //leap year
bool dateselected = false;
bool timeselected = false;
bool clock_pressed = false;
Si4703_Breakout radio(resetPin, SDIO, SCLK); // Start radio
bool fmon = false;
int fmTimer = 0;
int volume = 6;
int channel = 880 ;
int channel1;
int channel2;
int M0 = 890;
int M1 = 897;
int M2 = 968;
int M3 = 975;
int M4 = 990;
int M5 = 1003;
int M6 = 1017;
int M7 = 1047;
int M8 = 1055;
int M9 = 1058;
int M10 = 1071;
int mstation = 0;
int memoryNum = 0;
int memoryCh = 0;
bool RDSon = true;
char rdsBuffer[16];
Adafruit_GFX_Button buttons[15];
void setup(void)
{
Wire.begin();
tft.reset();
identifier = tft.readID();
tft.begin(identifier);
tft.setRotation(1);
pinMode(1, OUTPUT);
pinMode(3, OUTPUT);
pinMode(2, OUTPUT);
digitalWrite(1, LOW);
delay(50);
digitalWrite(1, HIGH);
tft.fillScreen(BLACK);
tft.setTextSize(3);
tft.setTextColor(GREEN);
tft.setCursor(30, 80);
tft.print("version4 14.10.2022");
tft.setCursor(70, 150);
tft.print("Yiannis Dou");
delay(3000);
tft.fillScreen(BLACK);
set_rtc();
Homescreen();
}
void loop(void)
{
if (Seconds != Clock.getSecond())
{
set_rtc();
if (timeselected == false && dateselected == false)
{
displayTime();
}
/*if (fmon == true)
{
displayRDS();
}*/
}
tp = ts.getPoint();
pinMode(YP, OUTPUT); //restore shared pins
pinMode(XM, OUTPUT);
// See if there's any touch data for us
if (tp.z > MINPRESSURE && tp.z < MAXPRESSURE)
{
tp.x = map(tp.x, TS_LEFT, TS_RT, tft.height(), 0);
tp.y = map(tp.y, TS_BOT, TS_TOP, tft.width(), 0);
int y = tp.x;
int x = tp.y;
if ((x > 80) && (x < 140))
{
if ((y > 175) && (y < 240))
{
delay(100);
if (screen == 0) //fm power button pressed, turn radio on
{
if (fmon == false)
{
fmon = true;
Thirdframe();
greenPowerbtn();
RadioPowerOn();
fmradio();
}
else if (fmon == true) //fm power button pressed, turn radio off
{
fmon = false;
digitalWrite(2, LOW);
delay(100);
digitalWrite(2, HIGH);
Thirdframe();
dispRadioStatus();
}
}
}
}
if ((x > 0) && (x < 65)) //fm seek down
{
if ((y > 175) && (y < 240))
{
delay(100);
if (screen == 0 && fmon == true)
{
channel = radio.seekDown();
if (channel < 10)
{
channel = 1080;
radio.setChannel(channel);
}
printStation();
}
}
}
if ((x > 150) && (x < 230)) //fm seek up
{
if ((y > 175) && (y < 240))
{
delay(100);
if (screen == 0 && fmon == true)
{
channel = radio.seekUp();
if (channel < 10)
{
channel = 880;
radio.setChannel(channel);
}
printStation();
}
}
}
if ((x > 205) && (x < 265)) //fm volume down
{
if ((y > 175) && (y < 240))
{
delay(100);
if (screen == 0 && fmon == true)
{
volume--;
if (volume < 0)
{
volume = 0;
}
radio.setVolume(volume);
printVolume();
}
}
}
if ((x > 335) && (x < 400)) //fm volume up
{
if ((y > 175) && (y < 240))
{
delay(100);
if (screen == 0 && fmon == true)
{
volume++;
if (volume > 15)
{
volume = 15;
}
radio.setVolume(volume);
printVolume();
}
}
}
if ((x > 345) && (x < 400)) //fm M+ pressed
{
if ((y > 130) && (y < 170))
{
delay(100);
if (screen == 0 && fmon == true)
{
if (mstation < 10)
{
mstation++;
memStation();
}
else if (mstation == 10)
{
mstation = 0;
memStation();
}
}
}
}
if ((x > 205) && (x < 258)) //fm M- pressed
{
if ((y > 130) && (y < 170))
{
delay(100);
if (screen == 0 && fmon == true)
{
if (mstation > 0)
{
mstation--;
memStation();
}
else if (mstation == 0)
{
mstation = 10;
memStation();
}
}
}
}
if ((x > 260) && (x < 345)) //color button is pressed
{
if ((y > 130) && (y < 170))
{
delay(100);
if (screen == 0 && fmon == true)
{
backColor++ ;
if (backColor > 2)
{
backColor = 0;
}
Thirdframe();
greenPowerbtn();
printStation();
printVolume();
printMemoryframe();
}
}
}
if ((x > 195) && (x < 245)) //touch on seconds circle to set time
{
if ((y > 15) && (y < 65))
{
delay(100);
if (screen == 0 && timeselected == false && dateselected == false)
{
timeselected = true;
dateselected = false;
clockSetframe();
}
}
/*else if ((y > 70) && (y < 120))
{
delay(100);
if (screen == 0 && timeselected == false && dateselected == false)
{
timeselected = false;
dateselected = true;
dateSetframe();
}
}*/
}
if ((x > 0) && (x < 50))
{
if ((y > 0) && (y < 50))
{
delay(100);
if (screen == 0 && timeselected == true) // increase hours
{
setHours++;
if (setHours == 24)
{
setHours = 0;
}
timeSet();
Clock.setHour(setHours);
}
else if (screen == 0 && dateselected == true) // increase setMonthDayday
{
setMonthDay++;
if (setMonth == 4 || setMonth == 6 || setMonth == 9 || setMonth == 11)
{
if (setMonthDay == 31)
{
setMonthDay = 1;
}
}
else if (setMonth == 2 && disekto == true)
{
if (setMonthDay == 30)
{
setMonthDay = 1;
}
Clock.setDate(setMonthDay);
}
else if (setMonth == 2 && disekto == false)
{
if (setMonthDay == 29)
{
setMonthDay = 1;
}
}
else if (setMonthDay == 32)
{
setMonthDay = 1;
}
dateSet();
Clock.setDate(setMonthDay);
}
}
}
if ((x > 0) && (x < 50))
{
if ((y > 75) && (y < 120))
{
delay(100);
if (screen == 0 && timeselected == true) // decrease sethours
{
if (setHours > 0)
{
setHours--;
}
else if (setHours == 0)
{
setHours = 23;
}
timeSet();
Clock.setHour(setHours);
}
else if (screen == 0 && dateselected == true) // decrease setMonthDay
{
if (setMonthDay > 0)
{
setMonthDay--;
}
if (setMonthDay == 0)
{
if (setMonth == 4 || setMonth == 6 || setMonth == 9 || setMonth == 11)
{
setMonthDay = 30;
}
else if ((setMonth == 2) && (disekto == true))
{
setMonthDay = 29;
}
else if ((setMonth == 2) && (disekto == false))
{
setMonthDay = 28;
}
else if (setMonth == 1 || setMonth == 3 || setMonth == 5 || setMonth == 7 || setMonth == 8 || setMonth == 10 || setMonth == 12)
{
setMonthDay = 31;
}
}
dateSet();
Clock.setDate(setMonthDay);
}
}
}
if ((x > 55) && (x < 105))
{
if ((y > 0) && (y < 50))
{
delay(100);
if (screen == 0 && timeselected == true) // increase setMinutes
{
setMinutes++;
if (setMinutes == 60)
{
setMinutes = 0;
}
timeSet();
Clock.setMinute(setMinutes);
}
else if (screen == 0 && dateselected == true) // increase setMonth
{
setMonth++;
if (setMonth == 13)
{
setMonth = 1;
}
dateSet();
Clock.setMonth(setMonth);
}
}
}
if ((x > 55) && (x < 105))
{
if ((y > 75) && (y < 120))
{
delay(100);
if (screen == 0 && timeselected == true) //decrease setMinutes
{
if (setMinutes > 0)
{
setMinutes--;
}
else if (setMinutes == 0)
{
setMinutes = 59;
}
timeSet();
Clock.setMinute(setMinutes);
}
else if (screen == 0 && dateselected == true) //decrease setMonth
{
if (setMonth > 0)
{
setMonth--;
}
if (setMonth == 0)
{
setMonth = 12;
}
dateSet();
Clock.setMonth(setMonth);
}
}
}
if ((x > 110) && (x < 160))
{
if ((y > 0) && (y < 50))
{
delay(100);
if (screen == 0 && timeselected == true) //increase setSeconds
{
setSeconds++;
if (setSeconds == 60)
{
setSeconds = 0;
}
timeSet();
Clock.setSecond(setSeconds);
}
else if (screen == 0 && dateselected == true) // increase setYear
{
setYear++;
if (setYear % 4 == 0)
{
disekto = true;
}
else
{
disekto = false;
}
if (setYear == 100)
{
setYear = 0;
}
dateSet();
Clock.setYear(setYear);
}
}
}
if ((x > 110) && (x < 160))
{
if ((y > 75) && (y < 120))
{
delay(100);
if (screen == 0 && timeselected == true) //decrease setSeconds
{
if (setSeconds > 0)
{
setSeconds--;
}
else if (setSeconds == 0)
{
setSeconds = 59;
}
timeSet();
Clock.setSecond(setSeconds);
}
else if (screen == 0 && dateselected == true) // decrease setYear
{
delay(100);
if (setYear > 0)
{
setYear--;
}
else if (setYear == 0)
{
setYear = 99;
}
if (setYear % 4 == 0)
{
disekto = true;
}
else
{
disekto = false;
}
dateSet();
Clock.setYear(setYear);
}
}
}
if ((x > 160) && (x < 240))
{
if ((y > 75) && (y < 120))
{
delay(100);
if (screen == 0 && timeselected == true) //touch on next button to set date
{
timeselected = false;
dateselected = true;
dateSetframe();
}
else if (screen == 0 && dateselected == true)
{
timeselected = false;
dateselected = false;
Firstframe();
displayTime();
displayDate();
}
}
}
}
}
void Homescreen()
{
screen = 0;
set_rtc();
Firstframe();
Secondframe();
Thirdframe();
displayTime();
displayDate();
dispRadioStatus();
}
void set_rtc()
{
int temperature;
Seconds = Clock.getSecond();
Minutes = Clock.getMinute();
Hours = Clock.getHour(h12, PM);
Mday = Clock.getDate();
Month = Clock.getMonth(Century);
Year = Clock.getYear();
temperature = Clock.getTemperature();
}
void Firstframe()
{
tft.fillRoundRect(0, 0, 245, 120, 7, BLACK);
tft.drawRoundRect(0, 0, 245, 120, 7, LBLUE);
tft.fillRoundRect(5, 20, 182, 90, 10, GRAY);
tft.fillRoundRect(15, 10, 70, 70, 10, LGRAY);
tft.fillRoundRect(17, 12, 66, 66, 10, WHITE);
tft.fillRoundRect(105, 10, 70, 70, 10, LGRAY);
tft.fillRoundRect(107, 12, 66, 66, 10, WHITE);
}
void Secondframe()
{
tft.fillRoundRect(250, 0, 150, 120, 7, BLACK);
tft.drawRoundRect(250, 0, 150, 120, 7, LBLUE);
tft.fillCircle(300, 35, 25, YELLOW);
tft.fillCircle(325, 57, 30, WHITE);
tft.fillCircle(355, 57, 20, WHITE);
tft.fillCircle(290, 57, 20, WHITE);
tft.fillRoundRect(270, 75, 120, 40, 7, BLACK);
}
void Thirdframe()
{
tft.fillRoundRect(0, 125, 400, 115, 7, BLACK);
tft.drawRoundRect(0, 125, 400, 115, 7, LBLUE);
if (backColor == 0)
{
tft.fillRoundRect(5, 130, 195, 105, 7, RED); //radio left background
}
if (backColor == 1)
{
tft.fillRoundRect(5, 130, 195, 105, 7, ORANGE2); //radio left background
}
if (backColor == 2)
{
tft.fillRoundRect(5, 130, 195, 105, 7, MAGENTA2); //radio left background
}
tft.drawRoundRect(5, 130, 195, 105, 7, GRAY);
tft.fillCircle(40, 205, 25, BLUE); //seek down button
tft.fillTriangle(35, 195, 25, 205, 35, 215, WHITE);
tft.fillTriangle(50, 195, 40, 205, 50, 215, WHITE);
tft.fillCircle(102, 205, 25, BLUE); //radio on-off button
tft.drawCircle(102, 205, 13, RED);
tft.drawCircle(102, 205, 14, RED);
tft.drawCircle(102, 205, 15, RED);
tft.drawCircle(102, 205, 16, RED);
tft.drawFastVLine(99, 185, 15, BLUE);
tft.drawFastVLine(100, 185, 15, BLUE);
tft.drawFastVLine(101, 185, 15, RED);
tft.drawFastVLine(102, 185, 15, RED);
tft.drawFastVLine(103, 185, 15, RED);
tft.drawFastVLine(104, 185, 15, BLUE);
tft.drawFastVLine(105, 185, 15, BLUE);
tft.fillCircle(165, 205, 25, BLUE); //seek up button
tft.fillTriangle(170, 195, 180, 205, 170, 215, WHITE);
tft.fillTriangle(155, 195, 165, 205, 155, 215, WHITE);
if (backColor == 0)
{
tft.fillRoundRect(205, 130, 190, 105, 7, BLUE); //radio right background
}
if (backColor == 1)
{
tft.fillRoundRect(205, 130, 190, 105, 7, LBLUE); //radio right background
}
if (backColor == 2)
{
tft.fillRoundRect(205, 130, 190, 105, 7, CYAN2); //radio right background
}
tft.drawRoundRect(205, 130, 190, 105, 7, GRAY);
tft.fillRoundRect(215, 135, 170, 40, 7, LGRAY);
tft.fillCircle(240, 205, 25, RED); //volume down button
tft.fillRoundRect(225, 198, 20, 16, 2, WHITE);
tft.fillTriangle(245, 190, 232, 205, 245, 220, WHITE);
tft.drawFastHLine(250, 204, 10, WHITE);
tft.drawFastHLine(250, 205, 10, WHITE);
tft.fillCircle(300, 205, 25, RED); // volume steps
tft.fillCircle(360, 205, 25, RED); //volume up button
tft.fillRoundRect(345, 198, 20, 16, 2, WHITE);
tft.fillTriangle(365, 190, 352, 205, 365, 220, WHITE);
tft.drawFastHLine(370, 204, 11, WHITE);
tft.drawFastHLine(370, 205, 11, WHITE);
tft.drawFastVLine(375, 200, 10, WHITE);
tft.drawFastVLine(376, 200, 10, WHITE);
}
void greenPowerbtn()
{
tft.fillCircle(102, 205, 25, BLUE); //radio power button on
tft.drawCircle(102, 205, 13, GREEN);
tft.drawCircle(102, 205, 14, GREEN);
tft.drawCircle(102, 205, 15, GREEN);
tft.drawCircle(102, 205, 16, GREEN);
tft.drawFastVLine(99, 185, 15, BLUE);
tft.drawFastVLine(100, 185, 15, BLUE);
tft.drawFastVLine(101, 185, 15, GREEN);
tft.drawFastVLine(102, 185, 15, GREEN);
tft.drawFastVLine(103, 185, 15, GREEN);
tft.drawFastVLine(104, 185, 15, BLUE);
tft.drawFastVLine(105, 185, 15, BLUE);
}
void displayTime()
{
tft.setTextColor(BLACK, WHITE);
tft.setTextSize(5);
tft.setCursor(22, 25);
if (Hours < 10)
{
tft.print("0");
}
tft.print(Hours);
tft.setTextColor(WHITE, GRAY);
tft.setTextSize(3);
tft.setCursor(87, 35);
tft.print(":");
tft.setTextColor(BLACK, WHITE);
tft.setTextSize(5);
tft.setCursor(112, 25);
if (Minutes < 10)
{
tft.print("0");
}
tft.print(Minutes);
tft.drawCircle(214, 42, 20, WHITE);
tft.drawCircle(214, 42, 21, WHITE);
tft.drawCircle(214, 42, 22, WHITE);
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(2);
tft.setCursor(204, 35);
if (Seconds < 10)
{
tft.print("0");
}
tft.print(Seconds);
}
void displayDate()
{
tft.setTextColor(WHITE, GRAY);
tft.setTextSize(2);
tft.setCursor(35, 87);
if (Mday < 10)
{
tft.print("0");
}
tft.print(Mday);
tft.print(".");
if (Month < 10)
{
tft.print("0");
}
tft.print(Month);
tft.print(".");
tft.print("20");
if (Year < 10)
{
tft.print("0");
}
tft.print(Year);
tft.setTextSize(3);
tft.setCursor(275, 85);
tft.setTextColor(YELLOW, BLACK);
//tft.print("T:");
tft.print(Clock.getTemperature(), 1);
tft.setCursor(360, 85);
tft.print("C");
tft.drawCircle(354, 85, 2, YELLOW);
}
void clockSetframe()
{
tft.fillRoundRect(0, 0, 245, 120, 7, BLACK);
tft.drawRoundRect(0, 0, 245, 120, 7, LBLUE);
tft.fillCircle(25, 25, 20, WHITE);
tft.fillCircle(80, 25, 20, WHITE);
tft.fillCircle(135, 25, 20, WHITE);
tft.setTextColor(BLACK, WHITE);
tft.setTextSize(3);
tft.setCursor(17, 15);
tft.print("+");
tft.setCursor(72, 15);
tft.print("+");
tft.setCursor(127, 15);
tft.print("+");
tft.fillCircle(25, 95, 20, WHITE);
tft.fillCircle(80, 95, 20, WHITE);
tft.fillCircle(135, 95, 20, WHITE);
tft.setCursor(17, 85);
tft.print("-");
tft.setCursor(72, 85);
tft.print("-");
tft.setCursor(127, 85);
tft.print("-");
tft.fillRoundRect(165, 75, 70, 40, 7, WHITE);
tft.setTextSize(2);
tft.setTextColor(BLACK, WHITE);
tft.setCursor(177, 87);
tft.print("Next");
setHours = Hours;
setMinutes = Minutes;
setSeconds = Seconds;
timeSet();
}
void timeSet()
{
tft.setTextSize(3);
tft.setTextColor(WHITE, BLACK);
tft.setCursor(10, 50);
if (setHours < 10)
{
tft.print("0");
}
tft.print(setHours);
tft.print(":");
if (setMinutes < 10)
{
tft.print("0");
}
tft.print(setMinutes);
tft.print(":");
if (setSeconds < 10)
{
tft.print("0");
}
tft.print(setSeconds);
}
void dateSetframe()
{
tft.fillRoundRect(0, 0, 245, 120, 7, BLACK);
tft.drawRoundRect(0, 0, 245, 120, 7, LBLUE);
tft.fillCircle(25, 25, 20, WHITE);
tft.fillCircle(80, 25, 20, WHITE);
tft.fillCircle(135, 25, 20, WHITE);
tft.setTextColor(BLACK, WHITE);
tft.setTextSize(3);
tft.setCursor(17, 15);
tft.print("+");
tft.setCursor(72, 15);
tft.print("+");
tft.setCursor(127, 15);
tft.print("+");
tft.fillCircle(25, 95, 20, WHITE);
tft.fillCircle(80, 95, 20, WHITE);
tft.fillCircle(135, 95, 20, WHITE);
tft.setCursor(17, 85);
tft.print("-");
tft.setCursor(72, 85);
tft.print("-");
tft.setCursor(127, 85);
tft.print("-");
setMonthDay = Mday;
setMonth = Month;
setYear = Year;
dateSet();
tft.fillRoundRect(165, 75, 70, 40, 7, WHITE);
tft.setTextSize(2);
tft.setTextColor(BLACK, WHITE);
tft.setCursor(177, 87);
tft.print("Back");
}
void dateSet()
{
tft.setTextSize(3);
tft.setTextColor(WHITE, BLACK);
tft.setCursor(10, 50);
if (setMonthDay < 10)
{
tft.print("0");
}
tft.print(setMonthDay);
//tft.setCursor(100, 135);
tft.print("-");
//tft.setCursor(140, 135);
if (setMonth < 10)
{
tft.print("0");
}
tft.print(setMonth);
//tft.setCursor(200, 135);
tft.print("-");
//tft.setCursor(230, 135);
tft.print("20");
if (setYear < 10)
{
tft.print("0");
}
tft.print(setYear);
}
void dispRadioStatus()
{
if (fmon == false)
{
if (backColor == 0)
{
tft.setTextColor(WHITE, RED);
}
if (backColor == 1)
{
tft.setTextColor(WHITE, ORANGE2);
}
if (backColor == 2)
{
tft.setTextColor(WHITE, MAGENTA2);
}
tft.setTextSize(2);
tft.setCursor(15, 148);
tft.print("FM RADIO IS OFF");
tft.setTextColor(WHITE, LGRAY);
tft.setCursor(220, 148);
tft.print("YiannisDou V4");
}
}
void printMemoryframe()
{
tft.setTextSize(2);
tft.setTextColor(BLACK, LGRAY);
tft.setCursor(227, 148);
tft.print("M-");
tft.drawFastVLine(259, 135, 40, BLACK);
tft.drawFastVLine(260, 135, 40, BLACK);
tft.drawFastVLine(261, 135, 40, BLACK);
tft.setCursor(272, 148);
tft.print("Color");
tft.drawFastVLine(339, 135, 40, BLACK);
tft.drawFastVLine(340, 135, 40, BLACK);
tft.drawFastVLine(341, 135, 40, BLACK);
tft.setCursor(352, 148);
tft.print("M+");
}