Assalamu'alaikum, pada tutorial kali ini saya akan memodifikasi gadget sederhana saya yang ada di tutorial "Menampilkan Jadwal Waktu Sholat api.myquran.com di Layar LCD 20x4". Modifikasi yang saya lakukan adalah mengganti tanggal Masehi dengan tanggal Hijriyah pada tampilan layar LCD dan menambahkan backlight LCD menjadi ON ketika waktu sholat tinggal 3 menit lagi. Latar belakang modifikasi ini dalam rangka berbagi ilmu di bulan suci Ramadhan 1433 H dengan harapan bisa menjadi ladang pahala buat saya, Aamiiiin.
LCD backlight Off
LCD backlight On, 3 menit menjelang waktu sholat
Karena saya akan menampilkan tanggal Hijriyah maka saya harus mengkonversi tanggal Masehi yang saya dapat dari NTP Client menjadi tanggal Hijriyah, oleh karena itu saya akan menggunakan bantuan penyedia layanan API lainnya untuk hal tersebut. Kok layanan API lainnya? Iya, soalnya layanan API utamanya adalah API Jadwal Waktu Sholat miliknya api.myquran.com [nanya sendiri, jawab sendiri]. Jadi sekali lagi, di sini saya melakukan 2 kali https request pada layanan API, yang pertama API konversi tanggal Masehi ke tanggal Hijriyah dan yang kedua API Jadwal Waktu Sholat (JWS).
Layanan API konversi tanggal Masehi ke tanggal Hijriyah yang saya gunakan di sini adalah https://pdsi.unisayogya.ac.id/api-konversi-masehi-ke-hijriah/
1. Prasyarat
Agar praktik dari tutorial ini bisa berjalan dengan baik, teman-teman harus sudah melakukan hal berikut:
2. Hardware
Masih menggunakan komponen elektrikal pada tutorial Menampilkan Real TIme Tanggal dan Jam di Layar LCD 20x4 yaitu:
1. Board Wemos D1 R1
2. Kabel data micro USB
3. Breadboard
4. LCD 20x4
5. I2C LCD
6. Kabel Jumper
3. Upload Sketch
Hubungkan board Wemos D1 R1 ke komputer melalui port USB dan pastikan port USB yang sudah terhubung dengan Wemos D1 R1 terbaca di device manager.
Dari gambar di atas terlihat board Wemos D1 R1 sudah terkoneksi dengan komputer melalui ports COM8 (USB-SERIAL CH340).
Langkah selanjutnya adalah setting board dan port dari perangkat Wemos D1 R1. Buka Arduino IDE, pilih board LOLIN(Wemos D1 R1) melalui Tools->Board, kemudian pilih port seperti yang tertera di Device Manager yaitu port USB-SERIAL CH340 (COM8).
Copy sketch di bawah ini kemudian paste di Arduino IDE.
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
#include <WiFiUdp.h>
#include <Wire.h> // I2C library already built in Arduino IDE
#include <LiquidCrystal_I2C.h> //library via Include Library > Manage Library >
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);
const char *ssid = "erik"; // sesuaikan dengan ssid wifi
const char *password = "triyono"; // sesuaikan dengan password wifi
//Web/Server address to read/write from
const char *host = "api.myquran.com";
const char *host2 = "service.unisayogya.ac.id";
const int httpsPort = 443; //HTTPS= 443 and HTTP = 80
//SHA1 finger print of certificate use web browser to view and copy
const char fingerprint[] PROGMEM = "95:3F:1A:FF:CB:5F:DA:AE:D0:B7:C8:C6:EF:80:81:8D:08:7D:05:24";
const char fingerprint2[] PROGMEM = "A0:DE:85:05:2F:C5:42:C8:4C:42:3F:AE:23:0F:D1:F9:F8:01:A3:70";
const long utcOffsetInSeconds = 25200;
String daysOfTheWeek[7] = {"Ahad ", "Senin ", "Selasa", "Rabu ", "Kamis ", "Jumat ", "Sabtu "};
String months[12] = {"Muharram", "Shafar", "Rabi'ulAwal", "Rabi'ulAhir", "JumadilAwal", "JumadilAhir", "Rajab", "Sya'ban", "Ramadhan", "Syawwal", "Dzulqaidah", "Dzulhijjah"};
String strMMDD = "NA";
String strMMDDLast = strMMDD;
String strYY;
String Link;
#include <TimeLib.h>
tmElements_t tm;
int Year, Month, Day, Hour, Minute, Second ;
char firstDateTime[20];
char secondDateTime[20];
unsigned long firstTime;
unsigned long secondTime;
String strYear, strMonth, strDate, strYMD;
String strHour, strMinute, strSecond, strHms;
String strTahun, strBulan, strTanggal;
String fullHijriyahDate;
String waktuSholat[5];
String waktuSholatTerdekat;
char chrTanggal[2];
char chrBulan[2];
char chrTahun[4];
char jamsolat[5];
String SubuhTime, DzuhurTime, AsharTime, MaghribTime, IsyaTime;
// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "id.pool.ntp.org", utcOffsetInSeconds);
void setup()
{
Serial.begin (115200);
WiFi.mode(WIFI_OFF); //Prevents reconnection issue (taking too long to connect)
delay(1000);
WiFi.mode(WIFI_STA); //Only Station No AP, This line hides the viewing of ESP as wifi hotspot
WiFi.begin(ssid, password); //Connect to your WiFi router
Serial.println("");
Serial.print("Connecting");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
//If connection successful show IP address in serial monitor
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
timeClient.begin();
timeClient.setTimeOffset(25200);
lcd.begin(20,4); // initializing the LCD 16 x 2
lcd.setBacklightPin(3,POSITIVE); // Enable or Turn On the backlight
lcd.setBacklight(LOW);
lcd.home();
lcd.print("Assalamu'alaikum"); // Start Print text to Line 1
lcd.setCursor(0, 1);
lcd.print("--------------------"); // Start Print Test to Line 2
delay(1000);
}
void loop() {
timeClient.update();
strMMDD = String(timeClient.getMonth())+"/"+String(timeClient.getDate());
if (strMMDDLast != strMMDD) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Get Data ...");
strMMDDLast = strMMDD;
strYY = String(timeClient.getYear());
getHijriahDate();
getSholatTime();
} else {
strYear = "20"+strYY;
if (timeClient.getMonth() > 9) {
strMonth = String(timeClient.getMonth());
} else {
strMonth = "0"+String(timeClient.getMonth());
}
if (timeClient.getDate() > 9) {
strDate = String(timeClient.getDate());
} else {
strDate = "0"+String(timeClient.getDate());
}
strYMD = strYear+"-"+strMonth+"-"+strDate;
if (timeClient.getHours() > 9) {
strHour = String(timeClient.getHours());
} else {
strHour = "0"+String(timeClient.getHours());
}
if (timeClient.getMinutes() > 9) {
strMinute = String(timeClient.getMinutes());
} else {
strMinute = "0"+String(timeClient.getMinutes());
}
if (timeClient.getSeconds() > 9) {
strSecond = String(timeClient.getSeconds());
} else {
strSecond = "0"+String(timeClient.getSeconds());
}
strHms = strHour+":"+strMinute+":"+strSecond;
assign(strYMD+" "+strHms, "first");
// this for loop works correctly with an array of any type or size
for (byte i = 0; i < (sizeof(waktuSholat) / sizeof(waktuSholat[0])); i++) {
String strSecondTime = strYMD+" "+waktuSholat[i];
// String strSecondTime = strYMD+" 19:59:00";
assign(strSecondTime, "second");
waktuSholatTerdekat = strSecondTime;
if ((secondTime - firstTime)/60 < 70000000) {
break;
} else {
waktuSholatTerdekat = strYMD+" "+waktuSholat[0];
}
}
fullHijriyahDate = strTanggal+" "+months[strBulan.toInt() - 1]+" "+strTahun+"H";
lcd.setCursor(0, 0);
lcd.print(fullHijriyahDate);
lcd.setCursor(0, 1);
lcd.print("Dzhr : ");
lcd.setCursor(7, 1);
lcd.print(DzuhurTime.substring(0,5));
lcd.setCursor(0, 2);
lcd.print("Ashr : ");
lcd.setCursor(7, 2);
lcd.print(AsharTime.substring(0,5));
lcd.setCursor(0, 3);
lcd.print("Mgrb : ");
lcd.setCursor(7, 3);
lcd.print(MaghribTime.substring(0,5));
if (nonblocking_delay(1000)) {
lcd.setBacklight(LOW);
if ((secondTime - firstTime)/60 <= 2) {
lcd.setBacklight(HIGH);
}
lcd.setCursor(15, 3);
lcd.print(strHour+":"+strMinute);
}
}
}
void assign(String Test1, String firstOrSecond) {
char chTest[20];
Test1.toCharArray(chTest, 20);
if (firstOrSecond == "first") {
strcpy(firstDateTime, chTest);
createElements(firstDateTime);
firstTime = makeTime(tm);
} else {
strcpy(secondDateTime, chTest);
createElements(secondDateTime);
secondTime = makeTime(tm);
}
}
void createElements(const char *str) {
sscanf(str, "%d-%d-%d %d:%d:%d", &Year, &Month, &Day, &Hour, &Minute, &Second);
tm.Year = CalendarYrToTm(Year);
tm.Month = Month;
tm.Day = Day;
tm.Hour = Hour;
tm.Minute = Minute;
tm.Second = Second;
}
void getHijriahDate() {
WiFiClientSecure httpsClient; //Declare object of class WiFiClient
Serial.println(host2);
Serial.printf("Using fingerprint '%s'\n", fingerprint2);
httpsClient.setFingerprint(fingerprint2);
httpsClient.setTimeout(15000); // 15 Seconds
delay(1000);
Serial.print("HTTPS Connecting");
int r=0; //retry counter
while((!httpsClient.connect(host2, httpsPort)) && (r < 30)){
delay(100);
Serial.print(".");
r++;
}
if(r==30) {
Serial.println(". Connection failed");
}
else {
Serial.println(". Connected to web");
}
//GET Data
Link = "/kalender/api/masehi2hijriah/muhammadiyah/20"+strYY+"/"+strMMDD; //address from which we need to get the data inside the server.
Serial.print("requesting URL: ");
Serial.println(host2+Link);
httpsClient.print(String("GET ") + Link + " HTTP/1.1\r\n" +
"Host: " + host2 + "\r\n" +
"Connection: close\r\n\r\n");
Serial.println("request sent");
while (httpsClient.connected()) {
String line = httpsClient.readStringUntil('\n');
if (line == "\r") {
Serial.println("headers received");
break;
}
}
Serial.println("reply was:");
Serial.println("==========");
String line;
while(httpsClient.available()){
line = httpsClient.readStringUntil('\n'); //Read Line by Line
Serial.println(line);
// Get tanggal ///////////////////
int pos1 = line.indexOf("\"tanggal\"");
if (pos1 >= 0) {
int i = 0;
for(i=0; i<2; i++){
if (String(line[pos1 + 10 + i]) != ",") {
chrTanggal[i] = line[pos1 + 10 + i];
}
}
strTanggal = chrTanggal;
}
//////////////////////////////////////
// Get bulan ///////////////////
int pos2 = line.indexOf("\"bulan\"");
if (pos2 >= 0) {
int j = 0;
for(j=0; j<2; j++){
if (String(line[pos2 + 8 + j]) != ",") {
chrBulan[j] = line[pos2 + 8 + j];
}
}
strBulan = chrBulan;
}
//////////////////////////////////////
// Get tahun ///////////////////
int pos3 = line.indexOf("\"tahun\"");
if (pos3 >= 0) {
int k = 0;
for(k=0; k<4; k++){
chrTahun[k] = line[pos3 + 8 + k];
}
strTahun = chrTahun;
strTahun = strTahun.substring(0,4);
}
//////////////////////////////////////
}
Serial.println("==========");
Serial.println("closing connection");
delay(2000);
}
void getSholatTime() {
WiFiClientSecure httpsClient; //Declare object of class WiFiClient
Serial.println(host);
Serial.printf("Using fingerprint '%s'\n", fingerprint);
httpsClient.setFingerprint(fingerprint);
httpsClient.setTimeout(15000); // 15 Seconds
delay(1000);
Serial.print("HTTPS Connecting");
int r=0; //retry counter
while((!httpsClient.connect(host, httpsPort)) && (r < 30)){
delay(100);
Serial.print(".");
r++;
}
if(r==30) {
Serial.println(". Connection failed");
}
else {
Serial.println(". Connected to web");
}
//GET Data
Link = "/v1/sholat/jadwal/1204/20"+strYY+"/"+strMMDD; //address from which we need to get the data inside the server.
Serial.print("requesting URL: ");
Serial.println(host+Link);
httpsClient.print(String("GET ") + Link + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
Serial.println("request sent");
while (httpsClient.connected()) {
String line = httpsClient.readStringUntil('\n');
if (line == "\r") {
Serial.println("headers received");
break;
}
}
Serial.println("reply was:");
Serial.println("==========");
String line;
while(httpsClient.available()){
line = httpsClient.readStringUntil('\n'); //Read Line by Line
// Get Subuh time ///////////////////
int pos1 = line.indexOf("\"subuh\"");
if (pos1 >= 0) {
int j = 0;
for(j=0; j<5; j++){
jamsolat[j] = line[pos1 + 9 + j];
}
SubuhTime = jamsolat;
}
//////////////////////////////////////
// Get Dzuhur time ///////////////////
int pos2 = line.indexOf("\"dzuhur\"");
if (pos2 >= 0) {
int k = 0;
for(k=0; k<6; k++){
jamsolat[k] = line[pos2 + 10 + k];
}
DzuhurTime = jamsolat;
}
//////////////////////////////////////
// Get Ashar time ////////////////////
int pos3 = line.indexOf("\"ashar\"");
if (pos3 >= 0) {
int l = 0;
for(l=0; l<5; l++){
jamsolat[l] = line[pos3 + 9 + l];
}
AsharTime = jamsolat;
}
//////////////////////////////////////
// Get Maghrib time //////////////////
int pos4 = line.indexOf("\"maghrib\"");
if (pos4 >= 0) {
int m = 0;
for(m=0; m<7; m++){
jamsolat[m] = line[pos4 + 11 + m];
}
MaghribTime = jamsolat;
}
//////////////////////////////////////
// Get Isya time ////////////////////
int pos5 = line.indexOf("\"isya\"");
if (pos5 >= 0) {
int n = 0;
for(n=0; n<5; n++){
jamsolat[n] = line[pos5 + 8 + n];
}
IsyaTime = jamsolat;
}
//////////////////////////////////////
waktuSholat[0] = SubuhTime.substring(0,5)+":00";
waktuSholat[1] = DzuhurTime.substring(0,5)+":00";
waktuSholat[2] = AsharTime.substring(0,5)+":00";
waktuSholat[3] = MaghribTime.substring(0,5)+":00";
waktuSholat[4] = IsyaTime.substring(0,5)+":00";
Serial.println("Subuh : "+waktuSholat[0]);
Serial.println("Dzuhur : "+waktuSholat[1]);
Serial.println("Ashar : "+waktuSholat[2]);
Serial.println("Maghrib : "+waktuSholat[3]);
Serial.println("Isya : "+waktuSholat[4]);
Serial.println("----- ### -----");
}
Serial.println("==========");
Serial.println("closing connection");
delay(2000);
}
// tambahan untuk membuat delay non blocking
unsigned long nonblocking_time = millis();
unsigned long nonblocking_last = millis();
boolean nonblocking_delay(long milidetik){
nonblocking_time = millis();
if(nonblocking_time - nonblocking_last >= milidetik){
nonblocking_last = nonblocking_time;
return true;
}
return false; }
Kemudian upload sketch dan tunggu sampai done uploading.
4. Rangkaian Elektrikal
Rangkai komponen-komponen di atas seperti wiring diagram berikut:
Penjelasan wiring diagram:
- Tancapkan 16 pin dari LCD 20x4 dan 16 pin I2C LCD ke dalam breadboard dengan posisi sejajar.
- Hubungkan pin VCC I2C ke pin 5V Wemos D1 R1
- Hubungkan pin GND I2C ke pin Gnd Wemos D1 R1
- Hubungkan pin SDA I2C ke pin D14/SDA Wemos D1 R1
- Hubungkan pin SCL I2C ke pin D15/SCL Wemos D1 R1
I2C | Wemos |
---|---|
VCC | 5V |
GND | GND |
SDA | D14/SDA |
SCL | D15/SCL |
Setelah komponen elektrikal dirangkai, hubungkan Wemos D1 R1 dengan power supply 5 Volt.
Proses Get data sampai dengan hasil akhir ditampilkannya informasi tanggal Hijriyah, JWS dan real time jam dan menit dari NTP Client.