/**
Horloge1
pour 02- LILYGO TTGO T5 + 2.13" E-Paper Screen (250 x 122 px)
OK compilé avec type de carte = "ESP32 Dev Module"
**/
#define version1 "4.1"
#include <stdint.h>
String recp_time = "12345678";
String recp_date = "87654321";
#include <GxEPD.h> // note: cette lib inclue la lib "Adafruit_GFX.h" dans laquelle se trouvent les fonctions de base
#include "SPI.h"
#include <Wire.h>
#include "uRTCLib.h"
#include "DHT.h"
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "TPGPS_123";
const char* password = "abcd1234";
const char* srvName_heure = "http://192.168.4.1/heure";
const char* srvName_date = "http://192.168.4.1/date";
uRTCLib rtc(0x68);
//! There are three versions of the 2.13 screen
//#include <GxGDE0213B1/GxGDE0213B1.h> // 2.13" b/w
//#include <GxGDEH0213B72/GxGDEH0213B72.h> // 2.13" b/w new panel
#include <GxGDEH0213B73/GxGDEH0213B73.h> // 2.13" b/w newer panel
#include "chiffres/60_75/chiffres60_75.c"
// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
#define SPI_MOSI 23
#define SPI_MISO -1
#define SPI_CLK 18
#define ELINK_SS 5
#define ELINK_BUSY 4
#define ELINK_RESET 16
#define ELINK_DC 17
#define SDCARD_SS 13
#define SDCARD_CLK 14
#define SDCARD_MOSI 15
#define SDCARD_MISO 2
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
#define DHTPIN 19 // Digital pin connected to the DHT sensor
//#define bouton1 39
//#define led1 12 //const int led1 = 12;
const int led1 = 12;
const int bouton1 = 39;
bool led1_etat = LOW;
bool bouton1_etat; // état bouton1
const uint32_t partial_update_period_s = 1;
const uint32_t full_update_period_s = 6 * 60 * 60;
uint32_t start_time;
uint32_t next_time;
uint32_t previous_time;
uint32_t previous_full_update;
uint32_t memoM1 = 0;
uint32_t memoM2 = 0;
uint32_t currentMillis=0;
const uint32_t tempo1 = 2000; // 2000 ms = 2s
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 2 /* Time ESP32 will go to sleep (secondes) */
uint8_t annee;
uint8_t mois;
uint8_t jour;
uint8_t jour_de_la_semaine;
uint8_t heure=0;
uint8_t minute=0;
uint8_t memo_minute=0;
uint8_t seconde=0;
uint8_t annee_in=0;
uint8_t mois_in=0;
uint8_t jour_in=0;
uint8_t heures_in=0;
uint8_t minutes_in=0;
uint8_t secondes_in=0;
uint8_t W_chiffres = 60;
uint8_t H_chiffres = 75;
uint16_t box1_x = 0;
uint16_t box1_y = 0;
uint16_t box1_w = 249;
uint16_t box1_h = 110;
uint16_t box2_x = 0;
uint16_t box2_y = 121-20;
uint16_t box2_w = 175;
uint16_t box2_h = 20;
GxIO_Class io(SPI, ELINK_SS, ELINK_DC, ELINK_RESET);
GxEPD_Class display(io, ELINK_RESET, ELINK_BUSY);
SPIClass sdSPI(VSPI);
const char *skuNum = "SKU:H239";
int startX = 40, startY = 10;
DHT dht(DHTPIN, DHTTYPE);
uint8_t WiFi_status=0;
static void smartdelay(unsigned long ms)
{
unsigned long start = millis();
while (millis() - start < ms) {;}
}
int connection_WiFi()
{
//Serial.println("Cnx Client WiFi");
WiFi.persistent(false);
WiFi.begin(ssid, password);
delay(2000);
uint8_t n=0;
while(WiFi.status() != WL_CONNECTED)
{
delay(500);
n++;
display.setTextColor(GxEPD_BLACK);
display.setFont(&FreeMonoBold9pt7b);
display.setTextSize(1);
display.setCursor(0, display.height() -2);
display.print(".");
display.updateWindow(box2_x, box2_y, box2_w, box2_h, true);
if (n>10) {return 1;}
// ECRAN_1.print(".");
//Serial.print(".");
}
//Serial.println("");
//Serial.print("Connected to WiFi - IP Address : ");
//Serial.println(WiFi.localIP());
//Serial.println("\n");
return 0;
}
void httpGetTime()
{
//Serial.println("envoi req Heure");
HTTPClient http1;
http1.begin(srvName_heure);
int httpResponseCode = http1.GET();
if (httpResponseCode>0)
{
recp_time = http1.getString();
}
http1.end();
}
void httpGetDate()
{
//Serial.println("envoi req Date");
HTTPClient http2;
http2.begin(srvName_date);
int httpResponseCode = http2.GET();
if (httpResponseCode>0)
{
recp_date = http2.getString();
}
http2.end();
}
void ajuste_time()
{
//Serial.println("ajuste_time");
//Serial.println( recp_time);
if(recp_time.length() == 8)
{
WiFi_status =1;
//String data_in = "11:40:30"
heures_in =(recp_time.substring(0,2)).toInt();
//Serial.print(heures_in); //Serial.print(":");
minutes_in =(recp_time.substring(3,5)).toInt();
//Serial.print(minutes_in); //Serial.print(":");
secondes_in =(recp_time.substring(6,8)).toInt();
//Serial.println(secondes_in);
//secondes_in++; // pour compenser le temps de traitement
if ((heures_in==0) && (minutes_in==0)) { return; }
if (heure != heures_in) {heure = heures_in;}
if (minute != minutes_in) {minute = minutes_in;}
if (seconde != secondes_in) {seconde = secondes_in;}
}
else
{
//Serial.println("y a qq chose qui cloche !");
WiFi_status=0;
}
}
void ajuste_date()
{
//Serial.println("ici7");
if(recp_date.length() == 8)
{
WiFi_status =1;
//Serial.println("ajuste_date");
//Serial.println( recp_date);
// String data_in = "01:02:21"
jour_in =(recp_date.substring(0,2)).toInt();
//Serial.println(jour_in);
mois_in =(recp_date.substring(3,5)).toInt();
//Serial.println(mois_in);
annee_in =(recp_date.substring(6,8)).toInt();
//Serial.println(annee_in);
if (jour != jour_in) {jour = jour_in;}
if (mois != mois_in) {mois = mois_in;}
if (annee != annee_in) {annee = annee_in;}
}
else {WiFi_status=0;}
}
void set_time_par_wifi()
{
display.setTextColor(GxEPD_BLACK);
display.setFont(&FreeMonoBold9pt7b);
display.setTextSize(1);
display.fillRect(box2_x, box2_y, box2_w, box2_h, GxEPD_WHITE);
display.print("Cnx Wifi");
//display.drawRect(box2_x, box2_y, box2_w, box2_h, GxEPD_BLACK); // pour test visuel de la position et taille de la box
//display.updateWindow(box2_x, box2_y, box2_w, box2_h, true);
int w1=connection_WiFi();
if (w1==0)
{
if(WiFi.status()== WL_CONNECTED )
{
//display.print("OK !");
delay(500);
display.fillRect(box2_x, box2_y, box2_w, box2_h, GxEPD_WHITE);
display.setCursor(0, display.height() -2);
display.print("Rx DATE...");
display.updateWindow(box2_x, box2_y, box2_w, box2_h, true);
httpGetDate();
ajuste_date();
display.print(recp_date);
display.updateWindow(box2_x, box2_y, box2_w, box2_h, true);
delay(2000);
}
}
else
{
display.fillRect(box2_x, box2_y, box2_w, box2_h, GxEPD_WHITE);
display.setCursor(0, display.height() -2);
display.print("No WIfI");
display.updateWindow(box2_x, box2_y, box2_w, box2_h, true);
smartdelay(1000);
display.fillRect(box2_x, box2_y, box2_w, box2_h, GxEPD_WHITE);
display.updateWindow(box2_x, box2_y, box2_w, box2_h, true);
return ;
}
//---------------------------------------------------------------------
int w2=connection_WiFi();
if (w2==0)
{
if(WiFi.status()== WL_CONNECTED )
{
//display.print("OK !");
delay(500);
display.fillRect(box2_x, box2_y, box2_w, box2_h, GxEPD_WHITE);
display.setCursor(box2_x+5, box2_y+20);
display.print("Rx TIME...");
display.updateWindow(box2_x, box2_y, box2_w, box2_h, true);
httpGetTime();
ajuste_time();
display.print(recp_time);
display.updateWindow(box2_x, box2_y, box2_w, box2_h, true);
delay(2000); // pour éviter collision accès wifi
}
}
delay(1000);
incremente_heure(6); // pour compenser les delais de traitement
// paramétrage du module RTC DS1307
//Serial.println("parametrage du module RTC DS1307");
rtc.set(seconde, minute, heure, jour_de_la_semaine, jour, mois, annee);
delay(500);
/*
display.fillRect(box2_x, box2_y, box2_w, box2_h, GxEPD_WHITE);
for(int8_t n =0; n<4; n++)
{
display.updateWindow(box2_x, box2_y, box2_w, box2_h, true);
}
*/
display.fillRect(box2_x, box2_y, box2_w, box2_h, GxEPD_WHITE);
display.updateWindow(box2_x, box2_y, box2_w, box2_h, true);
delay(100);
//display.update(); //full pour éviter de garder des moirages
//Serial.println("deconnexion WiFi");
WiFi.disconnect();
}
void Set_Time()
{
// appelée par appui sur le bouton (en bord de carte) après avoir correctement paramétré ces données.
uint8_t second = 3;
uint8_t minute = 39;
uint8_t hour = 5;
uint8_t dayOfWeek = 4; // toutefois le jour de la semaine sera recalculé plus bas, en temps réel
uint8_t dayOfMonth = 20;
uint8_t month = 1;
uint8_t year = 21; // 2021
// ensuite je re-commente la ligne ci-dessous pour éviter de reprogrammer l'heure en appuyant sur le bouton par inadvertance...
// rtc.set(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}
void incremente_heure(uint8_t nb_s)
{
for (uint8_t n=0; n<nb_s; n++)
{
if (seconde < 59) {seconde+=1;}
else
{
seconde=0;
if (minute < 59) {minute+=1;}
else
{
minute=0;
if (heure < 23) {heure+=1;}
else
heure=0;
}
}
}
}
void setup()
{
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
delay (1000);
pinMode(bouton1, INPUT);
pinMode(led1, OUTPUT);
//Serial.begin(115200);
//Serial.println("//Serial OK");
#ifdef ARDUINO_ARCH_ESP8266
URTCLIB_WIRE.begin(0, 2); // D3 and D4 on ESP8266
#else
URTCLIB_WIRE.begin();
#endif
start_time = next_time = previous_time = previous_full_update = millis();
display.init();
display.setRotation(1);
//display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setFont(&FreeMonoBold12pt7b);
display.setCursor(0, 0);
//esp_sleep_enable_ext0_wakeup((gpio_num_t)BUTTON_PIN, LOW);
display.fillScreen(GxEPD_WHITE);
//display.eraseDisplay();
display.update();
dht.begin();
start_time = next_time = previous_time = previous_full_update = millis();
Lit_RTC();
affichages();
//set_time_par_wifi();
//delay(1000);
//affichages();
}
void print_big_chiffre(uint8_t nb, uint16_t x0 ,uint16_t y0) //avec bitmaps perso
{
uint16_t w0=60;
uint16_t h0=75;
switch (nb)
{
case 0: {display.drawBitmap(chiffre0, x0, y0, w0, h0, GxEPD_BLACK); } break;
case 1: {display.drawBitmap(chiffre1, x0, y0, w0, h0, GxEPD_BLACK); } break;
case 2: {display.drawBitmap(chiffre2, x0, y0, w0, h0, GxEPD_BLACK); } break;
case 3: {display.drawBitmap(chiffre3, x0, y0, w0, h0, GxEPD_BLACK); } break;
case 4: {display.drawBitmap(chiffre4, x0, y0, w0, h0, GxEPD_BLACK); } break;
case 5: {display.drawBitmap(chiffre5, x0, y0, w0, h0, GxEPD_BLACK); } break;
case 6: {display.drawBitmap(chiffre6, x0, y0, w0, h0, GxEPD_BLACK); } break;
case 7: {display.drawBitmap(chiffre7, x0, y0, w0, h0, GxEPD_BLACK); } break;
case 8: {display.drawBitmap(chiffre8, x0, y0, w0, h0, GxEPD_BLACK); } break;
case 9: {display.drawBitmap(chiffre9, x0, y0, w0, h0, GxEPD_BLACK); } break;
}
}
void affiche_heure()
{
display.fillRect(box1_x, box1_y, box1_w, box1_h, GxEPD_WHITE);
//display.setCursor(box1_x, cursor_y);
uint8_t x0 = box1_x;
uint8_t y0 = 5;
uint8_t heures_unites;
uint8_t heures_dizaines;
heures_unites = heure %10;
heures_dizaines = heure /10;
print_big_chiffre(heures_dizaines, x0, y0);
print_big_chiffre(heures_unites, x0+56, y0);
x0+=133;
uint8_t minutes_unites ;
uint8_t minutes_dizaines;
minutes_unites = minute %10;
minutes_dizaines = minute /10;
print_big_chiffre(minutes_dizaines, x0, y0);
print_big_chiffre(minutes_unites, x0+56, y0);
display.setCursor(106, 70);
display.setTextSize(3);
display.println(":");
display.updateWindow(box1_x, box1_y, box1_w, box1_h, true);
}
void calcul_jour_de_la_semaine()
{
// d'après l'Algorithme de Mike Keith
uint16_t d, m, y, z, jds;
d=jour;
m=mois;
y=annee;
if (m>=3)
{
jds = ( ((23*m)/9) + d + 4 + y + (y/4) - (y/100) + (y/400) - 2 ) % 7;
}
else
{
z = y-1;
jds = ( ((23*m)/9) + d + 4 + y + (z/4) - (z/100) + (z/400) ) % 7;
}
jour_de_la_semaine = jds;
}
uint8_t decToBcd( int val )
{
return (uint8_t) ((val / 10 * 16) + (val % 10));
}
String conv_time(uint8_t t)
{
String r;
r=String(t);
if (t<10) {r="0"+r;}
return r;
}
void affiche_date()
{
display.fillRect(box2_x, box2_y, box2_w, box2_h, GxEPD_WHITE);
String date;
calcul_jour_de_la_semaine();
switch (jour_de_la_semaine)
{
case 0: { date+="DIM ";} break;
case 1: { date+="LUN ";} break;
case 2: { date+="MAR ";} break;
case 3: { date+="MER ";} break;
case 4: { date+="JEU ";} break;;
case 5: { date+="VEN ";} break;
case 6: { date+="SAM ";} break;
}
date += String(conv_time(jour))+" ";
switch (mois)
{
case 1: {date+="JAN"; } break;
case 2: {date+="FEV"; } break;
case 3: {date+="MARS";} break;
case 4: {date+="AVR"; } break;
case 5: {date+="MAI"; } break;
case 6: {date+="JUIN";} break;
case 7: {date+="JUIL";} break;
case 8: {date+="AOUT";} break;
case 9: {date+="SEPT";} break;
case 10: {date+="OCT"; } break;
case 11: {date+="NOV"; } break;
case 12: {date+="DEC"; } break;
}
date += " 20"+String(annee);
//date;
uint16_t x0=290, y0=75;
display.setTextColor(GxEPD_BLACK);
display.setFont(&FreeMonoBold9pt7b);
display.setTextSize(1);
display.setCursor(0, display.height() -2);
display.print(date);
display.updateWindow(box2_x, box2_y, box2_w, box2_h, true);
currentMillis = millis();
if (currentMillis > 2000) memoM1= currentMillis - 2000; // pour afficher +rapidement au départ
}
void affiche_temperature(double T)
{
uint16_t y0 = 122; // position verticale du bord supérieur de la box
uint16_t dy = 34; // dimension verticale de la box
uint16_t box2_x = 180; // position horizontale du bord gauche de la box
uint16_t box2_y = y0-dy;
uint16_t box2_w = 65; // largeur de la box
uint16_t box2_h = dy;
display.fillRect(box2_x, box2_y, box2_w, box2_h, GxEPD_WHITE); // efface la surface de la box (en RAM de l'afficheur)
display.setTextColor(GxEPD_BLACK);
display.setFont(&FreeMonoBold12pt7b);
display.setTextSize(1,2);
display.setCursor(box2_x, y0-4);
display.print(T,1);
display.setFont(&FreeMonoBold9pt7b);
display.setTextSize(1);
display.setCursor(box2_x +30, display.height() -20);
display.print("o"); // le signe 'degré' (° Celsius en l'occurence) , absent de la police de caractères
// display.drawRect(box2_x, box2_y, box2_w, box2_h, GxEPD_BLACK); // pour test visuel de la position et taille de la box
display.updateWindow(box2_x, box2_y, box2_w, box2_h, true); // affichage physique sur l'e-paper
}
void affichages()
{
affiche_heure();
affiche_date();
float H1 = dht.readHumidity();
double T1 = dht.readTemperature(); // °C par defaut
//Serial.print(F("Temperature: ")); ////Serial.println(T1);
affiche_temperature(T1);
}
void Lit_RTC()
{
rtc.refresh();
annee=rtc.year();
mois=rtc.month();
jour=rtc.day();
jour_de_la_semaine=rtc.dayOfWeek();
heure = rtc.hour();
memo_minute = minute;
minute = rtc.minute();
seconde = rtc.second();
}
void loop()
{
bouton1_etat = digitalRead(bouton1);
if (bouton1_etat == 0)
{
Set_Time();
for(int n=0; n<20; n++)
{
digitalWrite(led1, HIGH);
delay(20);
digitalWrite(led1, LOW);
delay(20);
}
}
currentMillis = millis();
if(currentMillis - memoM1 >= tempo1)
{
memoM1 = currentMillis;
// B = digitalRead(BUTTON_PIN);
digitalWrite(led1, HIGH); // allume la led (ajoutée) (pour un bref petit flash) -> test visuel du fonctionnement
Lit_RTC();
digitalWrite(led1, LOW); // éteint la led ajoutée
if(minute != memo_minute)
{
affichages();
}
}
esp_light_sleep_start();
}