Semua Akan Digital Pada Akhirnya... Dari Audio, Video, TV, Kontrol, Keuangan, Kesehatan dan Sebagainya. Blog Ini Ditujukan Buat Kamu Yang Ingin Belajar Dasar Digital Dan Yang selalu Bertanya, Kenapa Bisa Begini Dan Harus Begitu ?

  • IC Timer 555 yang Multifungsi

    IC timer 555 adalah sirkuit terpadu (chip) yang digunakan dalam berbagai pembangkit timer, pulsa dan aplikasi osilator. Komponen ini digunakan secara luas, berkat kemudahan dalam penggunaan, harga rendah dan stabilitas yang baik

  • Kontrol Perangkat Rumah Dari Internet

    Internet Of Things sudah menjadi istilah yang semakin dikenal orang. Mau tahu bagaimana konsep, cara pembuatan dan pemanfaatannya ?

  • Bermain DOT Matrix - LOVEHURT

    Project Sederhana dengan Dot Matrix dan Attiny2313. Bisa menjadi hadiah buat teman atau pacarmu yang ulang tahun dengan tulisan dan animasi yang dapat dibuat sendiri.

  • JAM DIGITAL 6 DIGIT TANPA MICRO FULL CMOS

    Jika anda pencinta IC TTL datau CMOS maka project jam digital ini akan menunjukkan bahwa tidak ada salahnya balik kembali ke dasar elektronika digital , sebab semuanya BISA dibuat dengan teknologi jadul

  • Node Red - Kontrol Industri 4.0

    Teknologi kontrol sudah melampaui ekspektasi semua orang dan dengan kemajuan dunia elektronika, kini semakin leluasa berkreasi melalui Node Red

Tampilkan postingan dengan label attiny. Tampilkan semua postingan
Tampilkan postingan dengan label attiny. Tampilkan semua postingan

Minggu, 19 September 2021

Lanjutan Praktek Input Output - Jam 4 Digit Dengan Tombol Non Blocking

 



Apa gak bosen kali ya saya menulis tentang jam digital  ?  Kalu dipikir memang saya maniak per-jam-an digital, dari yg paling sederhana pake delay sampai yg murni tanpa microcontroller, FULL CMOS. Saya rangkum dulu deh isi blog ini yg membahas jam mana saja...



Wah masih banyak lagi yang tidak saya sebutkan karena panjang, cek aja sendiri pasti banyak ketemu pembahasan tentang jam yang keseluruhannya memanfaatkan register timer pada microcontroller sekelas AVR.  Kali ini saya akan melanjutkan praktek I/O pada microcontroller Attiny2313 dengan melengkapi 7 segmen agar lebih bermanfaat yaitu ketika digabung beberapa buah menjadi jam yg dapat digunakan. Rangkaiannya seperti berikut ini.




Metode yang sangat terkenal saat pin I/O terbatas adalah metode scanning cepat, dimana tiap display 7 segmen ditampilkan secara bergantian. Jadi ke 7 kaki segmen dari masing-masing display 7 segmen terhubung semuanya. Sedangkan untuk melakukan penyalaannya diberikan tegangan pada common anoda secara satu-persatu dengan kecepatan tinggi sehingga menipu mata kalau nyalanya bareng. Jadi logikanya sesuai flowchart berikut :



Proses scanning penjelasannya seperti berikut :


  • Bagi nilai jam dengan 10 untuk mendapatkan puluhan jam, kemudian aktifkan PB#0, sedangkan PB#1,2,3 OFF. Nilai 7 segmen adalah segmen[puluhan_jam]
  • Ambil sisa pembagian jam dengan 10, kemudian aktifkan PB#1, sedangkan PB#0,2,3 OFF. Nilai 7 segmen adalah segmen[satuan_jam]
  • Bagi nilai menit dengan 10 untuk mendapatkan puluhan menit, kemudian aktifkan PB#2, sedangkan PB#0,1,3 OFF. Nilai 7 segmen adalah segmen[puluhan_menit]
  • Ambil sisa pembagian menit dengan 10, kemudian aktifkan PB#3, sedangkan PB#0,1,2 OFF. Nilai 7 segmen adalah segmen[satuan_menit]

Scriptnya seperti berikut ini :


#define F_CPU 1000000UL      // frekuensi clock internal 1Mhz
#include <avr/io.h> // definisi library standar IO port
#include <util/delay.h> // definisi include untuk delay
#include <avr/interrupt.h>
#include <stdlib.h>

int jam=23, menit=59, detik=50; //variable global untuk menyimpan data2 waktu


//susunan segmen dari portD = GFEDCBA
//7 segmen common ANODA


uint8_t segmen[11]= 
	{0b1000000, // 0
	0b1111001, // 1
	0b0100100, // 2
	0b0110000, // 3
	0b0011001, // 4
	0b0010010, // 5
	0b0000010, // 6
	0b1111000, // 7
	0b0000000, // 8
	0b0010000, //9
	0b1111111}; // 10 / blank



ISR(TIMER1_COMPA_vect)  // 1 detik
{

	detik ++;

	if ( detik == 60)
	{       detik=0;
		menit++;
	}

	if ( menit == 60)
	{       menit = 0;
		jam++ ;
	}
	
	if (jam >23) jam=0;
}

int main(void)
{
    DDRD |= (1<<PD6) |(1<<PD5) |(1<<PD4) |(1<<PD3) |(1<<PD2) |(1<<PD1) | (1<<PD0) ; //segmen
    DDRB |= (1<<PB0) | (1<<PB1) |(1<<PB2) |(1<<PB3) | (1<<PB6) ; //Scan 7 segmen
    DDRB &= ~(1<<PB4) & ~(1<<PB5); // tombol tambah menit dan jam
    
    TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
    TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
    OCR1A  = 15625; //compare the CTC A for 1 second 
    TCCR1B |= (1 << CS11)|(1 << CS10); // Start timer at Fcpu/64

	//untuk tombol anti blocking
	uint16_t waktu =0;  
	bool pencet = false;

	sei(); //start interrupt
   
		
   while (1) 
{ PORTD = segmen[10]; //blanking biar tidak membayang PORTB |=(1<<PB0); //nyalakan 7 segmen no 1 (puluhan jam) PORTB &= ~(1<<PB1) & ~(1<<PB2) & ~(1<<PB3) ; PORTD = segmen[jam / 10]; //ambil nilai puluhan jam _delay_ms(1); //delay disesuaikan terang tampilan 7 seg PORTD = segmen[10]; PORTB |=(1<<PB1); //nyalakan 7 segmen no 2 (satuan jam) PORTB &= ~(1<<PB0) & ~(1<<PB2) & ~(1<<PB3) ; PORTD = segmen[jam % 10]; //modulus atau sisa untuk satuan jam _delay_ms(1); PORTD = segmen[10]; PORTB |=(1<<PB2); //nyalakan 7 segmen no 3 (puluhan menit) PORTB &= ~(1<<PB0) & ~(1<<PB1) & ~(1<<PB3) ; PORTD = segmen[menit / 10]; //ambil nilai puluham menit _delay_ms(1); PORTD = segmen[10]; PORTB |=(1<<PB3); //nyalakan 7 segmen no 4 (satuan menit) PORTB &= ~(1<<PB0) & ~(1<<PB1) & ~(1<<PB2) ; PORTD = segmen[menit% 10]; //modulus atau sisa untuk satuan jam _delay_ms(1); //Tombol if (bit_is_set(PINB, PINB5)) { if(pencet == false) { jam++; if(jam==24) jam =0; } pencet=true; waktu=TCNT1; } if (bit_is_set(PINB, PINB4)) { if(pencet == false) { menit++; if(menit==60) menit=0; } pencet=true; waktu=TCNT1; } if(abs(waktu - TCNT1) > 4000) { //non blocking delay tombol waktu=0; pencet = false; } //blink Led Pemisah Jam : menit if(TCNT1 <7500) PORTB |=(1<<PB6); else PORTB &= ~(1<<PB6); } }

*) catatan :

  • clock yg digunakan adalah RC oscillator  internal pada attiny2313 yg sangat tidak akurat, untuk itu jika menggunakan nilai yg akurat bisa menggunakan xtal oscillator seperti praktek jam lainnya dan jangan lupa merubah fusebit seperti penjelsan disini  dan jika menggunakan USBASP maka butuh batuan fusebit calculator disini .
  • Jika menggunakan clock 4 MHZ maka nilai fusebitnya :


  • Sedangkan perubahan untuk menyesuaikan clock dilakukan pada script dibagian ini :

#define F_CPU 4000000UL
==========================================
			
	TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
	TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
	OCR1A  = 62499; //compare the CTC A (clock 4 Mhz)
	TCCR1B |= (1 << CS11)|(1 << CS10); // Start timer at Fcpu/64

	
  • Non blocking delay pada tombol akan berpengaruh pada tampilan yang tidak terlihat kedip saat tombol dipencet, seperti animasi paling atas dimana saya menggunakan  _delay_ms(300); setelah penekanan tombol.

Share:

Sabtu, 17 April 2021

Jam 4 Digit - Kembali Ke Attiny2313 Saat Atmel Ternyata Sudah Dibeli Microchip

 




Kemana aja sih masbro kok baru di 2021 sadar ATMEL yang memproduksi IC microcontroller legendaris telah dibeli Microchip di 2016? Gak kemana-mana kok... masih disini saja berkutat dengan dunia Elektronika diluar per - IC - an, setelah di tahun 2015 menghadapi kenyataan pasar elektronika digital tergerus dengan solusi Arduino yg memanjakan pengguna microcontroller 8 bit. Tapi kini di 2021 gak salah kita ulik kembali IC kesayangan ATTINY2313 di Era baru saat IC jadul akan diprediksi di korek-korek lagi dan muncul kembali akibat adanya perang "CHIP" antara USA vs CHINA. 





Kita gak ngomong politik-politikan ah...yang penting kita tetap berusaha memanfaatkan kondisi yang ada sebaik mungkin. Kita lanjut bercerita mengenai Microchip yg sudah mengakuisi ATMEL, dan saya akan bahas pada sisi development toolsnya. Kini yang namanya AVR Studio (Win AVR) - ATMEL STUDIO (sampai versi 7) kini telah digabungkan lebih lengkap dalam MICROCHIP STUDIO. Masih setia dengan GCC nya dimana librarynya tinggal install dari lib software maupun driver programmer. Yang saya masih punya di rumah adalah AVRISP - MKII dan ternyata tinggal colok sudah dapat dideteksi oleh komputer PC yang saya gunakan.



Yang menjadi pemicu dari kembalinya saya ke dunia ATtiny adalah sebuah WA dari orang senegal yg bekerja di prancis namanya jean paul, yang meminta saya untuk membuatkan program dari rangkaian jam berbasis C2051 diatas. Kita ketahui IC micro seri itu sudah obsolete dan karena memiliki kaki dan pola yang mirip puuool dengan ATTiny2313 maka langsung aja saya ambil lagi komponen dan breadboard dan mencoba membuat praktek LED blink untuk membangkitkan gairah dan  menghidupkan sel otak yg hampir 5 tahun dipakai untuk hal yg berbeda.






Ternyata Downloader , ATtiny dan PC saya masih bersahabat dan membuat adapatasinya lumayan cepat. Sehingga dalam waktu singkat sudah bisa membuat counter 7 segmen dengan script sederhana yang tinggal copy paste dari blog ini juga.



#define F_CPU 1000000UL // default internal RC clock 
#include <avr/io.h>
#include <util/delay.h>


void segmen (int angka)

{

//susunan segmen dari portB = AFBEDCGdp
//menggunakan 7 segmen common katoda 

	switch (angka)
	{
	                          //AFBEDCGdp	
    	        case 0 : { PORTB =0b11111100; break ; }
		case 1 : { PORTB =0b00100100; break ; }
		case 2 : { PORTB =0b10111010; break ; }
		case 3 : { PORTB =0b10101110; break ; }
		case 4 : { PORTB =0b01100110; break ; }
		case 5 : { PORTB =0b11001110; break ; }
		case 6 : { PORTB =0b11011110; break ; }
		case 7 : { PORTB =0b10100100; break ; }
		case 8 : { PORTB =0b11111110; break ; }
		case 9 : { PORTB =0b11101110; break ; }
		case 10 : { PORTB =0b0; break ; } 
	}


}



int main(void)

{

	int counter=0; //variabel delay
	int digit=0; //variabel digit yang ditampilkan


	// Port untuk display 7 segment
	DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5)|(1<<PB6)|(1<<PB7);



	while(1)

	{

		counter++ ; //bikin delay nambah terusss

		// sesuaikan nilai max counter dengan detik yg pas, tentunya tidak akurat
		if(counter >= 20000) { 
			counter =0 ; 
			digit++;
			if(digit == 10) digit=0;
			
			
			 }

		// nilai 1/2 dari counter untuk blink dot "."
		if(counter >= 10000) PORTB |=(1<<PB0) ;

		// tampilkan digit
	           segmen(digit);

			


	}

	return 0;

}





Dari circuit yang saya dapat dari orang senegal tadi, kita menggunakan 7 segmen komon katoda / komon negatif, sehingga kalau kita ingat rangkaian LED dalam 7 segmen vs Attiny seperti ini :


Dalam rangkaian segmen dihubungkan ke port B (pin 12 - 19 , 7 segmen 1 dot) sehingga dengan susunan yang pas maka script untuk menulis segmen menjadi seperti ini :


switch (angka)
{
                          //AFBEDCGdot
            case 0 : { PORTB =0b11111100; break ; }
case 1 : { PORTB =0b00100100; break ; }
case 2 : { PORTB =0b10111010; break ; }
case 3 : { PORTB =0b10101110; break ; }
case 4 : { PORTB =0b01100110; break ; }
case 5 : { PORTB =0b11001110; break ; }
case 6 : { PORTB =0b11011110; break ; }
case 7 : { PORTB =0b10100100; break ; }
case 8 : { PORTB =0b11111110; break ; }
case 9 : { PORTB =0b11101110; break ; }
 
}

Dan hasil dari praktek counter 1 segmen menjadi seperti ini :




Selanjutnya kita hanya butuh memparalel 4 buah 7 segmen dan menghubungkan common dari tiap 7 segmen menuju microcontroller, lalu dibuat proses scanning bergantian menyalakan 7 segmen. Dari rangkaian yg diberikan kita akan menggunakan port D0-3 untuk melakukan scanning sehingga urutan 7 segmen yg ditampilkan seperti berikut :

  • (1) Port D0 Mati , Port D1,D2,D3 On , 7 segmen menampilkan digit puluhan jam
  • (2) Port D1 Mati , Port D0,D2,D3 On , 7 segmen menampilkan digit satuan jam
  • (3) Port D2 Mati , Port D0,D1,D3 On , 7 segmen menampilkan digit puluhan menit
  • (4) Port D3 Mati , Port D1,D2,D0 On , 7 segmen menampilkan digit satuan menit

Karena masing 7 segmen di nyalakan bergantian secara cepat, namun mata akan melihatnya lebih lambat dan efeknya 7 segmen tidak terasa berkedip. Script menampilkan scanning 7 segmen seperti berikut :


     segmen(10); //blanking biar tidak berbayang
     digit = jam/10;
     PORTD &= ~(1<<PD0);
     PORTD |= (1<<PD1) |(1<<PD2) |(1<<PD3) ;
     segmen(digit);
     _delay_ms(1);

     segmen(10);
     digit = jam%10;
     PORTD &= ~(1<<PD1);
     PORTD |= (1<<PD0) |(1<<PD2) |(1<<PD3) ;
     segmen(digit);
    _delay_ms(1);

     segmen(10);
     digit = min/10;
     PORTD &= ~ (1<<PD2);
     PORTD |= (1<<PD1) |(1<<PD0) |(1<<PD3) ;
     segmen(digit);
     _delay_ms(1);

     segmen(10);
     digit = min%10;
     PORTD &= ~ (1<<PD3);
     PORTD |= (1<<PD1) |(1<<PD2) |(1<<PD0) ;
     segmen(digit);
     _delay_ms(1);


Sedangkan untuk menjadikan jamnya akurat saya menggunakan clock external berupa XTAL 4Mhz sehingga ATTiny butuh diubah fusebitnya menjadi CLK_DIV8 tidak aktif dan clock external 3-8Mhz. 







Dan yang tidak kalah pentingnya menggunakan Interupt Timer yang sangat ampuh mendapatkan clock 1 detik yang akurat. Scriptnya seperti berikut :


ISR(TIMER1_COMPA_vect)

{

detik ++;

if ( detik == 60)
{  detik=0;
min++;
}

if ( min == 60)
{ min = 0;
jam++ ;
}
if (jam == 24) jam=0;

}


int main(void)

{
int digit=0; //variabel digit yang ditampilkan
   
   
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
OCR1A  = 62499; //compare the CTC A
TCCR1B |= (1 << CS11)|(1 << CS10); // Start timer at Fcpu/64

     sei();

..........................
}




Sebenarnya saya hanya mengulang saja tulisan lawas saya yang bisa dibaca di link dibawah ini :


Hasilnya seperti ini brooo....







SELAMAT MENCOBA



.
Share:

Rabu, 19 November 2014

[TUTORIAL & SCRIPT BREAKDOWN] RPM - TACHOMETER HONDA dengan ATTINY2313




Akhirnya balik lagi ke blog ini setelah beberapa waktu vakum. Dan kali ini menjawab beberapa request yang masuk untuk membahas lebih lanjut mengenai RPM - TACHOMETER untuk sepeda motor yang pernah dibahas disini . Sebenernya jika selalu mengikuti perkembangan blog ini maka tidak terlalu susah asal dasar pengetahuan timer dan interupt nya lengkap. 

Intinya pada project ini adalah mendeteksi RADIASI pulsa CDI ke BUSI dan dimasukkan ke PIN INTERRUPT dan kemudian dihitung jumlah pulsa yang muncul vs waktu. Dan didapatkanlah RPM yang diinginkan. Kali ini kita juga akan membuat animasi graph / level sehingga tidak bosan dengan angka-angka saja.

Perhatikan skematik dibawah ini dan bahan2nya bisa dilihat dari gambar berikut (klik untuk gambar lebih jelas)



Jangan lupa juga untuk menyediakan motor yang akan di "HIAS" yang kali ini meminjam motor anak buah saya yaitu HONDA SUPRA VIT. Saya memiliki pengalaman jika bebek honda lebih bocor sinyal CDI nya ketimbang motor lain. Jadi jika menggunakan motor lain maka disesuaikan pemilihan resistor sebelum transistor pembaca pulsa (2N3904) dan pengalaman lainnya ketika menggunakan sepeda motor Yamaha Vega maka transistor yg digunakan adalah PNP 2N3906 dengan tanpa menggunakan resistor pada basis dan VCC ke EMITOR sedangkan INTERUPT ke COLECTOR (dibalik).





Langsung aja kita bahas script nya biar ga bingung, agak panjang tapi ga rugi kok



>>>HEADER<<

Attiny 2313 yang digunakan adalah default yg memiliki clock 1MHz. 

#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



>>>PENERJEMAH ANGKA ke SEGMEN<<

7 segmen yang digunakan merupakan common Anoda sehingga untuk menyalakan segmen dibutuhkan logic "LOW" atau 0 volt / Ground. Untuk animasi dan huruf dapat dikreasikan sendiri dengan kombinasi "LOW" untuk segmen menyala dan "HIGH" untuk segmen mati.

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; 
     }


}

}




>>>ANIMASI LEVEL RPM<<

Nilai RPM akan diterjemahkan dari angka menjadi level / bar graph

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; }
         }

}



>>>INISIALISASI COUNTER<<

Counter 0 adalah counter 8 bit, sedangkan Counter 1 adalah 16 bit. Silahkan membaca terlebih dahulu penjelasan mengenai counter dan timer disini.

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

}




>>>INTERRUPT TIMER<<


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; 
         }

                 }


}


>>>COUNTER INTERRUPT dari BUSI<<

SIGNAL (SIG_INT0) //INTERRUPT 0 menghitung pulsa dari radiasi CDI vs BUSI
{
number++;

}



>>>TOMBOL<<

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);


  }
}


>>>MEMBACA EEPROM  nilai KALIBRASI<<

void baca_eeprom(void)
{

kalibrasi = eeprom_read_byte((uint8_t*)20);

if(kalibrasi == 0xFF) kalibrasi=3;


}



>>>MAIN PROGRAM<<

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
Share:

Kontak Penulis



12179018.png (60×60)
+628155737755

HP: 081331339072
Mail : ahocool@gmail.com

Site View

Categories

555 (8) 7 segmen (3) adc (4) amplifier (2) analog (15) android (12) antares (3) arduino (21) artikel (11) attiny (3) attiny2313 (19) blog (1) bluetooth (1) cmos (2) crypto (2) dasar (45) digital (1) display (3) esp8266 (25) euro2020 (13) gcc (1) iklan (1) infrared (2) Input Output (3) iot (44) jam (7) jualan (12) kereta api (1) keyboard (1) keypad (3) kios pulsa (2) kit (6) komponen (16) komputer (3) komunikasi (1) kontrol (7) lain-lain (8) lcd (2) led (14) led matrix (6) line tracer (1) lm35 (1) memory (1) metal detector (4) microcontroller (70) micropython (6) mikrokontroller (12) mikrotik (5) mqtt (1) ninmedia (3) ntp (1) paket belajar (19) palang pintu otomatis (1) parabola (78) pcb (2) power (1) praktek (2) project (33) proyek (1) python (3) radio (15) raspberry pi (4) remote (1) revisi (1) rfid (1) robot (1) rpm (2) rs232 (1) script break down (3) sdcard (3) sensor (1) sharing (3) signage (1) sinyal (1) sms (6) software (18) solar (1) solusi (1) tachometer (2) technology (1) teknologi (2) telegram (2) telepon (9) televisi (145) television (28) transistor (2) troubleshoot (3) tulisan (83) tutorial (80) tvri (2) vu meter (2) vumeter (2) wav player (3) wayang (1) wifi (3)

Arsip Blog

Diskusi


kaskus
Forum Hobby Elektronika