/*
* Title: ESP32 RTC_WEB + ILI9341_SPI LCD
* Author: @red9030
*
* References: https://wokwi.com/projects/325324981270479442
*/
/*
*****************************************************
* LIBRERIAS
*****************************************************
*/
#include <Wire.h> //Librería para uso de protocolo I2C
#include "SPI.h" //Librería para uso de protocolo SPI
#include "Adafruit_GFX.h" //Librería para gr´ficar en pantalla TFT
#include "Adafruit_ILI9341.h" //Librería para control de pantalla TFT ILI9341
//#include "RTClib.h" //Librería para conexión DS1307
//#include <ESP32Time.h> //Librería para uso del RTC interno ESP32
/*
*****************************************************
* VARIABLES
*****************************************************
*/
//Variables para TFT
#define TFT_DC 2 //azul TFT RST pin is connected to arduino pin 2
#define TFT_CS 15 //rosa TFT RST pin is connected to arduino pin 15
#define TFT_RST 4 //amarillo TFT RST pin is connected to arduino pin 4
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
//NOTA: Para usar los colores escribir el formato ILI9341_COLOR
//Variables uso RTC
//RTC_DS1307 rtc;
//Dimensiones pantalla portrait
/*
const int TFT_Width = 240;
const int TFT_Height = 320;
const int TFT_MINX = 0;
const int TFT_MAXX = 130; // TFT_WIDTH - TFT_HEIGHT/3
const int TFT_MINY = 0;
const int TFT_MAXY = TFT_Height;
*/
//Botonres para cambio de parámetros
#define button1 25 // Button B1 is connected to Arduino pin 25
#define button2 26 // Button B2 is connected to Arduino pin 26
//Variables para reloj
char Time[] = " : : ";
char Calendar[] = " / /20 ";
char temperature[] = " 00.00";
char temperature_msb;
byte i, second, minute, hour, day, date, month, year, temperature_lsb;
/*
*****************************************************
* SETUP
*****************************************************
*/
void setup(void) {
//Serial.begin(115200);
//Serial.println("Loading...");
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
tft.begin();
tft.fillScreen(ILI9341_BLACK); // initialize a ILI9341 chip, black tab
tft.setRotation(0); //cambia la rotacion de la pantalla
tft.fillScreen(ILI9341_BLACK);
//Wire.begin(); // Join i2c bus
tft.drawFastHLine(0, 53, tft.width(), ILI9341_BLUE); // Draw horizontal blue line at position (0, 53)
tft.drawFastHLine(0, 106, tft.width(), ILI9341_BLUE); // Draw horizontal blue line at position (0, 106)
draw_text(52, 64, "TIME", 1, ILI9341_MAGENTA);
draw_text(30, 117, "TEMPERATURE", 1, ILI9341_RED);
}
/*
*****************************************************
* LOOP
*****************************************************
*/
void loop() {
//DateTime now = rtc.now();
if(!digitalRead(button1)){ // If button B1 is pressed
i = 0;
while(!digitalRead(button1)); // Wait for button B1 release
while(true){
while(!digitalRead(button2)){ // While button B2 pressed
day++; // Increment day
if(day > 7) day = 1;
display_day(); // Call display_day function
delay(200); // Wait 200 ms
}
tft.fillRect(40, 10, 54, 8, ILI9341_BLACK); // Draw rectangle (earase day from the display)
blink_parameter(); // Call blink_parameter function
display_day(); // Call display_day function
blink_parameter(); // Call blink_parameter function
if(!digitalRead(button1)) // If button B1 is pressed
break;
}
date = edit(4, 27, date); // Edit date
month = edit(40, 27, month); // Edit month
year = edit(100, 27, year); // Edit year
hour = edit(16, 81, hour); // Edit hours
minute = edit(52, 81, minute); // Edit minutes
// Convert decimal to BCD
minute = ((minute / 10) << 4) + (minute % 10);
hour = ((hour / 10) << 4) + (hour % 10);
date = ((date / 10) << 4) + (date % 10);
month = ((month / 10) << 4) + (month % 10);
year = ((year / 10) << 4) + (year % 10);
// End conversion
// Write data to DS3231 RTC
Wire.beginTransmission(0x68); // Start I2C protocol with DS3231 address
Wire.write(0); // Send register address
Wire.write(0); // Reset sesonds and start oscillator
Wire.write(minute); // Write minute
Wire.write(hour); // Write hour
Wire.write(day); // Write day
Wire.write(date); // Write date
Wire.write(month); // Write month
Wire.write(year); // Write year
Wire.endTransmission(); // Stop transmission and release the I2C bus
delay(200); // Wait 200ms
}
Wire.beginTransmission(0x68); // Start I2C protocol with DS3231 address
Wire.write(0); // Send register address
Wire.endTransmission(false); // I2C restart
Wire.requestFrom(0x68, 7); // Request 7 bytes from DS3231 and release I2C bus at end of reading
second = Wire.read(); // Read seconds from register 0
minute = Wire.read(); // Read minuts from register 1
hour = Wire.read(); // Read hour from register 2
day = Wire.read(); // Read day from register 3
date = Wire.read(); // Read date from register 4
month = Wire.read(); // Read month from register 5
year = Wire.read(); // Read year from register 6
Wire.beginTransmission(0x68); // Start I2C protocol with DS3231 address
Wire.write(0x11); // Send register address
Wire.endTransmission(false); // I2C restart
Wire.requestFrom(0x68, 2); // Request 2 bytes from DS3231 and release I2C bus at end of reading
temperature_msb = Wire.read(); // Read temperature MSB
temperature_lsb = Wire.read(); // Read temperature LSB
display_day();
DS3231_display(); // Diaplay time & calendar
delay(50); // Wait 50ms
}
/*
*****************************************************
* FUNCIONES
*****************************************************
*/
//====================================================
// Función para hacer TEST
//====================================================
void hola_mundo(){
tft.setCursor(20, 120);
tft.setTextColor(ILI9341_RED);
tft.setTextSize(3);
tft.println("Hello ESP32");
tft.setCursor(24, 160);
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(2);
tft.println("I can do SPI :-)");
}
//====================================================
// Función para mostrar pantalla de carga
//====================================================
void display_day(){
switch(day){
case 1: draw_text(40, 10, " SUNDAY ", 1, ILI9341_CYAN); break;
case 2: draw_text(40, 10, " MONDAY ", 1, ILI9341_CYAN); break;
case 3: draw_text(40, 10, " TUESDAY ", 1, ILI9341_CYAN); break;
case 4: draw_text(40, 10, "WEDNESDAY", 1, ILI9341_CYAN); break;
case 5: draw_text(40, 10, "THURSDAY ", 1, ILI9341_CYAN); break;
case 6: draw_text(40, 10, " FRIDAY ", 1, ILI9341_CYAN); break;
default: draw_text(40, 10, "SATURDAY ", 1, ILI9341_CYAN);
}
}
void DS3231_display(){
// Convert BCD to decimal
second = (second >> 4) * 10 + (second & 0x0F);
minute = (minute >> 4) * 10 + (minute & 0x0F);
hour = (hour >> 4) * 10 + (hour & 0x0F);
date = (date >> 4) * 10 + (date & 0x0F);
month = (month >> 4) * 10 + (month & 0x0F);
year = (year >> 4) * 10 + (year & 0x0F);
// End conversion
Time[7] = second % 10 + 48;
Time[6] = second / 10 + 48;
Time[4] = minute % 10 + 48;
Time[3] = minute / 10 + 48;
Time[1] = hour % 10 + 48;
Time[0] = hour / 10 + 48;
Calendar[9] = year % 10 + 48;
Calendar[8] = year / 10 + 48;
Calendar[4] = month % 10 + 48;
Calendar[3] = month / 10 + 48;
Calendar[1] = date % 10 + 48;
Calendar[0] = date / 10 + 48;
if(temperature_msb < 0){
temperature_msb = abs(temperature_msb);
temperature[0] = '-';
}
else
temperature[0] = ' ';
temperature_lsb >>= 6;
temperature[2] = temperature_msb % 10 + 48;
temperature[1] = temperature_msb / 10 + 48;
if(temperature_lsb == 0 || temperature_lsb == 2){
temperature[5] = '0';
if(temperature_lsb == 0) temperature[4] = '0';
else temperature[4] = '5';
}
if(temperature_lsb == 1 || temperature_lsb == 3){
temperature[5] = '5';
if(temperature_lsb == 1) temperature[4] = '2';
else temperature[4] = '7';
}
draw_text(4, 27, Calendar, 3, ILI9341_YELLOW);
draw_text(16, 81, Time, 3, ILI9341_GREEN);
draw_text(14, 134, temperature, 2, ILI9341_WHITE);
tft.drawCircle(90, 134, 3, ILI9341_WHITE); // Degree symbol (°)
draw_text(96, 134, "C", 3, ILI9341_WHITE);
}
void blink_parameter(){
byte j = 0;
while(j < 10 && digitalRead(button1) && digitalRead(button2)){
j++;
delay(25);
}
}
byte edit(byte x_pos, byte y_pos, byte parameter){
char text[3];
uint16_t color = ILI9341_YELLOW;
sprintf(text,"%02u", parameter);
if(i == 3 || i == 4)
color = ILI9341_GREEN;
while(!digitalRead(button1)); // Wait until button B1 released
while(true){
while(!digitalRead(button2)){ // If button (pin #9) is pressed
parameter++;
if(i == 0 && parameter > 31) // If date > 31 ==> date = 1
parameter = 1;
if(i == 1 && parameter > 12) // If month > 12 ==> month = 1
parameter = 1;
if(i == 2 && parameter > 99) // If year > 99 ==> year = 0
parameter = 0;
if(i == 3 && parameter > 23) // If hours > 23 ==> hours = 0
parameter = 0;
if(i == 4 && parameter > 59) // If minutes > 59 ==> minutes = 0
parameter = 0;
sprintf(text,"%02u", parameter);
draw_text(x_pos, y_pos, text, 2, color);
delay(200); // Wait 200ms
}
tft.fillRect(x_pos, y_pos, 22, 16, ILI9341_BLACK);
blink_parameter();
draw_text(x_pos, y_pos, text, 2, color);
blink_parameter();
if(!digitalRead(button1)){ // If button (pin #8) is pressed
i++; // Increament 'i' for the next parameter
return parameter; // Return parameter value and exit
}
}
}
void draw_text(byte x_pos, byte y_pos, char *text, byte text_size, uint16_t text_color) {
tft.setCursor(x_pos, y_pos);
tft.setTextSize(text_size);
tft.setTextColor(text_color, ILI9341_BLACK);
tft.print(text);
}