luni, 23 februarie 2026

Ceas LCD 2x16 cu termometru

 Va salut !

Si inca un montaj cu Wemos D1 mini (sper ca nu v-am plictisit !). Un ceas cu termometru (DS18B20), cu display LCD 2x16, conectare la WiFi. Functioneaza perfect, de multa vreme. 

 


//ceas cu termometru, ora iarna/vara, cu modificari AI
//
// vers.febr.2026-bug fixed
//
#ifdef ESP8266
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif
#include <Wire.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <time.h>
#include <LiquidCrystal_I2C.h>

// --- CONFIGURARE ---
#define ONE_WIRE_BUS D3
const char* ssid = "your_SSID";
const char* password = "your_PSW";
const char* TZ_INFO = "EET-2EEST,M3.5.0/3,M10.5.0/4";
#define WIFI_RETRY_LIMIT 15
#define WIFI_RETRY_DELAY 1000

// Obiecte Globale
LiquidCrystal_I2C lcd(0x27, 16, 2);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

byte customDegreeC[] = {
0x08, 0x14, 0x08, 0x07,
0x08, 0x08, 0x07, 0x00
};

tm timeinfo;
time_t now;
String StrTempC = "---";
int prevSec = -1;
float tempSum = 0;
int tempCount = 0;
#define TEMP_SAMPLES 5
unsigned long lastSensorMillis = 0;

char* getDOW(uint8_t tm_wday) {
switch (tm_wday) {
case 1: return (char*)"Luni"; case 2: return (char*)"Marti"; case 3: return (char*)"Miercuri";
case 4: return (char*)"Joi"; case 5: return (char*)"Vineri"; case 6: return (char*)"Sambata";
case 0: return (char*)"Duminica"; default: return (char*)"Error";
}
}

void showTimeDateTemp(tm *localTime) {
char oraStr[9];
sprintf(oraStr, "%02d:%02d:%02d", localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
String tVal = StrTempC;
while (tVal.length() < 5) tVal = " " + tVal;
int spatiiMijloc1 = 16 - 8 - 6;
lcd.setCursor(0, 0);
lcd.print(oraStr);
for(int i=0; i < spatiiMijloc1; i++) lcd.print(" ");
lcd.print(tVal);
if (StrTempC != "Err") lcd.write(0); else lcd.print(" ");

char dataStr[6];
sprintf(dataStr, "%02d/%02d", localTime->tm_mday, localTime->tm_mon + 1);
char* dow = getDOW(localTime->tm_wday);
int spatiiMijloc2 = 16 - 5 - strlen(dow);
lcd.setCursor(0, 1);
lcd.print(dataStr);
for(int i=0; i < spatiiMijloc2; i++) lcd.print(" ");
lcd.print(dow);
}

void setup() {
sensors.begin();
sensors.setWaitForConversion(false); // REPARĂ BUG-UL: Nu mai blochează procesorul
Serial.begin(115200);
Wire.begin(4, 5);
delay(1000);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.createChar(0, customDegreeC);

lcd.setCursor(0, 0);
lcd.print("Conectare WiFi..");
WiFi.begin(ssid, password);
int incercari = 0;
while (WiFi.status() != WL_CONNECTED && incercari < WIFI_RETRY_LIMIT) {
delay(WIFI_RETRY_DELAY);
lcd.setCursor(0, 1);
lcd.print("Incercari: "); lcd.print(incercari + 1);
incercari++;
}

if (WiFi.status() == WL_CONNECTED) {
lcd.clear();
lcd.setCursor(0, 0); lcd.print("WiFi:"); lcd.print(WiFi.SSID());
lcd.setCursor(0, 1); lcd.print("IP:"); lcd.print(WiFi.localIP());
delay(3000);
} else {
lcd.clear();
lcd.setCursor(0, 0); lcd.print("Eroare WiFi !");
lcd.setCursor(0, 1); lcd.print("Resetare ...");
delay(5000);
ESP.restart();
}

lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sincro timp...");
configTime(0, 0, "pool.ntp.org", "ro.pool.ntp.org");
setenv("TZ", TZ_INFO, 1);
tzset();

int ntp_timeout = 0;
time_t acum = time(nullptr);
struct tm *ti = localtime(&acum);
while (ti->tm_year < 120 && ntp_timeout < 30) {
delay(1000); acum = time(nullptr); ti = localtime(&acum);
lcd.setCursor(ntp_timeout % 16, 1); lcd.print(".");
ntp_timeout++;
}
if (ti->tm_year < 120) ESP.restart();
lcd.clear();
}

void loop() {
time(&now);
localtime_r(&now, &timeinfo);

// Afisare imediata la schimbarea secundei (fara blocaj)
if (timeinfo.tm_sec != prevSec) {
showTimeDateTemp(&timeinfo);
prevSec = timeinfo.tm_sec;
}

// Gestionare senzor fara a opri timpul in loc
if (millis() - lastSensorMillis >= 2000) {
float t = sensors.getTempCByIndex(0); // Citeste valoarea deja calculata
if (t <= -126.0 || t >= 85.0) {
StrTempC = "Err";
tempCount = 0; tempSum = 0;
} else {
tempSum += t;
tempCount++;
if (tempCount >= TEMP_SAMPLES) {
StrTempC = String(tempSum / TEMP_SAMPLES, 1);
tempSum = 0; tempCount = 0;
}
}
sensors.requestTemperatures(); // Porneste noua conversie "in fundal"
lastSensorMillis = millis();
}
}

Niciun comentariu:

Trimiteți un comentariu