Wireless data transmission between two PIC microcontrollers using low-cost RF modules

A lot of times we need to keep track of data from a device or a sensor located in a remote location from the point where it is processed. In other situations we desire wireless solutions for ease.  Using long cables, infrared (IR) or other means are often tedious and not loss-less. Imagine collecting pH level data from a chemically lethal or toxic treatment plant where human presence is highly health hazardous. Running long cables from the pH sensor to the control or monitor station will surely introduce noisy signals and signal-to-noise ratio will thus drastically decrease. The result is erroneous data acquisition and thereby false decisions may be generated. If infrared signals or other optical means including lasers are used, they will need good obstacle-free line of sight or expensive and delicate optical fibers. Thus the solution stays in the radio frequency (RF) domain. This article talks about interfacing low cost RF modules (KST-TX01 and KST-RX806) for transmitting data between two remotely located PIC microcontrollers.

Data broadcast using RF modules

In this demo, we will see how to achieve an easy data transaction between two PIC16F877A microcontrollers using inexpensive RF modules. The theory is pretty simple and straight. It uses KST-TX01 and KST-RX806 RF modules which is a 433 MHz serial data transmitter/receiver pair. One PIC16F877A is programmed to transmit its ADC data (RA0/AN0 channel) serially using its built-in USART hardware at 1200 baud with no parity and 8-bit data stream. The PIC’s USART transmitter (TX) pin feeds the data into the data pin of the KST-TX01 which transmits it using 433 MHz ASK RF signal. On the receiving end the KST-RX806 module receives the data and its output is connected to the another PIC’s USART input pin. The second PIC is programmed to read its USART receiver (RX) pin. On both ends, two LCD displays are also connected which show the transmitted and received bytes. Since RS232 communications typically allow 8-bit data, the 8-bit A/D conversion is used here for simplicity, instead of the more common 10-bit ADC.

Transmitting unit

Receiving unit

Wireless data transmission between two PIC micros

Software

The demo codes given for the receiver and the transmitter PICs are written using CCS PCWHD compiler. The firmwares are easy to understand and needs no explanation. In CCS PCWHD, the LCD pins are defined in the lcd.c file. By default, it uses the PORTD pins (as shown in the circuit diagram above) as connections to the LCD. If you are using a different port, you need to edit the lcd.c file accordingly.

Receiving side code

#include <16F877A.h>
#device *= 16
#fuses HS, NOWDT, NOPROTECT, NOLVP, PUT
#fuses NOBROWNOUT, CPD, NODEBUG, NOWRT
#use delay(clock=10MHz)
#use rs232(baud=1200, rcv=PIN_C7, bits=8, parity=N) 

#include <lcd.c>                 

void main()
{
 byte c;
 lcd_init();
 lcd_putc("\f");
 while(true)
 {
 c=getc();
 printf(lcd_putc,"\fRx Data = %u",c);
 delay_ms(100);
 }
}

Transmitting side code

#include <16F877A.h>
#device *= 16
#device adc=8
#fuses HS, NOWDT, NOPROTECT, NOLVP, PUT
#fuses NOBROWNOUT, CPD, NODEBUG, NOWRT
#use delay(clock=10MHz)
#use rs232(baud=1200, xmit=PIN_C6, bits=8, parity=N)     

#include <lcd.c>               

void main()
{
 byte s=0;
 lcd_init();
 lcd_putc("\f");
 setup_adc_ports(adc_clock_internal);
 setup_adc(AN0);
 set_adc_channel(0);
 while(true)
 {
 read_adc(adc_start_only);
 while(!adc_done());
 s = read_adc(adc_read_only);
 lcd_gotoxy(1,1);
 printf(lcd_putc, "\fTx Data = %u" s);
 putc(s);
 delay_ms(100);
 }
}

Summary

Thus we saw that KST-TX01 and KST-RX806 RF modules are very easy to use for RF transmission and reception of data as they can be directly interfaced to the UART port of microcontrollers. However, there are few things that I noted while experimenting with them. One is, when the ADC value (8-bit in this demo) is around 250 or higher the receiver starts getting garbage data. It seems like when the data contains too many 1s, it is not recognized by the receiver which literally “believes” that the data is static. One solution could be dividing the ADC byte into two nibbles and send them separately. It will slow down the net data transmission rate but the received data will be less likely to be erroneous. It also adds an extra overhead of reconstructing the bytes from the nibbles. Similarly, if you want to use 10-bit (or more) resolution for A/D conversion, the ADC result can also be broken into two 5-bit fragments (MSB 5-bit and LSB 5-bit) before transmission. Adding three extra 0s on the MSB end of each fragment completes the transmission byte. By doing so, the numerical value of each data byte will be less than 32.

Another important fact to note is the range of the modules. Many manufactures claim ranges of up to 10m or so. In reality this may not be what they claim because of the antenna length and the quality of the modules themselves. A wire of 12 inches or so is adequate for a reasonably good wireless communication.

Lastly, I found the two RF modules perform best at 1200 baud. While data transmission at 2400 baud is also possible, it will not be error free. Baud rates more than that are not useful at all. Several improvements can be done to add more features but I have kept it for those who are willing to explore it more and use it in various purposes.

The lesson from this demo can be expanded to a wide range of applications. Here are some common applications:

  • Remote appliance controllers,
  • Wireless headsets,
  • Remote data acquisition systems,
  • Surveillance and security systems,
  • Robotics,
  • Hands free devices,
  • Digital radios,
  • X-bee and Bluetooth,
  • Navigation systems,
  • Toys and so on.
Many thanks to Shawon Shahryiar for contributing this article to Embedded Lab. He works as an Engineer in the Research and Development Cell at ELECTRO Group in Dhaka, Bangladesh. You can contact him at:

Related Posts

47 comments

Leave a Reply

Your email address will not be published. Required fields are marked *