Summary of 433MHz RF remote control system based on PIC microcontroller
This article details a 5-channel wireless remote control system built using two PIC18F4550 microcontrollers and low-cost 433MHz RF modules. The transmitter uses five pushbuttons to send NEC protocol signals, while the receiver decodes these signals to toggle five LEDs. The project utilizes an internal 8MHz oscillator and is programmed in CCS C.
Parts used in the 5-Channel RF Remote Control:
- PIC18F4550 microcontroller (x2)
- 433MHz RF transmitter module
- 433MHz RF receiver module
- Pushbuttons (5 units for transmitter)
- LEDs (5 units for receiver)
- CCS PIC C compiler PCWHD version 5.0.51
The used RF modules in this project are cheap and easy to use with any microcontroller. These modules are shown below with pin configuration:

Communication protocol:
In this RF project data is transmitted from the transmitter circuit to the receiver circuit using NEC protocol. The NEC protocol uses pulse distance encoding of the bits. Each pulse is a 562.5µs long.
Logic 0: 562.5µs pulse burst followed by a 562.5µs space, with a total transmit time of 1125µs (562.5 x 2).
Logic 1: a 562.5µs pulse burst followed by a 1687.5µs (562.5 x 3) space, with a total transmit time of 2250µs (562.5 x 4).
The complete extended NEC protocol message is started by 9ms burst followed by 4.5ms space which is then followed by the Address and Command. The address is 16-bit length and the command is transmitted twice (8 bits + 8 bits) where in the second time all bits are inverted and can be used for verification of the received message. The following drawing shows an extended NEC message example.
5-Channel RF remote control using PIC18F4550 microcontroller:
This 433MHz RF remote control system has 2 circuits which are transmitter circuit which transmits the RF signals and receiver circuit which receives the RF signals.
RF Transmitter circuit:
The following image shows the RF transmitter circuit schematic diagram where PIC18F4550 microcontroller is used.
In the circuit there are five (5) pushbuttons as shown, each pushbutton sends a different RF signal code via an RF transmitter.
PIC18F4550 internal oscillator is used (8MHz) and MCLR is disabled.
RF Transmitter using PIC18F4550 CCS C code:
The following C code is the full code used for the transmitter circuit microcontroller which is written with CCS PIC C compiler PCWHD version 5.0.51.
// 5-Channel RF remote control using PIC18F4550 transmitter CCS C code // http://ccspicc.blogspot.com/ // [email protected] #include <18F4550.h> #fuses NOMCLR INTRC_IO #use delay(clock = 8000000) #use fast_io(B) #use fast_io(D) void send_signal(unsigned int32 number){ int8 i; // Send 9ms pulse output_high(PIN_D0); delay_ms(9); // Send 4.5ms space output_low(PIN_D0); delay_us(4500); // Send data for(i = 0; i < 32; i++){ // If bit is 1 send 560us pulse and 1680us space if(bit_test(number, 31 - i)){ output_high(PIN_D0); delay_us(560); output_low(PIN_D0); delay_us(1680); } // If bit is 0 send 560us pulse and 560us space else{ output_high(PIN_D0); delay_us(560); output_low(PIN_D0); delay_us(560); } } // Send end bit output_high(PIN_D0); delay_us(560); output_low(PIN_D0); delay_us(560); } void main(){ setup_oscillator(OSC_8MHZ); // Set internal oscillator to 8MHz setup_adc_ports(NO_ANALOGS); // Configure AN pins as digital output_b(0); // PORTB initial state set_tris_b(0x1F); // Configure RB0-to-RB4 as inputs port_b_pullups(TRUE); // Enable PORTB internal pull-ips output_d(0); // PORTD initial state set_tris_d(0); // Configure PORTD pins as outputs while(TRUE){ while(!input(PIN_B0)){ send_signal(0x40BF00FF); delay_ms(500); } while(!input(PIN_B1)){ send_signal(0x40BF807F); delay_ms(500); } while(!input(PIN_B2)){ send_signal(0x40BF40BF); delay_ms(500); } while(!input(PIN_B3)){ send_signal(0x40BF20DF); delay_ms(500); } while(!input(PIN_B4)){ send_signal(0x40BFA05F); delay_ms(500); } } }
RF Receiver circuit:
Receiver circuit schematic diagram is shown below.
PIC18F4550 internal oscillator is used (8MHz) and MCLR is disabled.
In the receiver circuit there are 5 LEDs, each LED is controlled by one pushbutton on the transmitter circuit. The RF receiver receives RF signals transmitted from the RF transmitter on the transmitter circuit.
RF Receiver using PIC18F4550 CCS C code:
The NEC message has 32 bits which are divided into address (16 bits), command (8 bits) and inverted command (8 bits).
The microcontroller waits until the RF receiver receives an RF signal which makes RB0 goes from logic 0 to logic 1 and the command used is:
while(!input(PIN_B0));
After that a function named remote_read() is called, this function checks if the received signal has NEC protocol form all the time with a resolution of 10us then returns the received code.
// 5-Channel RF remote control using PIC18F4550 receiver CCS C code // http://ccspicc.blogspot.com/ // [email protected] #include <18F4550.h> #fuses NOMCLR INTRC_IO #use delay(clock = 8000000) #use fast_io(B) unsigned int32 remote_code; short remote_read(){ int8 i; unsigned int16 count = 0; // Check 9ms pulse (remote control sends logic high) while((input(PIN_B0) == 1) && (count < 600)){ count++; delay_us(10);} if( (count > 599) || (count < 500)) // NEC protocol? return FALSE; count = 0; // Check 4.5ms space (remote control sends logic low) while((input(PIN_B0) == 0) && (count < 300)){ count++; delay_us(10);} if( (count > 299) || (count < 220)) // NEC protocol? return FALSE; // Read message (32 bits) for(i = 0; i < 32; i++){ count = 0; while((input(PIN_B0) == 1) && (count < 45)){ count++; delay_us(10);} if( (count > 44) || (count < 25)) // NEC protocol? return FALSE; count = 0; while((input(PIN_B0) == 0) && (count < 120)){ count++; delay_us(10);} if( (count > 119) || (count < 25)) // NEC protocol? return FALSE; if( count > 60) // If space width > 1ms bit_set(remote_code, (31 - i)); // Write 1 to bit (31 - i) else // If space width < 1ms bit_clear(remote_code, (31 - i)); // Write 0 to bit (31 - i) } return TRUE; } void main(){ setup_oscillator(OSC_8MHZ); // Set internal oscillator to 8MHz setup_adc_ports(NO_ANALOGS); // Configure AN pins as digital output_b(0); // PORTB initial state set_tris_b(1); // Configure RB0 as digital input pin while(TRUE){ while(!input(PIN_B0)); // Wait until RB0 pin goes high if(remote_read()){ if(remote_code == 0x40BF00FF) output_toggle(PIN_B1); if(remote_code == 0x40BF807F) output_toggle(PIN_B2); if(remote_code == 0x40BF40BF) output_toggle(PIN_B3); if(remote_code == 0x40BF20DF) output_toggle(PIN_B4); if(remote_code == 0x40BFA05F) output_toggle(PIN_B5); } } }
5-Channel RF remote control using PIC18F4550 microcontroller video:
The following video shows a prototype hardware circuit for this project.
In this video I used PORTD instead of PORTB for the 5 outputs of the receiver circuit.
Source : 433MHz RF remote control system based on PIC microcontroller
- What microcontrollers are used in this project?
The project uses two PIC18F4550 microcontrollers. - How does the communication protocol work?
Data is transmitted using the NEC protocol with pulse distance encoding of bits. - What frequency do the RF modules operate at?
The project uses cheap and easy-to-use 433MHz RF modules. - How many channels does this remote control system support?
The system supports 5 channels controlled by five pushbuttons on the transmitter. - What oscillator frequency is configured for the microcontroller?
The internal oscillator is set to 8MHz. - How is the received message verified?
The command is transmitted twice where the second time all bits are inverted for verification. - Which programming language and compiler are used?
The code is written in CCS C using PCWHD version 5.0.51. - What happens when a button is pressed on the transmitter?
Each pushbutton sends a different unique RF signal code via the transmitter.


