Sari la conținut
ELFORUM - Forumul electronistilor

Wemos D1 - ceas, termometru - temperaturi negative ??


fratello

Postări Recomandate

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

Editat de fratello
Link spre comentariu
  • Răspunsuri 73
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Top autori în acest subiect

Imagini postate

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 spre comentariu

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 spre comentariu

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 (???).

Editat de fratello
Link spre comentariu

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.

Editat de Liviu M
Link spre comentariu

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){
...

)

Editat de Liviu M
Link spre comentariu

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 spre comentariu

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 spre comentariu

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 spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări