#include <SPI.h> //SPI.
h must be included as DMD is written by SPI (the IDE complains
otherwise)
#include <DMD.h> //Library DMD yang menyediakan fungsi penampilan teks, gambar dsb
#include <TimerOne.h> //Library peripheral Timer1 untuk menjalankan prosedur pindai panel DMD
#include <Time.h> //Library waktu yang menyediakan tipe data, struktur, dan obyek waktu
#include <DS1307RTC.h> // Library RTC
// Font yang digunakan
#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#include "Arial_black_16.h"
#include "Arial_Black_16_ISO_8859_1.h"
#include "Arial14.h"
#include "DejaVuSans9.h"
#include "DejaVuSansBold9.h"
#include "DejaVuSansItalic9.h"
#include "Droid_Sans_12.h"
#include "Droid_Sans_16.h"
#include "Mono5x7.h"
#include "SystemFont5x7.h"
#define WAKTU_TAMPIL_JAM 10 //detik
#define WAKTU_TAMPIL_KALENDAR 5 //detik
#define DISPLAY_COLUMN_COUNT 2
#define DISPLAY_ROW_COUNT 1
#define PIXELS_PER_COLUMN 32
#define PIXELS_PER_ROW 16
int cacah;
DMD dmd(DISPLAY_COLUMN_COUNT, DISPLAY_ROW_COUNT);
unsigned char show = 0;
const char namaHari[7][7] PROGMEM = { "MINGGU", "SENIN", "SELASA",
"RABU", "KAMIS", "JUMAT", "SABTU"
};
const char namaBulan[12][10] PROGMEM = { "01", "02", "03",
"04", "05", "06", "07",
"08", "09", "10",
"11", "12"
};
void AturWaktuRTC();
void (*restart)(void) = 0x00;
void print2digits(int number);
unsigned char DetikTerakhir, MenitTerakhir, JamTerakhir,
HariTerakhir, TanggalTerakhir, BulanTerakhir;
unsigned int TahunTerakhir;
tmElements_t wkt;
unsigned char SecCount = 0;
bool Mode = false; // false = tampilan Jam, true = tampilan hari,tanggal,bulan,tahun
//Fire up the DMD library as dmd
//DMD dmd(2, 1);
/*--------------------------------------------------------------------------------------
Interrupt handler for Timer1 (TimerOne) driven DMD refresh scanning, this gets
called at the period set in Timer1.initialize();
-------------------------------------------------------------------------------------- */
void ScanDMD()
{
dmd.scanDisplayBySPI();
}
/*--------------------------------------------------------------------------------------
Show clock numerals on the screen from a 4 digit time value, and select whether the
flashing colon is on or off
--------------------------------------------------------------------------------------*/
void DisplayHour(unsigned char Hour)
{
dmd.drawChar( 34, 2, ' ', GRAPHICS_NORMAL );
dmd.drawChar( 34, 2, '0' + (Hour / 10), GRAPHICS_NORMAL );
dmd.drawChar( 40, 2, ' ', GRAPHICS_NORMAL );
dmd.drawChar( 40, 2, '0' + (Hour % 10), GRAPHICS_NORMAL );
}
void DisplayMinute(unsigned char Minute)
{
dmd.drawChar( 49, 2, ' ', GRAPHICS_NORMAL );
dmd.drawChar( 49, 2, '0' + (Minute / 10), GRAPHICS_NORMAL );
dmd.drawChar( 55, 2, ' ', GRAPHICS_NORMAL );
dmd.drawChar( 55, 2, '0' + (Minute % 10), GRAPHICS_NORMAL );
}
void DisplayDate(unsigned char DayOfWeek,
unsigned char Day,
unsigned char Month,
unsigned int Year)
{
char DayName[7];
char MonthName[10];
memset(DayName, 0, 7);
memset(MonthName, 0, 10);
strcpy_P(DayName, namaHari[DayOfWeek - 1]);
strcpy_P(MonthName, namaBulan[Month - 1]);
char lineBuff[20];
//dmd.drawString(32, 3, lineBuff, strlen(lineBuff), GRAPHICS_NORMAL);
//dmd.drawString(0, 3, DayName, strlen(DayName), GRAPHICS_NORMAL);
sprintf(lineBuff, "%s %02d/%s/%d", DayName, Day, MonthName, Year - 2000);
ShowMarquee(lineBuff,false);
}
void ShowDateTime(unsigned char Day,
unsigned char Date,
unsigned char Month,
unsigned int Year,
unsigned char Hour,
unsigned char Minute,
bool bColonOn)
{
dmd.clearScreen(true);
// units
/*--------------------------------------------------------------------------------------
setup
Called by the Arduino architecture before the main loop begins
-------------------------------------------------------------------------------------- */
void setup(void)
{
bool aturRTC = false;
// Inisialisai komunikasi serial dengan PC
Serial.begin(9600);
delay(1000);
if ((!(RTC.read(wkt))) || (aturRTC)) { // Jika fresh run
AturWaktuRTC();
}
else {
Serial.println("Ketik 'ATUR' Untuk mengatur ulang waktu RTC");
}
// inisialisasi awal nilai waktu
DetikTerakhir = 99;
MenitTerakhir = 99;
JamTerakhir = 99;
HariTerakhir = 99;
TanggalTerakhir = 99;
BulanTerakhir = 99;
TahunTerakhir = 99999;
//initialize TimerOne's interrupt/CPU usage used to scan and refresh the display
Timer1.initialize( 1000 ); //period in microseconds to call ScanDMD. Anything longer than 5000
(5ms) and you can see flicker.
Timer1.attachInterrupt( ScanDMD ); //attach the Timer1 interrupt to ScanDMD which goes to
dmd.scanDisplayBySPI()
//clear/init the DMD pixels held in RAM
dmd.clearScreen( true ); //true is normal (all pixels off), false is negative (all pixels on)
//delay(1500);
}
/*--------------------------------------------------------------------------------------
loop
Arduino architecture main loop
--------------------------------------------------------------------------------------*/
void loop(void)
{
int i;
unsigned char DetikSekarang, MenitSekarang, JamSekarang,
HariSekarang, TanggalSekarang, BulanSekarang;
unsigned int TahunSekarang;
// Lihat apakah input serial dari pengguna
// lebih besar atau sama dg 4 byte
if (Serial.available() >= 4) {
char buff[5];
Serial.readBytes(buff, 4);
// Jika input serial dari pengguna adalah ATUR, maka lakukan prosedur
// pengaturan waktru RTC
if ((buff[0] == 'A') && (buff[1] == 'T') && (buff[2] == 'U') && (buff[3] == 'R')) {
AturWaktuRTC();
}
}
if (!RTC.read(wkt)) {
Serial.println("RTC error!");
delay(500);
restart();
}
DetikSekarang = wkt.Second;
MenitSekarang = wkt.Minute;
JamSekarang = wkt.Hour;
dmd.selectFont(DejaVuSansBold9);
DisplayMinute(MenitSekarang);
dmd.selectFont(DejaVuSansBold9);
DisplayHour(JamSekarang);
if ( DetikSekarang % 2 == 0 )
dmd.drawChar( 46, 2, ':', GRAPHICS_OR); // clock colon overlay on
else
dmd.drawChar( 46, 2, ':', GRAPHICS_NOR); // clock colon overlay off
HariSekarang = wkt.Wday;
TanggalSekarang = wkt.Day;
BulanSekarang = wkt.Month;
TahunSekarang = wkt.Year;
cacah++;
delay(200);
if(cacah > 150){
dmd.selectFont(DejaVuSans9);
dmd.selectFont(Mono5x7);
DisplayDate(HariSekarang, TanggalSekarang,
BulanSekarang, tmYearToCalendar(TahunSekarang));
cacah = 0;
}
void AturWaktuRTC()
{
int input;
char buff[10];
tmElements_t wkt;
Serial.println(F("-------------------------\nAtur ulang waktu RTC"));
// Minta pengguna memasukan hari
Serial.println(F("\nMasukkan 2 digit kode hari\n01: Minggu\n02: Senin\n03: " \
"Selasa\n04: Rabu\n05: Kamis\n06: Jumat\n07: Sabtu\n>>>"));
while (Serial.available() < 2);
Serial.readBytes(buff, 2);
sscanf(buff, "%02d", &input);
if ((input >= 1) && (input <= 7)) {
wkt.Wday = input;
Serial.print("Sekarang hari: ");
strcpy_P(buff, (const char*)namaHari[wkt.Wday - 1]);
Serial.println(buff);
}
else {
Serial.print("Input salah! Restarting...");
restart();
}
// Minta pengguna memasukan tanggal
Serial.println(F("\nMasukkan 2 digit tanggal (01-31)\n>>>"));
while (Serial.available() < 2);
Serial.readBytes(buff, 2);
sscanf(buff, "%02d", &input);
if ((input >= 1) && (input <= 31)) {
wkt.Day = input;
Serial.print("Sekarang tanggal: ");
Serial.println(wkt.Day, DEC);
}
else {
Serial.print("Input salah! Restarting...");
restart();
}
// Minta pengguna memasukan bulan
Serial.println(F("\nMasukkan 2 digit kode bulan\n01: Jan\n02: Feb\n03: " \
"Mar\n04: Apr\n05: Mei\n06: Jun\n07: Jul\n08: Ags\n09: Sep\n10: Okt\n"
"11: Nov\n12: Des\n>>>"));
while (Serial.available() < 2);
Serial.readBytes(buff, 2);
sscanf(buff, "%02d", &input);
if ((input >= 1) && (input <= 12)) {
wkt.Month = input;
Serial.print("Sekarang bulan: ");
strcpy_P(buff, (const char*)namaBulan[wkt.Month - 1]);
Serial.println(buff);
}
else {
Serial.print("Input salah! Restarting...");
restart();
}
// Minta pengguna memasukan tahun
Serial.println(F("\nMasukkan 4 digit tahun (2000-2100)\n>>>"));
while (Serial.available() < 4);
Serial.readBytes(buff, 4);
sscanf(buff, "%4d", &input);
if (input >= 2000 && input <= 2100) {
wkt.Year = CalendarYrToTm(input);
Serial.print("Sekarang tahun: ");
Serial.println(tmYearToCalendar(wkt.Year), DEC);
}
else {
Serial.print(F("Input salah!, tahun akan diatur ke 2015 secara default"));
wkt.Year = CalendarYrToTm(2015);
}
// Minta pengguna memasukan jam
Serial.println(F("\nMasukkan 2 digit jam (00-23)\n>>>"));
while (Serial.available() < 2);
Serial.readBytes(buff, 2);
sscanf(buff, "%02d", &input);
wkt.Hour = input;
Serial.println(F("\nMasukkan 2 digit menit (00-59)\n>>>"));
while (Serial.available() < 2);
Serial.readBytes(buff, 2);
sscanf(buff, "%02d", &input);
wkt.Minute = input;
Serial.print(F("Sekarang pukul "));
sprintf(buff, "%02d:%02d", wkt.Hour, wkt.Minute);
Serial.println(buff);
Serial.print(F("\nMengkonfigurasi waktu RTC..."));
if (RTC.write(wkt)) {
Serial.println(F("OK"));
Serial.print(F("Membaca waktu RTC..."));
if (RTC.read(wkt)) {
Serial.println(F("OK"));
Serial.print("Pukul = ");
print2digits(wkt.Hour);
Serial.write(':');
print2digits(wkt.Minute);
Serial.write(':');
print2digits(wkt.Second);
Serial.print(", Date (D/M/Y) = ");
Serial.print(wkt.Day);
Serial.write('/');
Serial.print(wkt.Month);
Serial.write('/');
Serial.print(tmYearToCalendar(wkt.Year));
Serial.println();
}
else {
Serial.println(F("FAILED"));
}
}
else {
Serial.println(F("FAILED"));
}
Serial.println(F("-------------------------"));
}
void print2digits(int number) {
if (number >= 0 && number < 10) {
Serial.write('0');
}
Serial.print(number);
}
void ShowMarquee(char *Text, bool LeftToRight)
{
long start=millis();
long timer=start;
boolean ret=false;
if (LeftToRight) {
dmd.drawMarquee(Text,strlen(Text),
-(dmd.fontWidth()*(strlen(Text)-1)),3);
}
else
dmd.drawMarquee(Text,strlen(Text),
(PIXELS_PER_COLUMN*DISPLAY_COLUMN_COUNT)-1,3);
while(!ret){
if ((timer+100) < millis()) {
if (LeftToRight)
ret=dmd.stepMarquee(1,0); // Geser 1 karakter ke kiri
else
ret=dmd.stepMarquee(-1,0); // Geser 1 karakter ke kanan
timer=millis();
}
}
}