Mahir Arduino Sketch dan Elektro secara praktek

Proyek sederhana untuk mengatur kecepatan Motor DC, hanya 1 arah, menggunakan komponen power transistor, diode dan eksternal power supply (untuk memberi daya pada motor) dan  potentiometer untuk mengatur kecepatan motor.

Transistor TIP120 dapat digantikan dengan transistor namun pastikan menggunakan transistor untuk beban arus tinggi. Sesuaikan dengan voltage dan arus  yang digunakan motor. Disarankan menggunakan heat sink pada transistor jika arus yang digunakan >= 1 amp.

External power supply bisa berupa baterai atau external DC power supply yang dapat kamu beli di toko-toko penyedia elektronik. Pastikan cukup voltage dan ampere untuk menjalankan motor namun tidak melebihi spek motor.

Pada proyek ini digunakan DC power supply dengan spek 5V dan 500mA. Bila volt lebih besar akan berisiko merusak motor.

Komponen yang digunakan

  • DC Motor
  • 10kΩ Potentiometer
  • TIP120 Transistor*
  • 1N4001 Diode*
  • Jack Plug
  • External Power Supply
  • 1K Resistor

Skema
Pertama, pastikan Arduino tidak terhubung dengan arus listrik. Baru rangkai seperti gambar dibawah.
Pastikan terhubung dengan benar. Salah rangkaian dapat menyebabkan kerusakan pada komponen bahkan pada Arduino board.

Diode penting untuk menjaga Arduino dari  EMF.




Sketch

!!! Perhatian: Sebelum upload code, matikan eksternal power supply ke motor dan pastikan potentiometer mentok di 0 (putar habis kearah sebalik jarum jam hingga mentok)


Setelah upload, hubungkan eksternal power supply. Sekarang potentiometer dapat kamu putar untuk mengatur kecepatan motor.

// Project 15 - Simple Motor Control
int potPin = 0; // Analog in 0 connected to the potentiometer
int transistorPin = 9; // PWM Pin 9 connected to the base of the transistor
int potValue = 0; // value returned from the potentiometer

void setup() {
// set the transistor pin as output:
pinMode(transistorPin, OUTPUT);
}

void loop() {
// read the potentiometer, convert it to 0 - 255:
potValue = analogRead(potPin) / 4;
// use that to control the transistor:
analogWrite(transistorPin, potValue);
}


Penjelasan Kode

Pertama-tama, kita deklarasikan 3 variable untuk menyimpan nilai dari analog pin yang terhubung dengan potentiometer, PWM pin yang terhubung dengan kaki base transistor dan variable untuk menyimpan value yang dibaca dari potentiometer

int potPin = 0; // Analog in 0 connected to the potentiometer
int transistorPin = 9; // PWM Pin 9 connected to the base of the transistor
int potValue = 0; // value returned from the potentiometer
.
Pada setup( ) function  kita atur pin mode transistor sebagai output.
void setup() {
// set the transistor pin as output:
pinMode(transistorPin, OUTPUT);
}

Pada main loop potValue diisi oleh nilai yang dibaca dari analog pin 0 (the potPin) kemudian dibagi 4.

analogWrite(transistorPin, potValue);

Kita perlu membagi dengan 4  karena range nilai analog ada diantara 0 (0 volts) hingga 1023 (5 volts) sedangkan range nilai yang akan kita tulis pada pin transistor (digital pin 9) adalah 0 - 255.

Selanjutnya, program akan menulis nilai dari potentiometer.

analogWrite(transistorPin, potValue);

Jadi, saat kita memutar potentiometer, nilai antara 0 -1023 akan terbaca, kemudian diconvert menjadi 0-255 kemudian nilai tersebut kita gunakan untuk mengubah kecepatan motor.

Putar arah balik jarum jam akan memperlambat motor, putar searah jarum jam akan menambah kecepatan motor.

Related Article
Proyek Sebelumnya - 16 - Proyek Light Sensor
Proyek Berikutnya - 18 - IC L293D
Pada projek sebelumnya, kita menggunakan transistor untuk mengatur motor. Pada projek ini, kita akan menggunakan IC motor driver yang terkenal, L293D. Keuntungan menggunakan chip ini adalah kita dapat mengatur 2 motor dalam sekali waktu, juga dapat mengatur arah putarannya. Chip ini juga dapat digunakan untuk mengatur stepper motor. Chip ini sudah ada diode internal, jadi kita tidak perlu menggunakan diode pada projek ini.


List Komponen

  • DC Motor
  • L293D or SN754410
  • Motor Driver IC
  • 10KΩ Potentiometer
  • Slide Switch
  • 10KΩ Resistor
  • Heatsink

Rangkaian


Sketch

// Using an L293D Motor Driver IC
#define switchPin 2 // switch input
#define motorPin1 3 // L293D Input 1
#define motorPin2 4 // L293D Input 2
#define speedPin 9 // L293D enable pin 1
#define potPin 0 // Potentiometer on analog Pin 0
int Mspeed = 0; // a variable to hold the current speed value

void setup() {
  //set switch pin as INPUT
  pinMode(switchPin, INPUT);
  // set remaining pins as outputs
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(speedPin, OUTPUT);
}

void loop() {
  Mspeed = analogRead(potPin)/4; // read the speed value from the   potentiometer
  analogWrite (speedPin, Mspeed); // write speed to Enable 1 pin
  if (digitalRead(switchPin)) { // If the switch is HIGH, rotate     motor clockwise
    digitalWrite(motorPin1, LOW); // set Input 1 of the L293D low
    digitalWrite(motorPin2, HIGH); // set Input 2 of the L293D       high
  }
  else { // if the switch is LOW, rotate motor anti-clockwise
    digitalWrite(motorPin1, HIGH); // set Input 1 of the L293D       low
    digitalWrite(motorPin2, LOW); // set Input 2 of the L293D         high
  }
}

Setelah code selesai diupload, atur potensiometer ditengah lalu hubungkan external power supply. Motor akan berputar dan kita dapat mengatur kecepatan motor dengan mangatur potentiometer. Untuk mengubah arah putara, atur dahulu kecepatan ke minimum kemudia tekan switch. Motor akan berputar kearah sebaliknya. Perlu diperhatikan, chipa mudah panas, chip akan panas sekali saat kita nyalakan.

Baca juga : L293D Motor Driver

Pembahasan Program

Kode pada proyek ini sangat mudah, pertama-tama kita definisikan pin yang akan kita gunakan.

#define switchPin 2 // switch input
#define motorPin1 3 // L293D Input 1
#define motorPin2 4 // L293D Input 2
#define speedPin 9 // L293D enable pin 1
#define potPin 0 // Potentiometer on analog Pin 0


Kemudian set sebuah integer untuk menyimpan nilai bacaan kecepatan motor dari potentiometer.

int Mspeed = 0; // a variable to hold the current speed value

Pada fungsi setup, kita set pin yang telah kita definisikan.

void setup() {
  //set switch pin as INPUT
  pinMode(switchPin, INPUT);
  // set remaining pins as outputs
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(speedPin, OUTPUT);
}


Pada main loop, pertama-tama kita baca nilai dari potentiometer yang terhubung pada analog pin 0 dan simpan di variable Mspeed.

  Mspeed = analogRead(potPin)/4; // read the speed value from the   potentiometer


Kemudian kita set nilai PWM  di pin 9  dengan kecepatan dari variable Mspeed.

  analogWrite (speedPin, Mspeed); // write speed to Enable 1 pin


Kemudian kita gunakan statemen if untuk menentukan nilai bacaan dari switch, HIGH atau LOW.
Jika, HIGH, maka output 1 pada IC  L293D di set LOW and output 2 di set to HIGH. Ini artinya, output 2 memiliki positive voltage dan output 1 adalah ground, menyebabkan motor berputar pada 1 arah.

  if (digitalRead(switchPin)) { // If the switch is HIGH, rotate     motor clockwise
    digitalWrite(motorPin1, LOW); // set Input 1 of the L293D low
    digitalWrite(motorPin2, HIGH); // set Input 2 of the L293D       high
  }

Jika switch pin bernilai LOW, maka output 1 di set HIGH dan output 2 di set LOW,  ini akan memutar balik arah putar motor.

  else { // if the switch is LOW, rotate motor anti-clockwise
    digitalWrite(motorPin1, HIGH); // set Input 1 of the L293D       low
    digitalWrite(motorPin2, LOW); // set Input 2 of the L293D         high
  }

Setelah itu fungsi loop akan kembali ke awal procedure. Dapat kita lihat, IC ini memudahkan kerja kita. Membuat skema diatas tanpa IC L293D akan lebih rumit. Begitu juga dengan kodenya. Jadi untuk pemula, jangan mudah terintimidasi oleh IC, karena IC dibuat untuk memudahkan kerja kita, asal tahu input, output dan aturan pakainya dengan membaca datasheet.

Related Article
Projek Sebelumnya - 17 - Simple Motor Control

Pada proyek ke 19, kita akan mencoba menggunakan IC (integrated circuits) shift registers, yang digunakan untuk mengatur LEDs menampilkan binary counter. Kita akan mengatur 8 buah LED dengan hanya menggunakan 3 output pin Arduino.

Komponen

  • 1 x 74HC595 Shift Register IC
  • 8 x 560Ω Resistors*
  • 8 x 5mm LEDs
  • 0.1uF Capacitor

Skema

Perhatian: hubungkan daya 5V dari Arduino di jalur bawah dibagian bawah breadboard dan ground di jalur atasnya. Lalu hubungkan dengan kabel dari bagian bawah breadboard ke bagian atas breadboard (lihat gambar).

Biasanya untuk mencari pin 1 dari chip, ditunjukan dengan titik bulat (dimple) pada sisi kiri bawah. Pin 1 dibawah dimple tersebut dan pin 8 ada di kanan bawah, pin 9 di kanan atas, and pin 16 di kiri atas.

Pasang kabel untuk menghubungkan pins 10 dan 16 ke sumber daya 5V , untuk ground hubungkan ke pins 8 dan 13.

Hubungkan kabel untuk digital pin 8 dengan pin 12 pada IC. Digital pin 12 ke pin 11 pada IC, dan dari digital pin 11 ke pin 14 pada IC.

Gunakan resistor 560Ω pada led, hubungkan katoda dari led dengan ground. Anoda pada LED 1 hubungkan dengan pin 15 pada IC. Dan untuk anoda LED 2 sampai 8 hubungkan dengan pin 1 sampai 7 pada IC.

Kita perlu melakukan bypass kapasitor (decoupling capacitor). Pastikan rating voltage lebih tinggi dibandingkan voltage yang digunakan. Pastikan kapasitor sedekat mungkin dengan chip. Manfaat dari kapasitor ini untuk mengurangi efek electrical noise pada rangkaian.

Silakan cek gambar dibawah, setelah rangkaian beres, masukan kode arduino.



Sketch

// Project 19
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)

void setup() {
//set pins to output
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  //count from 0 to 255
  for (int i = 0; i < 256; i++) {
    shiftDataOut(i);
    //set latchPin low then high to send data out
    digitalWrite(latchPin, LOW);
    digitalWrite(latchPin, HIGH);
    delay(1000);
  }
}

void shiftDataOut(byte dataOut) {
  // Shift out 8 bits LSB first, clocking each with a rising edge of the      clock line
  boolean pinState;
  for (int i=0; i<=7; i++) { // for each bit in dataOut send out a bit
    digitalWrite(clockPin, LOW); //set clockPin to LOW
    // if the value of DataOut and (logical AND) a bitmask
    // are true, set pinState to 1 (HIGH)
    if ( dataOut & (1<<i) ) {
      pinState = HIGH;
    }
    else {
      pinState = LOW;
    }

    //sets dataPin to HIGH or LOW depending on pinState
    digitalWrite(dataPin, pinState); //send bit out 
    digitalWrite(clockPin, HIGH);
  }
  digitalWrite(clockPin, LOW); //stop shifting out data
}

Baca Juga : Bitwise Operator

Overview 74HC595
Kita menggunakan shift register type 74HC595. Type ini adalah type 8-bit serial-in, serial or parallel-out shift register with output latches. Ini berarti kita dapat mengirim data ke shift register secara serial  dan ouput secara paralel. Series berarti, 1 bit per satu waktu. Parallel berarti lebih dari 1 bits, dalam hal ini adalah 8 bits dalam satu waktu.

Kita mengirimkan data pada shift registers 1 bit setiap waktu. Setiap bit akan dipush selama ada bit baru yang masuk, ketika bit ke 9 dimasukan, bit pertama tadi akan di push dari shist register dan hilang (bila kita tidak melakukan sesuatu pada data tersebut).

Ketika latch signal diubah dari LOW ke HIGH, isi dari shift registers saat ini di copy ke output latches.(Proses copy ini tidak mempengaruhi isi dari shift register).

Type shift register ini umum digunakan untuk konversi data dari serial ke paralel. Ada type juga dari masuk pararlel, keluar serial, yang digunakan untuk konversi dari paralel ke serial.

Pada case kita ini, data output adalah 1s dan 0s (atau 0V dan 5V), dapat kita gunakan untuk menyalakan atau mematikan 8 LEDs.

Shift register pada proyek ini hanya membutuhkan 3 input dari Arduino. Output dari Arduino dan Input shift registers 74HC595595 yang dibutuhkan adalah:

Arduino74HC595Deskripsi
812Storage Register Clock Input
1114Serial Data Input
1211Shift Register Clock Input

Kita tidak menggunakan pin 10 (master reset) dan13 (output enable input). Kita hanya perlu set high pada pin 10 atau  low pada pin 13 agar projek ini berjalan dengan baik.


Pembahasan Sketch

Pertama-tama, inisialisasi 3 variable untuk 3 pin yang akan kita gunakan.

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, pada setup, ataur pin ke mode output.

void setup() {
//set pins to output
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}


Pada loop , melakukan counting dari 0 sampai 255. Pada setiap iterasi, latchPin di set ke LOW untuk keperluan data entry. Kemudia panggil fungsi shiftDataOut, passing nilai dari i pada for.  Kemdian set latchPin ke HIGH, transfer data dari shift register ke output latches and output
pins. Kemudian delay setengah second sebelum melakukan iterasi berikutnya.

void loop() {
  //count from 0 to 255
  for (int i = 0; i < 256; i++) {
    shiftDataOut(i);
    //set latchPin low then high to send data out
    digitalWrite(latchPin, LOW);
    digitalWrite(latchPin, HIGH);
    delay(1000);
  }
}

Fungsi shiftDataOut menerima 1 byte (8-bit angka), yaitu angka dalam rentang 0 sampai 255.  Kita menggunakan byte  karena kita memang hanya membutuhkan 8 bit yang dikirimkan ke shift register.

void shiftDataOut(byte dataOut) {


Inisialisai boolean variable pinState. Digunakan untuk menyimpan status pin  ketika data dikirim.

boolean pinState;


Kita sudah siap mengirim 8 bits secara serie ke 74HC595, 1 bit per waktu Lihat loop for dibuat berulang 8 kali.
for (int i=0; i<=7; i++) {

Clock pin diatur ke LOW sebelum mengirim bit data.
digitalWrite(clockPin, LOW);

if/else statement untuk menentukan apakah pinState variable harus diset ke 1 atau 0.

if ( dataOut & (1<<i) ) {
  pinState = HIGH;
}
else {
  pinState = LOW;
}

Kode berikutnya melakukan digitalWrite nilai HIGH atau LOW  ke data pin dan set clockPin HIGH untuk menuliskan nilai bit ke  storage register.

digitalWrite(dataPin, pinState); //send bit out 
digitalWrite(clockPin, HIGH);

Kemudian ClockPin diset  ke LOW untuk memastikan tidak ada bit lagi yang ditulis ke storage register.
digitalWrite(clockPin, LOW); //stop shifting out data


Related Article
Proyek 18 - L293D-motor-driver
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

!!! 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++) {

    // 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
Pendahuluan
Pada projek ini akan digunakan LCD untuk menampilkan text dan simbol. Tipe display ini sering digunakan untuk kalkulator atau jam alarm. Banyak contoh proyek Ardunino menggunakan juga, jadi adalah penting untuk memahami dan tahu bagaimana cara menggunakan LCD.

Untuk mengontrol LCD diperlukan driver chip, chip ini sudah built in didalam modul LCD. Driver chip yang paling popular adalah Hitachi HD44780 (or compatible), dan paling umum digunakan.

Membuat proyek berbasiskan LCD cukup mudah karena sudah tersedia library yang bisa digunakan untuk mengakses LCD.

Arduino IDE sendiri sudah tersedia library, LiquidCrystal.h, dimana sudah memiliki fitur-fitur penting untuk mengakses LCD. Pada proyek ini, kita akan gunakan library ini.


Komponen
  • 16x2 Backlit LCD
  • Current Limiting Resistor (Backlight)
  • Contrast Setting Resistor atau pot


LCD yang digunakan adalah LCD dengan HD44780 driver. Silakan memilih warna yang diinginkan, dipasaran tersedia berbagai warna seperti text merah background hitam, atau tulisan hitam dengan background hijau atau biru. Yang penting, LCD yang akan digunakan memiliki backlight dan bisa menampilkan 16 kolom dan 2 baris karakter text.

Skema




Skema pada proyek kali ini cukup simple. Yang diperlukan adalah datasheet LCD yang digunakan. Silakan perhatikan tabel diatas untuk pin yang digunakan.

Data pins 0 to 3 tidak digunakan, karena kita akan menggunakan mode 4-bit. Untuk LCD umumnya skema pada gambar diatas bisa langsung digunakan. (Namun untuk keamanan, cek data sheet LCD yang digunakan)

Contrast Adjustment pin pada LCD harus dihubungkan dengan current-limiting resistor untuk mengatur contrast yang diinginkan. Resistor dengan nilai sekitar 10KΩ sudah bisa digunakan.

Jika kesulitan mencari resistor dengan nilai tersebut, gunakan potentiometer denga value antara 4KΩ - 10KΩ dengan kaki kiri dihubungkan dengan +5V,  kaki kanan dihubungkan dengan ground, dan kaki tengah dihubungkan dengan contrast adjustment pin (pin 3 pada kasus ini, bisa berbeda pada LCD yang Anda gunakan).

Dengan menggunakan potentiometer, kita dapat memutar knob untuk melakukan adjustment contrast.

Backlight dari LCD yang digunakan pada artikel ini membutuhkan 4.2V, oleh karena itu ditambahkan current-limiting resistor antara +5V dan LED power supply pin (pin 15 pada kasus ini).

Tentu saja kita bisa menggunakan PWM pin pada Arduino, namun untuk proyek ini, kita tidak menggunakan cara ini.

Setelah skema sudah sesuai, kita sudah bisa memasukan kode.

Code

#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // create an lcd object and assign the pins

void setup() {
  lcd.begin(16, 2); // Set the display to 16 columns and 2 rows
}

void loop() {
  // run the 7 demo routines
  basicPrintDemo();
  displayOnOffDemo();
  setCursorDemo();
  scrollLeftDemo();
  scrollRightDemo();
  cursorDemo();
  createGlyphDemo();
}

void basicPrintDemo() {
  lcd.clear(); // Clear the display
  lcd.print("Basic Print"); // print some text
  delay(2000);
}

void displayOnOffDemo() {
  lcd.clear(); // Clear the display
  lcd.print("Display On/Off"); // print some text
  for(int x=0; x < 3; x++) { // loop 3 times
    lcd.noDisplay(); // turn display off
    delay(1000);
    lcd.display(); // turn it back on again
    delay(1000);
  }
}

void setCursorDemo() {
  lcd.clear(); // Clear the display
  lcd.print("SetCursor Demo"); // print some text
  delay(1000);
  lcd.clear(); // Clear the display
  lcd.setCursor(5,0); // cursor at column 5 row 0
  lcd.print("5,0");
  delay(2000);
  lcd.setCursor(10,1); // cursor at column 10 row 1
  lcd.print("10,1");
  delay(2000);
  lcd.setCursor(3,1); // cursor at column 3 row 1
  lcd.print("3,1");
  delay(2000);
}

void scrollLeftDemo() {
  lcd.clear(); // Clear the display
  lcd.print("Scroll Left Demo");
  delay(1000);
  lcd.clear(); // Clear the display
  lcd.setCursor(7,0);
  lcd.print("Beginning");
  lcd.setCursor(9,1);
  lcd.print("Arduino");
  delay(1000);
  for(int x=0; x<16; x++) {
    lcd.scrollDisplayLeft(); // scroll display left 16 times
    delay(250);
  }
}

void scrollRightDemo() {
  lcd.clear(); // Clear the display
  lcd.print("Scroll Right");
  lcd.setCursor(0,1);
  lcd.print("Demo");
  delay(1000);
  lcd.clear(); // Clear the display
  lcd.print("Beginning");
  lcd.setCursor(0,1);
  lcd.print("Arduino");
  delay(1000);
  for(int x=0; x<16; x++) {
    lcd.scrollDisplayRight(); // scroll display right 16 times
    delay(250);
  }
}

void cursorDemo() {
  lcd.clear(); // Clear the display
  lcd.cursor(); // Enable cursor visible
  lcd.print("Cursor On");
  delay(3000);
  lcd.clear(); // Clear the display
  lcd.noCursor(); // cursor invisible
  lcd.print("Cursor Off");
  delay(3000);
  lcd.clear(); // Clear the display
  lcd.cursor(); // cursor visible
  lcd.blink(); // cursor blinking
  lcd.print("Cursor Blink On");
  delay(3000);
  lcd.noCursor(); // cursor invisible
  lcd.noBlink(); // blink off
}

void createGlyphDemo() {
  lcd.clear();
  byte happy[8] = { // create byte array with happy face
    B00000,
    B00000,
    B10001,
    B00000,
    B10001,
    B01110,
    B00000,
    B00000};

  byte sad[8] = { // create byte array with sad face
    B00000,
    B00000,
    B10001,
    B00000,
    B01110,
    B10001,
    B00000,
    B00000};

  lcd.createChar(0, happy); // create custom character 0
  lcd.createChar(1, sad); // create custom character 1
  for(int x=0; x<5; x++) { // loop animation 5 times
    lcd.setCursor(8,0);
    lcd.write((byte)0); // write custom char 0
    delay(1000);
    lcd.setCursor(8,0);
    lcd.write(1); // write custom char 1
    delay(1000);
  }
}


Pembahasan Kode
Pertama kita panggil library yang digunakan untuk mengontrol LCD. Arduino IDE sudah menyediakan library teserbut, yaitu LiquidCrystal.h. Library ini bagus dan mudah dimengerti dan digunakan.

Ada banyak librari lainnya, contoh dari type LCD juga dapat dilihat di http://www.arduino.cc/playground/Code/LCD

#include <LiquidCrystal.h>


Selanjutnya kita membuat object LiquidCrystal object dengan nama lcd dan mengatur pin yang digunakan.

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 

2 parameter pertama adalah pin untuk RS (Register Select) dan Enable. 4 parameter terakhir adalah data pin  D4 ke D7. Karena kita menggunakan mode 4-bit, kita hanya menggunakan 4 dari 8 datapins yang tersedia.

Perbedaan antara 4-bit dan 8-bit adalah pada mode 8-bit kita bisa mengirim data 1 byte dalam 1 waktu, pada mode 4-bit kita harus membagi menjadi 4-bit (disebut nibbles). Ini membuat kode menjadi lebih besar dan kompleks.

Namun, dikarenakan kita menggunakan library yang sudah mendukung, kita tidak perlu khawatir akan hal tersebut. Namun bila proyek concern akan space dan waktu, ada baiknya menggunakan mode 8-bit.

Menggunakan 4-bit ada keuntungan yaitu menghemat 4 pins, dimana sangat berguna bila proyek kita memerlukan pin lainnya untuk peralatan lainnya.

Pada fungsi setup(), kita inisialisasi kukuran display, pada contoh ini 16 kolom dan 2 baris.

void setup() {
  lcd.begin(16, 2); // Set the display to 16 columns and 2 rows

}

Pada loop kita akan menjalankan 7 demo rutin,  demo ini menunjukan rutin yang didukung librari LiquidCrystal.h.

void loop() {
  // run the 7 demo routines
  basicPrintDemo();
  displayOnOffDemo();
  setCursorDemo();
  scrollLeftDemo();
  scrollRightDemo();
  cursorDemo();
  createGlyphDemo();

}


basicPrintDemo() digunakan untuk menunjukan cara menggunakan perintah print(). Demo ini sederhana, menunjukan cara menghapus layar denga perintah lcd.clear(), kemudian menulis ke display dengan perintah lcd.print().

Perhatian, jika Anda menginisialisasi object LiquidCrystal object dengan nama contohnya lcd1 maka perintah yang digunakan adalah lcd1.clear() dan lcd1.print()

Perintah print() akan menulis apapun yang diinput dalam tanda kurung pada cursor aktif terakhir. Default awal kursor selalu di kolom 0 dan baris 0, yang berarti ada di kiri atas.

Ketika perintah print() digunakan, text yang kita kirim akan ditulis dilayar, lalu kursor akan berpindah pada akhir text. Setiap text berikutnya ditambahkan akan mulai dari posisi terakhir tersebut.

Cursor akan kembali ke default setiap kita melakukan perintah clear().

void basicPrintDemo() {
  lcd.clear(); // Clear the display
  lcd.print("Basic Print"); // print some text
  delay(2000);

}


Demo kedua untuk menunjukan cara menggunakan perintah display() dan noDisplay().  Perintah ini adalah untuk enable atau disable display.

void displayOnOffDemo() {
  lcd.clear(); // Clear the display
  lcd.print("Display On/Off"); // print some text
  for(int x=0; x < 3; x++) { // loop 3 times
    lcd.noDisplay(); // turn display off
    delay(1000);
    lcd.display(); // turn it back on again
    delay(1000);
  }

}


Demo berikutnya menunjukan cara mengatur kursor dengan perintah setCursor(). Perintah ini untuk mengarahkan kursor pada kolom dan baris tertentu.

Perintah setCursor() penting untuk mengatur layout dan memastikan kita bisa menulis di posisi yang kita inginkan.

void setCursorDemo() {
  lcd.clear(); // Clear the display
  lcd.print("SetCursor Demo"); // print some text
  delay(1000);
  lcd.clear(); // Clear the display
  lcd.setCursor(5,0); // cursor at column 5 row 0
  lcd.print("5,0");
  delay(2000);
  lcd.setCursor(10,1); // cursor at column 10 row 1
  lcd.print("10,1");
  delay(2000);
  lcd.setCursor(3,1); // cursor at column 3 row 1
  lcd.print("3,1");
  delay(2000);

}

Ada dua cara untuk scrolling text, yaitu scrollDisplayLeft() dan scrollDisplayRight(). Dari namanya cukup jelas scroll ke kiri dan ke kanan. Demo ini akan menunjukan penggunaan perintah ini, pertama akan menulis “Beginning Arduino” pada sebelah kanan displaydan ke kiri sebanyak 16 kali, dimana tulisan akan hilang dari layar.

void scrollLeftDemo() {
  lcd.clear(); // Clear the display
  lcd.print("Scroll Left Demo");
  delay(1000);
  lcd.clear(); // Clear the display
  lcd.setCursor(7,0);
  lcd.print("Beginning");
  lcd.setCursor(9,1);
  lcd.print("Arduino");
  delay(1000);
  for(int x=0; x<16; x++) {
    lcd.scrollDisplayLeft(); // scroll display left 16 times
    delay(250);
  }

}


Demo berikut ini sama, hanya saja mulai menulis di sebelah kiri layar dan di-scroll ke kanan sebanyak 16 kali.

void scrollRightDemo() {
  lcd.clear(); // Clear the display
  lcd.print("Scroll Right");
  lcd.setCursor(0,1);
  lcd.print("Demo");
  delay(1000);
  lcd.clear(); // Clear the display
  lcd.print("Beginning");
  lcd.setCursor(0,1);
  lcd.print("Arduino");
  delay(1000);
  for(int x=0; x<16; x++) {
    lcd.scrollDisplayRight(); // scroll display right 16 times
    delay(250);
  }
}


Sejauh ini cursor tidak tampak. Ada disana namun tidak terlihat  Setiap kita clear layar maka kurso akan kembali ke  kolom 0 dan baris 0. Setelah print, cursor akan ada tepat sesudah karakter terakhir. Demo berikut akan menghapus layar dan menyalakan cursor dengan perintah cursor() dan menulis teks. Cursor akan tampak sesudah text dengan simbol underscore ( _ ).


void cursorDemo() {
  lcd.clear(); // Clear the display
  lcd.cursor(); // Enable cursor visible
  lcd.print("Cursor On");
  delay(3000);
  lcd.clear(); // Clear the display
  lcd.noCursor(); // cursor invisible
  lcd.print("Cursor Off");
  delay(3000);
  lcd.clear(); // Clear the display
  lcd.cursor(); // cursor visible
  lcd.blink(); // cursor blinking
  lcd.print("Cursor Blink On");
  delay(3000);
  lcd.noCursor(); // cursor invisible
  lcd.noBlink(); // blink off
}


Demo terakhir adalah  membuat karakter khusus. Umumnya LCDs punya kemampuan untuk menampilkan karakter tertentu. LCD 16x2  memilik ruang untutk 8 karakter khusus untuk disimpan dalam memory

Karakter ini memiliki ukuran lebar 5 pixels dan tinggi 8 pixels. Display di clear kemudia 2 array dengan tipe byte akan di inisialisasi dengan binary pattern  wajah gembira dan sedih. Binary patterns  memiliki lebar 5 bits.

void createGlyphDemo() {
  lcd.clear();
  byte happy[8] = { // create byte array with happy face
    B00000,
    B00000,
    B10001,
    B00000,
    B10001,
    B01110,
    B00000,
    B00000};

  byte sad[8] = { // create byte array with sad face
    B00000,
    B00000,
    B10001,
    B00000,
    B01110,
    B10001,
    B00000,
    B00000};

  lcd.createChar(0, happy); // create custom character 0
  lcd.createChar(1, sad); // create custom character 1
  for(int x=0; x<5; x++) { // loop animation 5 times
    lcd.setCursor(8,0);
    lcd.write((byte)0); // write custom char 0
    delay(1000);
    lcd.setCursor(8,0);
    lcd.write(1); // write custom char 1
    delay(1000);
  }
}


Artikel sebelumnya  Led Dot Matrix Basic
Artikel selanjutnya LCD display Temperature