JWS ESP8266
JWS ESP8266
* JADWAL WAKTU SHOLAT MENGGUNAKAN NODEMCU ESP8266, LED P10, RTC DS3231, BUZZER
* FITUR : JADWAL SHOLAT 5 WAKTU DAN TANBIH IMSAK, JAM BESAR, TANGGAL, SUHU,
ALARAM ADZAN DAN TANBIH IMSAK,
* DAN HITUNG MUNDUR IQOMAH DAN UBAH WAKTU LEWAT WIFI DENGAN BROWSER.
*
*/
#include <Wire.h>
#include <RtcDS3231.h>
RtcDS3231<TwoWire> Rtc(Wire);
#include <HJS589.h>
#include <fonts/ElektronMart5x6.h>
#include <fonts/ElektronMart6x8.h>
#include <fonts/ElektronMart6x12.h>
#include <fonts/ElektronMart6x16.h>
#include <fonts/ElektronMartArabic5x6.h>
#include <fonts/ElektronMartArabic6x16.h>
#include <fonts/bmz6x16.h>
#include <fonts/bmz5x7.h>
#include <fonts/bmz6x7.h>
#include <fonts/bmz4x6.h>
#include <PrayerTimes.h>
//----------------------------
// SETUP DMD HJS589
#define DISPLAYS_WIDE 2
#define DISPLAYS_HIGH 1
HJS589 Disp(DISPLAYS_WIDE, DISPLAYS_HIGH); // Jumlah Panel P10 yang digunakan
(KOLOM,BARIS)
//----------------------------------------------------------------------
// HJS589 P10 FUNGSI TAMBAHAN UNTUK NODEMCU ESP8266
Disp.refresh();
timer0_write(ESP.getCycleCount() + 80000);
void Disp_init() {
Disp.start();
noInterrupts();
timer0_isr_init();
timer0_attachInterrupt(refresh);
interrupts();
Disp.clear();
//SETUP RTC
//year, month, date, hour, min, sec and week-day(Senin 0 sampai Ahad 6)
//DateTime dt(2018, 12, 20, 16, 30, 0, 3);
RtcDateTime now;
char weekDay[][7] = {"AHAD", "SENIN", "SELASA", "RABU", "KAMIS", "JUM'AT", "SABTU",
"AHAD"}; // array hari, dihitung mulai dari senin, hari senin angka nya =0,
char monthYear[][4] = { "DES", "JAN", "FEB", "MAR", "APR", "MEI", "JUN", "JUL",
"AGU", "SEP", "OKT", "NOV", "DES" };
// PrayerTimes
double times[sizeof(TimeName)/sizeof(char*)];
int ihti = 2;
int detikiqmh;
int menitiqmh;
// BUZZER
const int buzzer = 3; // Pin GPIO Buzzer - RX
//----------------------------------------------------------------------
// SETUP
void setup() {
Serial.begin(9600);
//Buzzer
pinMode(buzzer, OUTPUT);
digitalWrite(buzzer, LOW);
delay(50);
//RTC D3231
int rtn = I2C_ClearBus(); // clear the I2C bus first before calling Wire.begin()
if (rtn != 0) {
Serial.println(F("I2C bus error. Could not clear"));
if (rtn == 1) {
Serial.println(F("SCL clock line held low"));
} else if (rtn == 2) {
Serial.println(F("SCL clock line held low by slave clock stretch"));
} else if (rtn == 3) {
Serial.println(F("SDA data line held low"));
}
} else { // bus clear, re-enable Wire, now can start Wire Arduino master
Wire.begin();
}
Rtc.Begin();
if (!Rtc.GetIsRunning()) {
Rtc.SetIsRunning(true);
Rtc.Enable32kHzPin(false);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
//DMD
Disp_init();
Disp.setBrightness(20);
//----------------------------------------------------------------------
// LOOP
uint8_t tmputama;
void loop() {
switch(tmputama) {
case 0 :
tampiljws();
break;
case 1 :
iqomah();
break;
uint8_t tmpjws;
void tampiljws() {
switch(tmpjws) {
case 0 :
animLogoX();
AlarmSholat();
break;
case 1 :
JamBesar(1);
tampilinfo();
AlarmSholat();
break;
case 2 :
TeksBerjalanKananKiri();
AlarmSholat();
break;
uint8_t tmpinfo;
void tampilinfo() {
switch(tmpinfo) {
case 0 :
TampilTanggal();
break;
case 1 :
TampilSuhu();
break;
case 2 :
TampilJadwalSholat();
break;
//----------------------------------------------------------------------
// ALARM SHOLAT BERJALAN SAAT MASUK WAKTU SHOLAT
void AlarmSholat() {
JadwalSholat();
// Tanbih Imsak
get_float_time_parts(times[0], hours, minutes);
minutes = minutes + ihti;
minutes = 60 - minutes;
hours --;
} else {
minutes = minutes - 10 ;
BuzzerPendek();
Disp.clear();
Disp.setFont(bmz4x6);
textCenter(0, "TANBIH");
textCenter(8, "IMSAK");
delay(durasiadzan);
Disp.clear();
// Subuh
get_float_time_parts(times[0], hours, minutes);
minutes = minutes + ihti;
BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "SUBUH");
delay(durasiadzan);
menitiqmh = 12;
tmputama = 1;
Disp.clear();
}
// Dzuhur
get_float_time_parts(times[2], hours, minutes);
minutes = minutes + ihti;
BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "DZUHUR");
delay(durasiadzan);
Disp.clear();
menitiqmh = 7;
tmputama = 1;
BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "JUM'AT");
delay(durasiadzan);
// Ashar
get_float_time_parts(times[3], hours, minutes);
minutes = minutes + ihti;
BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "ASHAR");
delay(durasiadzan);
Disp.clear();
menitiqmh = 5;
tmputama = 1;
// Maghrib
get_float_time_parts(times[5], hours, minutes);
minutes = minutes + ihti;
BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "MAGHRIB");
delay(durasiadzan);
Disp.clear();
menitiqmh = 5;
tmputama = 1;
// Isya'
get_float_time_parts(times[6], hours, minutes);
minutes = minutes + ihti;
BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "ISYA'");
delay(durasiadzan);
Disp.clear();
menitiqmh = 5;
tmputama = 1;
//----------------------------------------------------------------------
// FORMAT TEKS
//----------------------------------------------------------------------
//TAMPILKAN RUNNING TEKS
static String nama1 = (" Belajar Membuat JWS ESP8266 Wifi ");
static String nama2 = (" Membuat JWS Running Teks ");
void TeksBerjalanKananKiri() {
RtcDateTime now = Rtc.GetDateTime();
char jam[3];
char menit[3];
char detik[3];
sprintf(jam, "%02d", now.Hour());
sprintf(menit, "%02d", now.Minute());
sprintf(detik, "%02d", now.Second());
Disp.setFont(bmz6x7);
Disp.drawText(8,-1,jam);
Disp.drawText(22,-1,":");
Disp.drawText(25,-1,menit);
Disp.drawText(39,-1,":");
Disp.drawText(42,-1,detik);
pM = cM;
if (x < fullScroll) {
++x;
} else {
x = 0;
Disp.clear();
tmpjws = 0;
Disp.setFont(bmz5x7);
Disp.drawText(width - x, 9, nama1);
void TeksBerjalanKiriKanan() {
Disp.setFont(ElektronMart6x8);
pM = cM;
if (x < fullScroll) {
++x;
} else {
x = 0;
//----------------------------------------------------------------------
//TAMPILKAN LOGO
//----------------------------------------------------------------------
// ANIMASI LOGO
void animLogoX() {
static uint8_t x;
static uint8_t s; // 0=in, 1=out
static uint32_t pM;
uint32_t cM = millis();
JamBesar2(16);
pM = cM;
x++;
if (s == 1 and x > 0) {
pM = cM;
x--;
s = 1;
if (x == 0 and s == 1) {
Disp.clear();
s = 0;
tmpjws = 1;
LogoA(Disp.width() - x);
LogoM(x - 16);
void LogoA(uint32_t x) {
16, 16,
0x00, 0x00, 0x7f, 0xfe, 0x7f, 0xfe, 0x00, 0x00, 0x7e, 0x66, 0x7e, 0x66, 0x06,
0x66, 0x06, 0x66, 0x7e, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7f,
0xfe, 0x7f, 0xfe, 0x00, 0x00
};
Disp.drawBitmap(x, 0, LogoA);
}
void LogoM(uint32_t x) {
16, 16,
0x00, 0x00, 0x66, 0x7e, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x7e, 0x7e, 0x7e,
0x7e, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x7e, 0x7e, 0x7e, 0x66, 0x06, 0x66, 0x06, 0x7f,
0xfe, 0x7f, 0xfe, 0x00, 0x00
};
Disp.drawBitmap(x, 0, LogoM);
}
//----------------------------------------------------------------------
//TAMPILKAN JADWAL SHOLAT
void JadwalSholat() {
/*
CALCULATION METHOD
------------------
Jafari, // Ithna Ashari
Karachi, // University of Islamic Sciences, Karachi
ISNA, // Islamic Society of North America (ISNA)
MWL, // Muslim World League (MWL)
Makkah, // Umm al-Qura, Makkah
Egypt, // Egyptian General Authority of Survey
Custom, // Custom Setting
JURISTIC
--------
Shafii, // Shafii (standard)
Hanafi, // Hanafi
ADJUSTING METHOD
----------------
None, // No adjustment
MidNight, // middle of night
OneSeventh, // 1/7th of night
AngleBased, // angle/60th of night
TIME IDS
--------
Fajr,
Sunrise,
Dhuhr,
Asr,
Sunset,
Maghrib,
Isha
*/
set_calc_method(Karachi);
set_asr_method(Shafii);
set_high_lats_adjust_method(AngleBased);
set_fajr_angle(20);
set_isha_angle(18);
void TampilJadwalSholat() {
JadwalSholat();
static uint8_t i;
static uint32_t pM;
uint32_t cM = millis();
char sholat[7];
char jam[5];
char TimeName[][8] = {"SUBUH","TERBIT","DZUHUR","ASHAR","TRBNM","MAGRIB","ISYA"};
int hours, minutes;
pM = cM;
Disp.drawRect(31,0,64,15,0,0);
Disp.setFont(bmz4x6);
textCenter1PKanan(-1, sholat);
Disp.drawLine(32,7,64,7,1);
Disp.setFont(bmz6x7);
textCenter1PKanan(8, jam);
i++;
if (i > 7) {
get_float_time_parts(times[0], hours, minutes);
minutes = minutes + ihti;
if (minutes < 11) {
minutes = 60 - minutes;
hours --;
} else {
minutes = minutes - 10 ;
}
sprintf(jam,"%02d:%02d", hours, minutes);
Disp.drawRect(31,0,64,15,0,0);
Disp.setFont(bmz4x6);
textCenter1PKanan(-1, "TANBIH");
Disp.drawLine(32,7,64,7,1);
Disp.setFont(bmz6x7);
textCenter1PKanan(8, jam);
if (i > 8) {
i = 0;
Disp.drawRect(0,0,64,15,0,0);
tmpinfo = 0;
tmpjws = 2;
}
//----------------------------------------------------------------------
// HITUNG MUNDUR WAKTU SETELAH ADZAN SAMPAI MULAI IQOMAH
void iqomah() {
Disp.setFont(ElektronMart5x6);
textCenter(0, "IQOMAH");
if (detikiqmh == 60) {
detikiqmh = 0;
}
if (detikiqmh < 0) {
detikiqmh = 59;
menitiqmh--;
}
//----------------------------------------------------------------------
//TAMPILKAN TANGGAL
void TampilTanggal() {
char hari[8];
char tanggal[7]; // 21 SEP
pM = cM;
flag++;
Disp.setFont(bmz4x6);
textCenter1PKanan(0, hari);
textCenter1PKanan(8, tanggal);
if (flag >= 2) {
flag = 0;
Disp.drawRect(32,0,64,15,0,0);
tmpinfo = 1;
//----------------------------------------------------------------------
// TAMPILKAN SUHU
void TampilSuhu() {
char suhu[3];
int koreksisuhu = 2; // Perkiraan selisih suhu mesin dengan suhu ruangan
pM = cM;
flag++;
Disp.setFont(bmz4x6);
textCenter1PKanan(0, "SUHU");
Disp.setFont(bmz5x7);
Disp.drawText(36,8, suhu);
Disp.drawCircle(49,9,1);
Disp.drawText(53,8, "C");
if (flag >= 2) {
flag = 0;
Disp.drawRect(32,0,64,15,0,0);
tmpinfo = 2;
//----------------------------------------------------------------------
// TAMPILKAN JAM
void JamBesar(uint16_t x) {
char jam[3];
char menit[3];
char detik[3];
if (pulse > 8) {
pulse=0;
}
if(y == 20) {
Disp.drawRect(x+13,3+pulse,x+16,11-pulse,0,1);
}
if(y == 0 and d == 1) {
d=0;
huruf = !huruf;
}
//JAM
if (huruf) {
Disp.setFont(bmz6x16);
} else {
Disp.setFont(bmz6x16);
}
Disp.drawText(x+0, y - 20, jam);
//MENIT
if (huruf) {
Disp.setFont(bmz6x16);
} else {
Disp.setFont(bmz6x16);
}
Disp.drawText(x+17, y - 20, menit);
//DETIK
void JamBesar2(uint16_t x) {
char jam[3];
char menit[3];
static uint8_t y;
static uint8_t d;
static uint32_t pM;
uint32_t cM = millis();
pMPulse = cM;
pulse++;
if (pulse > 8) {
pulse=0;
}
if(y == 20) {
Disp.drawRect(x+14,3+pulse,x+17,11-pulse,0,1);
}
if(y == 0 and d == 1) {
d=0;
huruf = !huruf;
}
//JAM
if (huruf) {
Disp.setFont(bmz6x16);
} else {
Disp.setFont(bmz6x16);
}
Disp.drawText(x+1, y - 20, jam);
//MENIT
if (huruf) {
Disp.setFont(bmz6x16);
} else {
Disp.setFont(bmz6x16);
}
Disp.drawText(x+18, y - 20, menit);
void TampilJamKecil() {
pMJam = cM;
//JAM
sprintf(jam,"%02d:%02d:%02d", now.Hour(), now.Minute(), now.Second());
Disp.setFont(bmz5x7);
Disp.drawText(20,7, jam);
//----------------------------------------------------------------------
// BUNYIKAN BEEP BUZZER
void BuzzerPanjang() {
digitalWrite(buzzer, HIGH);
delay(1000);
digitalWrite(buzzer, LOW);
delay(1000);
digitalWrite(buzzer, HIGH);
delay(1000);
digitalWrite(buzzer, LOW);
delay(3000);
void BuzzerPendek() {
digitalWrite(buzzer, HIGH);
delay(200);
digitalWrite(buzzer, LOW);
delay(100);
digitalWrite(buzzer, HIGH);
delay(200);
digitalWrite(buzzer, LOW);
delay(3000);
void BunyiBeep() {
pMBuz = cM;
beep = !beep;
if (beep) {
digitalWrite(buzzer, HIGH);
} else {
digitalWrite(buzzer, LOW);
//----------------------------------------------------------------------
// I2C_ClearBus menghindari gagal baca RTC (nilai 00 atau 165)
int I2C_ClearBus() {
#if defined(TWCR) && defined(TWEN)
TWCR &= ~(_BV(TWEN)); //Disable the Atmel 2-Wire interface so we can control the
SDA and SCL pins directly
#endif
pinMode(SDA, INPUT_PULLUP); // Make SDA (data) and SCL (clock) pins Inputs with
pullup.
pinMode(SCL, INPUT_PULLUP);
delay(2500); // Wait 2.5 secs. This is strictly only necessary on the first
power
// up of the DS3231 module to allow it to initialize properly,
// but is also assists in reliable programming of FioV3 boards as it gives the
// IDE a chance to start uploaded the program
// before existing sketch confuses the IDE by sending Serial data.