Kita akan membahas sebuah project untuk mendeteksi level air bendungan/sungai. Fungsi pendeteksian ini untuk memberi peringatan dini jika level air pada bendungan melebihi batas dan dikhawatirkan terjadi banjir. Sensor level air terpasang di bendungan sedang ruang operator berjarak ratusan meter dari letak sensor. Agar operator bisa mengetahui kondisi level air maka diperlukan pengiriman data sensor ke display ruang operator. Jika menggunakan kabel sebagai media pengiriman data , ini akan berdampak pada biaya dan rumitnya instalasi.
Solusi yg efisien dalam transmisi data adalah menggunakan sistem wireless (tanpa kabel), salah satu yg sistem wireless yg umum digunakan yaitu gelombang RF (Radio Frequency). Dlm project ini kita memakai RFM12B sebagai RF transceiver
RFM12B dibuat oleh HOPE RF, modul ini mudah digunakan dan harganya yang relatif lebih murah jika dibandingkan dengan XBee Pro. RFM12B Bisa digunakan sebagai Pengirim (Transmitter) maupun penerima (Receiver) Tapi saya kesulitan saat bikin PCBnya, karena pake RFM12B dengan package SMD, buat temen2 saya saranin cari package yang sudah dilengkapi connector biar tinggal colok aja ke microcontroller.
Berikut Gambar rangkaian yang saya gunakan:
Transmitter
Receiver
Alur Kerja:
Saat sensor aktif (terhubung ke +9V), maka Transmitter akan mengirim karakter-karakter khusus yang mewakili setiap sensor.
- Jika sensor Level Air Rendah aktif karakter yang dikirimkan adalah R
- Jika sensor Level Air Normal aktif karakter yang dikirimkan adalah N
- Jika sensor Level Air Tinggi aktif karakter yang dikirimkan adalah T
Jika ada 2 atau 3 sensor yang aktif bersamaan maka karakter yang dikirim adalah sensor Level yang lebih tinggi.
Jika tidak ada sensor yang aktif, maka karakter yang dikirim adalah karakter O
Receiver akan menunggu karakter-karakter diatas (R,N,T atau O), jika tidak ada karakter yang diterima maka LCD akan menampilkan: MENUNGGU DATA…
Saat karakter T diterima (tanda bahwa Sensor Level Air Tinggi aktif), maka relay akan ON. Dengan aktifnya relay otomatis Alarm akan aktif.
Prinsip kerja sensor:
Saat tidak ada air, tegangan tidak masuk ke kaki 1 ic 4n25, ini menyebabkan kaki 5 (colector) tidak terhubung ke emitor (kaki 4) / ground. Maka input microcontroller akan tetap berlogika HIGH (5 V).
Saat ada air, maka tegangan dari +9V masuk ke kaki 1. Tegangan yang masuk ini berkisar 7 volt karena besarnya resistansi air.Dengan adanya tegangan, maka led didalam IC 4n25 akan menyala sehingga mengkaktifkan sisi output. Sisi output IC 4n25 dikatakan aktif jika collector dan emitornya terhubung.
Saat kaki Colector terhubung ke Emitor ini berarti colector terhubung ke ground. Aliran arus listrik akan menuju ground. Sehingga input microcontroller berlogika LOW.
Dengan system inilah microcontroller mengetahui perubahan level air.
Seperti yang diterangkan di awal microcontroller pada sisi transmitter akan mengirim karakter sesuai kondisi inputan sensor nya.
Code program sisi Transmitter:
/*****************************************************
Chip type : ATmega8535
Program type : Application
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/#include <mega8535.h>
#include <delay.h>
#include <stdio.h>#define SCK 2 // SPI clock
#define SDO 0 // SPI Data output (RFM12B side) //MOSI
#define SDI 1 // SPI Data input (RFM12B side) //MISO
#define CS 3 // SPI SS (chip select)
#define NIRQ 4 // (PORTD)#define HI(x) PORTA |= (1<<(x))
#define LO(x) PORTA &= ~(1<<(x))
#define WAIT_NIRQ_LOW() while(PINA&(1<<NIRQ))#define LED 6
#define LED_OFF() PORTD &= ~(1<<LED)
#define LED_ON() PORTD |= (1<<LED)#define level_rendah PIND.0
#define level_normal PIND.1
#define level_tinggi PIND.2void portInit()
{
HI(CS);
HI(SDI);
LO(SCK);
PORTA.4=1;
DDRA = (1<<CS) | (1<<SDI) | (1<<SCK);
//DDRD = (1<<LED);
DDRD=0xf0;
PORTD=0x0f;
}unsigned int writeCmd(unsigned int cmd)
{
unsigned char i;
unsigned int recv;
recv = 0;
LO(SCK);
LO(CS);
for(i=0; i<16; i++) {
if(cmd&0x8000) HI(SDI); else LO(SDI);
HI(SCK);
recv<<=1;
if( PINA&(1<<SDO) ) {
recv|=0x0001;
}
LO(SCK);
cmd<<=1;
}
HI(CS);
return recv;
}void rfInit() {
writeCmd(0x80E7); //EL,EF,868band,12.0pF
writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC
writeCmd(0xA640); //frequency select
writeCmd(0xC647); //4.8kbps
writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
writeCmd(0xCED4); //SYNC=2DD4G
writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
writeCmd(0x9850); //!mp,90kHz,MAX OUT
writeCmd(0xCC17); //OB1COB0, LPX,IddyCDDITCBW0
writeCmd(0xE000); //NOT USE
writeCmd(0xC800); //NOT USE
writeCmd(0xC040); //1.66MHz,2.2V
}void rfSend(unsigned char data)
{
WAIT_NIRQ_LOW();
writeCmd(0xB800 + data);
}void main(void)
{
unsigned char data_rf;#asm("cli");
//for(i=0;i<1000;i++)for(j=0;j<123;j++);
portInit();
rfInit();// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;while (1)
{
// Place your code here
if(level_tinggi==0)data_rf='T';
else if(level_normal==0)data_rf='N';
else if(level_rendah==0)data_rf='R';
else data_rf='O';
LED_ON();
delay_ms(1000);
writeCmd(0x0000);
rfSend(0xAA); // PREAMBLE
rfSend(0xAA);
rfSend(0xAA);
rfSend(0x2D); // SYNC
rfSend(0xD4);
//Data yang akan dikirim
rfSend(data_rf);
///////////////
rfSend(0xAA); // DUMMY BYTES
rfSend(0xAA);
rfSend(0xAA);
LED_OFF();
delay_ms(100);
};
}
Code Program Receiver:
/*****************************************************
Chip type : ATmega8535
Program type : Application
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/#include <mega8535.h>
#include <delay.h>
#include <stdio.h>
#include <lcd.h>#define SCK 2 // SPI clock
#define SDO 0 // SPI Data output (RFM12B side) //MOSI
#define SDI 1 // SPI Data input (RFM12B side) //MISO
#define CS 3 // SPI SS (chip select)
#define NIRQ 4#define HI(x) PORTA |= (1<<(x))
#define LO(x) PORTA &= ~(1<<(x))
#define WAIT_NIRQ_LOW() while(PINA&(1<<NIRQ))#define ALARM PORTD.6
//#define LED 6
//#define LED_OFF() PORTD &= ~(1<<LED)
//#define LED_ON() PORTD |= (1<<LED)// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm// Declare your global variables here
char buff[16];void portInit()
{
HI(CS);
HI(SDI);
LO(SCK);
PORTA.0=1;
PORTA.4=1;
DDRA = (1<<CS) | (1<<SDI) | (1<<SCK);
DDRD = 0xff;
PORTD=0x00;
}unsigned int writeCmd(unsigned int cmd)
{
unsigned char i;
unsigned int recv;
recv = 0;
LO(SCK);
LO(CS);
for(i=0; i<16; i++) {
if(cmd&0x8000) HI(SDI); else LO(SDI);
HI(SCK);
recv<<=1;
if( PINA&(1<<SDO) ) {
recv|=0x0001;
}
LO(SCK);
cmd<<=1;
}
HI(CS);
return recv;
}void rfInit() {
writeCmd(0x80E7); //EL,EF,868band,12.0pF
writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC
writeCmd(0xA640); //frequency select
writeCmd(0xC647); //4.8kbps
writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
writeCmd(0xCED4); //SYNC=2DD4G
writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
writeCmd(0x9850); //!mp,90kHz,MAX OUT
writeCmd(0xCC17); //OB1COB0, LPX,IddyCDDITCBW0
writeCmd(0xE000); //NOT USE
writeCmd(0xC800); //NOT USE
writeCmd(0xC040); //1.66MHz,2.2V
}
/*
void rfSend(unsigned char data)
{
WAIT_NIRQ_LOW();
writeCmd(0xB800 + data);
}
*/
void FIFOReset()
{
writeCmd(0xCA81);
writeCmd(0xCA83);
}/*unsigned char rfRecv()
{
unsigned int data;
writeCmd(0x0000);
data = writeCmd(0xB000);
return (data&0x00FF);
}*/unsigned char rfRecv()
{
unsigned int data;
while(1)
{
data = writeCmd(0x0000);
if ( (data&0x8000) )
{
data = writeCmd(0xB000);
return (data&0x00FF);
}
}
}void main(void)
{
unsigned char data_rf;#asm("cli");
//for(i=0;i<1000;i++)for(j=0;j<123;j++);
portInit();
rfInit();
FIFOReset();// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;// LCD module initialization
lcd_init(16);
lcd_putsf("ALAT PENDETEKSI ");
lcd_gotoxy(0,1);
lcd_putsf(" BANJIR ");
delay_ms(2000);lcd_clear();
lcd_putsf(" MENGGUNAKAN ");
lcd_gotoxy(0,1);
lcd_putsf("KOMUNIKASI RADIO");
delay_ms(2000);lcd_clear();
lcd_putsf("Menunggu Data..");
while (1)
{
// Place your code here
data_rf = rfRecv();
FIFOReset();
lcd_clear();
if(data_rf=='O')
{
lcd_putsf("Koneksi OK..");
}
else if(data_rf=='R')
{
lcd_putsf("Level Air Rendah");
ALARM=0;
}
else if(data_rf=='N')
{
lcd_putsf("Level Air Normal");
ALARM=0;
}
else if(data_rf=='T')
{
lcd_putsf("Level Air Tinggi");
ALARM=1;
}
else
{
lcd_putsf("Koneksi Gagal");
buff[0]=data_rf;
lcd_gotoxy(0,1);
lcd_puts(buff);
}
delay_ms(1000);
lcd_clear();
lcd_putsf("Menunggu Data..");
//if(data_rf=='T')ALARM=1;
//else ALARM=0;
};
}
DOWNLOAD source code program, gambar rangkaian klik disini
Yuppss…. sekarang jangan duduk aja… cepet buat project mu…
Transmisi data memakai RFM12B ini bisa dikembangin jadi wireless data acquisition misal: membaca nilai suhu dan temperatur ato aplikasi remote control…
Let’s share… ide /saran/kritik kirim aja ke zigan@ymail.com
Copyright © AVRku.blogspot.com
makasih atas info anda
mantaf gan..
ane juga lagi buat TA ttg wireless..
transciever m receivernya kira2 harganya berapa ya??
Mantap. pakai wireles mudah ya
kunjungi blog saya.
http://iswanto.staff.umy.ac.id/ dan http://blog.umy.ac.id/iswanto
kira2 bli transmitternya dmn?
kun jungi jg yh http://www.saputro-eko.co.cc
itu bikin rangkaian sensor yg masuk ke air pake IC 4n25 gmn skemanya?
tq.