ZS-042 Real Time Clock (RTC)
Jedan jako zanimljiv modul je na redu da vam predstavim. Reč je o ZS-042
Real Time Clock modulu čiji je zadatak da meri tačno vreme. Modul je uz
odgovarajuće biblioteke sposoban da meri sate, minute i sekunde. Takođe
je u stanju da razlikuje dane u nedelji, kao i da odbrojava dane,
mesece i godine. Prestupnu godinu isto tako prepoznaje kao i različit
broj dana u mesecima. Pride, ima ugrađen i senzor za temperaturu pa je
pogodan za Data Logging projekte. Može da radi na naponima od 3,3V i 5V a
za napajanje interne memorije koristi LIR2032.
Ovaj modul
koristi DS3231 clock čip koji bi trebalo da prikazuje tačno vreme do
2100 godine. To teško da će neko od nas doživeti tako da ostaje da
verujemo proizvođaču (Dallas Semiconductor). Pomenuti memorijski čip
(EEPROM) je AT24C32 sa kapacitetom od 32K. Njemu se može pristupiti
preko 32K i SQW pinova. Modul u sebi ima ugrađen punjač za LIR2032
punjivu bateriju i preporuka proizvođača je da se ista koristi ali je
ceo sistem urađen malo traljavo gde nakon par godina (?!) rada postoji
mogućnost da ista eksplodira. Elektronika za punjenje litijumske
baterije je malo kompleksnija od onih par otpronika na ovom modulu. Na
netu se može naći da se koristi CR2032 baterija umesto LIR2032 i da se
otpornik zadužen da prati punjenje isključi "rezanjem" voda na PCB-u.
Ugrađena baterija ima ulogu da napaja RTC kada se modul (projekat u
celini) odvoji od računara ili iz nekog drugog razloga dođe do prekida
napajanja.
ZS-042
modul je dimenzija 38x22mm a debljina mu je zbog slota za bateriju čak
14mm. Na Arduino (ili kompatibilnu ploču) se povezuje putem I2C
protokola, za šta ima izlaze na dve strane. Sa gornje strane su 4
nezalemljena hedera: SCL, SDA, VCC i GND. Sa donje strane ima 6
zalemljenih hedera i to: 32K, SQW, SCL, SDA, VCC i GND. Na master ploču
se povezuje uglavnom:
SCL -> SCL (može i A5 za UNO ili D20 za Megu)
SDA -> SDA (može i A4 za Uno ili D21 za Megu)
VCC -> 5V(3,3v)
GND -> GND
Sve ovo na Fritzing šemi ispod.
U
sledećem primeru ćemo prikazati vreme i temperaturu na 1602 LCD sa I2C
adapterom. Mega je tu da celu priču pokrene. Prvo što nam treba je da
preuzmemo odgovarajuću biblioteku a za ovaj modul ćemo koristiti RCBlib
koja nema nativnu podršku za temperaturni senzor jer je pisana za
Adafruit modul. Neophodnu podršku ćemo dodati editovanjem bibiloteke.
Nakon
uspešno uvezene RTClib biblioteke potrebno je otvoriti sledeće fajlove u
nekom text editoru. Notepad++ je savršen za taj posao. Prvi koji ćemo
editovati je RTClib.cpp. Spustamo se do kraja i nakon linije 507 dodajemo sledeće redove:
------------------------------
float RTC_DS3231::getTemperature()
{
uint8_t msb, lsb;
Wire.beginTransmission(DS3231_ADDRESS);
Wire._I2C_WRITE(DS3231_TEMPERATUREREG);
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 2);
msb = Wire._I2C_READ();
lsb = Wire._I2C_READ();
// Serial.print("msb=");
// Serial.print(msb,HEX);
// Serial.print(", lsb=");
// Serial.println(lsb,HEX);
return (float) msb + (lsb >> 6) * 0.25f;
}
---------------------------------
Ovim smo dodali getTemperature() funkciju koju ćemo pozvati iz skeča. Sledeći na redu za editovanje je RTClib.h gde imamo par prepravki. Prvo nakon linije 21 definišemo I2C adresu:
-----------------------------------------
#define DS3231_TEMPERATUREREG 0x11
------------------------------------------
Nakon linije 106 dodajemo sledeću liniju:
-----------------------------------
static float getTemperature(); // in Celcius degree
----------------------------------
Snimamo
sve i ako smo uspešno otkucali sve bez grešaka u kucanju pozivanjem
rtc.getTemperature() funkcije u okviru skeča bi trebalo da dobijem
očitanu vrednost temperature u celzijusima. Dodao sam i DHT22 radi
upoređivanja temperature a znamo da je taj modul pouzdan i precizan.
Kada je sve spremno i povezano a baterija na svom mestu, podešavamo tačno vreme. To radimo tako što pod File->Examples->RTClib biramo ds3231 koji nakon uploada postavlja vreme sa našeg računara. Nakon toga ide skeč ispod:
-------------------------------------
#include <Wire.h>
#include <RTClib.h>
#include <DHT.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define DHTpin 7
LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7,3,POSITIVE);
DHT dht;
char daysOfTheWeek[7][12] = {"Nedelja", "Ponedeljak", "Utorak", "Sreda", "Cetvrtak", "Petak", "Subota"};
RTC_DS3231 rtc;
void setup() {
Serial.begin(9600);
Wire.begin();
rtc.begin();
dht.setup(DHTpin);
lcd.begin(16,2);
lcd.backlight();
}
void loop() {
float temp1=dht.getTemperature();
float temp2=rtc.getTemperature();
Serial.print(temp1);
Serial.println(" temp C - DHT");
DateTime now = rtc.now();
Serial.print(temp2);
Serial.println(" temp C - RTC");
Serial.print(now.day(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.year(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
Serial.println();
lcd.setCursor(0,0);
lcd.print(temp1);
lcd.print(" temp C - DHT");
lcd.print(temp2);
lcd.print(" temp C - RTC");
lcd.setCursor(0,1);
lcd.print(now.day(), DEC);
lcd.print("/");
lcd.print(now.month(), DEC);
lcd.print("/");
lcd.print(now.year(), DEC);
lcd.print("(");
lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);
lcd.print(")");
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
lcd.scrollDisplayLeft();
delay(1000);
}
-------------------------------------
Nakon
dodavanja neophodnih biblioteka, definišemo pin 7 koji nam treba za DHT
modul. Konfigurišemo I2C LCD-a i pravimo dht i rtc objekte. U setup
funkciji pokrećemo LCD, DHT i RTC. U loop-u prikupljamo očitavanja
temperature i sve to prikladno ispisujemo na serijal monitoru i LCD
ekranu.
Možemo
da zaključimo da ZS-042 modul nije baš najprecizniji u smislu da "žuri"
za oko jedan stepen Celzijusa a što se može korigovati u okviru skeča.
To naravno u vezi temperaturnih očitavanja. Vreme je očekivano bilo
tačno a najispravnije bi bilo ispratiti vreme nakon nekoliko meseci i
tada videti eventualna neslaganja.