Jam Digital Arduino Dot Matrix P10 dengan pengaturan via Bluetooth HC-05

Jam digital Dot matrix bluetooth
Sebelumnya telah dibahas mengenai aplikasi Dot Matrix Display P10 dan juga modul RTC DS1307. Pada post ini mari kita coba aplikasikan kedua komponen tersebut sebagai jam digital yang dapat disetting via bluetooth (jadi gak usah pencet-pencet ribet). Modul bluetooth yang digunakan adalah HC-05. Untuk dasar spesifikasinya silahkan dipelajari dulu terkait komponen-komponen tersebut.
A. Wiring
jam masjid dot matrix sederhana
Beberapa modul yang digunakan adalah Modul Bluetooth HC-05, Modul RTC DS1307, Modul Display Dot Matrix (DMD) P10, dan Arduino Uno.
jam masjid dot matrix sederhana

B. Kode Program
Sebelumnya, silahkan siapkan terlebihdahulu library dan file header(font) yang akan digunakan.
1. Library DMD bisa diunduh disini
2. Library TimerOne bisa diunduh disini
3. Font Calibri (Calibri_10.h dan Calibri_12.h) dan Droid Sans bisa diunduh disini
4. Library RTClib bisa diunduh disini
Ekstrak file library ke folder Arduino>libraries. Sementara untuk font header silahkan ekstrak di dalam folder library DMD. Selanjutnya buka Arduino IDE dan gunakan kode programberikut. *thanks to Fareed Read (for GLDC font creator) and Robin2-Arduino Forum (for serial data parsing)
#include <SPI.h>        
#include <DMD.h>        
#include <TimerOne.h>  
#include "Droid_Sans_12.h"
#include "Calibri_12.h"
#include "Calibri_10.h"
#include "RTClib.h"
#include <SPI.h>
#include <SoftwareSerial.h>

SoftwareSerial BTSerial(5, 4); // RX | TX
RTC_DS1307 rtc;
char HariDalamMinggu[7][12] = {"Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jum'at", "Sabtu"};
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];  
char set_code[numChars] = {0};
int data1 = 0;
int data2 = 0;
int data3 = 0;
boolean newData = false;
int count_switch=0;
#define DISPLAYS_ACROSS 1
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

void ScanDMD(){ 
  dmd.scanDisplayBySPI();
}

void setup(void){
  Timer1.initialize( 5000 );         
  Timer1.attachInterrupt( ScanDMD );  
  dmd.clearScreen( true );   
  
  BTSerial.begin(9600);
  BTSerial.println("#Arduino DS1307 Bluetooth Configurator#");
  if (! rtc.begin()) {
    Serial.println("RTC tidak terhubung, Cek kembali wiring!");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC tidak bekerja, Setel ulang waktu!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  
  intro_msg();
  delay(1000);
}

void loop(void){
   recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(tempChars, receivedChars);
        parseData();
        setParsedData();
        newData = false;
    }
   count_switch++;
   //30 = 60s delay 
   if (count_switch < 30){
      display_data(1);
   }
   if((count_switch > 30)&&(count_switch < 32)){
      display_data(2);
   }
   if (count_switch > 32){
      count_switch=0;
   }
   
}

void display_data(int display_mode){
  DateTime now = rtc.now();
  if (display_mode == 1){
    String jamD, minD;
    if (now.hour()<10)  jamD = "0";
    jamD += String(now.hour(), DEC);
    if (now.minute()<10) minD = "0";
    minD += String(now.minute(), DEC);
    
    char* hourD = jamD.c_str();
    char* minutesD = minD.c_str();
    
    dmd.selectFont(calibri_12);
    dmd.drawString(3,3,hourD,2,GRAPHICS_NORMAL);
    dmd.drawString(18,3,minutesD,2,GRAPHICS_NORMAL);   
    dmd.drawFilledBox( 15,9,16,10, GRAPHICS_OR );
    dmd.drawFilledBox(15,5,16,6, GRAPHICS_OR);
    delay( 1000 );
    dmd.drawFilledBox( 15,9,16,10, GRAPHICS_NOR );
    dmd.drawFilledBox(15,5,16,6, GRAPHICS_NOR);
    delay( 1000 );
  }
  if (display_mode == 2){
    String hariD, bulanD;
    if (now.day()<10)  hariD = "0";
    hariD += String(now.day(), DEC);
    if (now.month()<10) bulanD = "0";
    bulanD += String(now.month(), DEC);
    String tanggalD = hariD;
    tanggalD +="/";
    tanggalD +=bulanD;
    tanggalD +="/";
    tanggalD += String(now.year());
    char* dateD = tanggalD.c_str();
    
    
     dmd.clearScreen( true );
     dmd.selectFont(calibri_12);
     dmd.drawMarquee(dateD,10,(32*DISPLAYS_ACROSS)-1,3);
     long start=millis();
     long timer=start;
     boolean ret=false;
     while(!ret){
       if ((timer+300) < millis()) {
         ret=dmd.stepMarquee(-1,0);
         timer=millis();
       }
     }
  }
      
}
void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (BTSerial.available() > 0 && newData == false) {
        rc = BTSerial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; 
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void parseData() {      
    char * strtokIndx; 
    strtokIndx = strtok(tempChars,",");     
    strcpy(set_code, strtokIndx); 
    strtokIndx = strtok(NULL, ","); 
    data1 = atoi(strtokIndx);     
    strtokIndx = strtok(NULL, ",");
    data2 = atoi(strtokIndx);     
    strtokIndx = strtok(NULL, ",");
    data3 = atoi(strtokIndx);
}

void setParsedData() {
  DateTime now = rtc.now();
  String code= set_code;
    if (code == "date"){
      if((data1<2020)||(data2>12)||(data3>31)){
          BTSerial.println("Settings not accepted");
          BTSerial.println("Commad format= <date,YY,M,D>");
        }
      else{
        BTSerial.println("Settings accepted");
        BTSerial.print("Date= "); 
        BTSerial.print(data1); BTSerial.print("/"); 
        BTSerial.print(data2);BTSerial.print("/");
        BTSerial.println(data3);
        rtc.adjust(DateTime(data1, data2, data3, now.hour(), now.minute(), now.second()));
        BTSerial.print("Please wait.");
          int count=0;
          while(count != 10){
            BTSerial.print(".");
            count++;
            delay(500);     
          } 
        BTSerial.println();
        print_rtc_now();        
        }
    }
    else if (code == "time"){
      if((data1>24)||(data2>60)||(data3>60)){
          BTSerial.println("Settings not accepted");
          BTSerial.println("Commad format= <time,hh,mm,ss>");
        }
      else{
        BTSerial.println("Settings accepted");
        BTSerial.print("Time= "); 
        BTSerial.print(data1); BTSerial.print(":"); 
        BTSerial.print(data2); BTSerial.print(":");
        BTSerial.println(data3);
        rtc.adjust(DateTime(now.year(), now.month(), now.day(),data1, data2, data3));
        BTSerial.print("Please wait.");
          int count=0;
          while(count != 10){
            BTSerial.print(".");
            count++;
            delay(500);     
          } 
        BTSerial.println();
        print_rtc_now();        
        }        
    }
    else if(code == "check"){
        print_rtc_now();
      }
    else {
      BTSerial.print(code);BTSerial.print(data1);BTSerial.print(data2);BTSerial.print(data3);
      BTSerial.println("Wrong command!");
      intro_msg();
    }
}


void print_rtc_now(){
  DateTime now = rtc.now();
  //indonesian format D/M/YY
  String tanggal = String(now.day(),DEC); tanggal += "/";
  tanggal += String (now.month(), DEC); tanggal += "/";
  tanggal += String (now.year(), DEC);

  String jam = String(now.hour(), DEC);
  jam += ":"; jam += String(now.minute(), DEC);
  jam += ":"; jam += String(now.second(), DEC);
  
  BTSerial.print(HariDalamMinggu[now.dayOfTheWeek()]);
  BTSerial.print(", ");
  BTSerial.print(tanggal);
  BTSerial.print("  ");
  BTSerial.print(jam);
  BTSerial.println();
}
void intro_msg(){
  BTSerial.println("Check RTC now= <check>");
  BTSerial.println("Date Config. command= <date,YY,M,D>");
  BTSerial.println("Time Config. command= <time,hh,mm,ss>");
  BTSerial.println("*with no leading zeros");
  BTSerial.println();
  
  dmd.clearScreen( true );
  dmd.selectFont(Droid_Sans_12);
  dmd.drawMarquee("ARDUCODING.COM",14,(32*DISPLAYS_ACROSS)-1,3);
  long start=millis();
  long timer=start;
  boolean ret=false;
  while(!ret){
     if ((timer+200) < millis()) {
       ret=dmd.stepMarquee(-1,0);
       timer=millis();
     }
  }
}
Karena displaynya terbatas (cuma 1) maka tidak bisa menampilkan jam dan tanggal secara bersamaan. Jadinya untuk jam ditampilkan secara fix dan untuk tanggal secara scrolling. Fungsi untuk mengatur tampilan jam dan tanggal pada P10 ada di fungsi display_data(mode tampilan).  pilih mode tampilan 1 untuk menampilkan jam, dan 2 untuk menampilkan tanggal. Sementara untuk pengaturan switch antara tampilan jam dan tanggal ada di bagian ini:
count_switch++;
   //30 = 60s delay 
   if (count_switch < 30){
      display_data(1);
   }
   if((count_switch > 30)&&(count_switch < 32)){
      display_data(2);
   }
   if (count_switch > 32){
      count_switch=0;
   }
Untuk perintahnya/pengaturan via bluetooth terdapat 3 perintah yaitu setting tanggal, setting jam, dan cek waktu (hari, tanggal, jam). Format perintahnya adalah
  • Setting tanggal gunakan perintah <date,nilai_tahun,nilai_bulan,nilai_tanggal> . Contohnya: <date,2020,8,4> untuk pengaturan 4 agustus 2020
  • Setting jam gunakan perintah <time,nilai_jam,nilai_menit,nilai_detik>. Contohnya: <time,13,20,56> untuk pukul 13:20:56
  • Untuk mengecek waktu gunakan perintah <check>.   
C. Hasil
Nah untuk hasilnya dapat dilihat pada gambar dan video berikut. Untuk aplikasi androidnya, kamu bisa menggunakan aplikasi sejenis bluetooth terminal (saya menggunakan serial bluetooth terminal)
Arduino HC05 dot matrix P10
Arduino dot matrix P10 bluetooth control

Pencarian Terkait:
  1. Jam Masjid Dot Matrix sederhana
  2. Jam Masjid Arduino dengan bluetooth
  3. Simple Arduino bluetooth control text DMD P10
  4. Arduino wall clock dot matrix p10 with HC-05 bluetooth