In the above image, left one is HT12D the decoder and right one is HT12E, the encoder one. Both ICs are identical. A0 to A7 is used for special encoding. We can use microcontroller pins to control those pins and set configurations. The same configurations need to be matched on the other side. If both configurations are accurate and matched, we can receive data. These 8 pins can be connected to Gnd or VCC or left open. Whatever configurations we do in the encoder, we need to match the connection on the decoder. In this project we will left open those 8 pins for both encoder and decoder. 9 and 18 pin is VSS and VDD respectively. We can use the VT pin in HT12D as notification purposes. For this project we did not used it. The TE pin is for transmission enable or disable pin.
The important part is the OSC pin where we need to connect resistors is to provide oscillation to the encoder and decoder. The decoder needs higher oscillation than the decoder. Typically the Encoder resistor value will be 1Meg and the Decoder value is 33k. We will use those resistors for our project.
DOUT pin is the RF Transmitter data pin on HT12E and DIN pin in the HT12D is used to connect the RF module data pin.
In HT12E, AD8 to AD11 is four channel input which gets converted and serially transmitted through RF module and the exact reverse thing happens in HT12D, the serial data received and decoded, and we get 4 bit parallel output across the 4 pins D8 to D11.
Components Required:
- 2 – Bread board
- 1 – LCD 16×2
- 1 – Keypad
- HT12D and HT12E pair
- RX-TX RF Module
- 1- 10K preset
- 2 – 4.7k resistor
- 1- 1M Resistor
- 1- 33k resistor
- 2- 33pF ceramic capacitors
- 1 – 20Mhz crystal
- Bergsticks
- Few single strand wires.
- PIC16F877A MCU
- PIC18F4520 MCU
- A screw driver for controlling the frequency pot, need to be insulated from human body.
Circuit Diagram:
Circuit Diagram for Transmitter side (PIC16F877A):
![Circuit Diagram for Transmitter side using Pic-microcontorller]()
We have used PIC16F877A for Transmitting purpose. The Hex keypad connected across the PORTB and the 4 channels connected across last 4 bits of PORTD.
Pin out as follows-
1.AD11 = RD7
2.AD10 = RD6
3.AD9 = RD5
4.AD8 = RD4
Circuit Diagram for Receiver Side (PIC18F4520):
![Circuit Diagram for Receiver Side using Pic-microcontroller]()
In the above image, the Receiver circuit is shown. The LCD is connected across PORTB. We used internal oscillator of PIC18F4520 for this project. The 4 channels are connected the same way as we did before in the transmitter circuit.
This is the Transmitter side–
![PIC-to-PIC-Communication-Transmitter-side-Circuit-Hardware using Pic-microcontroller]()
And receiver side in separate breadboard–
![PIC-to-PIC-Communication-Receiver-side-Circuit-Hardware using Pic-microcontroller]()
Code Explanation:
There are two parts of the code, one is for the Transmitter and one is for the Receiver. You can download complete code from here.
PIC16F877A code for RF Transmitter:
As always first, we need to set the configuration bits in the pic microcontroller, define some macros, including libraries and crystal frequency. The AD8-AD11 port of the Encoder ic is defined as RF_TX at PORTD. You can check code for all those in the complete code given at the end.
We used two functions, void system_init(void) and void encode_rf_sender (char data).
The system_init is used for pin initialization and keyboard initializations. The keyboard initialization is called from the keypad library.
The keypad port is also defined in the keypad.h. We made the PORTD as output using TRISD = 0x00, and made the RF_TX port as 0x00 as default state.
void system_init(void){
TRISD = 0x00;
RF_TX = 0x00;
keyboard_initialization();
}
In the encode_rf_sender we have changed the 4 pin state depending on the Button pressed. We have created 16different hex values or PORTD states depending on (4×4) 16 different button pressed.
void encode_rf_sender (char data){
if(data=='1')
RF_TX=0x10;
if(data=='2')
RF_TX=0x20;
if(data=='3')
……… …. ..
…. ….
In the main function we first receive the keyboard button pressed data using switch_press_scan() function and store the data in key variable. After that we have encoded the data using encode_rf_sender() function and changing the PORTD status.
PIC18F4520 code for RF Receiver:
As always, we first set the configuration bits in PIC18f4520. Its little bit different from PIC16F877A, you can check the code in the attached zip file.
We included the LCD header file. Defined the D8-D11 port connection of Decoder IC across PORTD using #define RF_RX PORTD line, connection is same as used in the Encoder section. The LCD port declaration is also done in the lcd.c file.
#include <xc.h>
#include "supporing_cfile\lcd.h"
#define RF_RX PORTD
As stated before we are using internal oscillator for the 18F4520, we have used system_init function where we configured the OSCON register of the 18F4520 to set the internal oscillator for 8 MHz. We also set the TRIS bit for both LCD pins and the Decoder pins. As HT–12D provides output at D8-D11 ports, we need to configure the PORTD as input to receive the output.
void system_init (void){
OSCCON = 0b01111110; // 8Mhz, , intosc
//OSCTUNE = 0b01001111; // PLL enable, Max prescaler 8x4 = 32Mhz
TRISB = 0x00;
TRISD = 0xFF; // Last 4 bit as input bit.
}
We configured the OSCON register at 8 MHz, also made port B as output and port D as input.
Below function is made using the exact reverse logic used in the previous transmitter section. Here we get the same hex value from the port D and by that hex value we identify which switch was pressed in the transmitter section. We can identify each key press and submit the correspondent character to the LCD.
void rf_analysis (unsigned char recived_byte){
if(recived_byte==0x10)
lcd_data('1');
if(recived_byte==0x20)
lcd_data('2');
if(recived_byte==0x30)
……. ….. …
… ………..
The lcd_data is called from the lcd.c file.
In the main function we first initialize the system and LCD. We took a variable byte, and stored the hex value received from port D. Then by the function rf_analysis we can print the character on LCD.
void main(void) {
unsigned char byte = 0;
system_init();
lcd_init();
while(1){
lcd_com(0x80);
lcd_puts("CircuitDigest");
lcd_com (0xC0);
byte = RF_RX;
rf_analysis(byte);
lcd_com (0xC0);
}
return;
}
Before running it, we have tuned the circuit. First we have pressed the ‘D’ button in the keypad. So, the 0xF0 is being continuously transmitted by the RF transmitter. We then tuned the receiver circuit until the LCD shows the character ‘D’. Sometimes the module is tuned properly from the manufacturer, sometimes it is not. If everything is properly connected and not getting the button pressed value in the LCD then there are possibilities that the RF Receiver is not tuned. We have used the Insulated screwdriver for decreasing wrong tuning possibilities due to our body inductance.
This is how you can interface the RF Module to the PIC Microcontroller and communicate between two PIC microcontrollers wirelessly using RF Sensor.
You can download the complete code for Transmitter and Receiver from here, also check the demonstration Videobelow.