Semua Tentang Belajar Teknologi Digital Dalam Kehidupan Sehari - Hari

  • 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

  • Ayo Migrasi TV Digital

    Kami bantu anda untuk memahami lebih jelas mengenai migrasi tv digital, apa sebabnya dan bagaimana efek terhadap kehidupan. Jasa teknisi juga tersedia dan siap membantu instalasi - setting perangkat - pengaturan antena dan distribusi televisi digital ke kamar kos / hotel

  • 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 microcontroller. Tampilkan semua postingan
Tampilkan postingan dengan label microcontroller. Tampilkan semua postingan

Jumat, 17 Mei 2013

DHT-11: Sensor suhu dan kelembaban murah meriah

courtesy of : http://www.candrian.gr/index.php/dht-11-one-wire-bus/

Sensor DHT-11 merupakan sensor suhu & kelembaban versi LOW COST dengan hasil yang "cukup". Jika membutuhkan hasil yang lebih stabil maka kita perlu menggunakan sensor buatan sensirion SHT-11 dan seri sejenis.


Spesifikasi:

Supply Voltage: +5 V
Temperature range :0-50 °C error of ± 2 °C
Humidity :20-90% RH ± 5% RH error
Interface: Digital


  



Data bus sensor ini bukan TWI / I2C melainkan bus tersendiri dimana nilai 1 & 0 dibedakan melalui LEBAR PULSA HIGH

sebelum lanjut lebih mendalam, sebaiknya bagi yang belum menguasai penulisan ke LCD agar mempelajarinya disini.


skematik yang kita gunakan adalah sebagai berikut:






Lanjut kita akan bahas scriptnya, tapi hanya dibagian DHT11 nya, untuk detail LCD harap membaca posting sebelumnya (LCD & ADC/termometer LM35 terutama dibagian ITOA)

seperti sumber link diatas , 1 PIN I/O akan berfungsi sebagai Output dan Input bergantian, untuk langkah pertama akan dikirimkan perintah START oleh micro ke DHT 11



jadi kita kirim pulsa Low 18ms dan High 40us, lalu kita tunggu sebentar sampai ada response/jawaban dari DHT 11 berupa pulsa low - high selebar 54us & 80us



setelah itu hasil pengukuran akan dikirimkan sensor menggunakan format 8bit sebanyak 5 kali


scriptnya seperti yang dibawah ini :


void baca_sensor()
{

char dum;  // variabel sementara

suhu=0;
humi=0;
counter=0;

DDRD|=(1<<PD3); //PD3 sebagai output
_delay_ms(250);

PORTD &=~(1<<PD3); // nolkan PD3
_delay_ms(18); //tunggu 18 ms

PORTD |=(1<<PD3); // naikkan PD3
_delay_us(40); //tunggu 40us


DDRD &=~(1<<PD3); //PD3 sebagai input

//tunggu response dari DHT11

while(counter <100)
{
_delay_us(1);
counter++;
if (bit_is_set(PIND, 3)) break;
}

counter=0;

while(counter <100)
{
_delay_us(1);
counter++;
if (bit_is_clear(PIND, 3)) break;
}


//baca data setelah response, lihat script di pembahasan selanjutnya untuk routine hitung()

//8 bit pertama ( puluhan kelembaban )
humi=hitung();
//8 bit kedua( satuan kelembaban ), tidak usah di baca karena nilai selalu 0 untuk DHT11
hitung();
//8 bit ketiga ( puluhan suhu )
suhu=hitung();
//8 bit keempat ( satuan suhu ), tidak usah di baca karena nilai selalu 0 untuk DHT11
hitung();

//8 bit ke 5 tidak perlu dihitung 
//tulis lcd
lcd_gotoxy(9,0);
itoa(suhu,&dum;);
lcd_puts(&dum;);

lcd_gotoxy(9,1);
itoa(humi,&dum;);
lcd_puts(&dum;);



}
pada script diatas ada trick menggunakan variabel counter dan delay 1us, ini cara yg paling gampang dan menyederhanakan proses counter terhadap lebar pulsa
Setiap bit yang dikirim dimulai sinyal Low sepanjang 54uS , kemudian dikuti 24uS sampai 70uS sesuai bit yang diwakilinya. 
Bit '0' : ~54uS Low  kemudian ~24uS High
Bit '1' : ~54uS Low kemudian ~70uS High

Pada akhir paket data yg diberikan oleh DHT-11 akan muncul sinyal Low sepanjang 54uS dan kemudian bus menjadi high selamanya dan masuk ke sleep mode.

Script berikut menyederhanakan perhitungan dengan trick counter dan delay, dimana jika counter melebihi 24 , maka kita anggap nilainya 1 dan sebaliknya

uint8_t hitung(void)
{

uint8_t a,counter,hasil;

counter=0;
hasil=0;

for (a=8;a>0;a--) // 8 kali tiap perhitungan
{


while(counter <100) // deteksi saat LOW ( tidak ada perhitungan)
{
_delay_us(1);
counter++;
if (bit_is_set(PIND, 3)) break; //tunggu sampai high dan keluar loop
}

counter=0;

while(counter <100)
{
_delay_us(1);
counter++; // counter mendeteksi lebar pulsa
if (bit_is_clear(PIND, 3)) break; //jika low maka keluar dari loop
}

// perhitungan 8 bit decimal dengan geser-geser bit
//jika lebih 25us =1 , kurang < 25 us = 0
 
if(counter > 25) hasil += (1 << (a-1)) ; 

counter=0;

}

return hasil;


}

mudah bukan ? dan hasilnya lumayan mengecewakan jika dibanding dengan sensor yg paten sekelas SHT 11



SELAMAT MENCOBA



Share:

Rabu, 15 Mei 2013

TUTORIAL : Memanfaatkan ICP (INPUT CAPTURE PIN) sebagai penghitung lebar pulsa

parallax-ping-ultrasonic-sensor-large.jpg (552×348)


Berawal ketika mendapatkan sensor ultrasonic untuk ranging/deteksi jarak, jenis Ping)) (buatan paralax) dan berdasarkan datasheet diketahui bahwa sensor memiliki response terhadap jarak setelah diberikan trigger seperti gambar dibawah ini :



Setelah sinyal mendapatkan perintah melalui pulsa 10us pada pin SIG kemudian bagian Transmit dari ping)) akan mengeluarkan sinyal burst 20us dengan frekuensi 40khz, dan ketika mendapatkan halangan sebuah benda didepannya maka suara ultrasonic ini akan dipantulkan kembali dan kemudian dapat dibaca oleh sensor penerima ultrasonic.Penghitungan jarak berbanding terbalik dengan lama sinyal echo atau pantulan yang ditangkap oleh sensor, sehingga kita perlu menghitung lebar pulsa yang diterima balik oleh penerima ultrasonik.

Salah satu fungsi yang digunakan adalah fasilitas INPUT CAPTURE PIN (ICP) yang selalu dimiliki oleh fasilitas counter dari AVR. Maksudnya ICP adalah pin ini akan menangkap (melalui interupt) perubahan logic yg diberikan kepadanya. Saat capture terjadi maka sebuah register yaitu ICR akan mengambil timestamp dari sebuah timer yang sedang berjalan yaitu pada register TCNT . Prescaller dari timer masih berfungsi seperti halnya pada tutorial mengenai timer

Untuk mencobanya, perhatikan PIN dari ATTINY2313 berikut :



ICP berada paka pin no 11 (PD6) dan dapat dihubungkan menjadi input dari suatu frekuensi / sinyal pulsa TTL yang akan diukur. Permasalahannya adalah ketika ICP hanya mendeteksi satu sisi perubahan logic yaitu rising (0-1) atau falling (1-0) . Cara yang biasa dilakukan untuk mendapatkan frekuensi dari sinyal :

1. Mendeteksi 2 buah timestamp dan kemudian mencari selisihnya
2. Memanfaatkan pin INT (external interupt) sebagai pendeteksi edge yang arahnya berlawanan dengan ICP

sebelumnya kita akan memanfaatkan LCD 16x2 sebagai output dan tombol sebagai input pulsa yang akan kita baca lebarnya. Perhatikan terlebih dahulu tutorial menulis di LCD karena output akan kita tulis di LCD.




scriptnya seperti ini, kita akan membaca lebar dari ICP pada counter 16bit, dimana nilai yg muncul adalah 0-65335 , dimana tiap angka mewakili :

tick dari TCNT = 1 / (frekuensi xtal / prescaler) = prescaler / frek xtal

Code:
/* ====================

ICP TEST

ATTINY2313

ahocool@gmail.com

www.aisi555.com

=====================*/



#define F_CPU 4000000UL //frek xtal

#include <avr/io.h>

#include <avr/interrupt.h>

#include <string.h>

#include <util/delay.h>

#include "lcd.h" //baca dulu tutorial menulis di LCD



//variabel tulisan

char text1[]= "   LEBAR PULSA";

char text2[]= "     START      ";

char clear[]= "                ";



//fungsi sederhana untuk merubah angka ke ASCII

void reverse(char s[]) 

{ 

   int c, i, j; 

    

   for (i = 0, j = strlen(s)-1; i < j; i++, j--){ 

      c = s[i]; 

      s[i] = s[j]; 

      s[j] = c; 

   } 

} 

void itoa(uint16_t n, char s[]) 

{ 

   uint16_t i, sign; 

    

   if ((sign = n) < 0) // record sign 

      n = -n;         // make n positive 

   i = 0; 

   do {   // generate digits in reverse order 

      s[i++] = n % 10 + '0'; // get next digit 

   } while ((n /= 10) > 0); // delete it 

   if (sign < 0) 

      s[i++] = '-'; 

   s[i] = '\0'; // add null terminator for string 

   reverse(s); 

}  



//tulis menulis di LCD , kreasi sendiri oprekan pfleury library

void tulis(uint8_t pos,uint8_t posx,uint8_t posy,uint16_t tulisan)



{ 

char dum;



if(pos == 1) lcd_gotoxy(posx,posy);

itoa(tulisan,&dum);

lcd_puts(&dum);



}



//saat capture terjadi

ISR(TIMER1_CAPT_vect) 

{ 

   

   uint16_t capture;

   capture = ICR1; //pindahkan nilai hasil capture

   lcd_gotoxy(0,1);

   lcd_puts(clear);

   tulis(1,0,1,capture);  //hasil capture BCD tulis di LCD



//yang dibawah ini gunakan jika ingin menampilkan detik sebenarnya

//hilangkan yg diatas dan buka blok yg dibawah jika mau

/*    tulis(0,1,1,(capture / 62500) ); 

  lcd_putc(',');

   tulis(0,6,1,(capture % 62500) ); 

   lcd_puts(" detik");

*/

}



//pendeteksi edge logic yang lainnya 

SIGNAL (SIG_INT0)

{



 TIFR |= (1<<ICF1); //clear interrupt-flag

 TCNT1=0;

 lcd_gotoxy(0,1);

 lcd_puts(text2);

}



int main(void)

{



//PIN OUTPUT ke LCD    , liat skematik

DDRD  |= (1<<PD4)|(1<<PD5)|(1<<PD3); 

DDRB  |= (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3);



//Input tombol paralel di ICP dan INT0

  

//yang ini menyatakan kalau INT0 akan mendeteksi ketika pulsa turun



   MCUCR |= (1<<ISC01) ; // faling edge

   GIMSK |= (1<<INT0);



//yang ini menyatakan kalau ICP akan mendeteksi ketika pulsa naik  

//silahkan baca di datasheet ..lengkap broo

 

   TIMSK |=(1<<ICIE1); //enable input capture interrupt 

   TCCR1B |=(1<<ICNC1)|(1<<ICES1)|(1<<CS11)|(1<<CS10); 



//Noise canceller, with 64 prescaler , rising edge icp



 sei();//hidupkan interupt



lcd_init(LCD_DISP_ON);

lcd_gotoxy(0,0);

lcd_puts(text1);



while(1)



{

}



return 0;

}




Mudah bukan ? selanjutnya penjelasan diatas dapat digunakan ke applikasi penghitung frekuensi, phase sinyal dan  membaca ranging dari sensor pengukur jarak ultrasonic seperti PING)))





Share:

Senin, 04 Maret 2013

Timer dan Counter Pada Microcontroller AVR


- COUNTER/TIMER , apaan sih ? 

Adalah fasilitas di microcontroller untuk melakukan counter/perhitungan tanpa perlu menambahkan code di looping main program ( auto), sehingga nilai dari counter ( BIASANYA register TCNT) dapat di olah/manfaatkan sewaktu2


- JENIS COUNTER APA AJA ?

Secara umum Counter /Timer terdiri dari:

- Timer Biasa (8 bit & 16 bit)
- Clear Timer on Compare (CTC)
- Overflow Timer
- Output Compare 
- PWM timer ( bahasan tersendiri)

Kita bahas yang paling sering digunakan timer biasa dan timer CTC.


- Counter 8 bit & 16 Bit

Jadi ingat, 8 bit itu maximum nilai yg didapat 0 - 255, sedangkan 16 bit = 0 - 65535 , jadi berbeda di range nilai Counternya.

Semisal kita pakai IC attiny2313 dengan clock default 1MHZ, jadi jika kita dapat ambil matematika sederhana :


resolusi = 1/input clock = 1/1Mhz = 1 micro second


Jika kita inisialisasi counter dengan Full Speed , clock = input frek oscillator (1 Mhz),  dan digunakan 16 bit / counter 1 TCCR1B|=(1<<CS10), maka jika kita ingin menghidupkan suatu led di PortD dalam selang 1 detik,  kita tunggu nilai Counter(TCNT1) = 1000000;

wah....kelebihan ! Ingat..nilai TCNT1 max= 65535, jadi kita perlu membagi counter dengan variabel yg lain, semisal kita pake variable a; Jadi ketika TCTN1 = 10000; Lalu reset TCTN1=0 ; a++; (ditambah), berulang seterusnya sampe nilai a= 100; maka LED di PORTD dihidupkan/toogle. Berikut scriptnya :

Code:
#include <avr/io.h> 

int main (void) 
{ 
   DDRD |= (1 << PD0); // Set LED di portD0 

   TCCR1B |= (1 << CS10); // Set up counter dengan full speed 

int a;  variable

a=0;  //nilai awal dari variable
  
 while (1) 
   { 

   if(TCNT1 == 10000) 
      { a++;
         TCNT1=0;
      }

   if(a == 100)
     { 
     PORTD ^= (1 << PD0); // Toggle the LED 
     a=0;
     }

   } 
}


- PRESCALER 

Jika di pembahasan sebelumnya, kita menggunakan variabel sebagai pembagi counter yg berlebih, AVR memberikan suatu solusi dengan melakukan pembagian clock menjadi faktor 1/8, 1/64, 1/256, dan 1/1024

Dengan Prescaler ada pembagian resolusi  ( timer penambahan counter) yang  akan menjadi berkurang :

1(full speed) = 1 micro second
1/8 = 8 micro second
1/64 = 64 us
1/256= 256 us
1/1024=1024us

Nah...kita sekarang bisa membagi clock sesuai keinginan, dan menyederhanakan perhitungan

Semisal kita ingin mendelay LED 1 detik, dengan clock 1Mhz  maka kita coba dengan  prescale 1/8,  untuk mencari 1 detik nilai TCNT1 = 125000, masih lewat, prescale 1/64 maka nilai TCNT1 = 15625 ...nahh nilainya ga lewat dari batas 16 bit (65535) ....ketemu dehh....jadi kita sederhanakan script sebelumnya menjadi :

Code:
#define F_CPU 1000000UL //clock dari avr
#include <avr/io.h> 




int main (void) 

{ 

   DDRD |= (1 << PD0); // Set LED di portD0 
   TCCR1B |= (1 << CS11); // Set up counter dengan prescale 64
   //Baca datasheet untuk mencari konfigurasi prescaler yg laen



 while (1) 

   { 



   if(TCNT1 == 15624) 
 // nilai max 1 detik, perhitungan mulai 0 maka nilai dikurangi 1 dari 15625

   {
      PORTD ^= (1 << PD0); // Toggle the LED 
     TCNT1=0;
    }



   } 

}


- CLEAR TIME ON COMPARE + INTERUPT

selanjutnya AVR memberikan failitas CTC, yaitu kita menentukan nilai maximum dari TCNT1 dan secara otomatis akan mengclear nilai TCNT1. Nilai max dari TCNT1 diberikan melalui register OCR1A

setiap kali TCNT1 = OCR1A akan terjadi trigger interupt CTC, sehingga dapat dimanfaatkan untuk mentriger suatu output. codenya akan menjadi seperti ini


Code:
#define F_CPU 1000000UL //clock dari avr
#include <avr/io.h> 
#include <avr/interrupt.h>

ISR(TIMER1_COMPA_vect) //vector interupt compare

{ 

     PORTD ^= (1 << PD0); // Toggle the LED 

}

int main (void) 

{ 

   DDRD |= (1 << PD0); // Set LED di portD0 
   
   TCCR1B |= (1 << CS11); // Set up counter dengan prescale 64
   //Baca datasheet untuk mencari konfigurasi prescaler yg laen
   TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode       
   TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
   OCR1A = 15624; // nilai atas dari TCNT1, untuk perhitungan 1 detik

sei();   //hidupkan interupt


 while (1) 

   { 

    }

}


...mudah bukan ? atau makin pusing ?

Untuk counter dengan nilai frekuensi clock / XTAL lainnya dapat menggunakan rumus matematika sederhana untuk menetukan OCR1A 


OCR1A = [(Frekuensi AVR / Prescale) / frekuensi yg diinginkan ] - 1

atau

OCR1A = [(Frekuensi AVR / Prescale) * Periode yg di inginkan ] - 1


*) catatan : nilai prescale = 1,8,64,256,1024  bukan 1/prescale , untuk mempermudah saja


SELAMAT MENCOBA
Share:

Jumat, 08 Februari 2013

Pejelasan Mengenai Fusebit dari AVR

external-osc.jpg (527×554)


Ketika IC atau chip microcontroller-AVR keluar dari pabrik dapat dikatakan bahwa chip tersebut memiliki kondisi default. Umumnya produsen mensetting clock dari AVR bersumber dari oscillator R-C internal yang bernilai 1MHZ. Bagaimana jika ingin merubah menggunakan sumber clock yang lain? bagamana jika ingin mematikan fungsi dari JTAG dan sebagainya? Istilah FUSEBIT akan menjadi barang yang harus diketahui.

Fusebit pada umumnya merupakan bit yang disetting untuk menentukan fungsi-fungsi dari pin , clock dan fasilitas khusus. Seperti pada attiny2313 terdapat 3 buah fusebit yang terdiri dari  High Byte, Low Byte dan extended byte.



Fusebit khusus untuk Attiny2313 , ic microcontroller avr jenis lain mempunyai fusebit yg berbeda pula


Jangan dibingungkan dengan fusebit, karena beberapa fungsi nya dapat dibaca dari datasheet seperti diatas. Perubahan fusebit yang paling umum dilakukan adalah ketika ingin merubah sumber clock menjadi clock external, maka fusebitnya dirubah sesuai tabel berikut:


Masih kesusahan? Masuk aja ke menu programing fuse pada AVR studio dan kemudian fusebitnya dapat dirubah sesuai keinginan atau jika menggunakan programmer/downloader berbasis AVRDUDE dapat menggunakan fasilitas fusebit  manual di http://www.engbedded.com/fusecalc.

Ingat untuk berhati-hati dalam merubah fusebit karena ada beberapa fungsi yang tidak dapat diubah kembali seperti bit SPIEN (SPI enable). Untuk itu agar memperhatikan perubahan yg dilakukan secara baik-baik, karena jika kesalahan merubah sumber clock masih bisa dikerjakan dengan menyuntikkan sinyal generator ke kaki input xtal 0 dan kemudian merubah fusbit yang diinginkan. Jika tidak bisa maka diperlukan programmer parallel high voltage (HVPP) seperti ALL-7, ALL 10 dsb. Bersiaplah membuat IC AVR menjadi gantungan kunci jika salah menentukan fusebit.





Share:

Kamis, 17 Januari 2013

BERMAIN DENGAN TV PART #3 - OSD (Composite Video Text Overlay) dengan Attiny2313




Text Overlay atau On Screen Display (OSD) merupakan fitur yang umum dijumpai pada televisi modern. Gambar composite (AV in) dapat ditumpuk dengan text seperti text berjalan (scroll text / crawler) , logo , jam dan berbagai macam sesuai keinginan. Bagaimana cara menimpa gambar video dengan text akan kita bahas disini, dan diharapkan membaca penjelasan mengenai dasar-dasar bermain televisi menggunakan microcontroller disini:  PART#1  PART#2  JAM TV



Courtesy of  VIENA WIRELESS SOCIETY 


Gunakan rangkaian yg terhubung dengan AIN saja, yg di dekat TX RX diabaikan saja


Pada web aslinya yang digunakan ic microcontroller  ATMega8 ,prinsip utamanya memanfaatkan analog komparator untuk mendeteksi sinkronisasi vertikal & horisontal dari sinyal input video composit (semisal dari kamera atau dvd).


Pada script di web asli dijelaskan bahwa yg digunakan video NTSC..karena di indonesia menggunakan PAL maka saya ubah script menjadi PAL dan menggunakan ATTINY



dari gambar ic attiny 2313 kita akan menggunakan pin AIN0 dan AIN1 serta pin MOSI, dan beberapa pin digunakan sebagai tombol seperlunya, rangkai sesuai gambar asli. gunakan nilai komponen sesuai catatan dan dengan bereksperimen maka akan didapat efek2 yg tidak diduga seperti warna text, warna latar dsb.


untuk itu kita bahas script satu persatu ...


>>> Header <<



#define F_CPU 20000000UL //xtal 20MHz

#include <avr/io.h>

#include <util/delay.h>

#include <avr/interrupt.h>

#include <avr/pgmspace.h>

#include <avr/sleep.h>





#define FONTHEIGHT 12 //panjang text



//rumus dan variabel syncronisasi

#define HSYNC PORTB=0;

#define GREY PORTB=0x80;

#define COL(r) textnya=word[r][fontline];



static uint8_t fontline = 0;

static uint8_t fontzoom = 0;

static uint16_t rasterline=0;



// ARRAY untuk tulisan nomer 0,1,2 dst



const unsigned char font[12][FONTHEIGHT] PROGMEM = { 

   {

 0b00000000,

 0b01111100,

 0b11000110,

 0b11001110,

 0b11011110,

 0b11010110,

 0b11110110,

 0b11100110,

 0b11000110,

 0b01111100,

 0b00000000,

 0b00000000,

 },

 {

 0b00000000,

 0b00010000,

 0b00110000,

 0b11110000,

 0b00110000,

 0b00110000,

 0b00110000,

 0b00110000,

 0b00110000,

 0b11111100,

 0b00000000,

 0b00000000,

 },

 {

 0b00000000,

 0b01111000,

 0b11001100,

 0b11001100,

 0b00001100,

 0b00011000,

 0b00110000,

 0b01100000,

 0b11001100,

 0b11111100,

 0b00000000,

 0b00000000,

 },

 {

 0b00000000,

 0b01111000,

 0b11001100,

 0b00001100,

 0b00001100,

 0b00111000,

 0b00001100,

 0b00001100,

 0b11001100,

 0b01111000,

 0b00000000,

 0b00000000,

 },

 {

 0b00000000,

 0b00001100,

 0b00011100,

 0b00111100,

 0b01101100,

 0b11001100,

 0b11111110,

 0b00001100,

 0b00001100,

 0b00011110,

 0b00000000,

 0b00000000,

 },

 {

 0b00000000,

 0b11111100,

 0b11000000,

 0b11000000,

 0b11000000,

 0b11111000,

 0b00001100,

 0b00001100,

 0b11001100,

 0b01111000,

 0b00000000,

 0b00000000,

 },

 {

 0b00000000,

 0b00111000,

 0b01100000,

 0b11000000,

 0b11000000,

 0b11111000,

 0b11001100,

 0b11001100,

 0b11001100,

 0b01111000,

 0b00000000,

 0b00000000,

 },

 {

 0b00000000,

 0b11111110,

 0b11000110,

 0b11000110,

 0b00000110,

 0b00001100,

 0b00011000,

 0b00110000,

 0b00110000,

 0b00110000,

 0b00000000,

 0b00000000,

 },

 {

 0b00000000,

 0b01111000,

 0b11001100,

 0b11001100,

 0b11101100,

 0b01111000,

 0b11011100,

 0b11001100,

 0b11001100,

 0b01111000,

 0b00000000,

 0b00000000,

 },

 {

 0b00000000,

 0b01111000,

 0b11001100,

 0b11001100,

 0b11001100,

 0b01111100,

 0b00011000,

 0b00011000,

 0b00110000,

 0b01110000,

 0b00000000,

 0b00000000,

 },

 {

 0b00000000,

 0b00000000,

 0b00000000,

 0b00110000,

 0b00110000,

 0b00000000,

 0b00000000,

 0b00110000,

 0b00110000,

 0b00000000,

 0b00000000,

 0b00000000,

 },

 {

 0b00000000,

 0b00000000,

 0b00000000,

 0b00000000,

 0b00000000,

 0b00000000,

 0b00000000,

 0b00000000,

 0b00000000,

 0b00000000,

 0b00000000,

 0b00000000,

 }};





//variabel pelengkap



uint8_t word[7][12];

int y;

uint8_t jam,menit,detik,textnya,tick;







>>> timer untuk horisontal sync PAL (64us) <<


void timer_init(void){



 TCCR1B |= (1<<WGM12);

 TIMSK |= (1<<OCIE1A);

 OCR1A = 1280; //64*16;

 TCCR1B |= (1<<CS10);



}





>> geser2 bit untuk menampilkan angka dari Array <<



void geser(void)

{ 

PORTB = (textnya  & 0x80) +0x8  ;

textnya <<=1;

PORTB = (textnya  & 0x80) +0x8 ;

textnya <<=1;

PORTB = (textnya  & 0x80)  +0x8 ;

textnya <<=1;

PORTB = (textnya  & 0x80)  +0x8 ;

textnya <<=1;

PORTB = (textnya  & 0x80)  +0x8 ;

textnya <<=1;

PORTB = (textnya  & 0x80)   +0x8;

textnya <<=1;

PORTB = (textnya  & 0x80)   +0x8 ;

textnya <<=1;

PORTB = (textnya  & 0x80)   +0x8 ;



}





>> proses tulis tiap 1us dari frame horisontal 64us <<




void tulis(void){



//31 & 43 adalah batas tinggi karakter 12 scan/rasterline/vsync

//y adalah posisi rasterline(Vsync) yg sedang ditulis

 if( rasterline > (31+y) && rasterline <= (43+y) ) {

  _delay_us(8);

    COL(0);

    geser();

    COL(1);

    geser();

    COL(2);

    geser();

    COL(3);

    geser();

    COL(4);

    geser();

    COL(2);

    geser();

    COL(5);

    geser();

    COL(6);

    geser();

       PORTB=0;

      _delay_us(1);

  fontline++; //pindah ke array selanjutnya

 } 

//jika tidak menulis 

   else { 

  _delay_us(8);

   fontline = 0;

  fontzoom=0;

   }



// yang ini batas scannline trus bisa sisipkan proses

//      memasukkan data ke memory 

//  sesuaikan karena kaskus merubah text &word; (hilangkan ' ; ') 

 if( rasterline > 311 )

  { memcpy_P(&word;[0],&font;[jam/10],12);

   memcpy_P(&word;[1],&font;[jam],12);

   memcpy_P(&word;[2],&font;[10],12);

   memcpy_P(&word;[3],&font;[menit/10],12);

   memcpy_P(&word;[4],&font;[menit],12);

   memcpy_P(&word;[5],&font;[detik/10],12);

   memcpy_P(&word;[6],&font;[detik],12);

 

      }

}



// interupt 64us 

ISR (TIMER1_COMPA_vect) {



rasterline = 0;



}



>> comparator untuk mendeteksi awal Vsync dan Hsync <<



SIGNAL(SIG_COMPARATOR)



{ //trik mendeteksi hsync dan vsync dengan melihat lama blanking



 TCNT1=0; // reset timer

 while(TCNT1<70); // wait 5us to see if H or V sync



 if(!((ACSR>>ACO)&1)) { // its an H sync

  TCNT1=0; // reset timer

  rasterline++;

  tulis();

 }

 else { // this a V sync

  rasterline=0;

    

//sekalian aja ditambah timer untuk nambah detik

  tick++;

    if(tick >= 200){

    tick=0;

       detik++;

    if(detik==60){

      menit++;

   detik=0;}



       if(menit==60){

    menit=0;

    jam++;}

    if (jam==24) jam=0;

  }

 }

}  





>> Tombol untuk ubah jam dan geser2 posisi jam <<




void tombol(void)

{

if(bit_is_clear(PIND, PIND3)) 

{

jam++;



if(jam == 24) jam=0;



detik=0;

_delay_ms(200);

}



else if(bit_is_clear(PIND, PIND4))

{

menit++;  



if(menit == 60) menit =0;





detik=0;

_delay_ms(200);

}



else if(bit_is_clear(PIND, PIND5)) //naik

{

y-=3;



if(y<1) y=1;



_delay_ms(200);

}



else if(bit_is_clear(PIND, PIND6)) //turun

{

y+=3;



if(y>300) y=300;



_delay_ms(200);

}






>> main program<<




int main() {

tick=0;

jam=22;

menit=19;

detik=44;

rasterline=0;

y=0; //variable posisi text

    



    ACSR = (1<<ACIE)|(1<<ACIS0)|(1<<ACIS1);  //analog comparator

    DDRD &=~(1<<PD3) & ~(1<<PD4)&~(1<<PD5) & ~(1<<PD6) ; //tombol

    

  // data text dan MISO, PB0 pada web asli dirubah jadi PB3 attiny 

    DDRB |= (1<<PB7)|(1<<PB3);

  



        timer_init(); //idupin timer

    

 set_sleep_mode(SLEEP_MODE_IDLE); //menghemat tenaga



 sei();



 for( ;; )tombol();

}





rangkaian ini cocok buat nambahin text ke kamera CCTV murah yg ga ada textnya, jadi bisa ditambahin jam atau text penanda nomer kamera




SELAMAT MENCOBA
Share:

Kamis, 03 Januari 2013

Interrupt - solusi eksekusi perintah real time

interrupt.jpg (537×694)


Secara harfiah interrupt dapat diartikan sebagai "pemecah" atau "penyelaan" dari suatu keadaan yang sedang berlangsung. Ya begitulah interrupt dapat diartikan seperti halnya interupsi pada sidang-sidang dewan di senayan. Jika di tarik kedalam proses suatu microcontroller maka interrupt merupakan suatu keadaan "menyela" dari program utama untuk masuk kedalam proses yg dikendalikan oleh interrupt itu sendiri. Ingat bahwa proses kerja dari microprosessor atau microcontroller adalah melakukan perintah sesuai script yang diberikan dari atas ke bawah. Jadi perhatikan proses membaca tombol berikut ini seperti yang dibahas pada project dasar input - output :


int main(void)

{

DDRB |= (1<<PB5)|(1<<PB0) ; //inisialisasi port B#5 & B#0 sebagai output
DDRB &= ~(1<<PB1) & ~(1<<PB2) ; //inisialisasi port B#1 & B#2 sebagai input

PORTB |= (1<<PB5) | (1<<PB0); //kita SET LED NYALA semuanya

while(1)
{

// membaca jika port input B#1 di set atau HIGH 
//  atau 1 ( posisi awal di ground /LOW )

if (bit_is_set(PINB, PINB1)) 
{
PORTB ^=(1<<PB5) ; //TOGGLE LED di PORT B#1
_delay_ms(500);

}

// membaca jika port input B#2 di set atau HIGH 
// atau 1 ( posisi awal di ground/LOW )

if (bit_is_set(PINB, PINB2)) 
{
PORTB ^=(1<<PB0) ; //TOGGLE LED di PORT B#2
_delay_ms(500);
 
}
}

return 0;
}

Script diatas merupakan perintah pembacaan tombol yang terdapat pada PORT B1 dan B2 yang akan mengendalikan nyala dari 2 buah LED pada PORT B0 dan B5. Perintah pembacaan tombol ini merupakan cara 'pooling' dimana terpadat proses IF yang menunggu sampi BIT dari tombol berubah dari 0 ke 1. Bagaimana jika scipt nya panjang semisal ada proses perhitungan yang panjang ? Yang akan terjadi adalah proses pembacaan tombol harus menunggu beberapa waktu sampai posisi akumulator dari processor berada tepat pada proses IF.

Solusi dari permasalahan pooling adalah dengan menciptakan suatu table interupt yang memiliki prioritas tertentu dan tentunya prioritasnya lebih dari proses pooling biasa. Interupt ada beberapa jenis tergantung fasilitas yang disediakan oleh microprocessor atau microcontroller. Interupt dapat di kendalikan oleh proses luar (input external) maupun internal. External interupt umumnya merupakan proses perubahan logika(logic) dari pin input (biasanya pin ditentukan sebagai pin INT). Jenis perubahan logika ini terdiri dari :

-  AKTIF HIGH  : interupt akan dieksekusi ketika pin input mendapat logika "1"
-  AKTIF LOW   : interupt akan dieksekusi ketika pin input mendapat logika "0"
-  RISING EDGE  : interupt akan dieksekusi ketika pin input berubah dari logika "0" ke logika "1"
-  FALLING EDGE  : interupt akan dieksekusi ketika pin input berubah dari logika "1" menuju logika "0"

Ada 2 buah istilah baru yaitu rising dan falling edge yang lebih menekankan ke perubahan logika dari input interupt. Hal ini lebih bermafaat dikarenakan umumnya proses interupt dieksekusi sekali saja. Semisal kita akan menunggu interupt dari suatu pulsa untuk menambah atau mengurangi suatu nilai variabel ,  sehingga hanya perubahan yang dikehendaki saja akan menambah nilai tersebut dan hebatnya akan ditambah hanya sekali saja dalam proses interuptnya.

Interrupt secara internal pada umumnya di trigger oleh suatu kondisi dari hasil eksekusi program dan contoh yang paling sering kita temui adalah interupt yang di trigger oleh proses timer.

Untuk ATTINY 2313 proses interrupt external dikendalikan oleh 2 buah INT0 dan INT1 serta interupt lainnya berupa Pin Change Interupt yang dapat dipasang diantara PINB 0-7. Register atau memory yang merupakan memory kontrol dari interupt attiny seperti berikut :
















Contoh script dari  inisialisasi interupt external pada attiny2313 adalah sebagai berikut :


int main(void)
{

   // aktifkan interrupt 0 dan 1
   GIMSK |= (1<<INT0) |(1<<INT1);
   
   // interrupt rising EDGE ( perubahan 0 ke 1) 
   MCUCR |= (1<<ISC01) | (1<<ISC00) |(1<<ISC11) | (1<<ISC10); 

   
sei();   // perintah bahwa interupt aktif / enable

while(1)

{

//looping tak berhingga

}

return 0;

}


Sedangkan perintah (susunan script) ketika interupt mendapat trigger dan berada pada posisi aktif ditempatkan dengan posisi seperti berikut :




SIGNAL (SIG_INT0)
{

// masukkan perintah eksekusi interupt di pin INT0  
    
}

SIGNAL (SIG_INT1)
{

// masukkan perintah eksekusi interupt di pin INT1  
    
}



Berikut akan ditampilkan contoh interupt internal yang ditrigger oleh timer. Proses timer dengan interrupt sangatlah akurat sehingga cocok dipakai untuk timer atau jam digital.




void init_jam(void)
{
   TCCR1B |= (1 << WGM12); // konfihurasi timer 1 mode CTC 
   TIMSK |= (1 << OCIE1A); // Enable CTC interrupt 
   OCR1A  = 31249; //nilai timer 1 detik dari CTC A 
   TCCR1B |= (1 << CS11)|(1 << CS10); // Start timer Fcpu/64
   TCNT1 = 0;
   
   sei();
}


ISR(TIMER1_COMPA_vect) // interupt internal dari timer akurat 1 detik

{ 

detik++;

if(detik >= 60)

{  
   detik=0;
   menit++;



}

if(menit >= 60)

     { menit=0; 
       jam++;
     }

if (jam >= 24) jam = 0 ;




}






SELAMAT MENCOBA
Share:

Senin, 31 Desember 2012

[Part 3] Belajar dasar bahasa GCC - Kondisi Percabangan dan Pengulangan


Setiap bahasa pemrograman memiliki suatu proses yang dinamakan "conditonal statement". Yang dimaksud sebagai contional statement adalah percabangan dimana terdapat beberapa pilihan jalannya program sesuai dengan kondisi yang terjadi.
















Sementara itu pengulangan atau looping adalah proses pengulangan dari suatu perintah dimana bisa diberikan sebuah atau lebih kondisi yang menyebabkan pengulangan atau looping akan berhenti. Secara flowchart dapat digambarkan seperti berikut:

for.gif (383×402)


Kondisi Percabangan


Dalam bahasa C terdapat beberapa kondisi percabangan yang sering kita temui. Kita akan bahas satu persatu dengan contoh-contoh yang sering dipakai pada project di blog ini.

IF



if(kondisi == 1)
{
  //script 1

}

else if(kondisi == 3 || kondisi == 4)
{
  //script 2

}
 else if(kondisi <= 10 && kondisi >5)
{
   //script 3

}

else
 {   

 //script kondisi terakhir

}



Ada yang perlu diperhatikan pada percabangan yaitu selalu ada kondisi pembanding. Kondisi pembanding yang terdapat pada bahasa C adalah:


Pembanding sederhana:

==         Sama dengan

!=         Tidak sama dengan

<           Kurang dari

>           Lebih besar dari

<=         Kurang dari atau sama dengan

>=         Lebih besar dari atau sama dengan


Pembanding logika :

Hal ini dapat menggabungkan pembanding untuk mendapatkan logika yang lebih kompleks

&&         Dan (and)

||             Atau (or)



secara umum proses pencabangan IF .. ELSE  atau   IF .... ELSE IF ....ELSE membandingkan satu kondisi dengan kondisi yang lain , dan dapat juga menggabungkannya dengan tambahan pembanding logika. Untuk pencabangan IF .... ELSE IF ...dst .. yang terdiri dari banyak kondisi ELSE IF maka pencabangan akan menjalankan perintah pada kondisi yang benar kemudian mengabaikan yang lainnya. Perlu diingat jika eksekusi dari pencabangan mengikuti urutan atas ke bawah sehingga penempatan dari statement kondisi sangat penting.


SWITCH

Pola pencabangan yang lain adalah metode switch case seperti pada contoh berikut :


ISR(USART_RX_vect)

{ 

 char databyte;

 databyte = UDR; 



     switch (databyte)       

  {
     

    case 0xD : {  

             kirim_text(menu) ;

              break; }

    case '1' : {  

                     PORTB ^=(1<<0);

                     break; }

    case '2' : {

            
             PORTB ^=(1<<1);


                break; }

    default :{   
              PORTB |=(1<<1);
              break;}
  }  

}

Ketika mendefinisikan ekspresi kondisi yang hasilnya akan mengarah pada pelaksanaan program yang spesifik dan umumnya berjumlah banyak maka dapat menggunakan "switch".  Hasil yang berbeda tercantum dalam tiap tubuh "case" dari pernyataan switch dan setiap case memiliki eksekusi sendiri. Tubuh pernyataan switch dibatasi dari pembukaan ke penutupan kurung  kurawal: "{"   "}" dan jika memerlukan eksekusi tunggal maka diberikan perintah terminasi "break".  Sintaks dari kondisi switch seperti berikut :


switch(Expression)
{
    case Choice1:
        Statement1;
    case Choice2:
        Statement2;
    case Choice-n:
        Statement-n;
}






PENGULANGAN / LOOPING 


Pengulangan membantu program untuk menghemat penulisan pada urutan syntaxnya dengan memberikan kondisi keluar tertentu. Loop yang paling dasar adalah for(;;), yang memiliki 3 buah isian didalamnya berupa "kondisi awal" ; "kondisi keluar" ; "proses update" ; . Jika for tanpa isian seperti contoh for ( ; ; ) maka akan menciptakan looping tidak berhingga yang tak akan pernah selesai.


void proses (void) 

{
int a;


for(a=0; a < 10 ; a++) 
   {
      PORTB = a;
      PORTC = (10 - a) ;
   }

}


script diatas memiliki penjelasan bahwa nilia a berawal pada angka 0, akan diulang terus bila nilai a lebih kecil dari 10  sedangkan kondisi update nilai a ditambah 1 tiap pengulangan. Jadi nilai a bermula dari 0 diteruskan menuju 1,2,3,4,5,6,7,8,9  kemudian pada saat nilai a mencapai nilai 10 maka loop akan  selesai.


Jenis looping yang lain memiliki pola yang sama yaitu while(condition) {  }  dan do { } while(condition). Kondisi keluar dari loop ditentukan pada awal atau akhir namun memiliki pola yang sama yaitu kondisi awal dan akhir harus dirubah berdasarkan pengulangan atau kondisi luar ,seperti contoh berikut :




int a;
a=0;
while(a < 10)
{
  PORTB=a;
  PORTC=(10-a);

   a++;
}
a=0;


do
{
PORTB=a;
a++;
}
while(a <10)


while(bit_is_set(PIND, PIND3) )
{

PORTB|=_BV(PB3);
 
}


Ingat jika kondisi dari variabel harus di inisialisasikan terlebih dahulu sehingga tidak menimbulkan kesalahan dan warning saat dicompile. Contoh yang terakhir menunjukkan bahwa kondisi looping akan berhenti jika ada perubahan nilai dari luar , dalam hal ini nilai logika biner dari port microcontroller PIND3 .


SELAMAT BELAJAR


Share:

Kontak Penulis



12179018.png (60×60)
+628155737755

Mail : ahocool@gmail.com

Site View

Categories

555 (8) 7 segmen (3) adc (4) amplifier (2) analog (19) android (12) antares (9) arduino (26) artikel (11) attiny (3) attiny2313 (19) audio (5) baterai (5) blog (1) bluetooth (1) chatgpt (2) cmos (2) crypto (2) dasar (46) digital (11) dimmer (5) display (3) esp8266 (26) euro2020 (13) gcc (1) iklan (1) infrared (2) Input Output (3) iot (60) jam (7) jualan (12) kereta api (1) keyboard (1) keypad (3) kios pulsa (2) kit (6) komponen (17) komputer (3) komunikasi (1) kontrol (8) lain-lain (8) lcd (2) led (14) led matrix (6) line tracer (1) lm35 (1) lora (8) MATV (1) memory (1) metal detector (4) microcontroller (70) micropython (6) mikrokontroler (1) mikrokontroller (14) mikrotik (5) modbus (9) mqtt (3) ninmedia (5) ntp (1) paket belajar (19) palang pintu otomatis (1) parabola (88) pcb (2) power (1) praktek (2) project (33) proyek (1) python (7) radio (28) raspberry pi (4) remote (1) revisi (1) rfid (1) robot (1) rpm (2) rs232 (1) script break down (3) sdcard (3) sensor (2) 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 (167) television (28) transistor (2) troubleshoot (3) tulisan (93) tutorial (108) tv digital (6) tvri (2) vu meter (2) vumeter (2) wav player (3) wayang (1) wifi (3)

Arsip Blog

Diskusi


kaskus
Forum Hobby Elektronika