La rugamintea lui Gabi Loreti am inlocuit unul din senzorii DHT22 (AM2302) din proiectul anterior cu un senzor combinat AHT20 cu BMP280.
El e pasionat, in general, doar de afisaje VFD sau OLED, dar i-a placut modul cum arata informatiile pe un afisaj alfanumeric LCD2004, asa ca am modificat programul proiectului anterior si acum acesta este big_font_weather_clock_v2a.ino.Un blog ce completeaza site-ul www.arduinotehniq.com (www.tehnic.go.ro); o parte din articole sunt (si vor fi) postate si in engleza pe arduinotehniq.blogspot.com. Filmuletele tehnice se gasesc pe canalul de youtube...
vineri, 24 octombrie 2025
Ceas RTC cu caractere mari si date meteo pe afisaj LCD2004 (2)
luni, 13 octombrie 2025
Termostat reglabil cu ceas RTC si afisaj LCD2004
Dupa ce am fost multumit de modul de afisare, reglare si stabilitate la proietul anterior, de Ceas RTC cu caractere mari si termometru pe afisaj LCD2004 am trecut s la partea de proiect mult mai util, un termostat reglabil cu ceas RTC.
Schema deriva din cea a ceasului, doar ca am pus 3 leduri, unul rosu pentru temperatura scazuta (sub pragul de temperatura), unul verde pentru temperatura normala (valoare peste pragul de temperatura) si unul galben pentru a simula comanda la centrala / calorifer electric. etc (care se aprinde cand temperatura este sub pragul de temperatura si se stinge la depasirea pragului de temperatura plus valoarea histerezisului)
La o apasare scurta se comuta afisarea cu caractere mari a orei cu cea a temperaturii, apoi iar ora, etc. Cateva exemple:marți, 7 octombrie 2025
Ceas RTC cu caractere mari si date meteo pe afisaj LCD2004
In urma unei cautari pentru un ceas cu date meteo si eventual termostat, am dat de cel prezentat in articolul Big Characters Weather Clock (int/ext temp, hum, press) scris de un conational, Viorel Racoviteanu. Articolul este postat si pe blogul propriu in articolul cu acelasi nume.
PS: In timpul testelor am constatat ca unul din senzorii DHT22 (AM2302) indica eronat umiditatea, desi testele au fost facute doar in casa, la temperatura si umiditate in limite uzuale (normale), deci inaintea montarii definitive trebuie facute teste de mai lunga durata, pentru a fi siguri ca senzorul va functiona si in conditi extreme (frig/cald, umiditate ridicata, etc)
sâmbătă, 28 iunie 2014
Receptor GPS conectat la un Arduino (3)
TinyGPSCustom magneticVariation(gps, "GPRMC", 10)if (magneticVariation.isUpdated()){ Serial.print("Magnetic variation is "); Serial.println(magneticVariation.value());}TinyGPSCustom zdop(gps, "GPVTG", 7); // $GPVTG sentence, 7th element
iar partea de afisare:
// viteza extrasa custom lcd.setCursor(0,3); // put cursor at colon x and row y lcd.print("viteza: "); int viteza = atoi (zdop.value()); // lcd.print(zdop.value()); if (viteza>100.0) lcd.print(viteza); else if (viteza>10.0) {lcd.print(" "); lcd.print(viteza);} else if (viteza<10.0) {lcd.print(" "); lcd.print(viteza);} lcd.print("km/h");
Montajul de test, in timp ce masina se deplasa (in stanga este viteza obtinuta cum am aratat mai sus, iar in dreapta e ce ar afisa libraria, adica zero permanent):
// source: http://arduiniana.org/libraries/tinygpsplus/
// for see your position: http://www.gps-coordinates.net/
// for new article made by niq_ro: http://nicuflorica.blogspot.com/
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
/*
This sample code demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
It requires the use of SoftwareSerial, and assumes that you have a
4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 4800;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
#include <LiquidCrystal.h>
// folosesc libraria pentru afisaje LCD simple
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// indic modul de legare, vezi mai jos:
/* -------------------
| LCD | Arduino |
-------------------
LCD RS pin to digital pin 7 | RS | D7 |
LCD Enable pin to digital pin 6 | E | D8 |
LCD D4 pin to digital pin 5 | D4 | D9 |
LCD D5 pin to digital pin 4 | D5 | D10 |
LCD D6 pin to digital pin 3 | D6 | D11 |
LCD D7 pin to digital pin 2 | D7 | D12 |
LCD R/W pin to ground | R/W | GND |
-------------------
niq_ro adapted this sketch for see data on 2004 LCD
*/
// for speed in knots (noduri)
//TinyGPSCustom sdop(gps, "GPVTG", 5); // $GPVTG sentence, 5th element
// for speed in kilometers per hour
TinyGPSCustom zdop(gps, "GPVTG", 7); // $GPVTG sentence, 7th element
void setup()
{
Serial.begin(115200);
ss.begin(GPSBaud);
Serial.println(F("FullExample.ino"));
Serial.println(F("An extensive example of many interesting TinyGPS++ features"));
Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("by Mikal Hart"));
Serial.println();
Serial.println(F("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum"));
Serial.println(F(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail"));
Serial.println(F("---------------------------------------------------------------------------------------------------------------------------------------"));
lcd.begin(20, 4); // set up the LCD's number of columns and rows:
lcd.clear(); // clear the screen
lcd.setCursor(1, 0); // put cursor at colon x and row y
lcd.print("GPS data - 6.2014"); // print a text
lcd.setCursor(1, 1); // put cursor at colon x and row y
lcd.print("ver 1.5 by niq_ro"); // print a text
lcd.setCursor(1, 2); // put cursor at colon x and row y
lcd.print("Craiova - Romania"); // print a text
delay (2000);
lcd.clear(); // clear the screen
}
void loop()
{
// partea de ecran LCD 20x4
afisareecran();
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
printInt(gps.hdop.value(), gps.hdop.isValid(), 5);
printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
printInt(gps.location.age(), gps.location.isValid(), 5);
printDateTime(gps.date, gps.time);
printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.value()) : "*** ", 6);
unsigned long distanceKmToLondon =
(unsigned long)TinyGPSPlus::distanceBetween(
gps.location.lat(),
gps.location.lng(),
LONDON_LAT,
LONDON_LON) / 1000;
printInt(distanceKmToLondon, gps.location.isValid(), 9);
double courseToLondon =
TinyGPSPlus::courseTo(
gps.location.lat(),
gps.location.lng(),
LONDON_LAT,
LONDON_LON);
printFloat(courseToLondon, gps.location.isValid(), 7, 2);
const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);
printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);
printInt(gps.charsProcessed(), true, 6);
printInt(gps.sentencesWithFix(), true, 10);
printInt(gps.failedChecksum(), true, 9);
// speed in km/h
Serial.print(" ");
Serial.print(zdop.value());
int vitesa1 = atoi (zdop.value());
Serial.print("/");
Serial.print(vitesa1);
Serial.println();
smartDelay(1000);
if (millis() > 5000 && gps.charsProcessed() < 10)
Serial.println(F("No GPS data received: check wiring"));
}
// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
static void printFloat(float val, bool valid, int len, int prec)
{
if (!valid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i=flen; i<len; ++i)
Serial.print(' ');
}
smartDelay(0);
}
static void printInt(unsigned long val, bool valid, int len)
{
char sz[32] = "*****************";
if (valid)
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i=strlen(sz); i<len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len-1] = ' ';
Serial.print(sz);
smartDelay(0);
}
static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
if (!d.isValid())
{
Serial.print(F("********** "));
}
else
{
char sz[32];
sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
// sprintf(sz, "%02d/%02d/%02d ", gps.date.month(), gps.date.day(), gps.date.year());
Serial.print(sz);
}
if (!t.isValid())
{
Serial.print(F("******** "));
}
else
{
char sz[32];
sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
// sprintf(sz, "%02d:%02d:%02d ", gps.time.hour(), gps.time.minute(), gps.time.second());
Serial.print(sz);
}
printInt(d.age(), d.isValid(), 5);
smartDelay(0);
}
static void printStr(const char *str, int len)
{
int slen = strlen(str);
for (int i=0; i<len; ++i)
Serial.print(i<slen ? str[i] : ' ');
smartDelay(0);
}
static void afisareecran()
{
// lcd.clear(); // clear the screen
// partea de ora
// ora de vara a Romaniei -
// trebuie sa pun un comutator pentru selectie de iarna si de vara
int ora = 3 + gps.time.hour();
if (ora ==24) ora=0;
if (ora ==25) ora=1;
if (ora ==26) ora=2;
lcd.setCursor(0,2); // put cursor at colon 2 and row 2
if (ora<10) lcd.print(" ");
lcd.print(ora);
lcd.print(":");
if (gps.time.minute()<10) lcd.print("0");
lcd.print(gps.time.minute());
lcd.print(":");
if (gps.time.second()<10) lcd.print("0");
lcd.print(gps.time.second());
// parte de coordonate GPS
lcd.setCursor(0,0); // put cursor at colon 0 and row 0 = left/up
lcd.print("LAT:");
lcd.print(gps.location.lat(),6);
lcd.write(0b11011111);
lcd.setCursor(0,1); // put cursor at colon 0 and row 1
lcd.print("LON:");
lcd.print(gps.location.lng(),6);
lcd.write(0b11011111);
// numar sateliti receptionati
lcd.setCursor(10,2); // put cursor at colon 15 and row 2
lcd.print(gps.satellites.value());
if (gps.satellites.value() == 1) lcd.print(" satelit ");
else lcd.print(" sateliti");
// viteza
/*
lcd.setCursor(10,3); // put cursor at colon x and row y
double viteza = gps.speed.kmph();
// tests
// double viteza = 0.;
// double viteza = 5;
// double viteza = 14;
// double viteza = 104;
if (viteza>100.0) lcd.print(viteza);
else
if (viteza>10.0) {lcd.print(" "); lcd.print(viteza);}
else
if (viteza<10.0) {lcd.print(" "); lcd.print(viteza);}
// lcd.print(viteza);
// lcd.print(gps.speed.kmph());
lcd.print("km/h");
*/
// altitudine
lcd.setCursor(16,0); // put cursor at colon 16 and row 0
lcd.print("ALT:");
int cota = gps.altitude.meters();
lcd.setCursor(15,1); // put cursor at colon 15 and row 1
// cota=5;
//cota=15;
//cota=497;
//cota=2056;
if (cota>1000) lcd.print(cota);
else
if (cota>100) {lcd.print(" "); lcd.print(cota);}
else
if (cota>10) {lcd.print(" "); lcd.print(cota);}
if (cota<10) {lcd.print(" "); lcd.print(cota);}
lcd.print("m");
// viteza extrasa custom
lcd.setCursor(0,3); // put cursor at colon x and row y
lcd.print("viteza: ");
int viteza = atoi (zdop.value());
// lcd.print(zdop.value());
if (viteza>100.0) lcd.print(viteza);
else
if (viteza>10.0) {lcd.print(" "); lcd.print(viteza);}
else
if (viteza<10.0) {lcd.print(" "); lcd.print(viteza);}
lcd.print("km/h");
}
pentru schema de conectare din articolul anterior:
PS: intre timp am folosit caractere mari pentru viteza:
PS: Am reusit sa fac si niste teste in masina, doar ca am doar poze momentan:
-
Pentru cazuri cand trebuie sa alimentam un montaj sau un consumator (radio portabil, beculet, etc) de la o sursa de tensiune continua fix...
-
rezumat articol Avand o situatie in care am o masina de spalat automata veche (AEG Lavamat Regina 804), pe care am reusit s-o reconditi...
-
ultima modificare: 12.04.2020 Fata de sistemele clasice pentru incubatoare care regleaza doar temperatura, la solicitarea lui Vior...































