Jump to content
ELFORUM - Forumul electronistilor
fratello

Wemos D1 - ceas, termometru - temperaturi negative ??

Recommended Posts

Va salut ! Prin "combinarea" mai multor programe gasite pe net, am facut un ceas-termometru cu Wemos D1 si display LCD. Functioneaza bine ... DAR nu stiu cum sa afisez temperaturi negative !!! Postez codul integral, poate cineva cu experienta ma poate ajuta. Multumesc anticipat !

// by ND - 2021
#ifdef ESP8266
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif
#include <Arduino.h>
#define ONE_WIRE_BUS 0
#include <OneWire.h>
#include <DallasTemperature.h>
#include <time.h>
#include <LiquidCrystal_I2C.h> 
#include <stdio.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);  // Configure LiquidCrystal_I2C library with 0x27 address, 16 columns and 2 rows

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


OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
const char* ssid = "xxxxxxxx";            
const char* password = "yyyyyy";      

const char* NTP_SERVER = "ch.pool.ntp.org";
const char* TZ_INFO    = "EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00";

tm timeinfo;
time_t now;
long unsigned lastNTPtime;
unsigned long lastEntryTime;
String StrTempC;

String readDSTemperatureC() {
sensors.requestTemperatures();
float tempC = sensors.getTempCByIndex(0);

if(tempC == -127.00) {
Serial.println("Failed to read from DS18B20 sensor");
return "--";
} else {
Serial.print("Temperature Celsius: ");
Serial.println(tempC,1);
}
return String(tempC,1);
}


void setup() 
{
sensors.begin();
  Serial.begin(115200);
  lcd.begin(4, 5);                   // Initialize I2C LCD module (SDA = D2, SCL = D1)

  WiFi.begin(ssid, password);

  Serial.print("Connecting to network");
  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);    
    if (++counter > 100) 
      ESP.restart();
    Serial.print( "." );
  }
  Serial.println("\nWiFi connected\n\n");

  configTime(0, 0, NTP_SERVER);
  setenv("TZ", TZ_INFO, 1);

if (getTimeReducedTraffic(43200000))
  {  
    // wait up to 10sec to sync
  } 
  else 
  {
    Serial.println("Time not set");
    ESP.restart();
  }
  showTime(&timeinfo);
  lastNTPtime = time(&now);
  lastEntryTime = millis();

  lcd.createChar(0, customChar);
  lcd.home();
  lcd.write(0);
}

void loop() 
{
  getTimeReducedTraffic(43200000);
  showTime(&timeinfo);
  delay(1000);
}

bool getTimeReducedTraffic(int ms)
{
  {
    uint32_t start = millis();
    do
    {
      time(&now);
      localtime_r(&now, &timeinfo);
      delay(10);
    } while (((millis() - start) <= (1000000 * ms)) && (timeinfo.tm_year < (2016 - 1900)));
    
    if (timeinfo.tm_year <= (2016 - 1900)) 
        return false;  // the NTP call was not successful
    
    Serial.print("Time Now: ");  
    Serial.println(now); 
    StrTempC = readDSTemperatureC();
    Serial.print(StrTempC);
  }
  return true;
lcd.clear();
}

void showTime(tm *localTime) 
{
  //print to serial terminal if you want ; remove // from bellow
  //Serial.print(localTime->tm_mday);
  //Serial.print('/');
  //Serial.print(localTime->tm_mon + 1);
  //Serial.print('/');
  //Serial.print(localTime->tm_year - 100);
  //Serial.print('-');
  //Serial.print(localTime->tm_hour);
  //Serial.print(':');
  //Serial.print(localTime->tm_min);
  //Serial.print(':');
  //Serial.print(localTime->tm_sec);
  //Serial.print(" Day of Week ");
  //Serial.println(localTime->tm_wday);
  //Serial.println();

  //display on LCD
  char time_output[40];
  lcd.setCursor(0, 0);
  sprintf(time_output, "%02d:%02d:%02d", localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
  lcd.print(time_output);

  lcd.setCursor(0,1);
  sprintf(time_output, "%02d/%02d/%02d", localTime->tm_mday, localTime->tm_mon + 1, localTime->tm_year+1900);
  lcd.print(time_output);


  lcd.setCursor(11, 0); //
  lcd.print(getDOW(localTime->tm_wday));


// urmatoarele linii nu functioneaza, temperatura este afisata in aceeasi pozitie - 11
if (sensors.getTempCByIndex(0) > 9.9) {
    lcd.setCursor(11, 1);
    lcd.print(StrTempC);
}
else if (sensors.getTempCByIndex(0) < 9.9) {
    lcd.clear();
    lcd.setCursor(12, 1);
    lcd.print(StrTempC);
}

    lcd.setCursor(15, 1);
    lcd.write(0);
}

char * getDOW(uint8_t tm_wday)
{
  switch(tm_wday)
  {
    case 1:
      return " Luni";
      break;
    case 2:
      return "Marti";
      break;
    case 3:
      return "Mier.";
      break;
    case 4:
      return "  Joi";
      break;
    case 5:
      return " Vin.";
      break;
    case 6:
      return "Samb.";
      break;
    case 0:
      return " Dum.";
      break;
    default:
      return "Error";
      break;
  }
}

 

ceas.jpg

Edited by fratello
Link to post
Share on other sites

Salut,

  Vad ca datele sunt printate si pe Serial, acolo e ok partea cu temperaturi negative? Pentru temperatura vad ca e folosit "String" care este de evitat pe cat posibil, este foarte neeficient si poate cauza probleme de memorie. Nu am lucrat cu "String" uri insa posibil cand se face conversia temperaturii de la "float" la "string" sa se piarda partea negativa in cazul in care String nu suporta sa converteasca numere negative. Daca partea de Serial.print din functia "readDSTemperatureC" scrie corect in terminal temperatura negativa atunci trebuie putin refacut si scapat de "String", se paote inlocuii cu un char* si conversia sa se faca cu "sprintf". Verifica intai ce apare in terminal si daca acolo e ok te ajut cu scapatul de String.

Link to post
Share on other sites

Daca tot cenu merge e scris simbolul "-", la inceputul afisarii, testezi daca temperatura e negativa. Daca da, afisezi "-" si inmultesti rezultatul cu -1, dupa care continui.

Daca ai probleme si la conversia float -> string e mai complicat.

 

// urmatoarele linii nu functioneaza, temperatura este afisata in aceeasi pozitie - 11
double dTempAfis = sensors.getTempCByIndex(0);
if(dTempAfis < 0){
    lcd.setCursor(10, 1);
    lcd.print("-");                  
}
dTempAfis *= -1; 
if ( dTempAfis > 9.9) {
    lcd.setCursor(11, 1);
    lcd.print(StrTempC);
}
else if (sensors.getTempCByIndex(0) < 9.9) {
    lcd.clear();
    lcd.setCursor(12, 1);
    lcd.print(StrTempC);
}
Link to post
Share on other sites
Posted (edited)

Nu am mai avut rabdare si am testat... In serial.monitor temperatura este afisata corect cu comanda :

Serial.print(StrTempC);

 

Dl.Liviu, cu codul postat de dvs functionarea este urmatoarea  :

a)-temperaturile > 9.9 nu sunt afisate

b)-temperaturile sub 9.9 sunt afisate corect pana la 0.0

c)-temperaturile sub 0.0 sunt afisate doar cu cifra intregilor (-1. 'C) . 

Pct.c) cred ca se rezolva prin mutarea cursorului la stanga cu o pozitie (sper sa nu fie si temperaturi sun -9.9 'C :) )

 

LE :...si dupa scoaterea din congelator a senzorului, temperatura arata nu mai creste peste 9,8 'C (???).

Edited by fratello
Link to post
Share on other sites

Clar, inmultirea cu -1 trebuia numai pentru temperaturile negative, sorry:

// urmatoarele linii nu functioneaza, temperatura este afisata in aceeasi pozitie - 11
double dTempAfis = sensors.getTempCByIndex(0);
if(dTempAfis < 0){
    lcd.setCursor(10, 1);
    lcd.print("-");                  
    dTempAfis *= -1; 
}
                  
if ( dTempAfis > 9.9) {
    lcd.setCursor(11, 1);
    lcd.print(StrTempC);
} else {
    lcd.clear();
    lcd.setCursor(12, 1);
    lcd.print(StrTempC);
}

 

A propos, pe forum suntem coledzi, asa ca te rog, Liviu si tu. Merci.

Edited by Liviu M
Link to post
Share on other sites

Multumesc !

Acum este afisata corect temperatura >9.9 'C. Din pacate e prea tarziu sa mai umblu la congelator .... Testez maine si revin cu rezultatele.

Toate cele bune !

Link to post
Share on other sites

Am revenit ...

Temperatura mai mica de 0.0 grade este afisata " -x.'C"

Temperatura mai mica de 9.9 grade este afisata "--xx.'C"

In ambele cazuri nu mai este afisata zecimala.

Este corecta doar afisarea pentru temperaturile pozitive !

Multumesc !

Link to post
Share on other sites

Pune, te rog, un Serial.println(StrTempC) inainte de modificarea mea si posteaza rezultatul in cele doua cazuri negative. Ca ma tem ca problema e la conversia float->string.

// urmatoarele linii nu functioneaza, temperatura este afisata in aceeasi pozitie - 11
Serial.println(StrTempC);
double dTempAfis = sensors.getTempCByIndex(0);
if(dTempAfis < 0){
...

)

Edited by Liviu M
Link to post
Share on other sites

Mai jos o parte din rezultatul afisarii pe serial.

Time Now: 1616683293
Temperature Celsius: 1.8
1.81.8
1.8
Time Now: 1616683294
Temperature Celsius: 1.3
1.31.3
1.3
Time Now: 1616683295
Temperature Celsius: 0.9
0.90.9
0.9
Time Now: 1616683296
Temperature Celsius: 0.6
0.60.6
0.6
Time Now: 1616683297
Temperature Celsius: 0.1
0.10.1
0.1
Time Now: 1616683298
Temperature Celsius: -0.3
-0.3-0.3
-0.3
Time Now: 1616683300
Temperature Celsius: -0.6
-0.6-0.6
-0.6
Time Now: 1616683301
Temperature Celsius: -0.9
-0.9-0.9
-0.9
Time Now: 1616683302
Temperature Celsius: -1.3
-1.3-1.3
-1.3
Time Now: 1616683303
Temperature Celsius: -1.6
-1.6-1.6
-1.6
Time Now: 1616683304
Temperature Celsius: -1.9
-1.9-1.9
-1.9
Time Now: 1616683305
Temperature Celsius: -2.3
-2.3-2.3
-2.3
Time Now: 1616683306
Temperature Celsius: -2.6
-2.6-2.6
-2.6
Time Now: 1616683308
Temperature Celsius: -2.9
-2.9-2.9
-2.9
Time Now: 1616683309
Temperature Celsius: -3.2
-3.2-3.2
-3.2
Time Now: 1616683310
Temperature Celsius: -3.5
-3.5-3.5
-3.5
Time Now: 1616683311
Temperature Celsius: -3.8
-3.8-3.8
-3.8
Time Now: 1616683312
Temperature Celsius: -4.1
-4.1-4.1
-4.1
Time Now: 1616683313
Temperature Celsius: -4.4
-4.4-4.4
-4.4
Time Now: 1616683314
Temperature Celsius: -4.8
-4.8-4.8
-4.8
Time Now: 1616683316
Temperature Celsius: -5.1
-5.1-5.1
-5.1
Time Now: 1616683317
Temperature Celsius: -5.3
-5.3-5.3
-5.3
Time Now: 1616683318
Temperature Celsius: -5.6
-5.6-5.6
-5.6
Time Now: 1616683319
Temperature Celsius: -5.9
-5.9-5.9
-5.9
Time Now: 1616683320
Temperature Celsius: -6.1
-6.1-6.1
-6.1
Time Now: 1616683321
Temperature Celsius: -6.4
-6.4-6.4
-6.4
Time Now: 1616683323
Temperature Celsius: -6.7
-6.7-6.7
-6.7
Time Now: 1616683324
Temperature Celsius: -6.9
-6.9-6.9
-6.9
Time Now: 1616683325
Temperature Celsius: -7.1
-7.1-7.1
-7.1
Time Now: 1616683326
Temperature Celsius: -7.4
-7.4-7.4
-7.4
Time Now: 1616683327
Temperature Celsius: -7.6
-7.6-7.6
-7.6
Time Now: 1616683328
Temperature Celsius: -7.9
-7.9-7.9
-7.9
Time Now: 1616683329
Temperature Celsius: -8.1
-8.1-8.1
-8.1
Time Now: 1616683331
Temperature Celsius: -8.3
-8.3-8.3
-8.3
Time Now: 1616683332
Temperature Celsius: -8.6
-8.6-8.6
-8.6
Time Now: 1616683333
Temperature Celsius: -8.8
-8.8-8.8
-8.8
Time Now: 1616683334
Temperature Celsius: -8.9
-8.9-8.9
-8.9
Time Now: 1616683335
Temperature Celsius: -9.2
-9.2-9.2
-9.2
Time Now: 1616683336
Temperature Celsius: -9.4
-9.4-9.4
-9.4
Time Now: 1616683337
Temperature Celsius: -9.6
-9.6-9.6
-9.6
Time Now: 1616683339
Temperature Celsius: -9.8
-9.8-9.8
-9.8
Time Now: 1616683340
Temperature Celsius: -10.0
-10.0-10.0
-10.0
Time Now: 1616683341
Temperature Celsius: -10.1
-10.1-10.1
-10.1
Time Now: 1616683342
Temperature Celsius: -10.4
-10.4-10.4
-10.4
Time Now: 1616683343
Temperature Celsius: -10.6
-10.6-10.6
-10.6
Time Now: 1616683344
Temperature Celsius: -10.7
-10.7-10.7
-10.7
Time Now: 1616683346
Temperature Celsius: -10.9
-10.9-10.9
-10.9

 

Link to post
Share on other sites

OK, am vazut. Din pacate nu merge cum am zis eu, trebuie sa faci modificarea in functia readDSTemperatureC().

Cam asa ceva:

// by ND - 2021
#ifdef ESP8266
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif
#include <Arduino.h>
#define ONE_WIRE_BUS 0
#include <OneWire.h>
#include <DallasTemperature.h>
#include <time.h>
#include <LiquidCrystal_I2C.h> 
#include <stdio.h>
#include <ostream>


LiquidCrystal_I2C lcd(0x27, 16, 2);  // Configure LiquidCrystal_I2C library with 0x27 address, 16 columns and 2 rows

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


OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
const char* ssid = "xxxxxxxx";            
const char* password = "yyyyyy";      

const char* NTP_SERVER = "ch.pool.ntp.org";
const char* TZ_INFO    = "EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00";

tm timeinfo;
time_t now;
long unsigned lastNTPtime;
unsigned long lastEntryTime;
String StrTempC;

String readDSTemperatureC() {
  sensors.requestTemperatures();
  float tempC = sensors.getTempCByIndex(0);
  float fTempAfis = tempC;
  String sTempToStr = "";
  
  if(tempC == -127.00) {
    Serial.println("Failed to read from DS18B20 sensor");
    return "--";
  } else {
    Serial.print("Temperature Celsius: ");
    Serial.println(tempC,1);
  }

  if(tempC < 0.0){
    sTempToStr = "-";
    fTempAfis *= -1; 
  } else {
    sTempToStr = " ";
  }

  if (fTempAfis < 9.9) {
    sTempToStr += "0";
  }

  return (sTempToStr + String(fTempAfis,1));
}


void setup() 
{
  sensors.begin();
  Serial.begin(115200);
  lcd.begin(4, 5);                   // Initialize I2C LCD module (SDA = D2, SCL = D1)

  WiFi.begin(ssid, password);

  Serial.print("Connecting to network");
  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);    
    if (++counter > 100) 
      ESP.restart();
    Serial.print( "." );
  }
  Serial.println("\nWiFi connected\n\n");

  configTime(0, 0, NTP_SERVER);
  setenv("TZ", TZ_INFO, 1);

  if (getTimeReducedTraffic(43200000))
  {  
    // wait up to 10sec to sync
  } else {
    Serial.println("Time not set");
    ESP.restart();
  }
  showTime(&timeinfo);
  lastNTPtime = time(&now);
  lastEntryTime = millis();

  lcd.createChar(0, customChar);
  lcd.home();
  lcd.write(0);
}

void loop() 
{
  getTimeReducedTraffic(43200000);
  showTime(&timeinfo);
  delay(1000);
}

bool getTimeReducedTraffic(int ms)
{
  {
    uint32_t start = millis();
    do
    {
      time(&now);
      localtime_r(&now, &timeinfo);
      delay(10);
    } while (((millis() - start) <= (1000000 * ms)) && (timeinfo.tm_year < (2016 - 1900)));
    
    if (timeinfo.tm_year <= (2016 - 1900)) 
        return false;  // the NTP call was not successful
    
    Serial.print("Time Now: ");  
    Serial.println(now); 
    StrTempC = readDSTemperatureC();
    Serial.print(StrTempC);
  }
  return true;
  lcd.clear();
}

void showTime(tm *localTime) 
{
  //print to serial terminal if you want ; remove // from bellow
  //Serial.print(localTime->tm_mday);
  //Serial.print('/');
  //Serial.print(localTime->tm_mon + 1);
  //Serial.print('/');
  //Serial.print(localTime->tm_year - 100);
  //Serial.print('-');
  //Serial.print(localTime->tm_hour);
  //Serial.print(':');
  //Serial.print(localTime->tm_min);
  //Serial.print(':');
  //Serial.print(localTime->tm_sec);
  //Serial.print(" Day of Week ");
  //Serial.println(localTime->tm_wday);
  //Serial.println();

  //display on LCD
  char time_output[40];
  lcd.setCursor(0, 0);
  sprintf(time_output, "%02d:%02d:%02d", localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
  lcd.print(time_output);

  lcd.setCursor(0,1);
  sprintf(time_output, "%02d/%02d/%02d", localTime->tm_mday, localTime->tm_mon + 1, localTime->tm_year+1900);
  lcd.print(time_output);


  lcd.setCursor(11, 0); //
  lcd.print(getDOW(localTime->tm_wday));

  lcd.setCursor(10, 1);
  lcd.print(StrTempC);

  lcd.setCursor(15, 1);
  lcd.write(0);
}

char * getDOW(uint8_t tm_wday)
{
  switch(tm_wday)
  {
    case 1:
      return " Luni";
      break;
    case 2:
      return "Marti";
      break;
    case 3:
      return "Mier.";
      break;
    case 4:
      return "  Joi";
      break;
    case 5:
      return " Vin.";
      break;
    case 6:
      return "Samb.";
      break;
    case 0:
      return " Dum.";
      break;
    default:
      return "Error";
      break;
  }
}

 

Link to post
Share on other sites

Functioneaza corect ! Respect ! Mii de multumiri !

... doar o intrebare : e greu de eliminat zero ? Arata oarecum ciudat 09.9 'C si foarte ciudat 00.3 'C ... Desi, daca e greu, pot trai cu asta :) !

Inca o data : multumiri pentru timpul si efortul alocat !

Link to post
Share on other sites

Nu e greu, am citit gresit "tema". :rade: Joaca-te cu bucata asta de cod

if(tempC < 0.0){
    sTempToStr = "-";
    fTempAfis *= -1; 
  } else {
    sTempToStr = " ";
  }

  if (fTempAfis < 9.9) {
    sTempToStr += "0";
  }

Daca nu vrei nimic in locul lui 0, stergi cu totul al doilea if. Daca vrei sa ramana punctul zecimal pe aceeasi pozitie, inlocuiesti "0" cu " ".

La fel poti sa te joci si cu else de la primul if.

Testeaza si vezi cum iti place mai mult.

Link to post
Share on other sites
Posted (edited)

Am sters "0" de al doilea "if". Am redus anul la ultimii doi digiti si acum totul se afiseaza asa cum imi doream.

Multumesc !!!

 

 

Edited by fratello
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.





×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.Terms of Use si Guidelines