This Blog is protected by DMCA.com

Wednesday, January 29, 2020

Membuat Running Text dengan Led Strip WS2812 (Teori + Kode)


Pada artikel sebelumnya, kita sudah membahas bagaimana cara mengontrol led strip addressable menggunakan mikrokontroller. Namun pada artikel kali ini, kita dorong penggunaannya menjadi lebih advanced, yaitu memanfaatkan led strip untuk membuat running text sederhana.

Baca: Mengontrol Led Strip dengan Arduino + Penjelasan Lengkap

langsung saja, berikut daftar isi tutorial:



Memilih Led Strip

Pada artikel sebelumnya, sudah saya jelaskan beberapa jenis Led Strip berdasarkan faktor spesifikasinya. Di artikel kali ini, jenis Led Strip yang kita gunakan adalah led strip berjenis Addressable, yaitu led strip yang bisa kontrol lednya secara individual / sendiri-sendiri.

kemudian faktor lain yang bisa mempengaruhi hasil running text adalah sebagai berikut:

  • Density / Kerapatan
    Semakin rapat jarak antara lampu led di led strip, semakin bagus dan tajam hasilnya, namun dimensi ukurannya menjadi lebih kecil. Density Led Strip seperti 60 LED / M, sudah cukup untuk memberikan hasil yang bagus.

  • Voltage / Tegangan
    Pada tegangan 12V, tiap kontrol individual mencakup 3 LED sehingga tampak lebih besar dan gepeng. Jadi gunakan led strip bertegangan 5V untuk hasil yang lebih maksimal, jangan gunakan 12V kecuali jika anda ingin membuat dimensi ukuran raksasa.
  • Color / Warna
    Untuk warna, terserah anda. Anda bisa gunakan single color, ataupun RGB. Di indonesia sendiri, yang paling populer untuk addressable adalah RGB.

Persiapan

Berikut alat/bahan komponen yang dibutuhkan:

  • Arduino / Mikrokontroller lain yang sesuai
  • Led Strip WS2812 atau WS2811
  • Komputer / Laptop
Konfigurasi panjang * lebar yang saya gunakan adalah 8x8 sehingga komponen tersebut dirangkai sesuai dengan skema berikut ini:
Ingat bahwa sesuai dengan dokumentasi aslinya, neopixel membutuhkan ram 3 byte setiap 1 LED, jadi jika anda membuat dengan jumlah pixel yang lebih banyak, pastikan mikrokontroller memiliki ukuran RAM yang cukup. (referensi: Arduino Uno memiliki 32KB RAM)

Perhitungan RAM (dlm satuan byte) = 80 + (3 * jumlah pixel)

Dan untuk software yang dibutuhkan adalah:

  •  Arduino IDE
  • Library Adafruit_NeoPixel.h  (install lewat library manager)
  • Library font5x7.h (download dibawah ini, taruh di documents/arduino/library)
font5x7.rar | ~2KB



itu aja sih, Dan jika anda ingin meneruskan project ini sesuai dengan keinginan anda, anda perlu menguasai :


Teori

Jika anda membaca artikel lain dari blog ini, project ini termasuk gabungan dari tutorial dot matrix dan tutorial kontrol led strip.

Baca: Mengontrol Led strip dengan Arduino
Baca: Membuat Running Text Dot Matrix dengan 74HC595

Prinsip kerja utama dari display biasa adalah sebagai berikut:

  • Pada mikrokontroller disiapkan 1 variabel yang merepresentasikan kumpulan pixel dari display. Yang disimpan pada variabel tersebut adalah status hidup atau matinya setiap lampu pixel dalam format 1 dan 0 (biner) beserta lokasinya yang berdasarkan baris dan kolom.
    variabel tersebut disebut dengan nama Bitmap.
    Bitmap sederhananya adalah sebuah variabel array 2 dimensi atau array dalam array yang mempunyai lebar dan tinggi. Biasanya pada dimensi kedua / array bagian dalam di berikan nilai byte yang memiliki 8 bit biner agar dapat dengan mudah dimanipulasi (digeser, di tambahkan, dst), akibatnya 1 byte sudah mewakili 8 kolom sehingga 1 indeks array lebar merupakan kelompok 8 piksel.
    Berikut contoh array bitmap dengan resolusi 16 x 8 di tuliskan huruf "A a" : 

  • Untuk menampilkan ke layar, Bitmap tersebut ditampilkan dengan metode scan vertikal sehingga bit tersebut tampil di masing-masing pixel. Dan untuk menampilkan pergerakan (perubahan bitmap) biasanya ditampilkan berulang kali (misalnya 60 kali perdetik / 60 fps) untuk memperbarui tampilan.
    Menampilkan bitmap ke layar berulang kali ini disebut dengan Refresh
  • Bitmap dapat diisi sesuai kemauan kita (mau menampikan apa), pada kasus ini adalah running text, yaitu diambil dari font yang sudah ditetapkan. Huruf diisikan ke bitmap kolom demi kolom dan digeser bitnya ke kiri pada waktu interval tertentu sehingga membentuk animasi running text (continuous move left) dan melakukan refresh secara bersamaan tentunya. Pengisian bitmap ini dilakukan secara asyncronous/multiprocess sehingga tidak mengganggu proses refresh rate.
Cara kerja ini juga berlaku di monitor monitor yang selama ini kita kenal.
Namun berbeda dengan led strip, karena tidak ada komponen / sinyal khusus untuk membedakan antara baris dan kolom mengingat led-led tersebut dihubungkan secara "zigzag" dan hanya 1 pin untuk kontrol-nya, maka kita perlu metode scan refresh yang berbeda.

Karakteristik bitmap kita adalah mempunyai baris dan kolom sementara led strip diatur menggunakan urutan lampu led (indeks led). oleh karena itu, intinya kita harus bisa mengartikan lokasi bitmap tersebut agar tampil di lokasi yang sama di led strip dengan skema seperti ini.
Berikut pendekatan rumusnya :

ngomong-ngomong, seperti inilah programmer mengatasi masalah teknisnya. Saya beri nama mode refresh ini dengan: metode progessive linear scan :D.
dengan algoritma seperti itu, kita bisa menampikan bitmap baris demi baris, kolom demi kolom menggunakan formula rumus seperti ini.


Implementasi Kode

Kode dibawah saya adaptasi dari artikel tutorial sebelumnya (membuat running text dot matrix) dan memodifikasi dengan fungsi refresh display yang berbeda.


/*
 * Kode Ditulis oleh  : Moh. Badar Wildanie
 * Sub routine        : Implementasi pengeluaran output bitmap pada led strip
 * Client             : Tidak ada / Standalone
 * Scan Mode Hardware : Progessive linear scan
 */
#include <Adafruit_NeoPixel.h>
#include <font5x7.h>

// Penentuan lebar dan tinggi
const byte lebar = 8;
const byte tinggi = 8;

// Deklarasi objek strip
Adafruit_NeoPixel strip((lebar * tinggi), 8, NEO_GRB + NEO_KHZ800);
 
// Penentuan tulisan / running text
String tulisan = "ABC    ";
 
// Perhitungan jumlah modul untuk dibuatkan array bitmap
const byte jumlahModul = lebar/8;
byte bitmap[tinggi][jumlahModul];
 
 
// Penentuan konfigurasi scrolling dan variabelnya
int scrollSpeed = 70; // Atur ini untuk mengubah kecepatan
unsigned long scrollTiming = 0;
int scrollStep = 0;
 
// Fungsi untuk melakukan scrolling text
void scrollingText() {
  
  // Melakukan pergeseran bitmap kekiri disetiap [scrollSpeed] milidetik
  if (millis() - scrollTiming >= scrollSpeed) {
    scrollTiming = millis();
    scrollStep++;
    
 
    // Mereset scroll step jika melebihi jumlah lebar karakter (6 kolom + jarak antar karakter)
    // (Scroll step digunakan untuk mengetahui karakter mana yang akan di print berdasarkan sejauh mana pergeseran)
    if (scrollStep > tulisan.length() * 6) scrollStep = 1;
    uint8_t charIndexScreen = floor((scrollStep - 1) / 6);  // Indeks karakter dari variabel tulisan
    uint8_t charIndex = tulisan[charIndexScreen] - 32;  // Indeks karakter berdasarkan kode ASCII yang ada di library font5x7
    uint8_t col = (scrollStep - 1) % 6; // Kolom dari setiap karakter yang akan di print (juga berdasarkan pergeseran / scrollstep) pastinya
 
    // Melakukan pergeseran bitmap ke arah kiri 
    // selagi menambahkan bit baru berdasarkan [col] untuk membentuk huruf baru
    for (int row = 0; row < tinggi; row++) {
 
      // melakukan perulangan setiap modul, agar pada modul 1 dapat bergeser ke modul 2 dst..
      for (int col = 1; col < jumlahModul; col++) {
        bitmap[row][col] <<= 1;   // Ini gan pergeserannya
        bitWrite(bitmap[row][col], 0, bitRead(bitmap[row][col-1], 7));
      }
 
      // Menambahkan bit baru untuk huruf baru di kanan
      bitmap[row][0] <<= 1;
      if (col >= 5) {
        bitmap[row][0] |= 0; // Jika col lebih dari 5, maka kita gunakan untuk spasi antar huruf
      }
      else {
        bitmap[row][0] |= bitRead(pgm_read_byte(&Font5x7[charIndex*5+col]), row); // Jika tidak, berarti kita tambahkan bit baru tsb..
      }
    }
  }
}
void setup() {
  strip.begin();
  strip.show();
}

void loop() {
  scrollingText(); // Melakukan scrolling text ALIAS pergeseran bit ke kiri
  refresh(); // menampilkan bitmap ke strip matrix
}


 
// Fungsi untuk menampilkan array bitmap ke strip matrix
void refresh() {
  // Rumus berdasarkan urutan led strip:
  // f(row, col) = (tinggi - row + 1) * lebar - col;
  for (uint8_t row = 0; row < tinggi; row++) {
    for (int  modul = jumlahModul - 1; modul >= 0; modul--) {
      for (int col = 7; col >= 0; col--) {
        byte bitCond = bitRead(bitmap[row][modul], col);
        uint8_t indexStrip = ((tinggi - (row + 1) + 1) * lebar) - (8 - col);        
        strip.setPixelColor(indexStrip, ((bitCond == 1) ? strip.Color(0, 0, 255): 0)); // warna disetting biru
      }
    }
  }
  strip.show();
}

Penjelasan tertera pada komentar kode (//)


Hasil

Silahkan upload kode diatas ke arduino anda, pastikan wiring sudah sesuai seperti di atas.
Hasilnya kurang lebih seperti video dibawah ini:

Saya menggunakan led strip dengan kerapatan 30 LED / meter dengan resolusi 8x8, jadi terlihat besar, renggang dan tidak tajam dikarenakan penggunaan komponen seadanya.




Dipasaran, sebenarnya sudah ada produk sendiri untuk modul led matrix yang lebih bagus seperti P10, P5, P7 dan lain sebagainya. Tak hanya itu, produk tersebut lengkap juga dengan controller yang bermacam-macam fiturnya seperti: TF-AU, TF-A46UW yang bisa WiFi dan sebagainya, lalu apa untungnya menggunakan led strip untuk display layar?

Keuntungan : 

  • Lebih dapat di kustomisasi (bagi programmer/developer)
    Karena sejatinya, kita membuat firmware controller dari dasar sehingga bebas mau dikonfigurasi seperti apa.
  • Daya tahan komponen jauh lebih lama
    Setiap LED pada strip memiliki IC yang juga bersifat latching / dapat menyimpan kondisi status setiap LED
  • Integrasi dengan sensor-sensor / modul elektronik lain jauh lebih mudah
    Di karenakan hampir seluruhnya dibuat custom, mulai dari firmware, controller, dsb. 


Langkah selanjutnya

Setelah anda berhasil membuat running sederhana ini, anda bisa berkreasi sesuai dengan keinginan anda. Misalnya dengan project ini, anda bisa kembangkan menjadi :
  • Jadwal Sholat
  • Jam digital
  • Papan nama running text sederhana
  • dan lain sebagainya
Secara teknis, jika anda menguasai teknik pemrogramannya, anda juga bisa membuat banyak pengembangan seperti penambahan fitur EEPROM, kontrol via WiFi, bluetooth, integrasi sensor dan lain sebagainya.

Silahkan berikan pendapat anda di kolom komentar, jangan ragu untuk tanya, berikan kritik / saran atau lainnya.

Sekian.
Semoga bermanfaat.

13 Comments

Mas tutor LED RGB flash kaya bus malam dong �� yang banyak modenya

Terimakasih

Mas klw pakai ws2811 ip44 bisa g ya

Mas berikan saya pencerahan buat coding strobo fuel animasi rgb led strip ws2811

@Jojo: bisa, sama aja pakai ws2811..
utk full animasi cek ke artikel saya yg ini Klik disini
maaf very slow respond


@Light: terimakasih gan

Mas, kalo running textnya menggunakan 4 pin, gimana ya codingannya? Kayanya kalo menggunakan 4 data, prosesnya jadi agak cepet, gitu.

@Fauzan: Kalau menggunakan 4 pin data / 4 individual led strip, tentu aja lebih cepat, tapi konsumsi ramnya juga akan meningkat 4 kali lipat. Arduino uno biasa (Atmega328) mungkin gak akan kuat, jadi harus menggunakan ram yang besar misalnya Atmega2560 atau bahkan mini komputer macem Raspberry Pi

This comment has been removed by the author.

Kalau pakai led ukuran panjang 30leds dan tingginya 10baris leds mana yang perlu diganti ya pak?

 

Daftar isi artikel