Pada proyek ini digunakan 2 shift registers yang menghubungkan baris dan kolom dari LED dot matrix display. Kemudian kita akan tampilkan objek melakukan basic animation. 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
Perhatian: Wiring diagram pada proyek disesuaikan dengan dot matrix yang digunakan, yaitu mini 8×8 red dot matrix display unit. Dot matrix yang Anda gunakan bisa saja berbeda. SIlakan lihat dokumentasi penggunaan pin pada datasheet produk.
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.



Untuk proyek ini , LED 8 x 8 memiliki skema seperti gambar diatas, dimana urutan rows dan columns (anoda dan katoda) tidak berurutan. Dengan menggunakan informasi table-1 dan skema pada gambar-1, maka 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.
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 Sketch
Kode pada proyek ini menggunakan fitur dari ATmega chip, Hardware Timer. Berfungsi sebagai timer pada chip, digunakan untuk men-trigger 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. Contoh, kita sedang melakukan sesuatu, kemudian di interupsi untuk menjawab telpon, setelah selesai menerima telepon, kita kembali melanjutkan pekerjaan tadi terakhir dimana kita tinggalkan. Pada proyek ini, set timer digunakan untuk mengenerate event setiap 10000 microseconds.
Untuk mempermudah menggunakan interupt kita gunakan library 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 untuk 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 of byte dengan besar array 8. Array led[8] akan digunakan untuk menyimpan gambar yang akan ditampilkan pada dot matrix display.
byte led[8]; // 8 element unsigned integer array to hold the sprite
Pada setup routine, 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 diisi 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;
1 menunjukan dimana LED akan menyala, 0 menunjukan LED padam. Silakan bereksperimen mengubah isi array ini.
Berikutnya, Timer1 object digunakan. Pertama, inisialisasi frekuensi timer, pada proyek ini setiap 10000 microseconds atau 1/100 second. Setalah inisialisasi, hubungkan dengan interupt fungsi yang akan dijalankan ketikaperiode 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, iterator for digunakan untuk memutari setiap 8 element dari led array dan invert isinya dengan menggunakan ~ atau NOT bitwise operator. Bertujuna membuat gambar negatif dari gambar asli.
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);
}
Fungsi screenUpdate(), routine ini untuk memastikan LED pada dot matrix menyala dengan tepat sesuai image yang ditunjukan oleh 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 dan kirim data ke shift registers. Operator bitwise not (~) digunakan untuk 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 lakukan for loop dengan mengirimkan tegangan ground untuk semua row.
Pastikan display tidak menyala terlalu lama saat menunggu ISR berikutnya, untuk mencegah baris terakhir LED Matrix 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;
}