Rabu , 23 Agustus 2017

Cara Membuat Jam Digital Menggunakan RTC DS3231 dan LCD ST7735

ZONADUINO- Halo Sobat, di Pagi yang cerah ini Admin kembali menyapa kalian tentunya dengan Project-Project Arduino masa kini. Kali ini kita akan Membahas Tentang “Cara Membuat Jam Digital Menggunakan RTC DS3231 dan LCD ST7735”

Project Jam ini menampilkan 2 Waktu yaitu waktu setempat dan UTC waktu / GMT.

Ini memiliki 3 tombol yaitu untuk mengatur MENU, merubah jam, menit, hari dalam seminggu, tahun, bulan, hari, dan perbedaan antara waktu setempat dan waktu UTC (waktu GMT). Baiklah mari kita simak Penjelasan Berikut :

Alat dan Bahan :

  1. Arduino UNO & Genuino UNO × 1
  2. Real Time Clock (RTC) × 1
  3. Saklar Switch Button (6mm)× 3
  4. Kabel Jumper × 1
  5. Breadboard/Project Board (generic) × 1
  6. Resistor 1k ohm × 5
  7. Resistor 2.21k ohm × 1
  8. Adafruit ST7735 1.8″display × 1

Skema :

Code :

/*
   
A few colour codes:
 
code  color
0x0000  Black
0xFFFF  White
0xBDF7  Light Gray
0x7BEF  Dark Gray
0xF800  Red
0xFFE0  Yellow
0xFBE0  Orange
0x79E0  Brown
0x7E0 Green
0x7FF Cyan
0x1F  Blue
0xF81F  Pink
 */

#include <TFT_ST7735.h> // Graphics and font library for ST7735 driver chip
#include <SPI.h>
#include "EEPROM.h"

TFT_ST7735 tft = TFT_ST7735();  // Invoke library, pins defined in User_Setup.h
// see User_Setup.h: RST --> D7, CS --> D9, D/C --> D8, DIN --> D11, CLK --> D13


uint32_t targetTime = 0;       // for next 1 second timeout

byte omm = 99;
boolean initial = 1;
byte xcolon = 0;
byte xcolon2 = 0;
unsigned int colour = 0;

static uint8_t conv2d(const char* p) {
  uint8_t v = 0;
  if ('0' <= *p && *p <= '9')
    v = *p - '0';
  return 10 * v + *++p - '0';
}

#include <Wire.h>
// char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};  // english version
char daysOfTheWeek[7][12] = {"Duminica", "Luni", "Marti", "Miercuri", "Joi", "Vineri", "Sambata"};  // romanian version
byte hh, mm, ss;
byte yy, ll, dd, zz;

#define DS3231_I2C_ADDRESS 104
byte tMSB, tLSB;
float temp3231;
float temperatura, temperatura0;


#define meniu 2 
#define minus 3
#define plus 4
int nivel = 0;   // if is 0 - clock
                 // if is 1 - hour adjust
                 // if is 2 - minute adjust
                 // if is 3 - day of week adjust
                 // etc
byte jos = 10;
//byte hh1, mm1, zz1, dd1, ll1, yy1;   
int hh1, mm1, zz1, dd1, ll1, yy1;   
byte maxday;

int hh2;
int hh3;
byte hh4;
byte semn;

void setup(void) {
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(ST7735_BLACK);

  tft.setTextColor(ST7735_YELLOW, ST7735_BLACK); // Note: the new fonts do not draw the background colour

pinMode(meniu, INPUT); 
pinMode(plus, INPUT); 
pinMode(minus, INPUT); 
digitalWrite(meniu, HIGH);  // put inputs in high state (when push is to ground -> low state)
digitalWrite(plus, HIGH);
digitalWrite(minus, HIGH);

 Serial.begin(9600);
 Wire.begin();
// setDS3231time(30, 42, 21, 4, 26, 11, 1);
  targetTime = millis() + 1000; 

hh4 = EEPROM.read(100);
semn = EEPROM.read(101);

if ((hh4 < 0) || (hh4 > 12)) hh4 = 2;
if ((semn < 0) || (semn > 1)) semn = 1;   // if 1 -> +, 0 -> -

if (semn == 1) hh3 = hh4;
if (semn == 0) hh3 = -hh4;

hh2 = hh - hh3;  
}

void loop() {

if (nivel == 0)
{
if (digitalRead(meniu) == LOW)
  {
  nivel = nivel+1;
  delay(500);
  hh1=hh;
//  tft.fillScreen(ST7735_BLACK);
 sterg();
  }
tft.setTextSize(1);
  if (targetTime < millis()) {
    targetTime = millis()+1000;

// readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,&year);
 readDS3231time(&ss, &mm, &hh, &zz, &dd, &ll,&yy);
hh2 = hh - hh3;
if (hh2 > 23) hh2 = hh2-24;
if (hh2 < 0) hh2 = 24+hh2;

//temperatura = get3231Temp();

    tft.setTextSize(1);
    if (ss==0 || initial) {

   for (int y=52+jos; y < 60+jos; y+=1) 
   {
   tft.drawFastHLine(0, y, tft.width(), ST7735_BLACK);
   }
      
      initial = 0;
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.setCursor (15, 52+jos);
      tft.print(daysOfTheWeek[zz]);
      tft.setCursor (90, 52+jos);

      if (dd <10) tft.print("0");
      tft.print(dd);
      tft.print(".");
      if (ll <10) tft.print("0");
      tft.print(ll);
      tft.print(".");
      tft.print(yy+2000);
/*
if (temperatura0 != temperatura) 
    {
  if (digitalRead(meniu) == LOW) 
  {
  nivel = nivel+1;
  delay(500);
  hh1=hh;
  tft.fillScreen(ST7735_BLACK);    
    }
   for (int y=85; y < tft.height(); y+=1) {
   tft.drawFastHLine(0, y, tft.width(), ST7735_BLACK);
   }
int temperatura1 = temperatura;
float temperatura2 = 100*(temperatura - temperatura1);
   tft.setTextSize(3);
   tft.setTextColor(TFT_YELLOW);
   tft.setCursor (30, 85+jos);
   if (temperatura <10) tft.print(" ");
 //  tft.print(temperatura);
   tft.print(temperatura1);
   tft.print(".");
   tft.setCursor (85, 90+jos);
   tft.setTextSize(2); 
   if (temperatura2 == 0) tft.print("00");  
   else tft.print(temperatura2,0);
   tft.setCursor (124, 85+jos);
   tft.setTextSize(3);      
   tft.print("C");
   tft.setTextSize(2);       
   tft.setCursor (110, 84+jos);
   tft.print("O");
   tft.setTextSize(1);      
   temperatura0 = temperatura;
    }
*/
     }

    // Update digital time
    byte xpos = 16;
    byte ypos = 0+jos;
    byte xpos2 = 16;
    byte ypos2 = 65+jos;

      tft.setTextColor(ST7735_BLUE, ST7735_BLACK);
      tft.setCursor (0, 0);
      tft.print("GMT");
/*
      tft.setCursor (0, ypos+2);
      tft.print("G");
      tft.setCursor (0, ypos+10);
      tft.print("M");
      tft.setCursor (0, ypos+18);
      tft.print("T");
      tft.setCursor (0, ypos+34);
*/
      if (hh3 == 0) tft.print("=");
      if (hh3 > 0) tft.print("+");
      tft.print(hh3);
  

      tft.setCursor (0, ypos2+2);
      tft.print("G");
      tft.setCursor (0, ypos2+10);
      tft.print("M");
      tft.setCursor (0, ypos2+18);
      tft.print("T");


    
    if (omm != mm) { // Only redraw every minute to minimise flicker
    if (digitalRead(meniu) == LOW) {
    nivel = nivel+1;
    tft.fillScreen(ST7735_BLACK);
    delay(500);
    tft.fillScreen(ST7735_BLACK);
    }
      // Uncomment ONE of the next 2 lines, using the ghost image demonstrates text overlay as time is drawn over it
      //tft.setTextColor(ST7735_RED, ST7735_BLACK);  // Leave a 7 segment ghost image, comment out next line!
      tft.setTextColor(ST7735_BLACK, ST7735_BLACK); // Set font colour to back to wipe image
      // Font 7 is to show a pseudo 7 segment display.
      // Font 7 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : .
      tft.drawString("88:88",xpos,ypos,7); // Overwrite the text to clear it
      tft.drawString("88:88",xpos2,ypos2,7); // Overwrite the text to clear it
      tft.setTextColor(ST7735_RED, ST7735_BLACK); // Red
      omm = mm;

      if (hh<10) xpos+= tft.drawChar('0',xpos,ypos,7);
      xpos+= tft.drawNumber(hh,xpos,ypos,7);
      xcolon=xpos;
      xpos+= tft.drawChar(':',xpos,ypos,7);
      if (mm<10) xpos+= tft.drawChar('0',xpos,ypos,7);
      tft.drawNumber(mm,xpos,ypos,7);

// second clock
      tft.setTextColor(ST7735_YELLOW, ST7735_BLACK); // Red
      if (hh2<10) xpos2+= tft.drawChar('0',xpos2,ypos2,7);
      xpos2+= tft.drawNumber(hh2,xpos2,ypos2,7);
      xcolon2=xpos2;
      xpos2+= tft.drawChar(':',xpos2,ypos2,7);
      if (mm<10) xpos2+= tft.drawChar('0',xpos2,ypos2,7);
      tft.drawNumber(mm,xpos2,ypos2,7);   
    }

//animated points for clocks
    if (ss%2) { // Flash the colon
      tft.setTextColor(0x39C4, ST7735_BLACK);
      xpos2+= tft.drawChar(':',xcolon2,ypos2,7);
      //tft.setTextColor(0x39C4, ST7735_BLACK);
      xpos+= tft.drawChar(':',xcolon,ypos,7);

     // tft.setTextColor(ST7735_YELLOW, ST7735_BLACK);
    }
    else {
      tft.setTextColor(ST7735_YELLOW, ST7735_BLACK);
      tft.drawChar(':',xcolon2,ypos2,7);
      tft.setTextColor(ST7735_RED, ST7735_BLACK);
      tft.drawChar(':',xcolon,ypos,7);
      
       }
    
  }
}  // end loop for nivel = 0 (just clock)

if (nivel == 1)   // change hours
{
   
if (digitalRead(meniu) == LOW)
  {
  nivel = nivel+1;
  delay(500);
  mm1 = mm;
 sterg();
  }    

   // Update digital time
    byte xpos = 6;
    byte ypos = 0+jos;
   
      tft.setTextColor(ST7735_BLACK, ST7735_BLACK); // Set font colour to back to wipe image
 //     tft.drawString("88:88",xpos,ypos,7); // Overwrite the text to clear it
      tft.drawString("88",xpos,ypos,7); // Overwrite the text to clear it
      tft.setTextColor(ST7735_RED, ST7735_BLACK); // Red
 delay(50);
      
      if (hh1<10) xpos+= tft.drawChar('0',xpos,ypos,7);
      xpos+= tft.drawNumber(hh1,xpos,ypos,7);

       tft.setTextColor(ST7735_RED, ST7735_BLACK); // Red
       
      xcolon=xpos;
      xpos+= tft.drawChar(':',xpos,ypos,7);
      if (mm<10) xpos+= tft.drawChar('0',xpos,ypos,7);
      tft.drawNumber(mm,xpos,ypos,7);
delay(50);
     
if (digitalRead(plus) == LOW)
    {
    hh1 = hh1+1;
    delay(150);
    }
if (digitalRead(minus) == LOW)
    {
    hh1 = hh1-1;
    delay(150);
    }    
if (hh1 > 23) hh1 = 0;
if (hh1 < 0) hh1 = 23;       
     
}  // end loop stare = 1 (change the hours)

if (nivel == 2)   // change minutes
{
if (digitalRead(meniu) == LOW)
  {
  delay(500);
  zz1 = zz;  // next step
  sterg();
  nivel = nivel+1;
  }    

   // Update digital time
    byte xpos = 6;
    byte ypos = 0+jos;

  //     tft.drawString("88:88",xpos,ypos,7); // Overwrite the text to clear it

      tft.setTextColor(ST7735_RED, ST7735_BLACK); // Red
      if (hh1<10) xpos+= tft.drawChar('0',xpos,ypos,7);
      xpos+= tft.drawNumber(hh1,xpos,ypos,7);
      xcolon=xpos;
      xpos+= tft.drawChar(':',xpos,ypos,7);
      
     tft.setTextColor(ST7735_BLACK, ST7735_BLACK); // Set font colour to back to wipe image
     tft.drawString("88",xpos,ypos,7); // Overwrite the text to clear it
 delay(50);
       tft.setTextColor(ST7735_RED, ST7735_BLACK); // Red
         
      if (mm1<10) xpos+= tft.drawChar('0',xpos,ypos,7);
      tft.drawNumber(mm1,xpos,ypos,7);
delay(50);
     
if (digitalRead(plus) == LOW)
    {
    mm1 = mm1+1;
    delay(150);
    }
if (digitalRead(minus) == LOW)
    {
    mm1 = mm1-1;
    delay(150);
    }    
if (mm1 > 59) mm1 = 0;
if (mm1 < 0) mm1 = 59;       
     
}  // end loop nivel = 2 (change the minutes)

if (nivel == 3)   // change day in week
{
if (digitalRead(meniu) == LOW)
  {
  nivel = nivel+1;
  delay(500);
  yy1 = yy;;  // next step
 sterg();
  }    

  for (int y=52+jos; y < 60+jos; y+=1) 
   {
   tft.drawFastHLine(0, y, tft.width(), ST7735_BLACK);
   }
   delay(50);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.setCursor (15, 52+jos);
      tft.print(daysOfTheWeek[zz1]);
    delay(50);   
     
if (digitalRead(plus) == LOW)
    {
    zz1 = zz1+1;
    delay(150);
    }
if (digitalRead(minus) == LOW)
    {
    zz1 = zz1-1;
//    if (zz1 < 0) zz1 = 6;       
    delay(150);
    }    
if (zz1 > 6) zz1 = 0;
if (zz1 < 0) zz1 = 6;       
Serial.println(zz1);
     
}  // end loop stare = 3 (change the day of the week)


if (nivel == 4)   // change year
{
if (digitalRead(meniu) == LOW)
  {
  delay(500);
  ll1 = ll;;  // next step
  sterg();
  nivel = nivel+1;
  }    

  for (int y=52+jos; y < 60+jos; y+=1) 
   {
     tft.drawFastHLine(125, y, 35, ST7735_BLACK);
   }
   delay(50);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.setCursor (90, 52+jos);
/*      
      if (ll <10) tft.print("0");
      tft.print(ll);
      tft.print("/");
      if (dd <10) tft.print("0");
      tft.print(dd);
      tft.print("/");
*/
      if (dd <10) tft.print("0");
      tft.print(dd);
      tft.print(".");
      if (ll <10) tft.print("0");
      tft.print(ll);
      tft.print(".");
      tft.print(yy1+2000);
    delay(50);   
     
if (digitalRead(plus) == LOW)
    {
    yy1 = yy1+1;
    delay(150);
    }
if (digitalRead(minus) == LOW)
    {
    yy1 = yy1-1;
    delay(150);
    }    
if (yy1 > 49) yy1 = 49;
if (yy1 < 16) yy1 = 16;       
     
}  // end loop stare = 4 (change the year)



if (nivel == 5)   // change mounth
{
if (digitalRead(meniu) == LOW)
  {
  delay(500);
  dd1 = dd;;  // next step
  sterg();
  nivel = nivel+1;
  }    

  for (int y=52+jos; y < 60+jos; y+=1) 
   {
//   tft.drawFastHLine(90, y, 14, ST7735_BLACK);
tft.drawFastHLine(106, y, 14, ST7735_BLACK);
   }
   delay(50);
 
      tft.setCursor (90, 52+jos);
      if (dd <10) tft.print("0");
      tft.print(dd);
      tft.print(".");
      if (ll1 <10) tft.print("0");
      tft.print(ll1);
      tft.print(".");
      tft.print(yy1+2000);    
    delay(50);   
     
if (digitalRead(plus) == LOW)
    {
    ll1 = ll1+1;
    delay(150);
    }
if (digitalRead(minus) == LOW)
    {
    ll1 = ll1-1;
    delay(150);
    }    
   
if (ll1 > 12) ll1 = 1;
if (ll1 < 1) ll1 = 12;       
     
}  // end loop stare = 5 (change the day as data)



if (nivel == 6)   // change day as data
{
if (digitalRead(meniu) == LOW)
  {
   delay(500);
   sterg();
   nivel = nivel+1;
  }    

  for (int y=52+jos; y < 60+jos; y+=1) 
   {
tft.drawFastHLine(90, y, 14, ST7735_BLACK);    
//   tft.drawFastHLine(106, y, 14, ST7735_BLACK);
   }
   delay(50);
 
      tft.setCursor (90, 52+jos);
  /*
      if (ll1 <10) tft.print("0");
      tft.print(ll1);
      tft.print("/");
      if (dd1 <10) tft.print("0");
      tft.print(dd1);
      tft.print("/");
  */
    if (dd1 <10) tft.print("0");
      tft.print(dd1);
      tft.print(".");
      if (ll1 <10) tft.print("0");
      tft.print(ll1);
      tft.print(".");    
      tft.print(yy1+2000);
      delay(50);   
     
if (digitalRead(plus) == LOW)
    {
    dd1 = dd1+1;
    delay(150);
    }
if (digitalRead(minus) == LOW)
    {
    dd1 = dd1-1;
    delay(150);
    }    
    
 if (ll == 4 || ll == 5 || ll == 9 || ll == 11) { //30 days hath September, April June and November
    maxday = 30;
  }
  else {
  maxday = 31; //... all the others have 31
  }
  if (ll ==2 && yy % 4 ==0) { //... Except February alone, and that has 28 days clear, and 29 in a leap year.
    maxday = 29;
  }
  if (ll ==2 && ll % 4 !=0) {
    maxday = 28;
  }

if (dd1 > maxday) dd1 = 1;
if (dd1 < 1) dd1 = maxday;       
     
}  // end loop nivel = 6 (change the day as data)


if (nivel == 7)   // change hours
{
   
if (digitalRead(meniu) == LOW)
  {
  delay(500);
  sterg();
  nivel = nivel+1;
  }    

      tft.setCursor (90, 42+jos);
      tft.print("GMT");
      
  for (int y=52+jos; y < 60+jos; y+=1) 
   {
tft.drawFastHLine(90, y, 69, ST7735_BLACK);
   }
   delay(50);
 
      tft.setCursor (90, 52+jos);
      if (hh3 > 0) tft.print("+");
      tft.print(hh3);
      delay(50);   

     
if (digitalRead(plus) == LOW)
    {
    hh3 = hh3+1;
    delay(150);
    }
if (digitalRead(minus) == LOW)
    {
    hh3 = hh3-1;
    delay(150);
    }    
if (hh3 > 12) hh3 = 12;
if (hh3 < -12) hh3 = -12;       
     
}  // end loop stare = 7 (change the hours)



 if (nivel == 8)  // adjust the clock
 {
sterg();

// setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year);
setDS3231time(0, mm1, hh1, zz1, dd1, ll1, yy1);

if (hh3 > 0)
{
  hh4 = hh3;
  semn = 1;
}
if (hh3 <0)
{
  hh4 = -hh3;
  semn = 0;
}
if (hh3 == 0)
{
  hh4 = 0;
  semn = 1;
}

  EEPROM.write(100, hh4);
  EEPROM.write(101, semn);
  

 nivel = 9;
 } // end loop nivel = 8

 
 if (nivel >=9)  // readfy to return to main loop
 {nivel = 0;  
 omm = 99;
 temperatura0 = 0.0;
 initial = 1;
 }
}  // end main loop

void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
                   dayOfMonth, byte month, byte year)
{
    // sets time and date data to DS3231
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set next input to start at the seconds register
    Wire.write(decToBcd(second)); // set seconds
    Wire.write(decToBcd(minute)); // set minutes
    Wire.write(decToBcd(hour)); // set hours
    Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
    Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
    Wire.write(decToBcd(month)); // set month
    Wire.write(decToBcd(year)); // set year (0 to 99)
    Wire.endTransmission();
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
    return ( (val / 16 * 10) + (val % 16) );
}

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
    return ( (val / 10 * 16) + (val % 10) );
}

void readDS3231time(byte *second,
                    byte *minute,
                    byte *hour,
                    byte *dayOfWeek,
                    byte *dayOfMonth,
                    byte *month,
                    byte *year)
{
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set DS3231 register pointer to 00h
    Wire.endTransmission();
    Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
    // request seven bytes of data from DS3231 starting from register 00h
    *second = bcdToDec(Wire.read() & 0x7f);
    *minute = bcdToDec(Wire.read());
    *hour = bcdToDec(Wire.read() & 0x3f);
    *dayOfWeek = bcdToDec(Wire.read());
    *dayOfMonth = bcdToDec(Wire.read());
    *month = bcdToDec(Wire.read());
    *year = bcdToDec(Wire.read());
}

void sterg()
   {for (int y=0; y < 127; y+=1) 
   {
   tft.drawFastHLine(0, y, tft.width(), ST7735_BLACK);
   }
   }

About syafrie

Seorang pemungut ilmu yang tak mau ketinggalan dengan dunia IT yang kemudian ditulis ulang dalam bentuk tulisan-tulisan ngawur yang ga jelas.

Tinggalkan Balasan

Alamat surel Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *