Subscribe via email

Enter your email address:

Delivered by FeedBurner

Deteksi Level Air via RFM12B

clip_image002[6]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

image 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

TX(.JPG)

Receiver

RX(JPG)

Alur Kerja:

Saat sensor aktif (terhubung ke +9V), maka Transmitter akan mengirim karakter-karakter khusus yang mewakili setiap sensor.

  1. Jika sensor Level Air Rendah aktif karakter yang dikirimkan adalah R
  2. Jika sensor Level Air Normal aktif karakter yang dikirimkan adalah N
  3. 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:

clip_image002[8]

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).

 

 

clip_image002[10]

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.2

void 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=2DD4G
  writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
  writeCmd(0x9850); //!mp,90kHz,MAX OUT
  writeCmd(0xCC17); //OB1COB0, LPX,IddyCDDITCBW0
  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=2DD4G
  writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
  writeCmd(0x9850); //!mp,90kHz,MAX OUT
  writeCmd(0xCC17); //OB1COB0, LPX,IddyCDDITCBW0
  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 [email protected]

 

Copyright  ©  AVRku.blogspot.com

Comments :

6 comments to “Deteksi Level Air via RFM12B”

makasih atas info anda

Anonim mengatakan...
on 

mantaf gan..
ane juga lagi buat TA ttg wireless..
transciever m receivernya kira2 harganya berapa ya??

Anonim mengatakan...
on 

Mantap. pakai wireles mudah ya
kunjungi blog saya.
http://iswanto.staff.umy.ac.id/ dan http://blog.umy.ac.id/iswanto

iswanto mengatakan...
on 

kira2 bli transmitternya dmn?

Fariz_oloy mengatakan...
on 

kun jungi jg yh http://www.saputro-eko.co.cc

Anonim mengatakan...
on 

itu bikin rangkaian sensor yg masuk ke air pake IC 4n25 gmn skemanya?

tq.

Anonim mengatakan...
on