Langsung aja kita bahas script nya biar ga bingung, agak panjang tapi ga rugi kok
#define F_CPU 1000000UL // sesuaikan clock yang digunakan !!
#include <avr/io.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#include <inttypes.h>
#include <avr/interrupt.h>
// ini untuk animasi kata awal, ubah sesuai keinginan atau hapus jika tidak mau
uint8_t angka1=16 ;
uint8_t angka2=17 ;
uint8_t angka3=20 ;
uint8_t angka4=15 ;
uint8_t segstep=0; // untuk pindah segmen
uint8_t kalibrasi=3; // kalibrasi awal
uint8_t valid=0; // variabel untuk mengatasi noise ke tombol
int number=0; // variabel menyimpan jumlah counter
void conv_segmen(uint8_t digit)
// Rutin ini merubah angka dan animasi ke segmen
{
switch (digit)
{
//angka biasa
case 0 :
{
PORTB &= ~_BV(PB0) & ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB5); //PORT YG NYALA
PORTB |= _BV(PB6) ; //PORT YG MATI
break;
}
case 1 :
{
PORTB &= ~_BV(PB1) & ~_BV(PB2) ;
PORTB |= _BV(PB0) | _BV(PB3) | _BV(PB4) | _BV(PB5) | _BV(PB6) ;
break;
}
case 2 :
{
PORTB &= ~_BV(PB0) & ~_BV(PB1) & ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB6) ;
PORTB |= _BV(PB2) | _BV(PB5) ;
break;
}
case 3 :
{
PORTB &= ~_BV(PB0) & ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB6) ;
PORTB |= _BV(PB4) | _BV(PB5) ;
break;
}
case 4 :
{
PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB5) & ~_BV(PB6) ;
PORTB |= _BV(PB0) | _BV(PB3) | _BV(PB4) ;
break;
}
case 5 :
{
PORTB &= ~_BV(PB0) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB5) & ~_BV(PB6) ;
PORTB |= _BV(PB1) | _BV(PB4) ;
break;
}
case 6 :
{
PORTB &= ~_BV(PB0) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB5) & ~_BV(PB6) ;
PORTB |= _BV(PB1) ;
break;
}
case 7 :
{
PORTB &= ~_BV(PB0) & ~_BV(PB1) & ~_BV(PB2) ;
PORTB |= _BV(PB3) | _BV(PB4) | _BV(PB5)| _BV(PB6) ;
break;
}
case 8 :
{
PORTB &= ~_BV(PB0) & ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB5) & ~_BV(PB6);
break;
}
case 9 :
{
PORTB &= ~_BV(PB0) & ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB5) & ~_BV(PB6);
PORTB |= _BV(PB4) ;
break;
}
case 10 : //kosong
{
PORTB |= _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB4) | _BV(PB5) | _BV(PB6) ;
break;
}
//11 - 14 khusus untuk animasi level
case 11 :
{
PORTB &= ~_BV(PB4);
PORTB |= _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB5) | _BV(PB6);
break;
}
case 12 :
{
PORTB &= ~_BV(PB4) & ~_BV(PB2);
PORTB |= _BV(PB0) | _BV(PB1) | _BV(PB3) | _BV(PB5) | _BV(PB6);
break;
}
case 13 :
{
PORTB &= ~_BV(PB4) & ~_BV(PB2) & ~_BV(PB5);
PORTB |= _BV(PB0) | _BV(PB1) | _BV(PB3) | _BV(PB6) ;
break;
}
case 14 :
{
PORTB &= ~_BV(PB4) & ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB5);
PORTB |= _BV(PB0) | _BV(PB3) | _BV(PB6) ;
break;
}
// kebetulan nama pemilik motor seperti ini, ubah sesuai keinginan
case 15 : //r
{
PORTB &= ~_BV(PB6) & ~_BV(PB4) ;
PORTB |= _BV(PB0) | _BV(PB1) | _BV(PB3) | _BV(PB2) | _BV(PB5) ;
break;
}
case 16 : //i
{
PORTB &= ~_BV(PB4);
PORTB |= _BV(PB0) | _BV(PB1) | _BV(PB3) | _BV(PB2) | _BV(PB5) | _BV(PB6) ;
break;
}
case 17 : //b
{
PORTB &= ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB5) & ~_BV(PB2) & ~_BV(PB6);
PORTB |= _BV(PB0) |_BV(PB1) ;
break;
}
case 18 : //y
{
PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB5) & ~_BV(PB6);
PORTB |= _BV(PB4)| _BV(PB0);
break;
}
case 19 : //u
{
PORTB &= ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB4) ;
PORTB |= _BV(PB1)| _BV(PB0) | _BV(PB5) | _BV(PB6);
break;
}
case 20 : //0
{
PORTB &= ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB2) & ~_BV(PB6);
PORTB |= _BV(PB0) |_BV(PB1) |_BV(PB5) ;
break;
}
}
}
void animasi(uint8_t posisi)
{
switch(posisi) {
case 0 :{ angka4=10; angka3=10 ; angka2=10; angka1=10;
break; }
case 1 :{ angka4=11; angka3=10 ; angka2=10; angka1=10;
break; }
case 2 :{ angka4=12; angka3=10 ; angka2=10; angka1=10;
break; }
case 3 :{ angka4=12; angka3=11 ; angka2=10; angka1=10;
break; }
case 4 :{ angka4=12; angka3=12 ; angka2=10; angka1=10;
break; }
case 5 :{ angka4=12; angka3=12 ; angka2=11; angka1=10;
break; }
case 6 :{ angka4=12; angka3=12 ; angka2=12; angka1=10;
break; }
case 7 :{ angka4=12; angka3=12 ; angka2=12; angka1=11;
break; }
case 8 :{ angka4=12; angka3=12 ; angka2=12; angka1=12;
break; }
case 9 :{ angka4=13; angka3=12 ; angka2=12; angka1=12;
break; }
case 10 :{ angka4=14; angka3=12 ; angka2=12; angka1=12;
break; }
case 11 :{ angka4=14; angka3=13 ; angka2=12; angka1=12;
break; }
case 12 :{ angka4=14; angka3=14 ; angka2=12; angka1=12;
break; }
case 13 :{ angka4=14; angka3=14 ; angka2=13; angka1=12;
break; }
case 14 :{ angka4=14; angka3=14 ; angka2=14; angka1=12;
break; }
case 15 :{ angka4=14; angka3=14 ; angka2=14; angka1=13;
break; }
case 16 :{ angka4=14; angka3=14 ; angka2=14; angka1=14;
break; }
default :{ angka4=14; angka3=14 ; angka2=14; angka1=14;
break; }
}
}
void init_ctr(void) //COUNTER 0 8 BIT untuk pindah kolom 7 segmen
{
TCCR0A |= (1 << WGM01); // Configure timer 0 for CTC mode
TIMSK |= (1 << OCIE0A); // Enable CTC interrupt
OCR0A = 50; // Set CTC compare value till blink disapear at 1MHz AVR clock, with a prescaler of 64
TCCR0B |= (1 << CS01)|(1 << CS00); // Start timer at Fcpu/64
}
void init_ctr1(void) //COUNTER 1 untuk penghitung pulsa saat 600ms
{
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
OCR1A = 586; //compare the CTC A = 600ms =586
TCCR1B |= ((1 << CS10) | (1 << CS12)); // Start timer at Fcpu/1024
}
ISR(TIMER1_COMPA_vect) //interrupt timer 1 (16 bit) untuk capture jumlah pulsa
{ uint16_t rpm,anime; //variabel
anime=0;
rpm=0;
switch(kalibrasi) { //Pemilih kalibrasi
case 1 :{
rpm=number/100;
break; }
case 2 :{
rpm=number/10;
break; }
case 3 :{
rpm=number;
break; }
case 4 :{
rpm=number*10;
break; }
case 5 :{
rpm=number*100;
break; }
case 6 :{
anime=1;
break; }
case 7 :{
anime=2;
break; }
}
//Pemilih antara angka rpm atau animasi level
switch(anime) {
case 0 : { //ANGKA RPM
OCR1A = 586;
angka1 = rpm%10;
if(rpm>9) angka2 = ((rpm%100) - (rpm%10)) /10 ;
else angka2=10;
if(rpm>99) angka3 = ((rpm%1000) - (rpm%100)) /100 ;
else angka3=10;
if(rpm>999) angka4 = ((rpm%10000) - (rpm%1000)) /1000 ;
else angka4=10;
break ; }
case 1 : { //ANIMASI MODE 1
OCR1A = 100;
animasi(number/10);
break ; }
case 2 : { //ANIMASI MODE 2
OCR1A = 100;
animasi(number/50);
break ; }
}
number=0;
}
ISR(TIMER0_COMPA_vect) // timer 0 (8 bit) untuk pindah kolom 7 segmen
{
//tiap segmen yg akan dinyalakan akan diberikan logic High
segstep++;
switch(segstep) {
case 1 :{ conv_segmen(10);
PORTD |= _BV(PD0);
PORTD &= ~_BV(PD1) & ~_BV(PD4) & ~_BV(PD5) ;
conv_segmen(angka4);
break;
}
case 2 :{ conv_segmen(10);
PORTD |= _BV(PD1);
PORTD &= ~_BV(PD0) & ~_BV(PD4) & ~_BV(PD5) ;
conv_segmen(angka3);
break;
}
case 3 :{ conv_segmen(10);
PORTD |= _BV(PD4);
PORTD &= ~_BV(PD1) & ~_BV(PD0) & ~_BV(PD5) ;
conv_segmen(angka2);
break;
}
case 4 :{ conv_segmen(10);
PORTD |= _BV(PD5);
PORTD &= ~_BV(PD1) & ~_BV(PD4) & ~_BV(PD0) ;
conv_segmen(angka1);
segstep=0;
break;
}
}
}
SIGNAL (SIG_INT0) //INTERRUPT 0 menghitung pulsa dari radiasi CDI vs BUSI
{
number++;
}
void tombol(void)
{
if(bit_is_clear(PIND, PIND3)) //pembacaan pada pin D3
{ valid++; //validasi penekanan
_delay_ms(10);
}
if( valid >= 50) //jika melebihi noise motor/getaran, ubah suai nilai ini
{
valid=0;
kalibrasi++; //ubah kalibrasi
if (kalibrasi >= 8) kalibrasi=1;
conv_segmen(10);
//Menulis nilai kalibrasi ke EEPROM
eeprom_write_byte((uint8_t*)20, kalibrasi);
_delay_ms(500);
}
}
void baca_eeprom(void)
{
kalibrasi = eeprom_read_byte((uint8_t*)20);
if(kalibrasi == 0xFF) kalibrasi=3;
}
int main(void)
{
//Inisialisasi Interrupt
GIMSK |= (1<<INT0) ; // inetrupt untuk hitung pulsa busi
MCUCR |= (1<<ISC01)| (1<<ISC11); //fall edge
//Inisialisasi PIN ATTINY2313
DDRD |= _BV(PD0) | _BV(PD1) | _BV(PD4) | _BV(PD5) ; // segmen select / common scans
DDRB |= _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB4) | _BV(PB5) | _BV(PB6) ; // seg a,b,c,d,e,f,g
DDRD &= ~_BV(PD3) ; // Input kalibrasi
init_ctr(); //hidupkan COUNTER0
sei();
_delay_ms(1000);
//tampilan kata ke 2, sesuaikan dengan kebutuhan atau hapus jika tidak mau
angka1=16 ;
angka2=1 ;
angka3=19 ;
angka4=18 ;
_delay_ms(1000);
init_ctr1(); //hidupkan COUNTER 1
baca_eeprom(); // baca nilai kalibrasi
//muter terussssss
while(1)
{
tombol();
}
}
videonya....seperti dibawah ini
tips: Tegangan pada lampu depan/ langsung dari coil bisa berlebih jika akimu rusak/habis. Jadi usahakan mencari sumber tegangan yg tidak merusak regulator 7805
Selamat Mencoba