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

board wemos d1 r1

2. Kabel data micro USB

kabel data micro usb

3. Breadboard

kabel data micro usb

4. LCD 20x4

lcd 20x4

5. I2C LCD

i2c lcd

6. Kabel Jumper

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.

wemos d1 r1 com usb port
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).

board wemos installed
arduino ide select port

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.

arduino ide select port

4. Rangkaian Elektrikal

Rangkai komponen-komponen di atas seperti wiring diagram berikut:

wiring diagram wemos d1 r1 i2c lcd 20x4

Penjelasan wiring diagram:

  1. Tancapkan 16 pin dari LCD 20x4 dan 16 pin I2C LCD ke dalam breadboard dengan posisi sejajar.
  2. Hubungkan pin VCC I2C ke pin 5V Wemos D1 R1
  3. Hubungkan pin GND I2C ke pin Gnd Wemos D1 R1
  4. Hubungkan pin SDA I2C ke pin D14/SDA Wemos D1 R1
  5. 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.

assalamualaikum

Proses Get data sampai dengan hasil akhir ditampilkannya informasi tanggal Hijriyah, JWS dan real time jam dan menit dari NTP Client.

get_data
lcd_jws_hijriyah