Merhaba arkadaşlar, bu yazımız da DS1302 Gerçek Zamanlı Saat Modülü RTC kullanımını arduino ile birlikte öğreneceğiz. Hepimiz biliyoruz ki, projelerimiz için kullandığımız çoğu MCU (işlemci) zamana duyarlı değildir; Projelerimizin çoğu için bu durum sorun değil, ancak zaman ile ilgili bir proje yapmak istediğimizde
DS1302 RTC modülü bir kurtarıcıdır. Veri kaydı, saat oluşturma, gerçek zaman takibi, zamanlayıcılar ve alarmlar içeren projeler için mükemmeldir.
Satın Alınabilir Ürünler;
DS1302 RTC Chip
Modülün merkezinde Maxim -
DS1302 düşük maliyetli, oldukça hassas bir RTC yongası var. Bu yonga tüm zaman işleyişi işlevlerini yönetir. Seçtiğiniz herhangi bir mikrodenetleyici ile kolayca arabirim oluşturabilen iki telli basit bir I2C arabirimine sahiptir.
Çip saniye, dakika, saat, gün, tarih, ay ve yıl bilgilerini korur(2100'e kadar). Ayın son günü 31 günden az aylar için otomatik olarak ayarlanır. Saat, AM / PM göstergesi ile 24 saat veya 12 saat formatında çalışır. Bu kartın diğer bir özelliği, 1Hz, 4kHz, 8kHz veya 32kHz'lik dört kare dalga frekansından birini veren ve programlı olarak etkinleştirilebilen SQW piniyle birlikte gelir.
Pil
DS1302 bir pil girişi içerir ve cihaza giden ana güç kesildiğinde gerçek zaman işleyişini korur. Dahili güç algılama devresi, elektrik kesintilerini tespit etmek için
VCC pininin durumunu sürekli olarak izler ve otomatik olarak yedek kaynağa geçer. Bu nedenle, elektrik kesintileri konusunda endişelenmenize gerek yoktur, MCU'nuz pil ile hala zamanı takip edebilir.
Kartın alt tarafında 20mm
3V lityum pil için bir
pil yuvası bulunur. Herhangi bir
CR2032 pil takılabilir.
Dahili 24C32 EEPROM
DS1302 RTC modülü ayrıca Atmel'den sınırlı okuma-yazma döngülerine sahip 32 bayt 24C32 EEPROM çipi ile birlikte gelir. Ayarları ve herhangi bir veriyi kaydetmek için kullanılabilir.
24C32 EEPROM iletişim için I2C arayüzünü kullanır ve DS1302 ile aynı I2C veriyolunu paylaşır.
Modülün Gizli Özelliği - DS18B20
DS1302 RTC modülümüzde genellikle fark edilmeyen bir bölüm vardır. DS18B20 sıcaklık sensörünü takmamızı sağlar. Pil yuvasının sağ üst köşesinde (U1 olarak etiketlenmiştir) bulunan 3 delik, DS18B20'nin takıldığı yerdir.
DS18B20'yi taktıktan sonra,
DS piminden sıcaklık okumaları alabilirsiniz. Bu okumalar ayrıca koddaki sıcaklığa dayalı zaman kaymasını telafi etmek için de kullanılabilir. DS18B20 lehim için serigrafi ekranını izleyin. Ayrıca
VCC ve
DS arasında bir 4.7K dirence ihtiyacınız olabilir.
DS1302 RTC Modülü Pin Çıkışı
DS1302 RTC modülünde, onu dış dünyaya bağlayan toplam 7 pim vardır. Bağlantılar aşağıdaki gibidir:
SQW pin, 1Hz, 4kHz, 8kHz veya 32kHz dört kare dalga frekansından birini verir ve programlı olarak etkinleştirilebilir.
DS pini modülünüzde pil tutucusunun hemen yanında (U1 olarak etiketlenmiş) bulunan pinlerden bir DS18B20 sıcaklık sensörü ile sıcaklık okumaları sağlanabilir.
SCL, I2C arayüzü için saat girişidir ve seri arayüzdeki veri hareketini senkronize etmek için kullanılır.
SDA, I2C seri arayüzü için veri girişi / çıkışıdır.
VCC pimi modüle güç sağlar. 3.3V ila 5.5V arasında ayarlanabilir.
GND bir topraklama pimidir.
BAT, cihaza giden ana güç kesintiye uğradığında doğru zaman işleyişini sürdürmek için herhangi bir standart 3V lityum pil için yedek bir besleme girdisidir.
DS1302 RTC Arduino UNO Bağlantısı - Kablolama
RTC'yi Arduino'ya bağlayalım. Bağlantılar oldukça basittir.
VCC pimini Arduino'daki 5V çıkışına bağlayarak başlayın ve
GND'yi toprağa bağlayın. Şimdi I2C iletişimi için kullanılan pinlerle ilgileniyoruz. Her Arduino Kartında buna göre bağlanması gereken farklı I2C pinleri bulunduğunu unutmayın. R3 mizanpajlı Arduino kartlarında,
SDA (veri hattı) ve
SCL (saat hattı)
AREF(Arduino Analog Referans Pini) pimine yakın pim başlıklarında bulunur. A5
SCL ve A4
SDA olarak da bilinirler.
Mega'nız varsa, pimler farklıdır! Dijital 21
SCL ve 20
SDA kullanmak gerekir. Arduino çeşitlerine göre pin farklarını hızlı anlama için aşağıdaki tabloya bakın.
Aşağıdaki şemada her şeyin nasıl kablolanacağı gösterilmektedir.
RTClib Kitaplığını Yükleme
Bir RTC modülü ile iletişim kurmak birden çok işlevi yapmak demektir. Neyse ki,
RTClib kütüphanesi tüm karmaşıklıkları kolaylaştırmak için yazılmıştır, böylece RTC verilerini okumak için basit komutlar verebiliriz. Kitaplığı yüklemek için
Taslak> Kitaplığı Dahil Et> Kitaplıkları Yönet… 'e gidin. Kitaplık Yöneticisi'nin kitaplıklar dizinini indirmesini ve yüklü kitaplıkların listesini güncellemesini bekleyin.
'
Rtclib ' yazarak aramanıza filtre
uygulayın. Birkaç sonuç olmalı. Adafruit tarafından RTClib arayın. Bu girişi tıklayın ve ardından Yükle'yi seçin.
Arduino Kodu - Okuma Tarihi ve Saati
Aşağıdaki kod DS1302 RTC modülünde tarih ve saatin nasıl ayarlanacağını / okunacağını tam olarak anlayacaktır ve daha pratik deneyler ve projeler için temel oluşturabilir.
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
void setup ()
{
Serial.begin(9600);
delay(3000); // wait for console opening
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (!rtc.isrunning()) {
Serial.println("RTC lost power, lets set the time!");
// Comment out below lines once you set the date & time.
// Following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Following line sets the RTC with an explicit date & time
// for example to set January 27 2017 at 12:56 you would call:
// rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));
}
}
void loop ()
{
DateTime now = rtc.now();
Serial.println("Current Date & Time: ");
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), 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("Unix Time: ");
Serial.print("elapsed ");
Serial.print(now.unixtime());
Serial.print(" seconds/");
Serial.print(now.unixtime() / 86400L);
Serial.println(" days since 1/1/1970");
// calculate a date which is 7 days & 30 seconds into the future
DateTime future (now + TimeSpan(7,0,0,30));
Serial.println("Future Date & Time (Now + 7days & 30s): ");
Serial.print(future.year(), DEC);
Serial.print('/');
Serial.print(future.month(), DEC);
Serial.print('/');
Serial.print(future.day(), DEC);
Serial.print(' ');
Serial.print(future.hour(), DEC);
Serial.print(':');
Serial.print(future.minute(), DEC);
Serial.print(':');
Serial.print(future.second(), DEC);
Serial.println();
Serial.println();
delay(1000);
}
Seri monitörün çıktısı şöyle görünür.
Kod Açıklaması:
Kod, modülle iletişim kurmak için
wire.h ve
RTClib.h kitaplıklarını eklemekle başlar. Daha sonra RTClib kütüphanesinin bir nesnesini oluştururuz ve
daysOfTheWeek gün bilgilerini saklamak için 2D karakter dizisini tanımlarız. Kodun kurulum ve döngü bölümlerinde, RTC modülüyle etkileşim kurmak için aşağıdaki işlevleri kullanırız.
begin () işlevi, RTC modülünün bağlı olmasını sağlar.
isrunning () işlevi, yonganın zaman kaybını kaybedip kaybetmediğini kontrol etmek için
DS1302'nin dahili I2C kayıtlarını okur. İşlev
false değerini döndürürse, tarih ve saati ayarlayabiliriz.
adjust () işlevi tarih ve saati ayarlar. Bu aşırı yüklenmiş bir işlevdir.
- Aşırı yüklenmiş bir yöntem DateTime(F(__DATE__), F(__TIME__)), çizimin derlendiği tarih ve saati ayarlar.
- Aşırı yüklenmiş ikinci yöntem DateTime(YYYY, M, D, H, M, s), RTC'yi açık bir tarih ve saat ile ayarlar. Örneğin, 27 Ocak 2017'yi 12:56 olarak ayarlamak için şunu arayabilirsiniz: rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));
now () işlevi geçerli tarih ve saati döndürür. Dönüş değeri genellikle DateTime veri türü değişkeninde saklanır.
year () işlevi geçerli yılı döndürür.
month () işlevi geçerli ayı döndürür.
day () işlevi geçerli günü döndürür.
dayOfTheWeek () işlevi haftanın geçerli gününü döndürür. Bu işlev genellikle yukarıdaki programda tanımlanan gibi gün bilgilerini depolayan bir 2D karakter dizisinin bir dizini olarak kullanılır
daysOfTheWeek.
hour () işlevi geçerli saati döndürür.
dakika () işlevi geçerli dakikayı döndürür.
second () işlevi geçerli saniyeyi döndürür.
unixtime () işlevi saniye cinsinden unix süresini döndürür. Unix zamanı, zaman içindeki bir noktayı tanımlayan bir sistemdir. Bu, 00:00:00'dan beri geçen saniye sayısıdır (Koordineli Evrensel Zaman - 1 Ocak 1970 Perşembe olarak bilinir).
TimeSpan () işlevi, geçerli zamana / zamanından zaman eklemek / çıkarmak için kullanılır. Gün, saat, dakika ve saniye ekleyebilir / çıkarabilirsiniz. Ayrıca aşırı yüklenmiş bir işlevdir.
Arduino Kodu - 24C32 EEPROM'da Okuma / Yazma
DS1302 RTC modülü ile bonus olarak 32 bayt Elektrikle Silinebilir ROM elde edersiniz. Cihazın ana gücü kesilse bile içeriği silinmeyecektir. Aşağıdaki program 24C32 EEPROM'dan bir mesaj yazar ve okur. Ayarları veya şifreleri veya gerçekten herhangi bir şeyi kaydetmek için bu programı kullanabilirsiniz.
#include <Wire.h>
void setup()
{
char somedata[] = "lastminuteengineers.com"; // data to write
Wire.begin(); // initialise the connection
Serial.begin(9600);
Serial.println("Writing into memory...");
// write to EEPROM
i2c_eeprom_write_page(0x57, 0, (byte *)somedata, sizeof(somedata));
delay(100); //add a small delay
Serial.println("Memory written");
}
void loop()
{
Serial.print("Reading memory: ");
int addr=0; //first address
// access the first address from the memory
byte b = i2c_eeprom_read_byte(0x57, 0);
while (b!=0)
{
Serial.print((char)b); //print content to serial port
addr++; //increase address
b = i2c_eeprom_read_byte(0x57, addr); //access an address from the memory
}
Serial.println(" ");
delay(2000);
}
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.write(rdata);
Wire.endTransmission();
}
// WARNING: address is a page address, 6-bit end will wrap around
// also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddresspage >> 8)); // MSB
Wire.write((int)(eeaddresspage & 0xFF)); // LSB
byte c;
for ( c = 0; c < length; c++)
Wire.write(data[c]);
Wire.endTransmission();
}
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.read();
return rdata;
}
// maybe let's not read more than 30 or 32 bytes at a time!
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,length);
int c = 0;
for ( c = 0; c < length; c++ )
if (Wire.available()) buffer[c] = Wire.read();
}
Ekran görüntüsü şöyle görünür.