Setelah begadang, kami pun melakukan presentasi tentang Piano Candy Machine kepada Pak Sonny selaku dosen matakuliah Interaksi Manusa dengan Komputer dan Antarmuka beserta teman-teman kami. Jujur karena harus begadang, maka kami belum melakukan persiapan yang matang terhadap materi presentasi, tapi ya karena apapun itu, show must go on.
Materi presentasi kami selain terdapat kisah bahagia merancang dan mengimplementasikan piano candy machine, juga terdapat block diagram hardware dan flowchart software.
Gambar 1 - block diagram piano candy machine
Gambar 2 - flowchart software
Nah, sekarang saya akan merangkum tantangan-tantangan dan pembelajaran seperti apa yang kami dapatkan dalam pembuatan piano candy machine ini adalah sebagai berikut:
Arus yang dibutuhkan untuk mengoperasikan servo
kami mencoba menggunakan 6 buah baterai berukuran AA @1.5V dan ternyata ada delay pada respon dari servo
Solusi dari pak Sonny adalah memparallelkan 6 buah baterai dengan 6 buah baterai lainnya sehingga arusnya bertambah
Desain PCB
Awalnya kami mendesain dengan ketebalan garis <0.3mm
Tidak membedakan antara IC yang akan digunakan SMD atau DIP
Tidak memikirkan bahwa komponen sebaiknya diletakan dibelakang jalur tembaga pada PCB
Solusi dari mas-mas yang jaga di Spectra adalah agar kedepannya desain dilakukan di bottom layer, jangan di top layer (pada software Altium), tebal garis harus >= 0.3mm, bedakan antara DIP dan SMD
Protokol Zigbee pada XBee S2
Penggunaan protokol Zigbee harus lebih diperhatikan urutan bitnya, sehingga tidak terjadi kesalahan pembacaan data yang dikirimkan
Pastikan Xbee saling terhubung melalui XCTU sebelum menghubungkan ke rangkaian utama
Penggunaan Shift Register
Pastikan selalu membaca datasheet yang sesuai, walaupun pada umunya desainnya sama, namun nama yang digunakan setiap vendor bisa berbeda
Sebagai kata penutup untuk mengakhiri project Piano Candy Machine ini, saya mengucapkan banyak terima kasih untuk anggota kelompok saya. Saya juga bereterima kasih kepada Pak Sonny yang sudah memberikan materi kuliah yang sangat menarik sehingga wawasan saya bertambah. Semoga postingan blog saya kali ini juga berguna bagi pembaca sekalian. Terima kasih!
Gambar 3 - anggota kelompok kami, dari kiri ke kanan : Ardian, Olivia, Hendy(saya), Anthony
Nah, rencana sekarang adalah merapikan capacitive piano yang ada. Kami memutuskan untuk membuat PCB sehingga penggunakan kabel dapat diminimalisir. Kami menggunakan software Altium untuk mendesain PCB.
Gambar 1 - PCB yang sudah didesain untuk capacitive piano
Kami menggunakan jasa sebuah toko di Jalan Ahmad Yani, Bandung yang bernama Spectra. Sesampainya disana, karena baru pertama kali mencetak PCB, saat itu saya dan Anthony yang kesana mendapatkan pengetahuan baru dari mas-mas yang menjaga disana. Ternyata desain PCB kami kurang tepat, hal yang seharusnya kami lakukan adalah:
desain garis untuk PCB minimal 0.3
desain di bottom layer
harus mengimajinasikan jika komponen akan diletakkan dibalik jalur PCB
perhatikan IC yang akan digunakan bertipe DIP atau SMD
Gambar 2 - PCB setelah di-edit oleh mas-mas di Spectra(kanan)
Proses mencetak PCB membutuhkan waktu 1 hari, setelah PCB jadi, kami langsung menyolder komponen-komponen ke PCB.
Gambar 3 - PCB yang sudah di solder(bawah)
Gambar 4 - PCB yang sudah di solder(atas)
Nah setelah itu kami mencoba menyusun kembali rangkaian seperti yang kami rangkai sebelumnya, akan tetapi hal ini tidak berhasil, kami rasa permasalahan ada pada shift register SN74HC595. Setelah ngotak-ngatik sampai jam 11an malam dan tidak mendapatkan hasil seperti yang kami inginkan, sedangkan besok paginya sudah harus presentasi, maka kami memutuskan untuk kembali ke desain awal, dimana tidak menggunakan shift register. Oleh karena itu, kode program juga harus diganti. Kode yang kami gunakan sekaligus menjadi kode final untuk presentasi adalah sebagai berikut.
#include <Servo.h>
int servoPin = 9;
int debugLED = 13;
unsigned long currentMillis;
unsigned long previousMillis;
Servo servo;
void setup()
{
pinMode(debugLED, OUTPUT);
servo.attach(servoPin);
Serial.begin(9600);
servo.write(0);
}
void loop()
{
if (Serial.available() >= 21) {
// look for the start byte
if (Serial.read() == 0x7E) {
//blink debug LED to indicate when data is received
digitalWrite(debugLED, HIGH);
delay(100);
digitalWrite(debugLED, LOW);
// read the variables that we're not using out of the buffer
for (int i = 0; i<20; i++) {
byte discard = Serial.read();
}
if((Serial.read() == 'W') && (Serial.read() == 'I') && (Serial.read() == 'N')){
currentMillis = millis();
servo.write(0);
previousMillis = currentMillis;
while(currentMillis - previousMillis < 250){
currentMillis = millis();
servo.write(125);
}
servo.write(0);
}
}
}
}
/* PIANO */
// Import the CapacitiveSensor Library.
#include <CapacitiveSensor.h>
int speaker = 10;
int LED[6] = {A5, A4, A3, A2, A1, A0};
//int song[49] = {1,2,3,1,3,1,3,2,3,4,3,2,4,3,4,5,3,5,3,5,4,5,6,5,4,6,5,1,2,3,4,5,6,2,3,4,5,6,7,3,4,5,6,7,6,4,7,5,1};
//int song[24] = {5, 3, 3, 4, 2, 2, 1, 2, 3, 4, 5, 5, 5, 5, 3, 3, 4, 2, 2, 1, 3, 5, 5, 1};
int song[24] = {5,6,5,4,3,4,5,2,3,4,3,4,5,5,6,5,4,3,4,5,2,5,3,1};
int state = 0;
int currNote = 0;
int cek = 0;
// Set the Send Pin & Receive Pin.
CapacitiveSensor cs_2_3 = CapacitiveSensor(2,3); // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired
CapacitiveSensor cs_2_4 = CapacitiveSensor(2,4); // 10M resistor between pins 4 & 6, pin 6 is sensor pin, add a wire and or foil
CapacitiveSensor cs_2_5 = CapacitiveSensor(2,5); // 10M resistor between pins 4 & 8, pin 8 is sensor pin, add a wire and or foil
CapacitiveSensor cs_2_6 = CapacitiveSensor(2,6); // 10M resistor between pins 4 & 8, pin 8 is sensor pin, add a wire and or foil
CapacitiveSensor cs_2_7 = CapacitiveSensor(2,7); // 10M resistor between pins 4 & 8, pin 8 is sensor pin, add a wire and or foil
CapacitiveSensor cs_2_8 = CapacitiveSensor(2,8); // 10M resistor between pins 4 & 8, pin 8 is sensor pin, add a wire and or foil
CapacitiveSensor cs_2_9 = CapacitiveSensor(2,9); // 10M resistor between pins 4 & 8, pin 8 is sensor pin, add a wire and or foil
void setup(){
cs_2_3.set_CS_AutocaL_Millis(0xFFFFFFFF); //turn off autocalibrate on channel 1 - just as an example
// Arduino start communicate with computer.
Serial.begin(9600);
pinMode(serPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
for(int i=0; i<6; i++)
pinMode(LED[i], OUTPUT);
ledCheck();
}
void loop(){
// Set a timer.
long start = millis();
// Set the sensitivity of the sensors.
long total1 = cs_2_3.capacitiveSensor(30);
long total2 = cs_2_4.capacitiveSensor(30);
long total3 = cs_2_5.capacitiveSensor(30);
long total4 = cs_2_6.capacitiveSensor(30);
long total5 = cs_2_7.capacitiveSensor(30);
long total6 = cs_2_8.capacitiveSensor(30);
long total7 = cs_2_9.capacitiveSensor(30);
//Turn on desired output on LED
turnLED(state);
// When hand is touched the sensor, the speaker will produce a tone.
// I set a threshold for it, so that the sensor won't be too sensitive.
if (total1 > 150) currNote = 1;
if (total2 > 150) currNote = 2;
if (total3 > 150) currNote = 3;
if (total4 > 150) currNote = 4;
if (total5 > 150) currNote = 5;
if (total6 > 150) currNote = 6;
if (total7 > 150) currNote = 7;
if (total1<=150 & total2<=150 & total3<=150 & total4<=150 & total5<=150 & total6<=150 & total7<=150)currNote = 8;
// When hand didn't touch on it, no tone is produced.
if (total1<=150 & total2<=150 & total3<=150 & total4<=150 & total5<=150 & total6<=150 & total7<=150)
noTone(speaker);
if (checkSong(state)==1) {
state++;
}
if (state == 24) {
makeSound(currNote);
state = 0;
Serial.print("WIN");
delay (500);
ledCheck();
}
delay(10); // arbitrary delay to limit data to serial port
makeSound(currNote);
}
void ledCheck(){
int counter = 0;
while(counter!=6){
digitalWrite(LED[counter], HIGH);
for(int j=0; j<6; j++){
if(counter != j)
digitalWrite(LED[j], LOW);
}
counter++;
delay(100);
}
counter--;
while(counter!=-1){
digitalWrite(LED[counter], HIGH);
for(int j=0; j<6; j++){
if(counter != j)
digitalWrite(LED[j], LOW);
}
counter--;
delay(100);
}
for(int i=0; i<3; i++){
for(int i=0; i<6; i++){
digitalWrite(LED[i], HIGH);
}
delay(200);
for(int i=0; i<6; i++){
digitalWrite(LED[i], LOW);
}
delay(200);
}
}
void makeSound(int note) {
// When hand is touched the sensor, the speaker will produce a tone.
// I set a threshold for it, so that the sensor won't be too sensitive.
if (note == 1) tone(speaker,523);
if (note == 2) tone(speaker,587);
if (note == 3) tone(speaker,659);
if (note == 4) tone(speaker,698);
if (note == 5) tone(speaker,784);
if (note == 6) tone(speaker,880);
if (note == 7) tone(speaker,988);
if (note == 8) noTone(speaker);
}
int checkSong (int state) {
if (currNote == song[state]) {
return 1;
}
else {
return 0;
}
}
void turnLED (int state) {
for(int i=0; i<6; i++){
if(i == (song[state]-1))
digitalWrite(LED[i], HIGH);
else
digitalWrite(LED[i],LOW);
}
}
Nah hasil akhir setelah dijalankan sekitar jam 3 pagi dapat dilihat pada video berikut.
Ohiya, sambil kita ngoprek, ada juga yang sambil membuat materi buat presentasi besoknya, materi presentasi dan hari presentasi akan diceritakan di post berikutnya, so tunggu postingan saya berikutnya ya!
Setelah membuat desain candy machine dengan kardus pada postingan sebelumnya, kami mencoba membuat desain candy machine dengan acrylic. Setelah menggambar dengan menggunakan salah satu software desain grafis, didapaptkan gambar seperti pada gambar 1. Gambar ini yang kemudian akan menjadi panduan dalam pemotongan acrylic.
Gambar 1 - desain bagian-bagian dari candy machine yang akan dijadikan acrylic
Kami menggunakan jasa toko Angkasa Putra untuk melakukan pemotongan acrylic. Setelah Acrylic terpotong, kami menggunakan hot glue gun untuk emnghubungkan antara tiap bagian. Setelah tiap bagian terhubung, kami menggunakan kode program dan komponen yang sama dengan percobaan sebelumnya. Hasilnya candy machine yang terbuat dari acrylic dapat dilihat pada video berikut.
Nah setelah membuat Candy Machine dengan acrylic, saatnya membuat capacitive piano. Capacitive Piano yang akan kami buat sudah di oprek terlebih dahulu oleh anggota kelompok kami, yaitu Olivia dan Ardian. Proses mereka membuat capacitive piano dapat dilihat di tautan berikut. Nah setelah jadi Capacitive Piano dapat dilihat seperti video dibawah ini.
Saya juga melakukan modifikasi pada piano sehingga dapat menyalakan 7 buah LED dengan menggunakan shift register 74HC595.
Saya merangkai dengan menggunakan skema seperti pada gambar 2.
Gambar 2 - skema rangkaian piano candy machine dengan shift register 74HC595
Kabel warna ungu nantinya disambungkan ke capacitive sensor untuk mendeteksi apakah tuts piano ditekan atau tidak.
Setelah ngoprek cukup lama, akhirnya saya berhasil menghubungkan capacitive piano dan candy machine dengan xbee seperti pada video berikut.
Nah selanjutnya tinggal melakukan modifikasi pada capacitive piano sehingga menjadi lebih rapi dan mudah digunakan. So, tunggu postingan selanjutnya ya!
Oke, sekarang saatnya membuat desain untuk candy machine. Pada awalnya, kami ingin membuat seperti pada website ini. Namun, setelah kami memikirkan ulang dan melakukan feasibility analysis, maka kami rasa untuk membuat candy machine seperti itu dibutuhkan effort, waktu dan biaya yang cukup besar, selain itu peralatan yang digunakan juga sulit untuk dicari. Oleh karena itu, kami berpikir dam mencoba membuat desain sendiri. Setelah kami merinci alat dan komponen apa saja yang dibutuhkan, kami mendapati bahwa kami pasti akan menggunakan servo dalam pembuatan candy machine ini. Oleh karena itu kami membeli servo di toko anam.
Gambar 1 - servo yang kami beli dari toko anam
Nah setelah servo sudah ada, kami membaca tutorial dari arduino.cc, setelah itu kami mulai mencoba-coba menggunakan servo, kami mencoba merangkai servo seperti pada gambar 2.
Gambar 2 - rangkain servo yang terhubung ke Arduino
Lalu kami membuat kode dan mengimplementasikannya ke Arduino. Kode yang kami gunakan adalah
Setelah cukup puas dengan servo, kami mencoba membuat kerangka untuk candy machine dengan menggunakan kardus, setelah motong-motong kardus dalam waktu yang cukup lama, kami mendapatkan hasil akhir seperti pada video berikut.
Akhinya design concept kami untuk candy machine selesai, berikutnya kami akan mencoba membuat capacitive pianonya, so, tunggu postingan selanjutnya ya!
Setelag ngoprek Arduino dengan berbagai macam sensor dan modul, sekarang saatnya untuk mengerjakan tugas besar dari mata kuliah Interaksi Manusia dengan Komputer dan Antarmuka. Saya dan 3 orang teman saya membuat kelompok. Kelompok saya terdiri dari Hendy(saya sendiri), Anthony, Olivia, dan Ardian. Kami sepakat untuk membuat piano candy machine, karena kami ingin membantu anak-anak untuk dapat bermain musik.
Gambar 1 - piano capacitive touch yang sangat menginspirasi (sumber)
Piano Candy Machine terinspirasi dari web ini untuk piano dengan capacitive touch, sedangkan candy machinenya sendiri terinspirasi dari web ini. Kami ingin menggabungkan kedua perangkat tersebut menjadi satu alat untuk pembelajaran. Candy machine dipilih sebagai reward yang akan memacu anak-anak untuk terus berlatih, karena seperti kita ketahui bahwa anak-anak sangat menyukai permen.
Gambar 2 - candy machine yang sangat menginspirasi (sumber)
Nah untuk part #1 nya hanya membahas sampai penentuan topik saja, tunggu post berikutnya yang jauh lebih menarik ya!
Setelah sekian lama tidak ngeblog karena banyaknya tugas di akhir semester, akhirnya sekarang saya berkesempatan untuk ngeblog lagi. Setelah membahas mengenai nRF24L01 pada postingan sebelumnya, dan juga saya sudah me-mention xbee pada postingan sebelumnya, kali ini saya akan membahas mengenai komunikasi antara Xbee dengan arduino. Tujuannya agar pembaca dapat memahami perbedaan Xbee dan nRF24L01.
Buku yang saya gunakan untuk belajar Xbee adalah Building Wireless Sensor Networks. Buku ini menjelaskan banyak hal mengenai Xbee mulai dari dasar hingga implementasinya. Namun sangat disayangkan karena buku ini hanya membahas mengenai xbee series 2.
Seperti yang diketahui, xbee ada 2 jenis, yaitu Xbee series 1 dan Xbee series 2, antara Xbee series 1 dan series 2 tidak bisa saling terhubung, karena protokolnya berbeda. Xbee series 1 beroperasi dengan menggunakan protokol 802.15.4(Low-Rate Wireless Personal Networks) sedangkan Xbee series 2 beroperasi pada protokol Zigbee (protokol yang dibangun diatas 802.15.4). Saya akan menggunakan Xbee series 2, saya memilih Xbee S2 karena setelah saya mencari tahu di internet, Xbee series 2 dapat mengimplementasikan mesh networking.
Gambar 1 - Xbee Series 2
Xbee S2 dapat mengimplementasikan mesh networking karena pada Xbee S2 tiap module XBee dapat ditentukan perannya dalam suatu topologi jaringan yang hendak kita bangun. Peran yang dimaksud adalah sebagai Coordinator, Router maupun End-Device.
Saya tidak akan membahas lebih lanjut mengenai Xbee, karena bisa satu buku untuk membahas Xbee sendiri, saya sangat menyarankan pembaca membaca buku Building Wireless Sensor Networks agar dapat memahami XBee S2 dengan lebih baik.
Untuk melakukan setting pada Xbee, dibutuhkan Xbee adapter, yaitu suatu adapter yang berisi chip converter FTDI to serial untuk mengupload firmware pada Xbee. Xbee ini unik karena memliki ukuran pin yang tidak biasa, sehingga memerlukan breakout board untuk dapat mengoperasikannya pada breadboard pada umumnya.
Gambar 2 - Xbee adapter dan breakout board
Yang paling perlu diperhatikan ketika menggunakan xbee adalah pastikan xbee terhubung dengan sumber tegangan sebesar 3.3V, karena berdasarkan pengalaman orang lain (saya belum dan tidak mau mencoba) ketika xbee dihubungkan dengan sumber tegangan 5V maka modul xbee tersebut dapat menjadi bricked atau rusak.
Oke, untuk percobaan kali ini, saya akan membuat 1 Xbee untuk mengirimkan kata-kata dan 1 Xbee lagi sebagai pemroses data, saya akan menggunakan alat sebagai berikut:
Arduino Uno x1
Arduino Mega x1
Xbee S2 x2
Xbee adapter x1
Xbee breakout board x2
breadboard x1
LED x1
kabel (untuk jumper) secukupnya
Nah, langkah pertama yang saya lakukan adalah melakukan setting pada Xbee. Saya akan mensetting firmware pada Xbee saya, 1 sebagai Coordinator dengan mode API, 1 lagi sebagai router dengan mode AT. Untuk mengupdate firmware pada Xbee digunakan program dari Digi yang bernama X-CTU. Program ini dapat diunduh secara gratis dari website Digi.
Gambar 3 - 1 buah Xbee S2 di setting dengan mode Coordinator API
Gambar 4 - 1 buah Xbee S2 di setting dengan mode Router AT
Nah, setelah mensetting XBee, saya langsung membuat rangkaian seperti pada gambar 5.
Gambar 5 - rangkaian Xbee S2 dengan mode Router ATyang terhubung dengan Arduino Mega
Selanjutnya saya juga membuat rangkaian untuk Xbee 1 lagi dan Arduino seperti pada gambar 6.
Gambar 6 - rangkaian Xbee S2 dengan mode Coordinator API yang terhubung dengan Arduino Uno
Nah jadi dari rangkaian itu dapat diketahui bahwa saya akan menyalakan LED di Arduino Uno berdasarkan data yang dikirim dari XBee yang terhubung dengan Arduino Mega. Kode yang saya gunakan adalah
int LED = 11;
int debugLED = 13;
void setup() {
pinMode(LED,OUTPUT);
pinMode(debugLED,OUTPUT);
Serial.begin(9600);
}
void loop() {
// make sure everything we need is in the buffer
if (Serial.available() >= 21) {
// look for the start byte
if (Serial.read() == 0x7E) {
//blink debug LED to indicate when data is received
digitalWrite(debugLED, HIGH);
delay(10);
digitalWrite(debugLED, LOW);
// read the variables that we're not using out of the buffer
for (int i = 0; i<20; i++) {
byte discard = Serial.read();
}
char pertama = Serial.read();
char kedua = Serial.read();
char ketiga = Serial.read();
if((pertama == 'o') && (kedua == 'n')){
digitalWrite(LED, HIGH);
}
else if((pertama == 'o') && (kedua == 'f') && (ketiga == 'f')){
digitalWrite(LED, LOW);
}
}
}
}
Hasil akhir percobaan ini dapat dilihat pada video berikut.
Nah setelah mencoba menggunakan Xbee dan nRF24L01, saya dapat mengatakan bahwa menggunakan Xbee masih lebih mudah dibandingkan dengan nRF24L01, hal ini dikarenakan untuk mengoperasikan nRF24L01, diperlukan pembuatan kode dari scratch/ dasar. Hal ini bisa menjadi keuntungan maupun kerugian bagi nRF24L01, karena dengan membuat kode sendiri bisa membuat nRF24L01 menjadi lebih sesuai dengan apa yang kita inginkan, namun disisi lain, dimana waktu dan tingkat kerumitan sangat diperhitungkan nRF24L01 sangat tidak disarankan. Di lain sisi, Xbee hanya tinggal plug & play saja (setelah di setting) namun perlu dipertimbangkan untuk menggunakan Xbee karena harganya yang berbeda jauh sekali dengan nRF24L01.
Demikian postingan saya kali ini, semoga bermanfaat!
Setelah tidak lama ngoprek karena kesibukan yang luar biasa, akhirnya hari ini ada kesempatan buat ngoprek. Hari ini saya mencoba bermain dengan radio, radio yang saya gunakan adalah nRF24L01.
Alasan saya menggunakan nRF24L01 adalah karena jarang orang yang mengetahui keberadaan chip ini untuk koneksi Arduino secara wireless. Sebagian besar orang jika ditanya cara untuk menghubungkan Arduino secara wireless, biasanya menjawab dengan menggunakan bluetooth atau menggunakan XBee. Karena XBee terlalu mahal dan bluetooth agak mahal, maka saya memilih menggunakan nRF24L01 ini.
Gambar 1 - nRF24L01
Saat tulisan ini diketik, harga 1 unit XBee yang biasa berkisar di Rp.300.000,00 - Rp.400.000,00,
harga 1 unit bluetooth module HC-05/ HC-07 berkisar di Rp. 100.000,00 - Rp. 175.000,00,
harga 1 unit nRF24L01 berkisar di Rp.50.000,00 - Rp.100.000,00
Nah dari harga saja sudah terlihat bahwa nRF24L01 terlihat lebih pas di kantong :)
Kalo dari segi teknis, XBee, Bluetooth, dan nFR24L01 sama-sama beroperasi di frekuensi 2,4GHz. Perlu diperhatikan juga bahwa ada XBee seri tertentu yang tidak beroperasi di 2,4GHz. Untuk pengetahuan teknis lebih lanjut bisa dibaca di XBee, bluetooth, dan nRF24L01
Percobaan pertama saya gatot alias gagal total, setelah lepas pasang kabel, cek sana sini, coba lagi, masih gatot juga. Akhirnya saya coba menelulsuri pelan-pelan, dan ternyata saya mendapatkan pencerahan, yaitu ternyata nRF24L01 ini menggunakan SPI, dan ternyata pin Arduino Uno dan Mega untuk komunikasi via SPI ini berbeda letaknya, berdasarkan http://arduino.cc/.
Kode yang saya gunakan adalah
/*
Copyright (C) 2011 J. Coliz
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
*/
/**
* Example for Getting Started with nRF24L01+ radios.
*
* This is an example of how to use the RF24 class. Write this sketch to two
* different nodes. Put one of the nodes into 'transmit' mode by connecting
* with the serial monitor and sending a 'T'. The ping node sends the current
* time to the pong node, which responds by sending the value back. The ping
* node can then see how long the whole cycle took.
*/
#include
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
//
// Hardware configuration
//
// Set up nRF24L01 radio on SPI bus plus pins 9 & 10
RF24 radio(9, 10);
//
// Topology
//
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = {
0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
//
// Role management
//
// Set up role. This sketch uses the same software for all the nodes
// in this system. Doing so greatly simplifies testing.
//
// The various roles supported by this sketch
typedef enum {
role_ping_out = 1, role_pong_back }
role_e;
// The debug-friendly names of those roles
const char* role_friendly_name[] = {
"invalid", "Ping out", "Pong back"};
// The role of the current running sketch
role_e role = role_pong_back;
void setup(void)
{
//
// Print preamble
//
Serial.begin(57600);
printf_begin();
printf("\n\rRF24/examples/GettingStarted/\n\r");
printf("ROLE: %s\n\r",role_friendly_name[role]);
printf("*** PRESS 'T' to begin transmitting to the other node\n\r");
//
// Setup and configure rf radio
//
radio.begin();
// optionally, increase the delay between retries & # of retries
radio.setRetries(15,15);
// optionally, reduce the payload size. seems to
// improve reliability
//radio.setPayloadSize(8);
//
// Open pipes to other nodes for communication
//
// This simple sketch opens two pipes for these two nodes to communicate
// back and forth.
// Open 'our' pipe for writing
// Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
//if ( role == role_ping_out )
{
//radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
}
//else
{
//radio.openWritingPipe(pipes[1]);
//radio.openReadingPipe(1,pipes[0]);
}
//
// Start listening
//
radio.startListening();
//
// Dump the configuration of the rf unit for debugging
//
radio.printDetails();
}
void loop(void)
{
//
// Ping out role. Repeatedly send the current time
//
if (role == role_ping_out)
{
// First, stop listening so we can talk.
radio.stopListening();
// Take the time, and send it. This will block until complete
unsigned long time = millis();
printf("Now sending %lu...",time);
bool ok = radio.write( &time, sizeof(unsigned long) );
if (ok)
printf("ok...");
else
printf("failed.\n\r");
// Now, continue listening
radio.startListening();
// Wait here until we get a response, or timeout (250ms)
unsigned long started_waiting_at = millis();
bool timeout = false;
while ( ! radio.available() && ! timeout )
if (millis() - started_waiting_at > 200 )
timeout = true;
// Describe the results
if ( timeout )
{
printf("Failed, response timed out.\n\r");
}
else
{
// Grab the response, compare, and send to debugging spew
unsigned long got_time;
radio.read( &got_time, sizeof(unsigned long) );
// Spew it
printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time);
}
// Try again 1s later
delay(1000);
}
//
// Pong back role. Receive each packet, dump it out, and send it back
//
if ( role == role_pong_back )
{
// if there is data ready
if ( radio.available() )
{
// Dump the payloads until we've gotten everything
unsigned long got_time;
bool done = false;
while (!done)
{
// Fetch the payload, and see if this was the last one.
done = radio.read( &got_time, sizeof(unsigned long) );
// Spew it
printf("Got payload %lu...",got_time);
// Delay just a little bit to let the other unit
// make the transition to receiver
delay(20);
}
// First, stop listening so we can talk
radio.stopListening();
// Send the final one back.
radio.write( &got_time, sizeof(unsigned long) );
printf("Sent response.\n\r");
// Now, resume listening so we catch the next packets.
radio.startListening();
}
}
//
// Change roles
//
if ( Serial.available() )
{
char c = toupper(Serial.read());
if ( c == 'T' && role == role_pong_back )
{
printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");
// Become the primary transmitter (ping out)
role = role_ping_out;
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
}
else if ( c == 'R' && role == role_ping_out )
{
printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
// Become the primary receiver (pong back)
role = role_pong_back;
radio.openWritingPipe(pipes[1]);
radio.openReadingPipe(1,pipes[0]);
}
}
}
/*
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
*/
/**
* Example for Getting Started with nRF24L01+ radios.
*
* This is an example of how to use the RF24 class. Write this sketch to two
* different nodes. Put one of the nodes into 'transmit' mode by connecting
* with the serial monitor and sending a 'T'. The ping node sends the current
* time to the pong node, which responds by sending the value back. The ping
* node can then see how long the whole cycle took.
*/
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
//
// Hardware configuration
//
// Set up nRF24L01 radio on SPI bus plus pins 9 & 10
RF24 radio(48, 49);
//
// Topology
//
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = {
0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
//
// Role management
//
// Set up role. This sketch uses the same software for all the nodes
// in this system. Doing so greatly simplifies testing.
//
// The various roles supported by this sketch
typedef enum {
role_ping_out = 1, role_pong_back }
role_e;
// The debug-friendly names of those roles
const char* role_friendly_name[] = {
"invalid", "Ping out", "Pong back"};
// The role of the current running sketch
role_e role = role_pong_back;
void setup(void)
{
//
// Print preamble
//
Serial.begin(57600);
printf_begin();
printf("\n\rRF24/examples/GettingStarted/\n\r");
printf("ROLE: %s\n\r",role_friendly_name[role]);
printf("*** PRESS 'T' to begin transmitting to the other node\n\r");
//
// Setup and configure rf radio
//
radio.begin();
// optionally, increase the delay between retries & # of retries
radio.setRetries(15,15);
// optionally, reduce the payload size. seems to
// improve reliability
//radio.setPayloadSize(8);
//
// Open pipes to other nodes for communication
//
// This simple sketch opens two pipes for these two nodes to communicate
// back and forth.
// Open 'our' pipe for writing
// Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
//if ( role == role_ping_out )
{
//radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
}
//else
{
//radio.openWritingPipe(pipes[1]);
//radio.openReadingPipe(1,pipes[0]);
}
//
// Start listening
//
radio.startListening();
//
// Dump the configuration of the rf unit for debugging
//
radio.printDetails();
}
void loop(void)
{
//
// Ping out role. Repeatedly send the current time
//
if (role == role_ping_out)
{
// First, stop listening so we can talk.
radio.stopListening();
// Take the time, and send it. This will block until complete
unsigned long time = millis();
printf("Now sending %lu...",time);
bool ok = radio.write( &time, sizeof(unsigned long) );
if (ok)
printf("ok...");
else
printf("failed.\n\r");
// Now, continue listening
radio.startListening();
// Wait here until we get a response, or timeout (250ms)
unsigned long started_waiting_at = millis();
bool timeout = false;
while ( ! radio.available() && ! timeout )
if (millis() - started_waiting_at > 200 )
timeout = true;
// Describe the results
if ( timeout )
{
printf("Failed, response timed out.\n\r");
}
else
{
// Grab the response, compare, and send to debugging spew
unsigned long got_time;
radio.read( &got_time, sizeof(unsigned long) );
// Spew it
printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time);
}
// Try again 1s later
delay(1000);
}
//
// Pong back role. Receive each packet, dump it out, and send it back
//
if ( role == role_pong_back )
{
// if there is data ready
if ( radio.available() )
{
// Dump the payloads until we've gotten everything
unsigned long got_time;
bool done = false;
while (!done)
{
// Fetch the payload, and see if this was the last one.
done = radio.read( &got_time, sizeof(unsigned long) );
// Spew it
printf("Got payload %lu...",got_time);
// Delay just a little bit to let the other unit
// make the transition to receiver
delay(20);
}
// First, stop listening so we can talk
radio.stopListening();
// Send the final one back.
radio.write( &got_time, sizeof(unsigned long) );
printf("Sent response.\n\r");
// Now, resume listening so we catch the next packets.
radio.startListening();
}
}
//
// Change roles
//
if ( Serial.available() )
{
char c = toupper(Serial.read());
if ( c == 'T' && role == role_pong_back )
{
printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");
// Become the primary transmitter (ping out)
role = role_ping_out;
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
}
else if ( c == 'R' && role == role_ping_out )
{
printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
// Become the primary receiver (pong back)
role = role_pong_back;
radio.openWritingPipe(pipes[1]);
radio.openReadingPipe(1,pipes[0]);
}
}
}
Nah, setelah mengganti kode RF24 radio(9, 10); dengan RF24 radio(48, 49); serta menyesuaikan pin SPI lainnya, akhirnya percobaan saya berhasil dan dapat dilihat pada video berikut.
Karena saya kurang puas dengan tutorial sebelumnya, akhirnya saya coba googling-googling lagi mencari tutorial yang lebih menantang, nah akhirnya saya menemukan tutorial yang agak menarik di http://www.bajdi.com/. Setelah saya lihat-lihat sekilas, ternyata tutorial yang ini berbeda dengan tutorial yang saya lakukan sebelumnya, tutorial ini menggunakan library Mirf.h, sedangkan tutorial sebelumnya menggunakan RF24.h. Oke, saya pun langsung mencoba merangkai.
Gambar 4 - tabel skema rangkaian yang seharusnya saya buat
Gambar 5 - rangkaian yang sudah saya buat
Oke ternyata tidak langsung berhasil, setelah saya lihat-lihat ternyata Mirf.h mendeklarasikan pin CE dan CSN pada Uno di pin 7 dan 8, saya pun memperbaiki rangkaian saya dan menjalankan lagi. Kode yang saya gunakan adalah
// http://www.bajdi.com
// Nrf24L01 connected to Arduino Uno
// Nrf24L01 connection details http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
// Receives analog value from transmitter and maps it to a PWM range (0-255) to dim a led
#include
#include
#include
#include
int rate;
int ledValue;
const int led = 3;
void setup(){
Serial.begin(9600);
pinMode(led, OUTPUT);
Mirf.spi = &MirfHardwareSpi;
Mirf.init();
Mirf.setRADDR((byte *)"serv1");
Mirf.payload = sizeof(rate);
Mirf.config();
}
void loop(){
while(!Mirf.dataReady()){
}
Mirf.getData((byte *) &rate);
ledValue = (map( rate, 0, 1024, 0, 255 ) );
analogWrite(led, ledValue);
Serial.println(ledValue);
delay(10);
}
// http://www.bajdi.com
// Nrf24L01 connected to Mega 2560
// Nrf24L01 connection details http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
// Transmit analog value from pin A0 to the receiver
#include
#include
#include
#include
int rate;
void setup(){
Serial.begin(9600);
Mirf.cePin = 48; //ce pin on Mega 2560, REMOVE THIS LINE IF YOU ARE USING AN UNO
Mirf.csnPin = 49; //csn pin on Mega 2560, REMOVE THIS LINE IF YOU ARE USING AN UNO
Mirf.spi = &MirfHardwareSpi;
Mirf.init();
Mirf.setRADDR((byte *)"clie1");
Mirf.payload = sizeof(rate);
Mirf.config();
}
void loop(){
rate = analogRead(A0);
Serial.println(rate);
Mirf.setTADDR((byte *)"serv1");
Mirf.send((byte *) &rate);
while(Mirf.isSending()){
}
}
Hasil akhirnya dapat dilihat pada video berikut.
Nah sekian saja postingan kali ini, semoga membuka wawasan pembaca mengenai komunikasi radio pada Arduino. Selamat mencoba!
Akhirnya tugas mata kuliah Interkasi Manusia Komputer untuk minggu ini selesai juga, jadinya saya membuat pemodelan secure door access control system dengan Arduino. Saya menggabungkan fungsi dari Arduino, keypad, 7-segment, dan speaker dan RGB LED.
Langsung saja, postingan saya kali ini akan membahas tentang bagaimana cara membuat pemodelan secure door access control system, sebelum saya melanjutkan, saya anggap pembaca sudah mengerti bagaimana cara mengoperasikan Arduino dengan keypad, 7-segment, dan speaker. Tutorial untuk RGB LED dapat dilihat di adafruit.com.
Agar lebih mudah membayangkan hasil akhirnya seperti apa, silahkan lihat video yang sudah saya buat dibawah ini.
Jadi skema rangkaian yang akan saya buat dapat dilihat pada gambar 1.
Gambar 1 - skema rangkaian pemodelan secure door access control system dengan Arduino
Gambar 2 - rangkaian yang sudah saya buat
Pada dasarnya, saya hanya menggabungkan kode-kode program yang ada pada tutorial Arduino dengan keypad, 7-segment, dan speaker dan RGB LED. Ditambah sedikit algoritma untuk menentukan state yang saya inginkan. State diagramnya dapat dilihat pada gambar 3.
Gambar 3 - state diagram secure door access control system yang akan saya buat
Saya membuat dengan ketentuan sebagai berikut:
state "no pin entered", yang terjadi:
LED berwarna biru
7-segment menunjukkan angka 0
state "pin entered", yang terjadi:
LED kedap kedip berwarna merah
7-segment menunjukkan angka yang dimasukkan dan angka 0 untuk angka yang belum dimasukkan
state "unlocked, yang terjadi:
LED berwarna hijau selama 3 detik
terdengar "beep" ketika pindah ke state "no pin entered"
state "alarm", yang terjadi:
LED kedap kedip berwarna putih, kuning, dan biru
bunyi alarm
tidak dapat melakukan apa-apa
state "incorrect pin", yang terjadi:
LED berwarna merah selama 2 detik
terdengar suara "beep" selama 2 detik
ketika keypad ditekan akan terdengar bunyi "beep"
'*' sebagai backspace
'#' sebagai enter
PIN yang saya simpan adalah "7601", kenapa 7601? karena setiap hari saya kuliah di ruangan 7601 :)
nah hasil jatuh bangun ngoding dan ngetes selama beberapa jam di hari sabtu dan minggu kemarin bisa dilihat dibawah ini.
/*----------Speaker---------*/
#include "pitches.h" //library untuk menentukan frekuensi dan nama note
const int speaker = 2; //deklarasi pin untuk speaker
/*----------RGB LED---------*/
//pin dihubungkan ke pin PWM karena fungsi yang akan digunakan menggunakan fungsi analogWrite()
const int redPin = 11; //deklarasi pin yang akan disambungkan dengan LED warna merah
const int greenPin = 10; //deklarasi pin yang akan disambungkan dengan LED warna hijau
const int bluePin = 9; //deklarasi pin yang akan disambungkan dengan LED warna biru
/*----------Keypad----------*/
const int numRows = 4; //jumlah baris pada keypad
const int numCols = 4; //jumlah kolom pada keypad
const int debounceTime = 50; //waktu dalam mili detik untuk menunggu tombol ke kondisi stabil
//keymap menentukan char apa yang muncul apabila suatu tombol ditekan
const char keymap[numRows][numCols] = {
{ '1', '2', '3', 'A' } ,
{ '4', '5', '6', 'B' } ,
{ '7', '8', '9', 'C' } ,
{ '*', '0', '#', 'D' }
};
//array ini menentukan pin yang akan digunakan untuk baris dan kolom pada keypad
const int rowPins[numRows] = { 13, 12, A5, A4 }; //baris 0 sampai 3
const int colPins[numCols] = { A3, A2, A1, A0 }; //kolom 0 sampai 3
/*----------7-segment-------*/
const int clockPin = 3;//deklarasi pin yang akan disambungkan dengan clock pada 74HC595
const int latchPin = 4;//deklarasi pin yang akan disambungkan dengan latch pada 74HC595
const int dataPin = 5;//deklarasi pin yang akan disambungkan dengan data pada 74HC595
/*-----------Main----------*/
const int maxTrial = 3; //kumlah maksimum untuk mencoba memasukkan pin
const char pinStored[4] = {'7', '6', '0', '1'}; //pin yang disimpan
int trial = 0; //counter untuk jumlah percobaan memasukkan pin
char pinTrial[4] = {0, 0, 0, 0}; //default value dari pin (diisi integer 0)
boolean pinEntered = false; //variabel untuk mengecek apakah user sedang memasukkan pin atau tidak
long previousMillis; //variabel untuk perhitungan waktu
unsigned long currentMillis; //variabel untuk perhitungan waktu
void setup(){
/*----------Speaker---------*/
//tidak ada yang perlu di setup dari speaker
/*----------RGB LED---------*/
pinMode(redPin, OUTPUT); //membuat nomor pin yang ada pada variabel redPin menjadi output
pinMode(greenPin, OUTPUT); //membuat nomor pin yang ada pada variabel greenPin menjadi output
pinMode(bluePin, OUTPUT); //membuat nomor pin yang ada pada variabel bluePin menjadi output
/*----------Keypad----------*/
for (int row = 0; row < numRows; row++){
pinMode(rowPins[row], INPUT); //set baris sebagai input
digitalWrite(rowPins[row], HIGH); //buat semua baris tidak aktif
}
for (int column = 0; column < numCols; column++){
pinMode(colPins[column],OUTPUT); //set kolom sebagai input
digitalWrite(colPins[column], HIGH); //buat semua kolom menjadi tidak aktif
}
/*----------7-segment-------*/
pinMode(clockPin, OUTPUT); //membuat nomor pin yang ada pada variabel clockPin menjadi output
pinMode(latchPin, OUTPUT); //membuat nomor pin yang ada pada variabel latchPin menjadi output
pinMode(dataPin, OUTPUT); //membuat nomor pin yang ada pada variabel dataPin menjadi output
}
void loop(){
currentMillis = millis(); //mengassign nilai pada variabel currentMillis dengan waktu ketika loop() dijalankan
readKey(); //menjalankan prosedur readKey();
if((!pinEntered) && (trial != maxTrial)){ //melakukan pengecekan apakah user sedang memasukkan pin atau tidak
idle();
}
else if((pinEntered) && (trial != maxTrial)){ //melakukan pengecekan apakah user sedang memasukkan pin
enterPin();
}
else if(trial == maxTrial){ //melakukan pengecekan apakah user sudah melewatai batas percobaan untuk memasukkan pin
activateAlarm();
}
write7Seg(); //menjalankan prosedur write7seg()
}
/*
prosedur ini menunjukkan state "idle" dimana tidak ada pin yang dimasukkan atau user sedang tidak memasukkan pin
*/
void idle(){
pinEntered = false;
setColor(0, 0, 255);//menyalakan LED dengan warna biru
}
/*
prosedur ini menunjukkan state "pin entered" dimana user sedang memasukkan pin
*/
void enterPin(){
//penggunaan currentMillis - previousMillis untuk menggantikan fungsi delay(), karena cara kerja tampilan di 7-segment tidak dapat mentolerir adanya delay pada program
if(currentMillis - previousMillis > 1000){
setColor(0, 0, 0);//mematikan LED
previousMillis = currentMillis;
}
else if(currentMillis - previousMillis > 500){
setColor(255, 0, 0);//menyalakan LED dengan warna merah
}
}
/*
prosedur ini menunjukkan state "unlocked" dimana user sudah berhasil memasukkan pin dengan benar
*/
void unlocked(){
pinEntered = false;
for(int i=0; i<4; i++){ //mengembalikan data yang tersimpan pada variabel pnyimpan input pin dari user ke keadaan semula
pinTrial[i] = 0;
}
trial = 0; //mengembalikan nilai variabel trial ke nilai semula
previousMillis = currentMillis;
while(currentMillis - previousMillis < 3000){
currentMillis = millis();
setColor(0, 255, 0);//menyalakan LED dengan warna hijau
write7Seg();
}
keypadTone(); //menjalankan prosedur keypadTone()
}
/*
prosedur ini menunjukkan state "incorrect pin" dimana user salah memasukkan pin
*/
void incorrectPin(){
tone(speaker, NOTE_G7, 2000); //men-generate suara dengan frekuensi NOTE_G7 selama 2 detik
pinEntered = false;
for(int i=0; i<4; i++){//mengembalikan data yang tersimpan pada variabel pnyimpan input pin dari user ke keadaan semula
pinTrial[i] = 0;
}
previousMillis = currentMillis;
while(currentMillis - previousMillis < 2000){
currentMillis = millis();
setColor(255, 0, 0); //menyalakan LED dengan warna merah
write7Seg();
}
}
/*
prosedur ini menunjukkan state "alarm" dimana user sudah salah memasukkan pin sebanyak 3x
*/
void activateAlarm(){
previousMillis = millis();
while(true){
currentMillis = millis();
if(currentMillis - previousMillis > 300){
setColor(255, 255, 255); //menyalakan LED dengan warna putih
previousMillis = currentMillis;
tone(speaker, NOTE_A7, 200); //meng-generate suara dengan frekuensi NOTE_A7 selama 200ms
}
else if(currentMillis - previousMillis > 200){
setColor(255 ,255 ,0); //menyalakan LED dengan warna kuning
}
else if(currentMillis - previousMillis > 100){
setColor(0 ,0 ,255); //menyalakan LED dengan warna biru
tone(speaker, NOTE_D7, 200); //meng-generate suara dengan frekuensi NOTE_D7 selama 200ms
}
write7Seg();
}
}
/*
prosedur ini berfungsi untuk memproses inputan dari user
*/
void readKey(){
char key = getKey(); //variabel sementara untuk input yang terbaca dari user
int pinTrialLength = 0;
for(int i=0; i<4; i++){ //mengecek apakah user sudah memasukkan pin sebanyak 4-digit atau belum
if(pinTrial[i] != 0){ //mengecek apakah user sudah memasukkan pin atau belum
pinTrialLength++;
}
}
if(key == '*'){ //proses yang akan dilakukan apabila user menekan tombol '*' pada keypad
for(int i=3; i>=0; i--){ //melakukan iterasi dari belakang untuk "menghapus" pin yang terkahir dimasukkan oleh user
if(pinTrial[i] != 0){ //mengecek apakah user sudah memasukkan pin atau belum
pinTrial[i] = 0;
if(i == 0){ //mengembalikkan ke state idle apabila user menghapus digit pin pertama yang ia masukkan
pinEntered = false;
}
break;
}
}
keypadTone();
}
else if((key == '#') && (pinTrialLength == 4)){ //proses yang akan dilakukan apabila user sudah memasukkan 4-digit pin kemudian menekan tombol '#' pada keypad
int pinMatched = 0;
trial++; //menambahkan jumlah trial yang dilakukan user
for(int i=0; i<4; i++){ //melakukan pengecekan apakah pin yang dimasukkan user benar/ salah
if(pinTrial[i] == pinStored[i]){
pinMatched++;
}
}
keypadTone();
if(pinMatched == 4){ //jika pin yang dimasukkan benar maka akan masuk ke kondisi unlocked
unlocked();
}
else if(pinMatched != 4){ //jika pin yang dimasukkan salah maka akan masuk ke kondisi incorrect pin
incorrectPin();
}
}
else if((key != 0) && (key != 'A') && (key != 'B') && (key != 'C') && (key != 'D') && (key != '#')){ //menentukan key input yang tidak akan diproses apabila dimasukkan/ user menekan tombol pada keypad
for(int i=0; i<4; i++){ //menyimpan input dari user pada variabel sementara (pinEntered[])
if(pinTrial[i] == 0){
pinTrial[i] = key;
pinEntered = true;
break;
}
}
keypadTone();
}
else if(key == '#'){ //apabila user menekan tombol '#' sebelum memasukkan pin sebanyak 4-digit
keypadTone();
}
}
/*
fungsi ini untuk membaca semua input dari user dengan cara menekan salah satu tombol pada keypad
*/
char getKey()
{
char key = 0; //0 menunjukkan tidak ada tombol yang ditekan
for(int column = 0; column < numCols; column++){
digitalWrite(colPins[column],LOW); //aktifkan kolom sekarang
for(int row = 0; row < numRows; row++){ //scan semua baris apakah
// ada tombol yang ditekan
if(digitalRead(rowPins[row]) == LOW) //jika tombol ditekan
{
delay(debounceTime); //debounce
while(digitalRead(rowPins[row]) == LOW)
; //menunggu hingga tombol tidak dalam kondisi ditekan
key = keymap[row][column]; //mengingat tombol apa yang ditekan
}
}
digitalWrite(colPins[column],HIGH); //membuat kolom sekarang menjadi tidak aktif
}
return key; //mengembalikan tombol yang ditekan, 0 jika tidak ada yang ditekan
}
/*
prosedur ini untuk menghasikan suara setiap kali keypad ditekan
*/
void keypadTone(){
tone(speaker, NOTE_G7, 100); //meng-generate suara dengan frekuensi NOTE_G7 selama 100ms
}
/*
prosedur ini berfungsi untuk menampilkan pin pada 7 segment
*/
void write7Seg(){
int8_t digit;
for(int i=0; i<4; i++){ //looping untuk menampilkan setiap digit pada 7-segment
int8_t digit = pinTrial[i];
switch(i){
case 0://digit ke-1
digit = (digit<<4) + 1;
break;
case 1://digit ke-2
digit = (digit<<4) + 2;
break;
case 2://digit ke-3
digit = (digit<<4) + 4;
break;
case 3://digit ke-4
digit = (digit<<4) + 8;
break;
}
digitalWrite(4, LOW);
shiftOut(5, 3, MSBFIRST, digit);//(datapin, clockpin, data)
digitalWrite(4, HIGH);
}
}
/*
fungsi untuk menentukan warna yang akan ditampilkan pada RGB LED
*/
void setColor(int red, int green, int blue){
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
analogWrite(redPin, red); //menulis nilai analog(PWM) sebesar variabel red pada redPin
analogWrite(greenPin, green); //menulis nilai analog(PWM) sebesar variabel green pada greenPin
analogWrite(bluePin, blue); //menulis nilai analog(PWM) sebesar variabel blue pada bluePin
}
Tidak terlalu banyak permasalahan yang dihadapi, palingan ada algoritma yang kurang mangkus atau perlu disempurnakan, saya tidak membuat dokumentasinya, karena memang secara fisik sulit dibedakan dan membutuhkan waktu yang sangat banyak untuk merekam video.
Pada dasarnya, permasalahan yang banyak muncul adalah dari programnya, karena program untuk mengatur rangkaiannya sudah dikerjakan dan dicoba terlebih dahulu sebelum muncul ide untuk membuat secure door access control system.
Gambar 4 - state "no pin entered" (kiri atas), state "pin entered" (kanan atas), state "unlocked" (kiri bawah), state "incorrect pin"(kanan bawah)
Gambar 5 - state "alarm"
Pada percobaan saya ini, saya hanya menggunakan 15 pin pada board Arduino termasuk 6 pin analog yang saya fungsikan sebagai pin digital. Perinciannya adalah sebagai berikut:
keypad menggunakan 8 pin
7-segment menggunakan 3 pin
RGB LED menggunakan 3 pin
speaker menggunakan 1 pin
Sebenarnya penggunaan pin ini masih bisa di minimalisir dengan membuat rangkaian yang dapat menghubungkan keypad dengan hanya 1 buah pin analog saja, namun saya tidak sempat untuk melakukan percobaan karena keterbatasan waktu.
Oke sekian saja postingan saya kali ini, selamat mencoba dan semoga bermanfaat!
Langsung saja, setelah bermain dengan shift register pada postingan sebelumnya dan tangan saya yang gatal melihat ada speaker kecil yang nganggur, saya memutuskan untuk mencoba menghubungkan speaker tersebut dengan Arduino.
Gambar 1 - speaker kecil 0.5W 8Ohm
Setelah googling, saya mendapatkan tutorial dari arduino.cc, nah saya langsung coba menghubungkan seperti yang ada pada link tersebut. Awalnya saya menyolder dahulu untuk menyambungkan speaker dengan kabel.
Gambar 2 - Speaker sudah disolder dan terhubung dengan kabel
Skema rangkaian yang akan saya buat menurut tutorial dari arduino.cc seperti pada gambar 3.
Gambar 3 - skema rangkaian yang akan saya buat
Setelah itu saya membuat rangkaian dan hasilnya dapat dilihat pada gambar 4.
/*
Melody
Plays a melody
circuit:
* 8-ohm speaker on digital pin 8
created 21 Jan 2010
modified 30 Aug 2011
by Tom Igoe
This example code is in the public domain.
http://arduino.cc/en/Tutorial/Tone
*/
#include "pitches.h"
// notes in the melody:
int melody[] = {
NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
4, 8, 8, 4,4,4,4,4 };
void setup() {
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 8; thisNote++) {
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000/noteDurations[thisNote];
tone(8, melody[thisNote],noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(8);
}
}
void loop() {
// no need to repeat the melody.
}
Ah saya sedikit kecewa karena suaranya kecil sekali hingga hampir tidak kedengaran, oleh karena itu kali ini saya tidak membuat videonya.
Saya rasa untuk membuat speaker ini menghasilkan suara yang lebih keras, saya harus menambahkan tegangan yang masuk ke dalam speaker tersebut, tapi saya tidak mau gegabah karena saya pernah baca bahwa ada arus maksimal yang dapat ditarik dari pin IO Arduino, oleh karena itu saya googling lagi dan melihat salah satu diskusi di forum dengan alamat forum.arduino.cc. Ternyata pin 5V pada Arduino tidak terhubung ke ATMega, sehingga tidak terlalu bermasalah ketika menarik arus yang cukup banyak, asalkan tidak melebihi batas arus dari sumber power Arduino, dalam hal ini USB port pada komputer saya. Oke, cukup menarik, jadi skema rangkaian yang akan saya buat dapat dilihat pada gambar 5.
Gambar 5 - skema rangkaian yang akan saya buat
Oh iya, sebelum membuat rangkaian, daftar alat dan komponen yang saya gunakan untuk membuat rangkaian ini adalah
Arduino Uno R3 x1
Kabel USB untuk power Arduino x1
Breadboard x1
Speaker kecil 0.8 ohm 0.5W x1
Transistor npn x1
Resistor 1k ohm x1
Resistor 220 ohm x1
Kabel (untuk jumper) secukupnya
Karena alat dan komponen sudah lengkap, saya langsung membuat rangkaian.
Gambar 6 - rangkaian yang sudah saya buat
Lalu saya menghubungkan Arduino dan menjalankan program yang sama. ternyata speakernya menghasilkan suara yang jauh lebih besar dari sebelumnya. Hasilnya dapat dilihat pada video berikut.
Akhirnya setelah secara random membeli speaker dan berhasil mencobanya, saya rasa postingan kali ini cukup sampai disini. Selamat mencoba dan semoga bermanfaat!