Membaca RTC DS1307 menggunakan interupsi SQW

RTC DS1307 memiliki pin keluaran/output SQW. Pin SQW berfungsi sebagai pembangkit sinyal digital yang frekuensinya bisa diatur pada 1, 4.096, 8.192, 32.768Hz.

Keluaran ini bisa dimanfaatkan oleh mikrokontroller untuk mendeteksi perubahan detik jika SQW diatur pada frekuensi 1Hz (saat pin SQW kondisi high).

penggunaan interupsi dalam mikrokontroller sangat bermanfaat karena:

  1. Menghentikan program yang sedang berjalan dan segera menjalankan baris program interupsi.
  2. Mengaktifkan mikrokontroller dari posisi sleep().
  3. Tidak memakai sumberdaya mikrokontroller, tidak seperti perintah delay() yang menyebabkan mikrokontroller melakukan proses perulangan di satu titik.

Kombinasi interupsi dan sleep() menjadikan kinerja mikrokontroler lebih efisien (hemat sumberdaya). Namun juga perlu diperhatikan bahwa penggunaan interupsi akan menghambat baris program lain, jadi pergunakan fungsi interupsi secepat mungkin.

fungsi interupsi SQW pada DS1307/interupsi SQW pada DS3231 adalah memliki register kontrol yang sama.

daftar interupsi pinChange:

  1. ISR (PCINT0_vect) pin change interrupt untuk D8 sampai D13
  2. ISR (PCINT1_vect) pin change interrupt untuk A0 sampai A5
  3. ISR (PCINT2_vect) pin change interrupt untuk D0 sampai D7

Skema RTC DS1307/DS3231 hemat energi dengan arduino:

berikut ini contoh sketch/program dari penggunaan RTC DS1307 menggunakan metode  interupsi:

#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <avr/sleep.h>

byte SQWPin = A3;
volatile bool interupsiDetik;

void setup() {
  Serial.begin(9600);
  Serial.println("Membaca DS1307 dengan metode interupsi SQW");
  Serial.println("https://www.project.semesin.com");

  //Mengaktifkan Pin SQW keluaran 1Hz pada DS1307
  Wire.beginTransmission(0x68);
  Wire.write((uint8_t)0x07);
  Wire.write(0x10);
  Wire.endTransmission();

  ////Mengaktifkan Pin SQW keluaran 1Hz pada DS3231
  //Wire.beginTransmission(0x68);
  //Wire.write((uint8_t)0x0E);
  //Wire.write(0x1C);
  //Wire.endTransmission();

  //Pendeteksi interupsi
  *digitalPinToPCMSK(SQWPin) |= bit (digitalPinToPCMSKbit(SQWPin));
  PCIFR  |= bit (digitalPinToPCICRbit(SQWPin));
  PCICR  |= bit (digitalPinToPCICRbit(SQWPin));

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
}

ISR (PCINT1_vect)
{
  if(digitalRead(SQWPin))
  {
    interupsiDetik = true;
  }
}  
 
void loop() {
  tmElements_t tm;
  if (interupsiDetik) 
  {
    interupsiDetik = false;

    RTC.read(tm);
    Serial.print("Time = ");
    print2digits(tm.Hour);
    Serial.write(':');
    print2digits(tm.Minute);
    Serial.write(':');
    print2digits(tm.Second);
    Serial.print(", Date (D/M/Y) = ");
    Serial.print(tm.Day);
    Serial.write('/');
    Serial.print(tm.Month);
    Serial.write('/');
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.println();
  }

  sleep_mode();
}

void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

2 thoughts on “Membaca RTC DS1307 menggunakan interupsi SQW

  1. Ola,
    Asep Kurniawan
    Parabéns pelo projeto!
    Você poderia me ajudar a implementar nesse código para que ele fizesse interrupções em horários predefinidos (00-03-06-09-12-15-18-21) e fizesse a leitura de sensor gravar os dados em modulo SD Card e voltar ao modulo sleep de economia de bateria.
    Grato!!!

Leave a Reply

Your email address will not be published. Required fields are marked *