Pada proyek ini digunakan 2 shift registers yang menghubungkan baris dan kolom dari dot matrix display. Kemudian kita akan tampilkan objek sederhana yang beranimasi. Tujuan dari proyek ini adalah agar kita paham cara kerja dot matrix display dan pengenalan konsep multiplexing (skill yang cukup penting)
Komponen
2 × 74HC595 Shift Register IC
8 × Current-Limiting Resistors (510W)
8×8 DotMatrix Display (C-)
Bypass (Decoupling) Capacitor
Skema
Pada proyek ini , LED 8 x 8 memiliki skema seperti pada Gambar-1 diatas, dimana urutan rows dan columns (anoda dan katoda) tidak berurutan. Dengan menggunakan table-1 dan skema pada gambar-1, dapat kita lihat pin 15 pada shift register harus dihubungkan dengan row 1 dan pin 9 pada display. Dan seterusnya seperti yang ditunjukan pada table-1.
Resistors dipasang antara shift register dan display. Perhatikan saat memilih nilai resistor yang akan digunakan, harus sesuai dengan display yang digunakan.
Perhatikan datasheet dari display yang Anda gunakan. Gunakan table-1 dan gambar-1 sebagai referensi Anda dalam menghubungkan rangkaian pada proyek Anda.
Sebelum memulai membuat sketch, ada baiknya memahami cara kerja LED dot matrix. Silakan lihat di artikel LED Dot Matrix. Dengan memahami prinsip dasar dari LED dot matrix, akan mempermudah kita dalam memahami logika sketch dibawah.
Sketch
#include <TimerOne.h> // Install the library first
int latchPin = 8; //Pin connected to Pin 12 of 74HC595 (Latch)
int clockPin = 12; //Pin connected to Pin 11 of 74HC595 (Clock)
int dataPin = 11; //Pin connected to Pin 14 of 74HC595 (Data)
byte led[8]; // 8 element unsigned integer array to hold the sprite
void setup() {
// set the 3 digital pins to outputs
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
// Load the binary representation of the image into the array
led[0] = B11111111;
led[1] = B10000001;
led[2] = B10111101;
led[3] = B10100101;
led[4] = B10100101;
led[5] = B10111101;
led[6] = B10000001;
led[7] = B11111111;
// set a timer of length 10000 microseconds (1/100th of a second)
// and attach the screenUpdate function to the interrupt timer
Timer1.initialize(10000);
Timer1.attachInterrupt(screenUpdate);
}
// invert each row of the binary image and wait 1/4 second
void loop() {
for (int i=0; i<8; i++) {
led[i]= ~led[i];
}
delay (250);
}
// Display the image
void screenUpdate() {
byte row = B10000000; // row 1
for (byte k = 0; k < 8; k++) {
// LED array
shiftOut(dataPin, clockPin, LSBFIRST, led[k] );
// row binary number (active low)
shiftOut(dataPin, clockPin, LSBFIRST, ~row);
// latch low to high to output data
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
// bitshift right
row = row >> 1;
}
byte row = B10000000; // row 1
for (byte k = 0; k < 8; k++) {
// Turn all rows off until next interrupt
shiftOut(dataPin, clockPin, LSBFIRST, 255);
shiftOut(dataPin, clockPin, LSBFIRST, row);
// latch low to high to output data
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
row = row >> 1;
}
}
Pembahasan Program
Kode pada proyek ini menggunakan fitur dari ATmega chip, Hardware Timer. Berfungsi sebagai timer pada chip yang dapat digunakan untuk men-trigger sebuah event. Event ini disebut interupts, karena menyebabkan processor interupt kode yang sedang berjalan dan menjalankan fungsi (interrupt service routine (ISR)) untuk menghandle event.
Setelah selesai memproses ISR, akan kembali melanjutkan memproses program dimana terakhir di interupsi. Seperti kita sedang melakukan sesuatu, kemudian di interupsi untuk menjawab telpon, kemudian setelah selesai menerima telepon, kita kembali melanjutkan pekerjaan tadi terakhir dimana kita tinggalkan. Pada proyek ini, kita akan set timer untuk mengenerate event setiap 10000 microseconds.
Untuk itu kita memerlukan library untuk mempermudah menggunakan interupt. library yang digunakan adalah TimerOne. Kita cukup memberitahu interval yang kita perlukan (dalam proyek ini 10000 mircoseconds) dan tunjuk fungsi yang akan diaktifkan setiap interupt terjadi, pada proyek ini adalah fungsi screenUpdate().
Perlu diperhatikan, Interrupt service routine harus pendek (lebih kecil dari waktu antara interrupts), bila tidak, processor tidak akan pernah kembali ke kode utama, dan lebih parah akan terjadi overflow stack.
TimerOne adalah external library, jadi kita perlu include pada kode kita. Caranya dengan menggunakan perintah berikut:
#include <TimerOne.h> // Install the library first
Selanjutnya, deklarasi variable untuk pin yang digunakan sebagai interface terhadap shift register.
int latchPin = 8; //Pin connected to Pin 12 of 74HC595 (Latch)
int clockPin = 12; //Pin connected to Pin 11 of 74HC595 (Clock)
int dataPin = 11; //Pin connected to Pin 14 of 74HC595 (Data)
Kemudian, buat array dengan tipe data byte dengan besar array 8. Array led[8] akan digunakan untuk menyimpan gambar yang akan kita tampilka pada dot matrix display.
byte led[8]; // 8 element unsigned integer array to hold the sprite
Pada setup routine, kita set latch, clock, and data pins sebagai output.
void setup() {
// set the 3 digital pins to outputs
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
Array led[8] akan kita isi dengan 8-bit binary images yang akan tampil pada setiap baris 8×8 dot matrix display:
// Load the binary representation of the image into the array
led[0] = B11111111;
led[1] = B10000001;
led[2] = B10111101;
led[3] = B10100101;
led[4] = B10100101;
led[5] = B10111101;
led[6] = B10000001;
led[7] = B11111111;
Dengan melihat array diatas, kita dapat bayangkan gambar apa yang aka tampil. 1 menunjukan dimana LED akan menyala, 0 menunjukan LED padam. Silakan bereksperimen mengubah isi array ini.
Berikutnya, Timer1 object digunakan. Pertama, inisialisasi timer dengan frekuensi dimana kita akan aktifkan, pada proyek ini setiap 10000 microseconds atau 1/100 second. Setalah inisialisasi, kita perlu hubungkan interupt fungsi mana yang akan dijalankan setiap periode waktu tercapai.
Pada proyek ini fungsi screenUpdate() akan dieksekusi setiap 1/100th second
// set a timer of length 10000 microseconds (1/100th of a second)
// and attach the screenUpdate function to the interrupt timer
Timer1.initialize(10000);
Timer1.attachInterrupt(screenUpdate);
Pada main loop, gunakan for untuk memutari setiap 8 element dari led array dan invert isinya dengan menggunakan ~ atau NOT bitwise operator. Ini akan membuat gambar negatif dari gambar asli kita.
Kemudian tunggu selama 250 milliseconds sebelum kembali ke awal loop.
// invert each row of the binary image and wait 1/4 second
void loop() {
for (int i=0; i<8; i++) {
led[i]= ~led[i];
}
delay (250);
}
Pada fungsi screenUpdate(), routine ini sangat penting karena bertanggung jawab untuk memastikan LED pada dot matrix menyala dengan tepat sesuai image yang kita inginkan (array led[8]).
Deklarasi variable row dengan tipe data byte dengan inisial value B10000000
byte row = B10000000; // row 1
Prosedur selanjutnya adalah loop led array dengan menggunakan loop for dan mengirim data ke shift registers.Dengan menggunakan operator bitwise not (~), untuk memastikan mematikan bagian kolom (mengirim tegangan ground) yang kemudian diikuti baris.
for (byte k = 0; k < 8; k++) {
// LED array
shiftOut(dataPin, clockPin, LSBFIRST, led[k] );
// row binary number (active low)
shiftOut(dataPin, clockPin, LSBFIRST, ~row);
// latch low to high to output data
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
// bitshift right
row = row >> 1;
}
Setelah shitfout baris aktif, lakukan bitshift pada row 1 bit.
row = row >> 1;
Berikutnya kita lakukan for loop yang sama, namun kali ini mengirimkan tegangan ground untuk semua row. Penting untuk dipastikan display tidak menyala terlalu lama saat menunggu ISR berikutnya untuk dijalankan, karena akan menyebabkan baris terakhir akan menyala lebih terang dari yang lainnya.
byte row = B10000000; // row 1
for (byte k = 0; k < 8; k++) {
// Turn all rows off until next interrupt
shiftOut(dataPin, clockPin, LSBFIRST, 255);
shiftOut(dataPin, clockPin, LSBFIRST, row);
// latch low to high to output data
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
row = row >> 1;
}
Related Article
Pengetahuan dasar hardware : LED dot matrix
Bitwise operator
Komponen
2 × 74HC595 Shift Register IC
8 × Current-Limiting Resistors (510W)
8×8 DotMatrix Display (C-)
Bypass (Decoupling) Capacitor
Skema
!!! Perhatian: Wiring diagram dibawah disesuaikan dengan dot matrix yang kami gunakan untuk proyek ini, yaitu mini 8x8 red dot matrix display unit. Pastikan saat Anda mengerjakan proyek ini, ada kemungkinan dot matrix yang digunakan berbeda. Perhatikan penggunaan pin pada datasheet produk dot matrix yang Anda gunakan.
Selesaikan dahulu rangkaiannya, baru hubungkan arduino dengan usb atau power. Bila rangkaian belum beres, bisa ada kemungkinan merusak komponen shift register atau dot matrix display.
Table-1. Referensi Shift Reg dengan Matrix Pin
Gambar-1. Skema Umum LED 8 x 8 dot matrix
Pada proyek ini , LED 8 x 8 memiliki skema seperti pada Gambar-1 diatas, dimana urutan rows dan columns (anoda dan katoda) tidak berurutan. Dengan menggunakan table-1 dan skema pada gambar-1, dapat kita lihat pin 15 pada shift register harus dihubungkan dengan row 1 dan pin 9 pada display. Dan seterusnya seperti yang ditunjukan pada table-1.
Resistors dipasang antara shift register dan display. Perhatikan saat memilih nilai resistor yang akan digunakan, harus sesuai dengan display yang digunakan.
Perhatikan datasheet dari display yang Anda gunakan. Gunakan table-1 dan gambar-1 sebagai referensi Anda dalam menghubungkan rangkaian pada proyek Anda.
Sebelum memulai membuat sketch, ada baiknya memahami cara kerja LED dot matrix. Silakan lihat di artikel LED Dot Matrix. Dengan memahami prinsip dasar dari LED dot matrix, akan mempermudah kita dalam memahami logika sketch dibawah.
Sketch
#include <TimerOne.h> // Install the library first
int latchPin = 8; //Pin connected to Pin 12 of 74HC595 (Latch)
int clockPin = 12; //Pin connected to Pin 11 of 74HC595 (Clock)
int dataPin = 11; //Pin connected to Pin 14 of 74HC595 (Data)
byte led[8]; // 8 element unsigned integer array to hold the sprite
void setup() {
// set the 3 digital pins to outputs
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
// Load the binary representation of the image into the array
led[0] = B11111111;
led[1] = B10000001;
led[2] = B10111101;
led[3] = B10100101;
led[4] = B10100101;
led[5] = B10111101;
led[6] = B10000001;
led[7] = B11111111;
// set a timer of length 10000 microseconds (1/100th of a second)
// and attach the screenUpdate function to the interrupt timer
Timer1.initialize(10000);
Timer1.attachInterrupt(screenUpdate);
}
// invert each row of the binary image and wait 1/4 second
void loop() {
for (int i=0; i<8; i++) {
led[i]= ~led[i];
}
delay (250);
}
// Display the image
void screenUpdate() {
byte row = B10000000; // row 1
for (byte k = 0; k < 8; k++) {
// LED array
shiftOut(dataPin, clockPin, LSBFIRST, led[k] );
// row binary number (active low)
shiftOut(dataPin, clockPin, LSBFIRST, ~row);
// latch low to high to output data
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
// bitshift right
row = row >> 1;
}
byte row = B10000000; // row 1
for (byte k = 0; k < 8; k++) {
shiftOut(dataPin, clockPin, LSBFIRST, 255);
shiftOut(dataPin, clockPin, LSBFIRST, row);
// latch low to high to output data
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
row = row >> 1;
}
}
Pembahasan Program
Kode pada proyek ini menggunakan fitur dari ATmega chip, Hardware Timer. Berfungsi sebagai timer pada chip yang dapat digunakan untuk men-trigger sebuah event. Event ini disebut interupts, karena menyebabkan processor interupt kode yang sedang berjalan dan menjalankan fungsi (interrupt service routine (ISR)) untuk menghandle event.
Setelah selesai memproses ISR, akan kembali melanjutkan memproses program dimana terakhir di interupsi. Seperti kita sedang melakukan sesuatu, kemudian di interupsi untuk menjawab telpon, kemudian setelah selesai menerima telepon, kita kembali melanjutkan pekerjaan tadi terakhir dimana kita tinggalkan. Pada proyek ini, kita akan set timer untuk mengenerate event setiap 10000 microseconds.
Untuk itu kita memerlukan library untuk mempermudah menggunakan interupt. library yang digunakan adalah TimerOne. Kita cukup memberitahu interval yang kita perlukan (dalam proyek ini 10000 mircoseconds) dan tunjuk fungsi yang akan diaktifkan setiap interupt terjadi, pada proyek ini adalah fungsi screenUpdate().
Perlu diperhatikan, Interrupt service routine harus pendek (lebih kecil dari waktu antara interrupts), bila tidak, processor tidak akan pernah kembali ke kode utama, dan lebih parah akan terjadi overflow stack.
TimerOne adalah external library, jadi kita perlu include pada kode kita. Caranya dengan menggunakan perintah berikut:
#include <TimerOne.h> // Install the library first
Selanjutnya, deklarasi variable untuk pin yang digunakan sebagai interface terhadap shift register.
int latchPin = 8; //Pin connected to Pin 12 of 74HC595 (Latch)
int clockPin = 12; //Pin connected to Pin 11 of 74HC595 (Clock)
int dataPin = 11; //Pin connected to Pin 14 of 74HC595 (Data)
Kemudian, buat array dengan tipe data byte dengan besar array 8. Array led[8] akan digunakan untuk menyimpan gambar yang akan kita tampilka pada dot matrix display.
byte led[8]; // 8 element unsigned integer array to hold the sprite
Pada setup routine, kita set latch, clock, and data pins sebagai output.
void setup() {
// set the 3 digital pins to outputs
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
Array led[8] akan kita isi dengan 8-bit binary images yang akan tampil pada setiap baris 8×8 dot matrix display:
// Load the binary representation of the image into the array
led[0] = B11111111;
led[1] = B10000001;
led[2] = B10111101;
led[3] = B10100101;
led[4] = B10100101;
led[5] = B10111101;
led[6] = B10000001;
led[7] = B11111111;
Dengan melihat array diatas, kita dapat bayangkan gambar apa yang aka tampil. 1 menunjukan dimana LED akan menyala, 0 menunjukan LED padam. Silakan bereksperimen mengubah isi array ini.
Berikutnya, Timer1 object digunakan. Pertama, inisialisasi timer dengan frekuensi dimana kita akan aktifkan, pada proyek ini setiap 10000 microseconds atau 1/100 second. Setalah inisialisasi, kita perlu hubungkan interupt fungsi mana yang akan dijalankan setiap periode waktu tercapai.
Pada proyek ini fungsi screenUpdate() akan dieksekusi setiap 1/100th second
// set a timer of length 10000 microseconds (1/100th of a second)
// and attach the screenUpdate function to the interrupt timer
Timer1.initialize(10000);
Timer1.attachInterrupt(screenUpdate);
Kemudian tunggu selama 250 milliseconds sebelum kembali ke awal loop.
// invert each row of the binary image and wait 1/4 second
void loop() {
for (int i=0; i<8; i++) {
led[i]= ~led[i];
}
delay (250);
}
Pada fungsi screenUpdate(), routine ini sangat penting karena bertanggung jawab untuk memastikan LED pada dot matrix menyala dengan tepat sesuai image yang kita inginkan (array led[8]).
Deklarasi variable row dengan tipe data byte dengan inisial value B10000000
byte row = B10000000; // row 1
Prosedur selanjutnya adalah loop led array dengan menggunakan loop for dan mengirim data ke shift registers.Dengan menggunakan operator bitwise not (~), untuk memastikan mematikan bagian kolom (mengirim tegangan ground) yang kemudian diikuti baris.
for (byte k = 0; k < 8; k++) {
// LED array
shiftOut(dataPin, clockPin, LSBFIRST, led[k] );
// row binary number (active low)
shiftOut(dataPin, clockPin, LSBFIRST, ~row);
// latch low to high to output data
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
// bitshift right
row = row >> 1;
}
Setelah shitfout baris aktif, lakukan bitshift pada row 1 bit.
row = row >> 1;
Berikutnya kita lakukan for loop yang sama, namun kali ini mengirimkan tegangan ground untuk semua row. Penting untuk dipastikan display tidak menyala terlalu lama saat menunggu ISR berikutnya untuk dijalankan, karena akan menyebabkan baris terakhir akan menyala lebih terang dari yang lainnya.
byte row = B10000000; // row 1
for (byte k = 0; k < 8; k++) {
shiftOut(dataPin, clockPin, LSBFIRST, 255);
shiftOut(dataPin, clockPin, LSBFIRST, row);
// latch low to high to output data
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
row = row >> 1;
}
Related Article
Pengetahuan dasar hardware : LED dot matrix
Bitwise operator
21 - LED Dot Matrix Display - Basic Animation
Reviewed by MCH
on
January 15, 2014
Rating:
No comments: