A modular PIC16F887-based embedded system that controls a wall fan with IR remote support, push-button input, visual LED indicators, PWM buzzer, and TRIAC-based speed/swing control.
This project implements a remote-controlled fan using the PIC16F887 microcontroller. It supports infrared remote decoding, manual push-buttons, LED feedback indicators, and a delay-off timer.
-
🎛️ TRIAC-Based Fan Speed Control
Provides three discrete speed levels (LOW, MEDIUM, HIGH) and OFF. -
🌬️ Swing Control
Toggle swing function via IR remote or push button. -
📡 IR Remote Decoder
Decodes IR commands from a TSOP1838 sensor. Supports ON, OFF, SWING, and TIMER. -
⏳ Delay-Off Timer
User-configurable 30/60/120-minute shutdown via IR remote. -
🔔 PWM Buzzer
Generates tones as audible feedback for remote/button actions. -
💡 LED Indicators
Show active fan speed and swing with dedicated LEDs. -
🔘 Manual Push Buttons
Hardware buttons on PORTB provide ON, OFF, and SWING control as a fallback or supplement to the remote. -
🔄 Robust Interrupt Handling
External interrupt for IR, IOCB for buttons, Timer0 for periodic tasks, and Timer2 for PWM. -
⚡ Clean Modular Codebase
Professionally structured with split.h
and.c
files for each peripheral/feature.
-
IR Remote Input
- External interrupt captures IR edges.
- Timer1 timestamps are stored and processed by the IR decoder.
- Decoded commands are passed to
admin_functions
.
-
Manual Button Input
- IOCB (Interrupt-On-Change) detects button presses.
- Debounced and processed identically to IR commands.
-
Admin Functions
- Central module that updates fan speed, swing, and timer state.
- Controls LEDs, buzzer, and TRIACs accordingly.
-
TRIAC Control
- Discrete TRIACs drive fan coils for speed and swing.
- Outputs are active-low for safe operation.
-
Delay-Off Timer
- Implemented in software using Timer0 ticks.
- Shuts down fan after selected timeout.
-
PWM Buzzer
- Uses CCP2 with Timer2 to generate feedback tones.
- Microcontroller: PIC16F887 (20 MHz crystal)
- IR Receiver: TSOP1838 (38 kHz carrier)
- TRIAC Drivers: 4 output channels (fan speed coils + swing)
- Push Buttons: ON, OFF, SWING on PORTB
- LEDs: Speed (3) and Swing indicators
- Buzzer: Driven via PWM (CCP2 on RC1)
remote-fan-controller/
├─ assets/ # Images etc.
│ └─ image.png
├─ include/ # Header files
│ ├─ admin_functions.h
│ ├─ blink_swing.h
│ ├─ button_handler.h
│ ├─ debug_support.h
│ ├─ decoder_buffer.h
│ ├─ delay_ms.h
│ ├─ delay_off.h
│ ├─ external_interrupt_conf.h
│ ├─ io_definitions.h
│ ├─ iocb_config.h
│ ├─ ir_definitions.h
│ ├─ ir_functions.h
│ ├─ pwm_config.h
│ ├─ timer0_conf.h
│ ├─ timer1_conf.h
│ ├─ timer2_config.h
│ ├─ triac_control.h
│ ├─ uart_conf.h
│ └─ uart_support.h
├─ src/ # Source files
│ ├─ admin_functions.c
│ ├─ blink_swing.c
│ ├─ button_handler.c
│ ├─ debug_support.c
│ ├─ decoder_buffer.c
│ ├─ delay_ms.c
│ ├─ delay_off.c
│ ├─ external_interrupt_conf.c
│ ├─ io_definitions.c
│ ├─ iocb_config.c
│ ├─ ir_functions.c
│ ├─ pwm_config.c
│ ├─ timer0_conf.c
│ ├─ timer1_conf.c
│ ├─ timer2_config.c
│ ├─ triac_control.c
│ ├─ uart_conf.c
│ └─ uart_support.c
├─ main.c # Main entry point
├─ README.md # This file
└─ LICENSE # MIT License
This project uses MPLAB X IDE with the XC8 compiler.
- Open MPLAB X IDE.
- Create a new XC8 project for PIC16F887.
- Add all
.c
files to Source Files. - Add all
.h
files to Header Files. - Set project properties:
- Device: PIC16F887
- Compiler: XC8
- Clock: 20 MHz (HS Oscillator)
- Build and flash using a PIC programmer (e.g., PICkit 3/4).
- All header and source files are written with portability in mind
- Configuration bits (
#pragma config
) are already set insidemain.c
. - No additional MPLAB settings are required apart from including all files in the project.
- EEPROM-based state retention (restore last fan speed on power-up).
- Additional IR remote buttons for extended modes.
- UART debug console for easier monitoring.
- Auto-restart after brown-out or watchdog reset.
🪪 License: MIT © Lakmal Weerasinghe