Siapkan bahan-bahan seperti berikut:
Attiny 2313 + downloader isp
Bagian power supply
- Trafo AC atau Adaptor yang dapat diatur tegangannya
- Jika menggunakan Trafo AC, maka ubah-ubah terminal sekunder trafo untuk V Segmen
- 7805 untuk menurunkan tegangan ke 5V
- Baterai backup 3v - 4.5 v
Dioda 1N4002 (4 + 1 )atau Dioda Bridge sebagai penyearah jika memakai Trafo AC
Capasitor 1000uF/25v , 100nF, 22pF (2buah) atau Varco 0-50pF
Resistor 10K (3 buah), 1K 2Buah
Led 4 buah sebagai pembatas digit
ULN 2003
OptoIsolator PC817 atau 4N25 atau yang sejenis (6 buah)
Xtal 4MHz atau sesuai keinginan
Push Buton tactile (2 buah)
7 segment common Anoda ukuran terserah (6 buah)
SKEMATIK
klik untuk memperjelas
Keterangan:
- Gunakan power supply berbeda (yang dapat diubah-ubah) untuk V SEGMEN sehingga dapat mengatur kecerahan dari 7 segmen
- Untuk mengkompensasi ketidak akuratan xtal, maka salah satu load cap dari xtal dibuat variabel
- Nilai Xtal yang digunakan disesuaikan dengan xtal yg tersedia dipasaran, jika berbeda maka silahkan baca pembahasan mengenai counter/timer disini.
- Baterai backup akan mencatu attiny jika listrik mati (tanpa display) sehingga time keeping tetap jalan.
SCRIPT
#define F_CPU 4000000UL //sesuaikan xtal yg dipakai
#include <avr/io.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <string.h>
uint8_t jam,menit,detik,bulan,tanggal,tahun,clock,menu,mode,blink;
uint8_t a = 0;
char bul_max[12]={31,28,31,30,31,30,31,31,30,31,30,31} ;
//tampilan 7 digit 7 segmen dan animasi
void segmen(uint8_t digit)
{
switch (digit)
{
case 0 :
{
PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB4)
& ~_BV(PB5) & ~_BV(PB6);
PORTB |= _BV(PB7);
break;
}
case 1 :
{
PORTB &= ~_BV(PB2) & ~_BV(PB3);
PORTB |= _BV(PB1)| _BV(PB4)| _BV(PB5)| _BV(PB6)| _BV(PB7);
break;
}
case 2 :
{
PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB7) & ~_BV(PB5) & ~_BV(PB4);
PORTB |= _BV(PB3)| _BV(PB6) ;
break;
}
case 3 :
{
PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB7);
PORTB |= _BV(PB5)| _BV(PB6) ;
break;
}
case 4 :
{
PORTB &= ~_BV(PB6) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB7) ;
PORTB |= _BV(PB4)| _BV(PB5) | _BV(PB1);
break;
}
case 5 :
{
PORTB &= ~_BV(PB1) & ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB7) & ~_BV(PB6);
PORTB |= _BV(PB2) | _BV(PB5);
break;
}
case 6 :
{
PORTB &= ~_BV(PB1) & ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB7) & ~_BV(PB6) & ~_BV(PB5);
PORTB |= _BV(PB2) ;
break;
}
case 7 :
{
PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3);
PORTB |= _BV(PB4)| _BV(PB5)| _BV(PB6)| _BV(PB7);
break;
}
case 8 :
{
PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB4)
& ~_BV(PB5) & ~_BV(PB6) & ~_BV(PB7);
break;
}
case 9 :
{
PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB4)
& ~_BV(PB6) & ~_BV(PB7);
PORTB |= _BV(PB5);
break;
}
case 10 :
{
PORTB |= _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB4)|
_BV(PB5) | _BV(PB6) | _BV(PB7) ;
break;
}
case 11 :
{
PORTB &= ~_BV(PB1);
PORTB |= _BV(PB2) | _BV(PB3) | _BV(PB4)|
_BV(PB5) | _BV(PB6) | _BV(PB7) ;
break;
}
case 12 :
{
PORTB &= ~_BV(PB4);
PORTB |= _BV(PB2) | _BV(PB3) | _BV(PB1)|
_BV(PB5) | _BV(PB6) | _BV(PB7) ;
break;
}
case 13 :
{
PORTB &= ~_BV(PB2);
PORTB |= _BV(PB4) | _BV(PB3) | _BV(PB1)|
_BV(PB5) | _BV(PB6) | _BV(PB7) ;
break;
}
case 14 :
{
PORTB &= ~_BV(PB3);
PORTB |= _BV(PB2) | _BV(PB4) | _BV(PB1)|
_BV(PB5) | _BV(PB6) | _BV(PB7) ;
break;
}
case 15 :
{
PORTB &= ~_BV(PB5);
PORTB |= _BV(PB2) | _BV(PB3) | _BV(PB1)|
_BV(PB4) | _BV(PB6) | _BV(PB7) ;
break;
}
case 16 :
{
PORTB &= ~_BV(PB6);
PORTB |= _BV(PB2) | _BV(PB3) | _BV(PB1)|
_BV(PB5) | _BV(PB4) | _BV(PB7) ;
break;
}
}
PORTB = _BV(PB0) | ~PORTB; //khusus memakai uln2003
}
//posisi scan digit
void posisi(uint8_t pos)
{
switch (pos)
{
case 0 :
{
PORTD &= ~_BV(PD0) & ~_BV(PD1) & ~_BV(PD4) & ~_BV(PD5) & ~_BV(PD6) ;
PORTB &= ~_BV(PB0);
break;
}
case 1 :
{
PORTD |= _BV(PD0);
PORTD &= ~_BV(PD1) & ~_BV(PD4) & ~_BV(PD5) & ~_BV(PD6) ;
PORTB &= ~_BV(PB0);
break;
}
case 2 :
{
PORTD |= _BV(PD1);
PORTD &= ~_BV(PD0) & ~_BV(PD6) & ~_BV(PD4) & ~_BV(PD5) ;
PORTB &= ~_BV(PB0);
break;
}
case 3 :
{
PORTD |= _BV(PD4);
PORTD &= ~_BV(PD1) & ~_BV(PD0) & ~_BV(PD5) & ~_BV(PD6) ;
PORTB &= ~_BV(PB0);
break;
}
case 4 :
{
PORTD |= _BV(PD5);
PORTD &= ~_BV(PD0) & ~_BV(PD1) & ~_BV(PD4) & ~_BV(PD6) ;
PORTB &= ~_BV(PB0);
break;
}
case 5 :
{
PORTD |= _BV(PD6);
PORTD &= ~_BV(PD0) & ~_BV(PD1) & ~_BV(PD4) & ~_BV(PD5) ;
PORTB &= ~_BV(PB0);
break;
}
case 6 :
{
PORTB |= _BV(PB0);
PORTD &= ~_BV(PD0) & ~_BV(PD1) & ~_BV(PD4) & ~_BV(PD5) & ~_BV(PD6) ;
break;
}
}
}
void animasi(void) //animasi pindah jam-kalender
{
posisi(1);
segmen(11);
_delay_ms(50);
posisi(2);
segmen(11);
_delay_ms(50);
posisi(3);
segmen(11);
_delay_ms(50);
posisi(4);
segmen(11);
_delay_ms(50);
posisi(5);
segmen(11);
_delay_ms(50);
posisi(6);
segmen(11);
_delay_ms(50);
segmen(13);
_delay_ms(50);
segmen(14);
_delay_ms(50);
posisi(5);
segmen(12);
_delay_ms(50);
posisi(4);
segmen(12);
_delay_ms(50);
posisi(3);
segmen(12);
_delay_ms(50);
posisi(2);
segmen(12);
_delay_ms(50);
posisi(1);
segmen(15);
_delay_ms(50);
segmen(16);
_delay_ms(50);
}
void tulis(void) //tulis ke 7 segmen
{
posisi(1);
if(menu == 1 && TCNT1 < 20000) segmen(10); //edit jam
else segmen((jam/10));
_delay_ms(1);
segmen(10);
posisi(2);
if(menu == 1 && TCNT1 < 20000) segmen(10); //edit jam
else segmen((jam%10));
_delay_ms(1);
segmen(10);
posisi(3);
if(menu == 2 && TCNT1 < 20000) segmen(10); //edit menit
else segmen((menit/10));
_delay_ms(1);
segmen(10);
posisi(4);
if(menu == 2 && TCNT1 < 20000) segmen(10); //edit menit
else segmen((menit%10));
_delay_ms(1);
segmen(10);
posisi(5);
if(menu == 3 && TCNT1 < 20000) segmen(10); //edit detik
else segmen((detik/10));
_delay_ms(1);
segmen(10);
posisi(6);
if(menu == 3 && TCNT1 < 20000) segmen(10); //edit detik
else segmen((detik%10));
_delay_ms(1);
segmen(10);
}
void tanggalan(void)
{
posisi(1);
if(menu == 4 && TCNT1 < 20000) segmen(10); //edit tgl
else segmen((tanggal/10));
_delay_ms(1);
segmen(10);
posisi(2);
if(menu == 4 && TCNT1 < 20000) segmen(10); //edit tgl
else segmen((tanggal%10));
_delay_ms(1);
segmen(10);
posisi(3);
if(menu == 5 && TCNT1 < 20000) segmen(10); //edit bulan
else segmen((bulan/10));
_delay_ms(1);
segmen(10);
posisi(4);
if(menu == 5 && TCNT1 < 20000) segmen(10); //edit bulan
else segmen((bulan%10));
_delay_ms(1);
segmen(10);
posisi(5);
if(menu == 6 && TCNT1 < 20000) segmen(10); //edit tahun
else segmen((tahun/10));
_delay_ms(1);
segmen(10);
posisi(6);
if(menu == 6 && TCNT1 < 20000) segmen(10); //edit tahun
else segmen((tahun%10));
_delay_ms(1);
segmen(10);
}
//INTERUPT 1 DETIK
ISR(TIMER1_COMPA_vect)
{
detik++;
clock++;
if(detik == 60)
{
detik=0;
menit++;
if(menit == 60)
{ menit=0;
jam++;
}
if (jam == 24)
{ tanggal++; jam = 0 ; }
if(tahun%4 == 0) bul_max[1]=29;
else bul_max[1]=28;
if (tanggal > bul_max[bulan-1]) {bulan++; tanggal =1 ;}
if (bulan > 12) {tahun++; bulan=1; }
}
}
void tombol(void)
{
if(bit_is_clear(PIND, PIND2))
{
if(menu == 0) menu =1;
else if (menu == 1) menu=2;
else if (menu == 2) menu=3;
else if (menu == 3) menu=4;
else if (menu == 4) menu=5;
else if (menu == 5) menu=6;
else if (menu == 6) menu=0;
_delay_ms(200);
}
else if(bit_is_clear(PIND, PIND3))
{
if(mode==0 && menu == 0)
{ animasi();
mode=1;
clock=0; }
else if(mode ==1 && menu ==0)
{mode=0;
clock=0;
}
if(menu == 1)
{ jam ++;
if (jam == 24) jam =0;
}
else if(menu == 2)
{ menit ++;
if (menit == 60) menit =0;
}
else if(menu == 3) detik = 0;
else if(menu == 4)
{ tanggal++;
if (tanggal == 32) tanggal =1;
}
else if(menu == 5)
{ bulan++;
if (bulan == 13) bulan =1;
}
else if(menu == 6)
{ tahun++;
if (tahun == 100) tahun=0;
}
_delay_ms(200);
}
}
int main(void)
{
DDRD |= _BV(PD0) | _BV(PD1) | _BV(PD4) | _BV(PD5) | _BV(PD6) ; //scan digit
DDRB |= _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB4) | _BV(PB5) | _BV(PB6) | _BV(PB7) ; //segment
DDRD &= ~_BV(PD2) & ~_BV(PD3); //tombol
// ------------ini untuk xtal 4Mhz----------------------
TCCR1B |= (1 << WGM12);
TIMSK |= (1 << OCIE1A);
OCR1A = 62499;
TCCR1B |= (1 << CS11)|(1 << CS10);
//------------------------------------------------------
jam = 0;
menit= 0;
detik=0;
tanggal=1;
bulan=1;
tahun=11;
clock=0; //perpindahan animasi jam dan kalender
mode=0;
menu=0;
sei();
while(1)
{
if(clock == 40 && mode == 1 && menu == 0)
{ animasi();}
else if(clock > 40 && clock <50 && mode == 1 && menu == 0)
{
tanggalan();
}
else if(clock == 50 && mode == 1 && menu == 0)
{ animasi(); clock =0; }
else if(menu == 0)
{ tulis(); }
else if(menu > 3)
{ tanggalan(); }
else
{ tulis(); }
tombol();
}
return 0;
}
ALTERNATIF UNTUK 7 SEGMEN LEBIH BESAR
Optoisolator PC817 mempunyai kekurangan yaitu dayanya kecil sehingga arus yg dapat dialirkan kecil saja. Hal ini akan menyebabkan 7 segmen besar menjadi redup sehingga perlu ditambahkan transistor yg memiliki daya lebih dan dengan rangkaian common Emiter menggunakan transistor PNP seperti BD140 dan PC817 sebagai control base nya (bisa juga transistor NPN 2N3906/2222) dengan contoh rangkaian pengganti sebagai berikut:
HASIL
SELAMAT MENCOBA
terimkasi udah selalu memberikan tutorial,,, lanjut terus gan transfer ilmunya ke anak bangsa .. supaya indonesia semakin maju
BalasHapussaya insya allah september akan beli produk agan dan belajar dari sini,, ane mau jago kaya agan
maaf baru bisa bulan september,, semua alat project saya ada di kos soalnya :D
gak pakek OptoIsolator PC817 atau 4N25 tdk bisa ta mas?
BalasHapus@Naufal Masyayikh
Fungsi opto adalah untuk memisahkan teg untuk 7segmen yg biasanya lebih tinggi...alternatif menggunakan transistor NPN seperti BD140 dengan kolektor pada com 7 seg, emiter ke v segmen, basis ke scan micro dan logikanya kudu dibalik jadi aktif low
BalasHapusJika memakai 7seg kecil ya ga usah pakai pasti nyaut kok ..
maaf mas minta board eagle nya dong... hehehe
BalasHapusmohon koreksi kalau salah,..
BalasHapuspin2 > digit1
pin3 > digit2
pin6 > tombol1
pin7 > tombol2
pin8 > digit3
pin9 > digit4
pin11 > digit5
pin12 > digit6
benar kah,..
terima kasih ..
hehe
permisi master
BalasHapusapakah jam tersebut sudah akurat,..?
terima kasih master
met mlm pak permisi,, nyimak dikit mas boleh minta file hex nya di window 32bit koq pas compile error trus trimksh yoezrasya@gmail.com
BalasHapusterima kasih atas tutorial yang sangat berharga ini
BalasHapuskalau scrip untuk kalender saja ada nggak bang...terima kasib
BalasHapus