Hardware components | ||||||
| × | 1 | ||||
| × | 1 |
The clock project using the TTGO T4 and the DS3231 RTC was originally written by me and became quite popular. The coding was simple and did not include any way to adjust the time from BST and GMT.
This enhanced project uses Bluetooth to connect to the Android Phone app to set the time.
The app connects to the TTGO T4 "T4_Set_Time" and allows the time to be synchronised with the current system time of the phone. This only needs to be done when the time needs to be corrected.
No additional hardware is required from the original program only the addition of the apk android app installation.
The TTGO T4 display uses the TFT_eSPI library. This requires the alteration of the User_Setup.h and User_Setup_Select.h files in the TFT_eSPI folder to be altered to reflect the model type of T4 you are using.
/* *********************************************************************************
* * The original TTGO T4 Clock Program, enhanced to be set over Bluetooth LE *
* * During the first 30 seconds after switch on, the TTGO T4 will look for a BLE *
* * Bluetooth connection from the Android phone app to set the time on the DS3231.*
* * After which it will go into display mode. *
*********************************************************************************
*/
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
#include <DS3231.h>
#include <Wire.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#define SERVICE_UUID "fe45c941-9b87-4ef1-ac31-990dd686f813"
#define CHARACTERISTIC_UUID "ebc2e890-8ad5-4d51-a4a1-0e60efc9df4a"
String BT_IN;
char inString[13];
byte Sec = 1;
byte Min = 38;
byte Hr = 12;
byte Weekday = 1;
byte Months;
byte DAY = 1;
byte date;
byte L_Weekday = 1;
byte Year;
String L_Sec = "01";
String L_Min = "38";
String L_Hr = "12";
byte L_Month = 1;
String L_DAY = "01";
char T_emp = 247;
String T_emp2 = String(T_emp) + "c";
byte Temp = 23;
String L_Temp = "23";
bool h12Flag,pmFlag;
bool century = false;
String Dow []= {"0","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday" };
int Spc []= {0,92,79,53,66,92,66,92};
String MONTH []= {"0"," JANUARY","FEBRUARY"," MARCH"," APRIL"," MAY"," JUNE"," JULY"," AUGUST","SEPTEMBER"," OCTOBER","NOVEMBER","DECEMBER" };
byte CountDown;
bool deviceConnected = false;
BLEServer *pServer;
BLEService *pService;
BLECharacteristic *pCharacteristic;
TFT_eSPI tft = TFT_eSPI();
DS3231 rtc;
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
CountDown = 1;
}
};
void setup() {
Wire.begin();
rtc.setClockMode(false); // Run Once to set 12 true 24hr false
tft.init();
tft.setRotation(1);
BLEDevice::init("T4_Set_Time");
pServer = BLEDevice::createServer();
pService = pServer->createService(SERVICE_UUID);
pServer->setCallbacks(new MyServerCallbacks());
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setValue("");
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
tft.fillScreen(TFT_BLACK);
Get_Time(); // Call routine to set over BLE
tft.fillScreen(TFT_BLACK);
tft.drawRect(0,0,319,239,TFT_RED);
tft.drawLine(0,100,319,100,TFT_RED);
tft.drawLine(0,160,319,160,TFT_RED);
tft.drawLine(160,160,160,239,TFT_RED);
tft.drawLine(160,200,339,200,TFT_RED);
tft.setTextColor(TFT_RED,TFT_BLACK);
tft.drawString("23",40,175,2);// Temperature
tft.drawString(T_emp2,92,175,1);
tft.setTextColor(TFT_YELLOW,TFT_BLACK);
tft.drawString("12:38",50,16,4); // Inititial Time
tft.setTextColor(TFT_WHITE,TFT_BLACK);
tft.drawString("00",250,16,2); // Initial Seconds
tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.drawString("Monday",92,104,2); // Initial Day
tft.setTextColor(TFT_WHITE,TFT_BLACK);
tft.drawString(MONTH [1],161,169,1);// Month
tft.setTextColor(TFT_YELLOW,TFT_BLACK);
tft.drawString("01",221,207,1); // Initial Date
}
void loop() {
Sec = rtc.getSecond(); // Get the seconds
if(L_Sec.toInt() != Sec) {
tft.setTextColor(TFT_BLACK,TFT_BLACK);
tft.drawString(L_Sec,250,16,2);
L_Sec = "0" + String(Sec);
L_Sec = L_Sec.substring(L_Sec.length()-2);
tft.setTextColor(TFT_WHITE,TFT_BLACK);
tft.drawString(L_Sec,250,16,2);
}
Min = rtc.getMinute(); // Get the minutes
if (L_Min.toInt() != Min) {
tft.setTextColor(TFT_BLACK,TFT_BLACK);
tft.drawString(L_Min,155,16,4);
L_Min = "0" + String(Min);
L_Min = L_Min.substring(L_Min.length()-2);
tft.setTextColor(TFT_YELLOW,TFT_BLACK);
tft.drawString(L_Min,155,16,4);
}
Hr = rtc.getHour(h12Flag,pmFlag); //Get the hours
if (L_Hr.toInt() != Hr) {
tft.setTextColor(TFT_BLACK,TFT_BLACK);
tft.drawString(L_Hr,50,16,4);
L_Hr = "0" + String(Hr);
L_Hr = L_Hr.substring(L_Hr.length()-2);
tft.setTextColor(TFT_YELLOW,TFT_BLACK);
tft.drawString(L_Hr,50,16,4);
}
Weekday = rtc.getDoW(); // Get the Day of the week
if (L_Weekday != Weekday) {
tft.setTextColor(TFT_BLACK,TFT_BLACK);
tft.drawString(Dow[L_Weekday],Spc[L_Weekday],104,2);
tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.drawString(Dow[Weekday],Spc[Weekday],104,2);
L_Weekday = Weekday;
}
Temp = rtc.getTemperature(); // Get the temperature
if (L_Temp.toInt() != Temp) {
tft.setTextColor(TFT_BLACK,TFT_BLACK);
tft.drawString(L_Temp,40,175,2);
L_Temp = "0" + String(Temp);
L_Temp = L_Temp.substring(L_Temp.length()-2);
tft.setTextColor(TFT_BLUE,TFT_BLACK);
tft.drawString(L_Temp,40,175,2);
}
Months = rtc.getMonth(century); // Get the Month
if (L_Month != Months) {
tft.setTextColor(TFT_BLACK,TFT_BLACK);
tft.drawString(MONTH[L_Month],161,169,1);
L_Month = Months;
tft.setTextColor(TFT_WHITE,TFT_BLACK);
tft.drawString(MONTH[L_Month],161,169,1);
}
DAY = rtc.getDate(); // Get the date
if (L_DAY.toInt() != DAY) {
tft.setTextColor(TFT_BLACK,TFT_BLACK);
tft.drawString(L_DAY,221,207,1);
L_DAY = "0" + String(DAY);
L_DAY = L_DAY.substring(L_DAY.length()-2);
tft.setTextColor(TFT_YELLOW,TFT_BLACK);
tft.drawString(L_DAY,221,207,1);
}
}
void Get_Time() {
CountDown = 30; // Seconds taken to set the time
tft.setTextColor(TFT_WHITE,TFT_BLACK);
tft.setTextSize(2);
tft.drawString("Waiting For Bluetooth",16,104,2);
tft.setTextSize(3);
tft.drawString(String(CountDown),40,16,4);
while (CountDown) {
while(deviceConnected) {
if(CountDown) {
tft.setTextColor(TFT_BLACK,TFT_BLACK);
tft.drawString(String(CountDown),40,16,4);
CountDown = 0;
tft.setTextSize(2);
tft.drawString("Waiting For Bluetooth",16,104,2);
tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.drawString("BLUETOOOTH CONNECTED",4,104,2);
tft.setTextSize(3);
}
BT_IN = pCharacteristic->getValue();
if (BT_IN.length() == 15) {
pCharacteristic->setValue("");
inString[0]= BT_IN[0]; //Y
inString[1]= BT_IN[1]; //Y
inString[2]= BT_IN[2]; //M
inString[3]= BT_IN[3]; //M
inString[4]= BT_IN[4]; //D
inString[5]= BT_IN[5]; //D
inString[6]= BT_IN[6]; //w
inString[7]= BT_IN[7]; //H
inString[8]= BT_IN[8]; //H
inString[9]= BT_IN[9]; //M
inString[10]= BT_IN[10];//M
inString[11]= BT_IN[11];//S
inString[12]= BT_IN[12];//S
Year = (((inString[0] -48)*10)+(inString[1] -48));
// now month
Months = (((inString[2] -48)*10)+(inString[3] -48));
// now date
date = (((inString[4] -48)*10)+(inString[5] -48));
// now Day of Week
Weekday = (inString[6] -48);
// now hour
Hr = (((inString[7] -48)*10)+(inString[8] -48));
// now minute
Min = (((inString[9] -48)*10)+(inString[10] -48));
// now second
Sec = (((inString[11] -48)*10)+(inString[12] -48));
rtc.setClockMode(false);// set to 24h
rtc.setYear(Year);
rtc.setMonth(Months);
rtc.setDate(date);
rtc.setDoW(Weekday);
rtc.setHour(Hr);
rtc.setMinute(Min);
rtc.setSecond(Sec);
rtc.turnOffAlarm(1);
rtc.turnOffAlarm(2);
delay(600);
BLEDevice:: deinit(true);
delay(600); // Allow RTC registers to set before any read occurs
return;
}
}
delay (1000) ;
tft.setTextColor(TFT_BLACK,TFT_BLACK);
tft.drawString(String(CountDown),40,16,4);
CountDown = CountDown - (CountDown > 0);
tft.setTextColor(TFT_WHITE,TFT_BLACK);
tft.drawString(String(CountDown),40,16,4);
}
BLEDevice:: deinit(true);
delay(600);
}
Comments