Sedikit Pengenalan

Jadwal Waktu Sholat (JWS), sekarang sering kita jumpai di dalam tempat ibadah umat muslim. Alat ini selain berfungsi menjadi penunjuk waktu/jam, juga dapat menampilkan jadwal jam sholat setiap harinya, mulai dari Subuh s/d Isya. Dengan menggunakan algoritma perhitungan rumus Penjadwalan waktu sholat berdasarkan zona waktu, bujur, lintang, ketinggian, tanggal, bulan, dan tahun, kita tidak perlu membuat database dan memasukanya dalam memory Arduino. Tentunya dengan menggunakan algorima ini akan mempermudah menggunaan, tanpa perlu update data setiap tahunnya.

Hingga kini banyak sekali varian dari jadwal sholat, mulai dari menggunakan tampilan 7 segmen, Dotmatrix, dan LCD. Pada project ini saya akan memberikan sebuat project bagaimana membuat jadwal sholat dengan LCD 16×2 untuk ruang kantor. Berbeda dengan JWS pada tempat ibadah, yang memiliki fitur untuk memberikan sinyal alarm waktu sholat, hitung mundur iqomah, dan display mati saat sholat. Disini saya akan memberikan fitur untuk alarm saat sholat tiba, oleh karena itu saya tunjukan untuk ruang kantor atau rumah, dengan model tampilan seperti cover diatas. OK langsung saja kita bahas projectnya.

Skematik Rangkaian

skematik jadwal sholat lcd 16x2

Buatlah rangkaian dengan menggunakan komponen- komponen berikut:

  • 1 buah Arduino Nano
  • 1 buah LCD 16×2
  • 1 buah Module RTC DS1307
  • 1 buah Buzzer 5V
  • 1 buah Trimpot 10K (untuk kontras LCD
  • 3 buah Tact Switch / Switch Button (ukuran bebas)

Berikut ini hasil rangkaian yang saya solder:

rangkaian jws lcd

Pemrograman Arduino

Berikut ini adalah Program Project JWS LCD 16×2:

//===================================================================
// > Name    : Jadwal LCD 16x2 Simple + Button Setting
// > Writer  : Irfan Indra Kurniawan - FansElectronics.com
// > Version : 1.2

// Program ini dibuat untuk tujuan Pendidikan / Amal.
// Dilarang menjual belikan program ini, jika anda beriman.

//===================================================================
#include <LiquidCrystal.h>
#include <PrayerTimes.h>
#include <Timer.h>
#include <RTClib.h>

#define Buzzer    5
#define IR        3
#define bUP       A1
#define bDN       A3
#define bOK       A2
#define Blink     13
#define ON        HIGH
#define OFF       LOW

//=============================================================
byte  jedaAdzan    = 1;                 // Waktu adzan (Menit)
byte  selisihWaktu = 0;                 // Selisi waktu sholat (Menit)
float lintang      = -7.98;             // Latitude
float bujur        = 112.62;            // Longitude
byte  zonaWaktu    = 7;                 // Zona Waktu

//=============================================================
String sholat[] = {"Subuh", " ", "Dhuhur", "Ashar", " ", "Maghrib", "Isya", " ", "Imsak"};
double times[sizeof(TimeName) / sizeof(char*)];
int jamSholat, mntSholat, tDtk, mntTunggu;
int jam, mnt, dtk, tgl, bln , thn;
int j, i, n, x;
int a, s, u;
bool setting = false;

//=============================================================
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
RTC_DS1307 rtc;
Timer tBlink, tMain, tHold ;

//=============================================================
byte puncak[8] = {
  B00100,
  B01110,
  B11111,
  B11111,
  B01110,
  B01110,
  B01110,
};

byte tinggi[8] = {
  B11111,
  B01110,
  B01110,
  B01110,
  B01110,
  B11111,
  B11111,
};

//===================================================================
void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  rtc.begin();

  set_calc_method(ISNA);                   // Methode perhitungan mengikuti ISNA
  set_asr_method(Shafii);                  // Pendapat Imam Syafi'i
  set_high_lats_adjust_method(AngleBased); //
  set_fajr_angle(20);                      // Sudut Waktu Subuh
  set_isha_angle(18);                      // Sudut Waktu Isya

  pinMode(Blink, OUTPUT);
  pinMode(Buzzer, OUTPUT);
  pinMode(bOK, INPUT_PULLUP);
  pinMode(bUP, INPUT_PULLUP);
  pinMode(bDN, INPUT_PULLUP);

  digitalWrite(Buzzer, OFF);

  lcd.createChar(0, puncak);
  lcd.createChar(1, tinggi);

  tBlink.oscillate(Blink, 500, LOW);
  tMain.every(800, realTimeScanJWS);
  tMain.every(5000, intSlide);
  tHold.every(1000, holdTime);

  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  //rtc.adjust(DateTime(2017, 10, 7, 11, 18, 30));
}

//===================================================================
void loop() {
  DateTime now = rtc.now();
  get_prayer_times(now.year(), now.month(), now.day(), lintang, bujur, zonaWaktu, times);
  int alm = now.second() % 2;
  if (alm == 1) {
    realTimeScanJWS();
  }
  
  if (digitalRead(bOK) == LOW) {                               // Tombol OK
    setting = true; 
  }
  
  while (setting) {
    menuSetting();
  }

  iconMasjidLCD();
  tampilJAM();
  slideShowJWS();

  if (!setting) {
    tBlink.update();
    tMain.update();
  }
}

//===================================================================
String konversi(int num) {
  if (num < 10) return "0" + String(num);
  else return String(num);
}

//===================================================================
void intSlide() {
  lcd.clear();
  if (n > 5) {
    n = 0;
  }
  switch (n) {
    case 0 : j = 8; break;  // Imsak
    case 1 : j = 0; break;  // Subuh
    case 2 : j = 2; break;  // Dhuhur
    case 3 : j = 3; break;  // Ashar
    case 4 : j = 5; break;  // Maghrib
    case 5 : j = 6; break;  // Isya'
  }
  n++;
}

//===================================================================
void holdTime() {
  tDtk++;
  if (tDtk >= 60) {
    mntTunggu++; tDtk = 0;
  }
}

//===================================================================
void resetHoldTime() {
  tDtk = 0; mntTunggu = 0;
}

//===================================================================
void iconMasjidLCD() {
  lcd.setCursor(0, 0);
  lcd.write(byte(0));
  lcd.setCursor(0, 1);
  lcd.write(byte(1));
  lcd.setCursor(15, 0);
  lcd.write(byte(0));
  lcd.setCursor(15, 1);
  lcd.write(byte(1));
}

//===================================================================
void tampilJAM() {
  DateTime now = rtc.now();
  byte _thn = now.year() - 2000;

  // Tampilan Jam
  lcd.setCursor(1, 0);
  lcd.print(konversi(now.hour()));
  lcd.setCursor(3, 0);
  if (digitalRead(Blink) == LOW) {
    lcd.print(':');
  }
  else {
    lcd.print(' ');
  }
  lcd.setCursor(4, 0);
  lcd.print(konversi(now.minute()));

  // Tampilan Tanggal
  lcd.setCursor(7, 0);
  lcd.print(konversi(now.day()));
  lcd.setCursor(9, 0);
  lcd.print('/');
  lcd.setCursor(10, 0);
  lcd.print(konversi(now.month()));
  lcd.setCursor(12, 0);
  lcd.print('/');
  lcd.setCursor(13, 0);
  lcd.print(konversi(_thn));
}

//===================================================================
void tampilJWS(byte _wkt, byte _jam, byte _mnt) {
  lcd.setCursor(1, 1);
  lcd.print(sholat[_wkt]);
  lcd.setCursor(10, 1);
  lcd.print(konversi(_jam));
  lcd.setCursor(12, 1);
  lcd.print(':');
  lcd.setCursor(13, 1);
  lcd.print(konversi(_mnt));
  tMain.update();
}
//===================================================================
void slideShowJWS() {
  get_float_time_parts(times[j], jamSholat, mntSholat);
  mntSholat += selisihWaktu;
  if (mntSholat >= 60) {
    mntSholat = 0;
    jamSholat++;
  }
  if (j == 8) {
    get_float_time_parts(times[0], jamSholat, mntSholat);
    mntSholat += selisihWaktu;
    if (mntSholat < 10) {
      mntSholat = 60 - mntSholat;
      jamSholat--;
    }
    else {
      mntSholat = mntSholat - 10 ;
    }
  }
  tampilJWS(j, jamSholat, mntSholat);
}

//===================================================================
void realTimeScanJWS() {
  for (i = 0; i < 7; i++) {
    DateTime now = rtc.now();
    if (i == 1 or i == 4) {
      i++;
    }
    get_float_time_parts(times[i], jamSholat, mntSholat);
    mntSholat += selisihWaktu;
    if (mntSholat >= 60) {
      mntSholat = 0;
      jamSholat++;
    }
    Serial.println(i);
    if (jamSholat == now.hour() && mntSholat == now.minute()) {
      alarmJWS(i, jamSholat, mntSholat);
    }
  }
}

//===================================================================
void alarmJWS(byte jws, byte _jam, byte _mnt) {
  String alarmText = " Waktu Sholat ";
  byte dBuzz = 1;
  DateTime now = rtc.now();
  resetHoldTime();
  lcd.clear();
  while (jedaAdzan >= mntTunggu) {
    now = rtc.now();
    int disp = now.second() % 2;
    if (jws == 0) {                                 // Alarm Subuh
      if (disp == 1) {
        iconMasjidLCD();
        lcd.setCursor(1, 0);
        lcd.print(alarmText);
        tampilJWS(0, _jam, _mnt);
      }
      else {
        lcd.clear();
      }
    }

    else if (jws == 2) {                                 // Alarm Dhuhur
      if (disp == 1) {
        iconMasjidLCD();
        lcd.setCursor(1, 0);
        lcd.print(alarmText);
        tampilJWS(2, _jam, _mnt);
      }
      else {
        lcd.clear();
      }
    }

    else if (jws == 3) {                                 // Alarm Ashar
      if (disp == 1) {
        iconMasjidLCD();
        lcd.setCursor(1, 0);
        lcd.print(alarmText);
        tampilJWS(3, _jam, _mnt);
      }
      else {
        lcd.clear();
      }
    }

    else if (jws == 5) {                                 // Alarm Maghrib
      if (disp == 1) {
        iconMasjidLCD();
        lcd.setCursor(1, 0);
        lcd.print(alarmText);
        tampilJWS(5, _jam, _mnt);
      }
      else {
        lcd.clear();
      }
    }

    else if (jws == 6) {                                 // Alarm Isya
      if (disp == 1) {
        iconMasjidLCD();
        lcd.setCursor(1, 0);
        lcd.print(alarmText);
        tampilJWS(6, _jam, _mnt);
      }
      else {
        lcd.clear();
      }
    }

    if (disp == 1) {
      digitalWrite(Buzzer, dBuzz);
    }
    else {
      digitalWrite(Buzzer, LOW);
    }
    if (tDtk >= 20 or mntTunggu > 0) {
      dBuzz = 0;
    }
    tHold.update();
  }
}

//===================================================================
void displayRTC(byte _t, byte _b, byte _d, byte _j, byte _m) {
  // Tampilan Jam
  lcd.setCursor(1, 1);
  lcd.print(konversi(_j));
  lcd.setCursor(3, 1);
  lcd.print(':');
  lcd.setCursor(4, 1);
  lcd.print(konversi(_m));

  // Tampilan Tanggal
  lcd.setCursor(7, 1);
  lcd.print(konversi(_d));
  lcd.setCursor(9, 1);
  lcd.print('/');
  lcd.setCursor(10, 1);
  lcd.print(konversi(_b));
  lcd.setCursor(12, 1);
  lcd.print('/');
  lcd.setCursor(13, 1);
  lcd.print(konversi(_t));
}
//============================================================
void readRTC() {
  DateTime now = rtc.now();
  thn = now.year() - 2000;
  bln = now.month();
  tgl = now.day();
  jam = now.hour();
  mnt = now.minute();
}
//============================================================
void menuSetting() {
  DateTime now = rtc.now();
  readRTC();
  lcd.clear();
  int tahun;
  //============================================================
setJAM:
  lcd.setCursor(0, 0);
  lcd.print("    Set  JAM    ");
  displayRTC(thn, bln, tgl, jam, mnt);

  if (digitalRead(bOK) == LOW) {
    goto setMNT;
  }
  else if (digitalRead(bUP) == LOW) {
    jam++;
    if (jam >= 24) jam = 0;
  }
  else if (digitalRead(bDN) == LOW) {
    jam--; 
    if (jam < 0) jam = 23;
  }

  now = rtc.now();
  tahun = thn + 2000;
  rtc.adjust(DateTime(tahun, bln, tgl, jam, mnt, now.hour()));
  goto setJAM;

  //============================================================
setMNT:
  lcd.setCursor(0, 0);
  lcd.print("    Set  MNT    ");
  displayRTC(thn, bln, tgl, jam, mnt);

  if (digitalRead(bOK) == LOW) {
    goto setTGL;
  }
  else if (digitalRead(bUP) == LOW) {
    mnt++;
    if (mnt >= 60) mnt = 0;
  }
  else if (digitalRead(bDN) == LOW) {
    mnt--;
    if (mnt < 0) mnt = 59;
  }

  now = rtc.now();
  tahun = thn + 2000;
  rtc.adjust(DateTime(tahun, bln, tgl, jam, mnt, now.hour()));
  delay(300);

  goto setMNT;

  //============================================================
setTGL:
 
  lcd.setCursor(0, 0);
  lcd.print("    Set  TGL    ");
  displayRTC(thn, bln, tgl, jam, mnt);

  if (digitalRead(bOK) == LOW) {
    goto setBLN;
  }
  else if (digitalRead(bUP) == LOW) {
    tgl++;
    if (tgl >= 31) tgl = 0;
  }
  else if (digitalRead(bDN) == LOW) {
    tgl--;
    if (tgl < 0) tgl = 31;
  }

  now = rtc.now();
  tahun = thn + 2000;
  rtc.adjust(DateTime(tahun, bln, tgl, jam, mnt, now.hour()));
  delay(300);
  goto setTGL;

  //============================================================
setBLN:
  lcd.setCursor(0, 0);
  lcd.print("    Set  BLN    ");
  displayRTC(thn, bln, tgl, jam, mnt);

  if (digitalRead(bOK) == LOW) {
    goto setTHN;
  }
  else if (digitalRead(bUP) == LOW) {
    bln++;
    if (bln >= 12) bln = 1;
  }
  else if (digitalRead(bDN) == LOW) {
    bln--;
    if (bln < 0) bln = 12;
  }

  now = rtc.now();
  tahun = thn + 2000;
  rtc.adjust(DateTime(tahun, bln, tgl, jam, mnt, now.hour()));
  delay(300);
  goto setBLN;

  //============================================================
setTHN:
  lcd.setCursor(0, 0);
  lcd.print("    Set  THN    ");
  displayRTC(thn, bln, tgl, jam, mnt);

  if (digitalRead(bOK) == LOW) {
    goto setEND;
  }
  else if (digitalRead(bUP) == LOW) {
    thn++;
    if (bln > 50) thn = 18;
  }
  else if (digitalRead(bDN) == LOW) {
    thn--;
    if (bln < 18) thn = 50;
  }

  now = rtc.now();
  tahun = thn + 2000;
  rtc.adjust(DateTime(tahun, bln, tgl, jam, mnt, now.hour()));
  delay(300);
  goto setTHN;

setEND:
  setting = false;
  delay(500);
  lcd.clear();
}

Cara Kerja Alat

Bagaimana kerja alat ini? Jadwal Sholat ini dibaris pertama akan menampilkan waktu dan kalender sekarang. Kemudian dibaris kedua akan menampilkan jadwal sholat 5 waktu + imsyak. Tampilan jadwal sholat akan berganti-ganti selama 5 detik sekali. Berikut ini adalah tampilan LCDnya:

Dari program diatas, saya menambahkan fitur Alarm dan Setting. Fitur Alarm dapat memberikan sinyal kepada kita dengan menggunakan suara dari Buzzer, alarm akan aktif selama 1 menit dan kemudian JWS kembali semula. Fitur Setting kita dapat mengatur ulang jam dan tanggal, jika tidak cocok. Disini saya akan jelaskan sedikit caranya, karena pada video dibawah saya menggunakan settingan Remote TV jadi, saya jelaskan disini saja. Tombol Tengah digunakan untuk masuk menu setting dan mengganti menu, Tombol UP untuk menambah nilai data, dan Tombol DOWN digunakan untuk mengurangi nilai. Sederhana bukan, berikut fungsi tombol.

Fungsi Tombol:

  • Tombol OK         : Masuk menu dan mengganti menu
  • Tombol UP         : Menambah nilai data
  • Tombol DOWN : Mengurangi nilai data

Ok mungkin sekian dulu, maaf kalau mungkin tulisan ini terkesan kurang jelas, bisa kita bahas di kotak komentar dibawah ya. Saya harap project uini dapat dikembangkan dengan tambahan-tambahan fitur lainya. Semoga bermanfaat

Download Library

Video

Maaf Video Belum Tersedia